Google Chart Geo Chart Quiz Beep Tutorial

Google Chart Geo Chart Quiz Beep Tutorial

Google Chart Geo Chart Quiz Beep Tutorial

We’ve long had on our minds a wish to incorporate a beep sound into quiz scenarios, and we’re revisiting this, again, for us, trying to get this going using the Geographical Quiz featuring in Google Chart Image Chart Map Chart Quiz Tutorial.

Why we feel a beep would be good here is that a user can use the beep while multitasking, and be told when to focus back on the quiz, while doing other things, perhaps, and the beep patterns can tell them …

  1. whether they are correct
  2. when the next question’s left hand map hint has been loaded

… while they are doing those other things, perhaps.

A beep is no big deal, right?! No, it is not such a big deal on non-mobile, true, but on mobile, it is a nightmare! Because …

  1. ever since this web browser approach on mobile, of only allowing audio (and/or video) play operations off a real user click “origin”, the task for mere non-Spotify mortals (and even they click, really, at least once) is more tortuous … and less of a pain, but a tad annoying, is that …
  2. Safari (web browser) not playing audio/wav files, so we looked around and came upon this excellent link, thanks, to get an MP3 beep

… all hold us up.

To get a kludgy solution on mobile we opted to …

  • overlay a dropdown (select) element the user uses to answer (which we later improved by overlaying a new “Beep” checkbox initially hidden from view, which we’re calling “non kludgy”), in the quiz … with an …
  • audio element positioned so that …
    1. mobile user can’t help but see it … and …
    2. they choose whether or not to involve audio beeps by clicking the audio element at a time of their choosing, or not, knowing …

    … there are still ways to get to the underlayed dropdown to answer the quiz question …

    function overselceqwq() {
    if (document.getElementById('divselcq').innerHTML.indexOf('<audio') == -1) {
    //document.getElementById('divselcq').innerHTML+='1:' + navigator.userAgent + '<br>';
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPod|iPad|Opera Mini|IEMobile/i) && 1 == 1) {
    //document.getElementById('divselcq').innerHTML+='01:' + navigator.userAgent + '<br>';
    rectisa=document.getElementById('selceqwq').getBoundingClientRect();
    //document.getElementById('divselcq').innerHTML+='11:' + navigator.userAgent + '<br>';
    if (1 == 11) {
    document.getElementById('divselcq').innerHTML+='<audio id=aselwq style="visibility:' + hidden + ';opacity:0.4;z-index:876;position:absolute;top:' + eval(-95 + eval('' + rectisa.top)) + ('px;left:' + eval(eval(0.55 * eval('' + rectisa.width)) + eval('' + rectisa.left))).replace('NaN','') + ('px;width:' + eval(0.10 * eval('' + rectisa.width))).replace('NaN','') + 'px;height:' + rectisa.height + 'px;' + '" type=audio/mp3 onplay="this.muted(false); setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); hidden=' + "'hidden'" + '; document.getElementById(' + "'audios'" + ').style.visibility=' + "'visible'" + '; document.getElementById(' + "'aselwq'" + ').style.display=' + "'none'" + '; document.getElementById(' + "'aselwq'" + ').style.visibility=' + "'hidden'" + '; },2000);" onmousedown="if (event.currentTarget == this) { this.muted=!this.muted; }" ontouchstart="if (event.currentTarget == this) { this.muted=!this.muted; }" onclick="if (event.currentTarget == this) { this.muted=!this.muted; setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); document.getElementById(' + "'audios'" + ').style.visibility=' + "'visible'" + '; document.getElementById(' + "'aselwq'" + ').style.display=' + "'none'" + '; }, 2000); }" controls muted><source type=audio/mp3 src="/beep.mp3"></source></audio>';
    } else if (1 == 1) {
    setTimeout(function(){
    rectisa=document.getElementById('audios').getBoundingClientRect();
    document.getElementById('divselcq').innerHTML+='<audio id=aselwq style="visibility:' + hidden + ';opacity:0.4;z-index:876;position:absolute;top:' + eval(-20 + eval('' + rectisa.top)) + ('px;left:' + eval(eval(10 + eval('' + rectisa.width)) + eval('' + rectisa.left))).replace('NaN','') + ('px;width:' + eval(1.0 * eval('' + rectisa.width))).replace('NaN','') + 'px;height:' + rectisa.height + 'px;' + '" type=audio/mp3 onplay="this.muted(false); setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); hidden=' + "'hidden'" + '; document.getElementById(' + "'audios'" + ').style.visibility=' + "'visible'" + '; document.getElementById(' + "'aselwq'" + ').style.display=' + "'none'" + '; document.getElementById(' + "'aselwq'" + ').style.visibility=' + "'hidden'" + '; },2000);" onmousedown="if (event.currentTarget == this) { this.muted=!this.muted; }" ontouchstart="if (event.currentTarget == this) { this.muted=!this.muted; }" onclick="if (event.currentTarget == this) { this.muted=!this.muted; setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); document.getElementById(' + "'audios'" + ').style.visibility=' + "'visible'" + '; document.getElementById(' + "'aselwq'" + ').style.display=' + "'none'" + '; }, 2000); }" controls muted><source type=audio/mp3 src="/beep.mp3"></source></audio>';
    }, 3000);
    } else {
    document.getElementById('divselcq').innerHTML+='<audio onload=this.muted(true); id=aselwq style="visibility:hidXden;opacity:0.2;z-index:876;position:absolute;top:' + eval(4 + eval('' + rectisa.top)) + ('px;left:' + eval(eval(0.80 * eval('' + rectisa.width)) + eval('' + rectisa.left))).replace('NaN','') + ('px;width:' + eval(0.10 * eval('' + rectisa.width))).replace('NaN','') + 'px;height:' + rectisa.height + 'px;' + '" type=audio/wav onplay="this.muted(false); setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); },2000);" onmousedown="this.muted(false);" ontouchdown="this.muted(false); " onclick="setTimeout(function(){ document.getElementById(' + "'selceqwq'" + ').click(); }, 2000);" controls><source type=audio/wav src="data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU="></source></audio>';
    }
    //document.getElementById('divselcq').innerHTML+='111:' + document.getElementById('aselwq').outerHTML.replace(/\</g,'<').replace(/\>/g,'>') + '<br>';
    //document.getElementById('divselcq').innerHTML+='<button id=bselwq style="background-color:transparent;z-index:1876;position:absolute;top:' + rectisa.top + 'px;left:' + rectisa.left + 'px;width:' + rectisa.width + 'px;height:' + rectisa.height + 'px;' + '" type=audio/wav onclick="beep(); document.getElementById(' + "'selceqwq'" + ').click();"></button>';
    }
    }
    }

    function mbeep() {
    if (useaudios) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPod|iPad|Opera Mini|IEMobile/i)) {
    if (top.document.getElementById('aselwq')) {
    top.document.getElementById('aselwq').play();
    } else {
    //var snd = new Audio("data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
    var snd = new Audio("/beep.mp3"); // "data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
    snd.play();
    setTimeout(beep, 5000);
    }
    }
    }
    }

    function beep() {
    if (useaudios) {
    if (top.document.getElementById('aselwq')) {
    top.document.getElementById('aselwq').play();
    } else {
    var snd = new Audio("/beep.mp3"); // "data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
    snd.play();
    }
    }
    }

    function beeptwo() {
    beep();
    setTimeout(function(){
    beep();
    }, 100);
    }

    function beepthree() {
    beep();
    setTimeout(function(){
    beep();
    }, 100);
    setTimeout(function(){
    beep();
    }, 200);
    setTimeout(function(){
    beep();
    }, 300);
    }

    function beepDoubleThree() {
    beepthree();
    setTimeout(function(){
    beepthree()
    }, 500);
    }

Codewise …

… you might want to revisit, yourself!


Previous relevant Google Chart Image Chart Map Chart Quiz Tutorial is shown below.

Google Chart Image Chart Map Chart Quiz Tutorial

Google Chart Image Chart Map Chart Quiz Tutorial

There is an expression so apt for today’s situation. But we hate it, so … no … we’ll say instead …

Our fault mainly, not Google’s fault only

… regarding yesterday’s …

However, this last one both needs more “wading through data” and “consideration” because it seems to be at Google Charts that not even the national boundary is shown when this regional data is not recognized.

We discovered today, that fallback colours directed towards an overall country code at the end of the URL regional colour entry list, is the way around some of the issue, that some meaning now we can get a country boundary showing, but still, for some countries, Google Charts, with its Image Chart Map Chart, will not show regional boundaries as you might see defined at Wikipedia for some ISO 3166-2 regional codes they have recorded.

So, what’s that got to do with quizzes? Well, the quiz got us interested in these colour mappings, and discovering how those mappings worked led us to this discovery. We hope colour blind people don’t suffer because our Country Regional Quiz functionality could easily be called …

Name the Red Region Quiz

Yes, if the user chooses the new “Quiz” input submit button modus operandi we arrange …

  • to leave out any legends
  • randomly pick a region which is coloured red … and now blue represents unaccounted for country parts not assigned a region and green represents the rest of the world and the oceans are as they ever were … and …
  • after a while we ask the user for their guess as to what this red region’s name is

Good ol’ “colour coding”! What did we do when the world was not colourful? Oops … [expression we hate, again, fits here] … my mistake. We wouldn’t have been around. But we digress.

Simple premise, building on yesterday’s Google Chart Image Chart Map Chart Context Tutorial, but surprisingly involved in our changed third draft image_chart.php PHP web application for you to try, below, perhaps


Previous relevant Google Chart Image Chart Map Chart Context Tutorial is shown below.

Google Chart Image Chart Map Chart Context Tutorial

Google Chart Image Chart Map Chart Context Tutorial

Onto yesterday’s Google Chart Image Chart Map Chart Primer Tutorial start with Google Charts Image Chart Map Chart interfacing, today we’ve come at it from two subcategories relating to fallback positions and “context” …

  • add Geo Chart and Map Chart optionally viewed details/summary iframes showing country TimeZone position data
  • add a mechanism that if we can determine a country’s ideal range of latitude,longitude “box” view, as we found GADM could help us with, thanks, we can flag that

    $ourtzlist=" ...<option value=\"Asia/Shanghai\" title=\"17,82,55,133\" data-geo=\"31.23333,121.46666,CST,CN,+8\">Asia/Shanghai</option><option value=\"Asia/Singapore\" data-geo=\"1.28333,103.85,+08,SG,+8\">Asia/Singapore</option> ...";

    … in the data

However, this last one both needs more “wading through data” and “consideration” because it seems to be at Google Charts that not even the national boundary is shown when this regional data is not recognized.

The first one, though, is useful in our changed second draft image_chart.php PHP web application for you to try, below, perhaps


Previous relevant Google Chart Image Chart Map Chart Primer Tutorial is shown below.

Google Chart Image Chart Map Chart Primer Tutorial

Google Chart Image Chart Map Chart Primer Tutorial

We hope today’s work does not confuse terms, because we’re exploring a new area of Google Charts functionality today they refer to as …

  • Google Charts Image Charts … and you’ll see there lots of suboptions we’ll explain a bit more about later, and all this is separate functionality to …
  • Google Charts Map Chart … and …
  • Google Charts Geo Chart

… and, as of today, we interface to all three categories of Google Charts above, with three separate PHP web applications.

So, what’s the potential confusion? Well, we start out today interfacing to an Image Chart suboption called “Map Chart”, but not the one above, because its look is more in keeping with what the “Geo Chart” above achieves. We’ve written a web application, here, to show regional places within a country (via its 2 letter code) if this has been catered for by Google Charts, and for the most part, that is the case.

And so, on the same theme as yesterday’s Google Chart Geo Chart Zoom In Quiz Translate Tutorial, and thanks to Wikipedia for regional code lookups, we would welcome you to try out our “proof of concept” first draft image_chart.php PHP web application for you to try, below, perhaps …


Previous relevant Google Chart Geo Chart Zoom In Quiz Translate Tutorial is shown below.

Google Chart Geo Chart Zoom In Quiz Translate Tutorial

Google Chart Geo Chart Zoom In Quiz Translate Tutorial

You could say the way we navigate to our recent …

World Quiz

… from our …

Geo Chart Interfacer

… in the web application as of yesterday’s Google Chart Geo Chart Zoom In Quiz Hints Tutorial was a bit cryptic, or convoluted, the way at a first prompt window we’d change an entry from the default My World Survey to My World Quiz or even to click that button that we’d arranged in this blog posting thread. Nevertheless, we were a bit loathe to change the arrangements, until we ran into problems involving today’s work of …

Adding a Google Translate layer on top of the World Quiz

… to facilitate some Internationalization (ie. language translation from English to non-English) into the mix. Yes, our PHP caused problems interfacing to Google Translate. So, what was our approach? We took a snapshot (ie. web browser View -> Page Source) at a point after the convolutions above, and worked off that to introduce a new code file member. Welcome …

… via our proof of concept geochart.html clientside only web application version (or the old access approach in all these changes to geo_chart.php PHP web application still works). Any downside doing this? A little, in that within a Google Translate “bubble” we could not work the Wikipedia images hint part of the logic. Also, you may run into problems with SVG image backgrounds using an svg+xml protocol, or we may just have been having a bad day?! So sad.


Previous relevant Google Chart Geo Chart Zoom In Quiz Hints Tutorial is shown below.

Google Chart Geo Chart Zoom In Quiz Hints Tutorial

Google Chart Geo Chart Zoom In Quiz Hints Tutorial

Yesterday’s Google Chart Geo Chart Zoom In Quiz Aesthetics Tutorial showed us …

  • using a web inspector to dynamically change CSS styling in place preparatory to making a permanent change … well, today, we’re here to reiterate …
  • using a web inspector can help with a myriad of Javascript logic errors or debugging, as well

… and we do that today adding hints to all these changes to geo_chart.php Geo Chart interfacer at this live run World Quiz web application link or click a button down below.

Do the hints look familiar? Take a read of Javascript Lazy Evaluation Country Game Hints Tutorial and it all might come back to you!


Previous relevant Google Chart Geo Chart Zoom In Quiz Aesthetics Tutorial is shown below.

Google Chart Geo Chart Zoom In Quiz Aesthetics Tutorial

Google Chart Geo Chart Zoom In Quiz Aesthetics Tutorial

We recently revisited the PHP web application we call …

Google Chart Geo Chart Zoom In Quiz

… last talked about at Google Chart Geo Chart Zoom In Quiz Sharing Tutorial, and noticed a bit of ugliness regarding its CSS styling, specifically related to the “too large” border-radius values we’d applied to the twin iframes cutting off wording in their bottom left corner.

This issue is an …

  • aesthetics, only …
  • CSS styling

… one … queue the Web Inspector! How come? Well, web inspectors, such as Google Chrome web browser’s one, allow you to …

  • in place … on our macOS MAMP local Apache/PHP/MySql web server system …
  • dynamically tweak …
  • CSS styling … especially good with inline CSS style syntax, that we happen to be very fond of too … so as to be able to …
  • make the changes for you to optionally re-tweak … ephemerally

… on a test system (ours being a macOS MAMP local Apache/PHP/MySql web server one) ahead of uploading and committing to a permanent change up at the live and public RJM Programming web server domain.

Take a look at how we went about what went into the aesthetically tweaked geo_chart.php Geo Chart interfacer at this live run link, where we remind you again, a substitution of “Survey” by “Quiz” at the first title prompt can show the “My World Zoom In Quiz” in a new window or click a button down below.


Previous relevant Google Chart Geo Chart Zoom In Quiz Sharing Tutorial is shown below.

Google Chart Geo Chart Zoom In Quiz Sharing Tutorial

Google Chart Geo Chart Zoom In Quiz Sharing Tutorial

Adding functionality to yesterday’s Google Chart Geo Chart Zoom In Quiz Tutorial we see an opportunity to …

  • add an element of “when” functionality onto the “where” strengths of the Google Chart Geo Chart recent work, via PHP TimeZones and interfacing to the work of the recent Looks Nice Nearby Speech to Text Game Video Tutorial … as well as …
  • means by which to share or collaborate with the “My World Zoom In Quiz” … via …
    1. email 📧 (via inline HTML PHP mail) … or …
    2. SMS 📟 (via “a” tag href=sms: link)

… and that last SMS methodology brought into focus our wish not to allow, yet, a URL approach to get directly to this new “My World Zoom In Quiz” (although we may change this strategy into the future). So, how to apply security over the use of a URL such as …

https://www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?wqperspective=Monday+10+Feb+2020+17:57:15.7182

… not linked, above, because there is no point. We have already clicked it in an SMS we got sent, and that nullifies its use from then on? Huh?! Yes, we use the PHP itself, as we are fond of doing, storing (a form of) that “Monday+10+Feb+2020+17:57:15.7182” away as a comment in amongst the PHP code and, hence, “file_get_contents” checkable by its or some other PHP code for its existence (as well as the “file_put_contents” based clean up removal of said comment after the SMSee’s (body) link is ever clicked), as the security check for whether we navigate to the “My World Zoom In Quiz” (bringing up that last correct answer) via an SMS body URL link, clicked by an SMSee. And that collaborator can do the same thing back to the original sender for the next wrong answer’s similar 📟 emoji button press instigation of this sharing and collaboration Javascript logic …


function smswho() {
if (smsorig == '') { smsorig=document.getElementById('smssend').href.split('0000')[0]; }
if (smsdateorig == '') { smsdateorig=document.getElementById('smsdate').value; }
var smsto=prompt('SMS to?', document.getElementById('smssend').href.split('sms:')[1].split('?')[0]);
if (smsto == null) { smsto = ''; }
if (smsto.trim() != '') {
document.getElementById('smsdate').value=smsdateorig + '.' + gsv.substring(0,1).charCodeAt(0) + gsv.substring(1).substring(0,1).charCodeAt(0);
document.getElementById('smsbut').click();
document.getElementById('smssend').href=(smsorig + '' + gsv.substring(0,1).charCodeAt(0) + gsv.substring(1).substring(0,1).charCodeAt(0)).replace('sms:?','sms:' + smsto + '?');
document.getElementById('smssend').click();
}
}


function emailwho() {
var emto=prompt('Email to?', document.getElementById('emailto').value);
if (emto == null) { emto = ''; }
if (emto.indexOf('@') != -1) {
document.getElementById('emailto').value=emto;
document.getElementById('hcont').value='<html><body><form action=' + document.URL + ' method=POST><input type=hidden value=' + gsv + ' name=wqperspective></input><input type=submit value=\"My World Zoom In Quiz\" style=\"background-color:yellow;\"></input></form></body></html>';
document.getElementById('iemail').click();
}
}

… in the context of all these changes to geo_chart.php Geo Chart interfacer at this live run link, where we remind you again, a substitution of “Survey” by “Quiz” at the first title prompt can show the “My World Zoom In Quiz” in a new window.


Previous relevant Google Chart Geo Chart Zoom In Quiz Tutorial is shown below.

Google Chart Geo Chart Zoom In Quiz Tutorial

Google Chart Geo Chart Zoom In Quiz Tutorial

Today we’re combining …

… to create another form of quiz (we think of as “My World Zoom In Quiz”) the user can navigate to via the way they answer that first title prompt (substituting “Survey” with “Quiz”). You might prefer to think of it as the “Geographical Perspective Quiz” with a degree of difficulty, often, because to see a “Zoomed In” display of a country or region can be disorienting and challenging to recognize. And so, for incorrect dropdown answers, we provide a “zoomed out” world view of where that “zoomed in” view sits (like an inset).

In order to show you this below please click

Again, a bit of a different tack to yesterday with the reworked geo_chart.php Geo Chart interfacer at this live run link, where a substitution of “Survey” by “Quiz” at the first title prompt can show the “My World Zoom In Quiz” (like above) in a new window.


Previous relevant Google Chart Geo Chart Small Region Tutorial is shown below.

Google Chart Geo Chart Small Region Tutorial

Google Chart Geo Chart Small Region Tutorial

Meanwhile, resuming our dreams of Andorra, there must be hundreds of readers there a bit sick of us going on and on and on and on and on about our Google Chart Geo Chart interfacing Quizzes and the use of complex “width” (and “height”) prompt user interactions. After all, we came onto this topic more to do with “small countries”. Well, let’s go back to that and let’s say …

  • as well as the “markers” mode (geographicals) latitude and longitude (helped out by PHP TimeZone places) way of signifying the position of a small country on a world or continent map … always, there behind the scenes, set up ages ago, was the interfacing we had set up to …
  • connect with the Google Chart “smarts” regarding “region” mapping to be able to hone in on a “region” (which can mean a whole country too) of interest

… and that means, today, we revisit our imaginary jaunts in Andorra setting out from the big smoke of …


Andorra la Vella

… to the border tranquillity of …


Pas de la Casa

… in the scenario of today’s tutorial picture … honing in on the user interaction before the width one (yayyyyyy!) with that title prompt. At this prompt we make use of two extensions to default behaviour with our PHP web application, those being …

  1. prefix of “region code” + “;” ( in the case of Andorra an ISO 2 Character Country Code “AD” + “;” = porkAD; )
  2. suffix of “heads up” placename list (making it so you will probably not need to fish around for any latitude and longitude geographicals yourself) via &areplaces=[comma (and + if you want lines joining) separated placename list] … eg. &areplaces=Andorra la Vella,+Pas de la Casa

… to end up with a user title data item user interaction entry of …


AD;My World Survey&areplaces=Andorra la Vella,+Pas de la Casa

… as the lead in to “not much thinking” (and as long as you are not Pinocchio, “follow your nose” ease) required for the other non-quiz-based prompts (ie. no need for width or height mantissae …

… in this scenario).

Quite a bit of a different tack to yesterday’s Google Chart Geo Chart Quiz Tooltip Flag Tutorial that you can see how we needed to tweak geo_chart.php Geo Chart interfacer at this live run link, showing the versatility and usefulness of Google Chart Geo Charts.


Previous relevant Google Chart Geo Chart Quiz Tooltip Flag Tutorial is shown below.

Google Chart Geo Chart Quiz Tooltip Flag Tutorial

Google Chart Geo Chart Quiz Tooltip Flag Tutorial

Yesterday’s Google Chart Geo Chart Quiz on Mobile Tutorial‘s Google Chart Geo Chart interfacing uses …

  • onmouseover event tooltip functionality for non-mobile platforms … and, better something than nothing, we guess …
  • first onclick event tooltip functionality for mobile platforms

… a blessing, in our view, that an onmouseover (ie. on hover) piece of functionality thinking survives into the mobile platform wooooooooorrrrrlllddd in some way shape or form. We generally find tooltips an optimistic and useful webpage functionality tool.

And with this in mind, it was worth our mind’s attention to ask … “what about if the Geo Chart Quiz functionality can, optionally, help out the user a bit without giving the game away?” … in the sense that ISO 2 character country codes can be baffling, yet help to make the quiz a challenge, on occasions, though enough of a turn off for some users, we’re sure. But to place an Emoji Flag could be a feature some quizzers will like and appreciate.

Rather than add to the navigational data we’d rather “add” an Emoji Flag on being “flagged” (tee hee) to do so, that “flagging” being to add argument “&flag=y” into the mix, at the width value prompt, which is the same prompt whereby a user decides to create a quiz in the first place. And because Emojis represent text data (albeit multibyte ones) we won’t even need to change data structures, just data content involving the one string structure member of …


['Latitude','Longitude','Country','Countdown']

… which we’ve been sending as that country’s ISO 2 character code (to leave some challenge to the quizzer, where the user has been seeing that ISO code only “on hover” up to today) … but if the user has “flagged” &flag=y this code below swings into play appending text data onto that ISO Code text data (of PHP variable (and argument) “$instuff” below) via String.fromCodePoint() function, as per …

<?php

$lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
$dri=["127462","127463","127464","127465","127466","127467","127468","127469","127470","127471","127472","127473","127474","127475","127476","127477","127478","127479","127480","127481","127482","127483","127484","127485","127486","127487"];

function maybequizflag($instuff) {
global $GETdata, $iso_country_codes, $flagentity, $lri, $dri;
if (isset($_GET['quiz']) || isset($_POST['quiz'])) {
if (isset($_GET['flag']) || isset($_POST['flag'])) {
if (strpos($instuff, "['Lat','Long',") !== false) {
return $instuff; //str_replace("'Country',", "'Country','Flag',", $instuff);
} else {
$outstuff=$instuff;
$cbits=explode("'", $instuff);
$outstuff=$cbits[0];
$uretv=" ' + '";
for ($iol=1; $iol<sizeof($cbits); $iol++) {
if (($iol % 2) == 1) {
if (strlen($cbits[$iol]) == 2) {
for ($jjm=0; $jjm<strlen($cbits[$iol]); $jjm++) {
for ($jm=0; $jm<sizeof($lri); $jm++) {
if (strtoupper(substr($cbits[$iol],$jjm,1)) == $lri[$jm]) {
$uretv=str_replace(" + '", " + String.fromCodePoint(" . $dri[$jm] . ") + '", $uretv); //uvaltosfcp($dri[$jm]);
}
}
}
$outstuff.="'" . $cbits[$iol] . $uretv;
$uretv="' + '";
} else {
$uretv=" ' + '";
for ($im=1; $im<sizeof($iso_country_codes); $im+=2) {
if ($uretv == " ' + '" && strpos(strtolower($iso_country_codes[$im]), strtolower(str_replace("%20"," ",str_replace("%E2%80%99","",str_replace("%2C",",",$cbits[$iol]))))) !== false) {
for ($jjm=0; $jjm<strlen($iso_country_codes[-1 + $im]); $jjm++) {
for ($jm=0; $jm<sizeof($lri); $jm++) {
if (strtoupper(substr($iso_country_codes[-1 + $im],$jjm,1)) == $lri[$jm]) {
$uretv=str_replace(" + '", " + String.fromCodePoint(" . $dri[$jm] . ") + '", $uretv); //uvaltosfcp($dri[$jm]);
}
}
}
}
}
$outstuff.="'" . $cbits[$iol] . $uretv;
$uretv="' + '";
}
} else {
$outstuff.="'" . $cbits[$iol];
}
}
return $outstuff; //str_replace("',9", "','x',9", str_replace("',8", "','x',8", str_replace("',7", "','x',7", str_replace("',6", "','x',6", str_replace("',5", "','x',5", str_replace("',4", "','x',4", str_replace("',3", "','x',3", str_replace("',2", "','x',2", str_replace("',1", "','x',1", str_replace("',0", "','x',0", $instuff))))))))));
}
}
}
return $instuff;
}

?>

Again, you can try the changed geo_chart.php Geo Chart interfacer at this live run link.


Previous relevant Google Chart Geo Chart Quiz on Mobile Tutorial is shown below.

Google Chart Geo Chart Quiz on Mobile Tutorial

Google Chart Geo Chart Quiz on Mobile Tutorial

We wanted to improve on the recent Google Chart Geo Chart More Quizzes Tutorial‘s “World Quiz” functionality approach of displaying window.open popups for mobile platforms. The reason for the concern on mobile platforms, and not such a concern on non-mobile platforms (though there is a concern about popup window web browser disabling settings), because the chance to “overlay” a popup window (via the use of a third argument to window.open calls) is ignored on mobile platforms, instead opening a new browser tab (at best). This can be disconcerting, akin to telling a room of students doing an important examination, to look out the window at an interesting magpie (warbling about Collingwood’s last triumph, no doubt).

Well, after extensive research, and first trying to position “anything new” down the bottom of the webpage we …

  • rejected idea of whole display of a relevant Wikipedia page content at the bottom (of a mobile user’s Geo Chart “quiz” webpage) … associated with a …
  • rejected “a” hashtag link down the bottom (but above proposed content above) to navigate back up to the quiz … to, instead …
  • start thinking that it is up to the mobile user to act themselves to ever navigate away from the quiz webpage, so, instead, initially condense the Wikipedia content down to an image that is …
    1. if HTTPS:// protocol being used, use the Google Page Insights screenshotting “smarts” you can see being used at PDF Slideshow and Form Creation Data URI Contents Tutorial
    2. if HTTP:// protocol being used, use the (thumbnail version of) the first image of the relevant Wikipedia webpage

    … encased by an “a” tag that the click of navigates the user to the relevant Wikipedia content in a new tab (at best), all positioned at the left hand side of the Geo Chart webpage’s H1 or H2 tag heading as a 70px width42px height thumbnail

The conduit here are Ajax Javascript techniques as per …


var myxhr = false;
var oursrc = '';
var woourl='';


function ajit(wourl) {
woourl=wourl;
var xurl = '';
if (document.URL.toLowerCase().indexOf('https') == 0) {
xurl='https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url=' + encodeURIComponent(wourl) + '&screenshot=true';
} else {
xurl=document.URL.split('/GeoChart')[0] + '/fgc/?tdinto=&inurl=' + encodeURIComponent(wourl);
}
if (window.XMLHttpRequest) {
myxhr = new window.XMLHttpRequest;
}
else {
try {
myxhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (othermicrosoft) {
try {
myxhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (failed) {
myxhr = false;
}
}
}
if (myxhr) {
myxhr.onreadystatechange = backin;
myxhr.open('GET', xurl, true);
myxhr.send(null);
}
}


function backin() {
if (myxhr.readyState == 4) {
if (myxhr.status == 200) {
if (myxhr.responseText) {
var dbits = myxhr.responseText.split('\"data\":');
if (dbits.length > 1) {
oursrc='data:image/jpeg;base64,' + dbits[1].split('\"')[1].split('\"')[0].replace(/\_/g,'/').replace(/\-/g,'+');
ism='nm';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
ism='';
document.getElementById(ism + 'dwoalttwo').style.position='absolute';
document.getElementById(ism + 'dwoalttwo').style.left='20px';
document.getElementById(ism + 'dwoalttwo').style.top='0px';
document.getElementById(ism + 'dwoalttwo').style.opacity='0.95';
document.getElementById(ism + 'dwoalttwo').style.zIndex='51';
} else {
document.getElementById(ism + 'dwoalt').innerHTML='<br><a id=btta href=#myh title=Top>Back to top</a>';
}
document.getElementById(ism + 'dwoalttwo').innerHTML='<a target=_blank id=adw title=Wikipedia style=z-index:52; href=' + woourl + '><img title=Wikipedia style=width:80px;z-index:52; src=' + oursrc + '></img></a>';
document.getElementById('myh').onclick=function() { document.getElementById('adw').click(); }
if (ism != '') { location.href='#btta'; }
} else if (myxhr.responseText.indexOf('<img') != -1) {
dbits = myxhr.responseText.split('<img');
dbits=dbits[1].split(' src=');
ism='nm';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
ism='';
document.getElementById(ism + 'dwoalttwo').style.position='absolute';
document.getElementById(ism + 'dwoalttwo').style.left='20px';
document.getElementById(ism + 'dwoalttwo').style.top='0px';
document.getElementById(ism + 'dwoalttwo').style.opacity='0.95';
document.getElementById(ism + 'dwoalttwo').style.zIndex='51';
} else {
document.getElementById(ism + 'dwoalt').innerHTML='<br><a id=btta href=#myh title=Top>Back to top</a>';
}
document.getElementById(ism + 'dwoalttwo').innerHTML='<a target=_blank id=adw title=Wikipedia style=z-index:52; href=' + woourl + '><img title=Wikipedia style=width:80px;z-index:52; src=' + dbits[1].split(' ')[0].split('>')[0] + '></img></a>';
document.getElementById('myh').onclick=function() { document.getElementById('adw').click(); }
if (ism != '') { location.href='#btta'; }
}
}
}
}
}

… with the effect, for a mobile user, of not being interrupted from their quiz, unless this thumbnail (Wikipedia content) appears at the top left, that they can “long click” to open in a “New Tab” (or, perhaps, a “Split View”) as required, at least on the iPad we tried this with.

And so, you can try the changed geo_chart.php Geo Chart interfacer at this live run link, we hope representing an improvement for the Quizzing User Experience for our mobile user readers.


Previous relevant Google Chart Geo Chart More Quizzes Tutorial is shown below.

Google Chart Geo Chart More Quizzes Tutorial

Google Chart Geo Chart More Quizzes Tutorial

In allowing the World Quiz web applications of yesterday’s Google Chart Geo Chart World Quizzes Tutorial work accept more than about …

  • the 10 places (per continent Geo Chart) fitting into a $_GET arguments URL (of about 850 characters, for rjmprogramming.com.au domain) … the first cab off the rank allowing for …
  • a lot more than 10 can be accepted via $_POST in an HTML form method=POST action=./geo_chart.php

You may wonder why “first cab off the rank” here. Well, we’re not sure we won’t involve window.sessionStorage or window.localStorage in future plans. It being PHP we’re writing though, we will need a compelling reason to try this.

We allow you to ask the web application to try more places by (optionally) appending space characters onto the height values they enter.

You can try the changed (and note “function iftoobig()” in particular, here) geo_chart.php Geo Chart interfacer at this live run link, and try it with a few right space appended “heights” to try out this new functionality.


Previous relevant Google Chart Geo Chart World Quizzes Tutorial is shown below.

Google Chart Geo Chart World Quizzes Tutorial

Google Chart Geo Chart World Quizzes Tutorial

We’re heading towards “prove it for n” on top of the recent Google Chart Geo Chart Oceania Quiz Tutorial (“prove it for 2”) progress, making quizzes for …

  • Europe
  • South East Asia and Oceania
  • Africa
  • South America
  • North and Central America
  • Asia

… but feel we need more testing to bed it down, as far as reliability issues go, and we’ll keep you posted on that.

We found clutter issue with ISO 2 character Country Codes …

ISO Code 1 Country TZ Place 1 (Lat,Long) Too Close To Country TZ Place 2 (Lat,Long) ISO Code 2
VA Vatican City
(41.90222,
12.45305)
(-0.02,
+0.03)
Rome, Italy
(41.9,
12.48333)
IT
BJ Porto-Novo, Benin
(6.48333,
2.61666)
(-0.03,
+0.78)
Lagos, Nigeria
(6.45,
3.4)
NG

… and so “fashioned” this into a numerical basis for a “declutter” algorithm


function setsixteenquiz() {
var sixteen=16;
var allcontinents=['Europe','South East Asia and Oceania', 'Africa', 'South America', 'North and Central America', 'Asia'];
var thiscontinent=isquiz;
var cisq=-1;
var exclusions=',';
var sofarq=',-1,';
var ourselceqih=selceqih.replace(/\ data\-alt\-/g, ' data-');
if (thiscontinent == 'South East Asia and Oceania') {
sixteen=10;
} else if (thiscontinent == 'Africa') {
sixteen=17;
} else if (thiscontinent == 'South America') {
sixteen=10;
} else if (thiscontinent == 'North and Central America') {
sixteen=10;
}
for (var isqis=0; isqis<allcontinents.length; isqis++) {
if (allcontinents[isqis] != thiscontinent) {
while (ourselceqih.indexOf(' data-continent=\"' + allcontinents[isqis] + '\"') != -1) {
ourselceqih=ourselceqih.replace(' data-continent=\"' + allcontinents[isqis] + '\"','');
}
}
}
var sqws=ourselceqih.split(' data-continent=\"' + thiscontinent + '\" value=\"');
document.body.title='Awaiting quiz clickable circle symbols to score ...';
document.body.style.cursor=pcur;
if (document.getElementById('chart')) {
document.getElementById('chart').title='Awaiting quiz clickable circle symbols to score ... ';
document.getElementById('chart').style.cursor=pcur;
}
var latsofar=[], longsofar=[], thislats=0.0, thislongs=0.0;
var valid=true, ivalid=0, difflatlong=0.0;

while (quizisos.length < sixteen) {
cisq=-1;
while (sofarq.indexOf(',' + cisq + ',') != -1 || exclusions.indexOf(',' + cisq + ',') != -1) {
cisq=Math.floor(Math.random() * eval(-1 + sqws.length));
cisq++;
if (ourtzlist.indexOf(',' + sqws[cisq].split('\"')[0] + ',') != -1) {
thislats=(eval(ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"').length)].split(',')[0]));
thislongs=(eval(ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"').length)].split(',')[1]));
}

if (thiscontinent == 'South East Asia and Oceania') {
if (ourtzlist.indexOf(',' + sqws[cisq].split('\"')[0] + ',') != -1) {
if (eval(ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + sqws[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"').length)].split(',')[1]) < 73.0) { // || eval(ourtzlist.split(',' + ourselceqih[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + ourselceqih[cisq].split('\"')[0] + ',')[0].split(' data-geo=\"').length)].split(',')[1]) >= 169.0) {
cisq=-1;
}
} else {
cisq=-1;
}
}
}
sofarq+='' + cisq + ',';
if (cisq != -1) {
if (sqws[cisq].split('\"')[0] == 'IT') { exclusions+='VA,'; } else if (sqws[cisq].split('\"')[0] == 'VA') { exclusions+='IT,'; }
if (sqws[cisq].split('\"')[0] == 'BJ') { exclusions+='NG,'; } else if (sqws[cisq].split('\"')[0] == 'NG') { exclusions+='BJ,'; }
difflatlong=0.0;
if (quizisos.length > 0) {
for (ivalid=0; ivalid<quizisos.length; ivalid++) {
difflatlong=Math.abs(eval('' + latsofar[ivalid]) - eval('' + thislats)) + Math.abs(eval('' + longsofar[ivalid]) - eval('' + thislongs));
}
}
if (difflatlong >= 2.0 || quizisos.length == 0) {
latsofar.push(thislats);
longsofar.push(thislongs);
quizisos.push(sqws[cisq].split('\"')[0]);
}

}
}
quizisos.push(\"\");
}

Here’s your chance to try the changed geo_chart.php Geo Chart interfacer at this live run link, and enter Africa, South America, North and Central America and Asia Quiz territory by following pointers at the “width” interactive entry (Javascript) prompt window.


Previous relevant Google Chart Geo Chart Oceania Quiz Tutorial is shown below.

Google Chart Geo Chart Oceania Quiz Tutorial

Google Chart Geo Chart Oceania Quiz Tutorial

Regular readers will know about our penchant for “mathematical induction” theory, in the way you …

  • prove it for 1
  • prove it for 2
  • prove it for n

… and earlier this morning “too proud” moi thought we’d be at “n”, skipping “2” by now getting our Geo Chart interfacing new “Quiz” functionality to have covered user interactions for all the major continents of greater than 10 (of category) places, looking towards the “10 is a bit lame” thinking, to follow. Oh, well! But maybe that’s the point of the “2” in the “mathematical induction” proof “game”. A lot might be discovered, and so it was for us, trying to open the door to … come in …


South East Asia and Oceania ...

… spinner! In broad brush concepts, we discovered …

  • we needed to start to worry about places with an ISO 2 code but no TimeZone …
  • we needed to start to worry about places off to the left, right, and top limits of the Geo Chart limits we establish via those weird width and height values you enter … and on this am sure many will have tweaked that the value integer parts are like a “scalar” measure and the mantissae are a “left zero padded percentage offset into the entire Geo Chart on which to lob” measure
  • we needed to rearrange the scoring system’s denominator as a “seconds timer” rather than a “number of goes”
  • we needed to, at least at the start, mention name of Quiz
  • we needed to start closing previous Wikipedia windows on opening a new one, as applicable
  • we needed to start to worry about clutter (eg. Vatican City and Rome geographicals for two different countries)
  • we needed to start to worry about “skewed representations” (going back to Europe Quiz) whereby the first mention of a country ISO 2 Code within the TimeZone list is a position of a colony or dominion

… whereas we optimistically imagined all we might need to worry about was just …

  • converting (boolean binary decision) variable isquiz=false/true (Javascript code logic) into (string ternary and more decision) variable isquiz=”/’Europe’/’South East Asia and Oceania’ (with more to come … until “n” (for) nirvana) … and associated …
  • adding data-continent=”South East Asia and Oceania” global data attributes into dropdown id=’selceq’ linking ISO 2 codes with Country names
  • trying to add a bit of cursor=’progress’ flagging of web application “thinking time”

Never mind! And so, onto yesterday’s Google Chart Geo Chart Europe Quiz Tutorial progress there is not that much difference user interaction wise, just the offer of another weird “width” value choice (on which to blow your mind) but behind the scenes a “hard working mathematical induction middlemanperson” can now offer you the chance to try the changed geo_chart.php Geo Chart interfacer at this live run link, and enter South East Asia and Oceania Quiz territory by following pointers at the “width” interactive entry (Javascript) prompt window.


Previous relevant Google Chart Geo Chart Europe Quiz Tutorial is shown below.

Google Chart Geo Chart Europe Quiz Tutorial

Google Chart Geo Chart Europe Quiz Tutorial

Up to yesterday’s Google Chart Geo Chart Sorted Small Countries Tutorial, as with interfacings to other Google Charts, we had a two phase aspect to the web application structures …

  1. ask for user interaction via the keyboard
  2. display the resultant Google Chart taking notice of that user interaction

… but today’s extension of Geo Chart interfacing functionality opens the door to the new

  • display the resultant Google Chart taking notice of that user interaction and allowing click/touch continuing interaction in the form of a quiz … first cab off the rank … Europe Quiz

The work recently has helped because …


function gck(igck) {
var ansis='';
if (document.getElementById('attachedImage' + ('' + igck).replace('-1',''))) {
var xxx=document.getElementById('attachedImage' + ('' + igck).replace('-1','')).getAttribute('title');
if (xxx.indexOf('#') != -1) {
if (isquiz) {
maybe_bad=false;
if (xxx.split('#')[1].indexOf('/') != -1) {
ansis=xxx.split('#')[1].split('/')[eval(-1 + xxx.split('#')[1].split('/').length)].toLowerCase();
} else {
ansis=xxx.split('#')[1];
}
if (document.getElementById('sans').getAttribute('data-title').toLowerCase().replace(/\ /g,'_') == ansis.toLowerCase().replace(/\ /g,'_')) {
score++;
goes++;
} else {
goes++;
}
document.getElementById('sans').innerHTML='? ' + score + '/' + goes;
}

window.open(xxx.split('#')[1],'_blank', 'top=50,left=50,width=500,height=500');
} else if (xxx == '') {
if (isquiz) {
maybe_bad=false;
if (document.getElementById('attachedImage' + ('' + igck).replace('-1','')).title.indexOf('/') != -1) {
ansis=document.getElementById('attachedImage' + ('' + igck).replace('-1','')).title.split('/')[eval(-1 + xxx.split('#')[1].split('/').length)].toLowerCase();
} else {
ansis=document.getElementById('attachedImage' + ('' + igck).replace('-1','')).title;
}
if (document.getElementById('sans').getAttribute('data-title').toLowerCase().replace(/\ /g,'_') == ansis.toLowerCase().replace(/\ /g,'_')) {
score++;
goes++;
} else {
goes++;
}
document.getElementById('sans').innerHTML='? ' + score + '/' + goes;
}

window.open(document.getElementById('attachedImage' + ('' + igck).replace('-1','')).title,'_blank', 'top=50,left=50,width=500,height=500');
} else {
if (isquiz) {
maybe_bad=false;
if (xxx.indexOf('/') != -1) {
ansis=xxx.split('/')[eval(-1 + xxx.split('/').length)].toLowerCase();
} else {
ansis=xxx;
}
if (document.getElementById('sans').getAttribute('data-title').toLowerCase().replace(/\ /g,'_') == ansis.toLowerCase().replace(/\ /g,'_')) {
score++;
goes++;
} else {
goes++;
}
document.getElementById('sans').innerHTML='? ' + score + '/' + goes;
}

window.open(xxx,'_blank', 'top=50,left=50,width=500,height=500');
}
}
}

… is an onclick place we’ve set aside for our SVG intervention work. Keep it to no keyboard for this Europe Quiz, and we are happy (with this new idea, reminiscent of recent tweaking at Google Chart Annotated Timeline Whitespace Delimitation Tutorial).

So, again, you can try the changed geo_chart.php Geo Chart interfacer at this live run link, and enter Europe Quiz territory by following pointers at the “width” interactive entry (Javascript) prompt window.


Previous relevant Google Chart Geo Chart Sorted Small Countries Tutorial is shown below.

Google Chart Geo Chart Sorted Small Countries Tutorial

Google Chart Geo Chart Sorted Small Countries Tutorial

Yesterday’s Google Chart Geo Chart Small Countries Overlay Tutorial‘s workings potentially using the geographicals (or marker) mode of use actually involve intervention logic within what Google provide SVG-wise for the Geo Chart content.

And so, for some time, the order in which we entered …

Country Surface Area (sq km)
Australia 7692024
New Zealand 269190
Andorra 468

… we entered, interactively by us, like, personally, like, in that order above, like. But for a day or two we were covering up a gap in the “wall of logic” plaster we had created for Google Chart select event logic (actually non-existant for the Geo Chart, but we code for onclick logic to navigate a user to a relevant Wikipedia page). The good news is we have fixed it now, not tying the user down to entering data in any particular order.

Fixed what, now? (I thought I heard you ask?!) Well, the alignment of &aregeographical= data to the symbology presented at the geographical positions on the Geo Map asks that the order we present corresponds to the relevant order of relevant Google SVG elements, and Google orders these from the largest numerical value down to the smallest, as you notice as far as Surface Area (sq km) suits an order of Australia, New Zealand, Andorra …

First non-overlay URL version goes https://www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Surface%20Areas%20(sq%20km)&width=1112&height=694&country=Country&popularity=Surface%20Area%20(sq%20km)&data=%20[-34.91667|138.58333|~Australia~,7692024]%20,%20[-36.86667|174.76666|~New%20Zealand~,269190]%20,%20[42.5|1.51666|~Andorra~,468]%20&aregeographicals=http.Australia%2Chttp.New%20Zealand%2Chttp.Andorra
Second overlay URL version goes https://www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Surface%20Areas%20(sq%20km)&width=1112&height=694&country=Country&popularity=Surface%20Area%20(sq%20km)&data=%20[-34.91667|138.58333|~Australia~,7692024]%20,%20[-36.86667|174.76666|~New%20Zealand~,269190]%20,%20[42.5|1.51666|~Andorra~,468]%20&overlay=y&aregeographicals=http.Australia%2Chttp.New%20Zealand%2Chttp.Andorra
But the recent work means overlay URL version created interactively with order New Zealand, Andorra, Australia https://www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Surface%20Areas%20(sq%20km)&width=1112&height=694&country=Country&popularity=Surface%20Area%20(sq%20km)&data=%20[-36.86667|174.76666|~New%20Zealand~,269190]%20,%20[42.5|1.51666|~Andorra~,468]%20,%20[-34.91667|138.58333|~Australia~,7692024]%20&overlay=y&aregeographicals=http.Australia%2Chttp.New%20Zealand%2Chttp.Andorra
also works

… and the changes necessary to ensure this go


// var pushfrom=[], pushto=[], pushag=[], selceqih='', saih='', oneistoosmall=false, oneisnotapplicable=false;
function assess_small(indatar) {
var ipl=0, jpl=0, kpl=0, pushxx=[];
var outsuffix='';
var outdatar=indatar;
if (pushfrom.length > 0 && !oneisnotapplicable && oneistoosmall) {
for (jpl=0; jpl<pushfrom.length; jpl++) { // for (var ipl=0; ipl<pushfrom.length; ipl++) {
if (jpl == 0) {
var huhdatas=indatar.split('~');
for (var ihuhdatas=2; ihuhdatas<huhdatas.length; ihuhdatas+=2) {
if (huhdatas[eval(-1 + eval('' + ihuhdatas))].split('~')[0].replace('%20',' ').indexOf(' ') != -1) {
pushxx.push(('00000000000000000000000' + huhdatas[ihuhdatas].split(',')[1].split(']')[0]).slice(-22) + ' ... ' + huhdatas[eval(-1 + eval('' + ihuhdatas))].split('~')[0]);
}
pushxx.push(('00000000000000000000000' + huhdatas[ihuhdatas].split(',')[1].split(']')[0]).slice(-22) + ' ... ' + encodeURIComponent(huhdatas[eval(-1 + eval('' + ihuhdatas))].split('~')[0]));
}
pushxx.sort();
pushxx.reverse();
}
ipl=jpl;
for (kpl=0; kpl<pushfrom.length; kpl++) {
if (ipl == jpl && pushxx[jpl].split(' ... ')[1] == pushfrom[kpl].split('~')[1].split('~')[0]) {
ipl=kpl;
pushxx[jpl]=pushxx[jpl].split(' ... ')[0] + ' ... ';
}
}

if (outdatar.indexOf(pushfrom[ipl]) != -1) {
if (outsuffix == '') {
outsuffix='&aregeographicals=' + pushag[ipl];
} else {
outsuffix+='%2C' + pushag[ipl];
}
while (outdatar.indexOf(pushfrom[ipl]) != -1) {
outdatar=outdatar.replace(pushfrom[ipl], pushto[ipl]);
}
}
}
}


return outdatar + outsuffix;
}

Yet again, you can try the changed geo_chart.php Geo Chart interfacer at this live run link.


Previous relevant Google Chart Geo Chart Small Countries Overlay Tutorial is shown below.

Google Chart Geo Chart Small Countries Overlay Tutorial

Google Chart Geo Chart Small Countries Overlay Tutorial

With “overlay” techniques available in life it might be tempting to say “never say never” because you don’t have to compromise a weak solution for a less weak solution. Yesterday’s Google Chart Geo Chart Small Countries Tutorial‘s Google Chart Geo Chart‘s homegrown interfacer tactics for Small Countries is a case in point.

You may recall from yesterday how we dynamically reverted to “geographicals mode” display (Google call it “Markers” mode) when the shading for a Small Country would lead to “data loss”. But what if we …

  • continue what we were doing yesterday “overlayed”

    … onto …

  • what we changed from URL-wise with “function assess_small()” (with the one codeline change

    outsuffix='&overlay=y&aregeographicals=' + pushag[ipl];

    ) … in the form of two new HTML iframe code below …
    <?php

    if (isset($_GET['overlay']) || isset($_POST['overlay'])) {
    echo "<script> function overlayit() {
    var ourls=documentURL.split('&overlay=')[0].split('[');
    var ourl=ourls[0];
    for (var iouris=1; iouris<ourls.length; iouris++) {
    if (ourls[iouris].substring(0,1) == '~') {
    ourl+='[' + ourls[iouris];
    } else {
    ourl+='[' + ourls[iouris].replace(ourls[iouris].split('~')[0],'');
    }
    }
    document.body.style.zIndex='-12';
    document.getElementById('doverlay').innerHTML='<iframe style=\"position:absolute;top:0px;left:0px;width:100%;height:100vh;z-index:2;opacity:0.95;\" src=\"' + ourl + '\"></iframe>';
    document.getElementById('doverlaytwo').innerHTML='<iframe style=\"position:absolute;top:0px;left:0px;width:100%;height:100vh;z-index:22;opacity:0.9;\" src=\"' + documentURL.replace('&overlay=','&qw=') + '&guess=' + '\"></iframe>';
    }
    setTimeout(overlayit, 2000);
    </script>
    ";
    }

    ?>

Again, you can try the changed geo_chart.php Geo Chart interfacer at this live run link.


Previous relevant Google Chart Geo Chart Small Countries Tutorial is shown below.

Google Chart Geo Chart Small Countries Tutorial

Google Chart Geo Chart Small Countries Tutorial

We last used the excellent Google Chart Geo Chart tool with the work of Window LocalStorage Client Versus Server Map Tutorial, and it was this project that alerted us to both a weakness and a strength of that chart …

  • a weakness being its inability to get the resolution to shade a small country (eg. today’s tutorial picture‘s Andorra) … but, the good news, as used with this integration work above …
  • a strength is the alternative display mechanism via geographical entries

… and so, what if …

  • as the user enters in their Country (or Geographical) data …
  • if we can determine it as being a Country being entered … and…
  • you have only ever been entering Countries … and …
  • any one Country so defined has a surface area less than 10000 square kilometers … then …
  • we navigate to a Geographical data version of this “only Countries entered” data set … so that …
  • even small such Countries will be displayed …
  • as they would not if still in the default “only Countries entered” mode of display

We introduce three new sources of data in order to piece together the (Javascript via PHP coding) logic for this …

  1. TimeZone and Geographicals and ISO 2 Letter Code information …

    var ourtzlist='<option value="Africa/Abidjan" data-geo="5.31666,-4.03334,GMT,CI,+0">Africa/Abidjan</option><option value="Africa/Accra" data-geo="5.55,-0.21667,GMT,GH,+0">Africa/Accra</option>'; // etcetera etcetera etcetera
  2. Country Name and ISO 2 Letter Code information (etcetera etcetera etcetera) …

    <div id=dlookups>
    <select id='selceq' style='display:none;'>
    <option value='AF'>Afghanistan</option>
    <option value='AX'>Aland Islands</option>
    <option value='AL'>Albania</option>
    </select></div>
  3. Surface Areas of Countries thanks to Wikipedia (etcetera etcetera etcetera) …

    <table style='display:none;' id='surface_area' border='1' cellpadding='2' cellspacing='0'>
    <tbody><tr bgcolor='#efefef'>
    <th>Pos
    </th><th>Country
    </th>
    <th>Area (km²)
    </th></tr>
    <tr>
    <td>1</td>
    <td><a data-href='/wiki/Russia' title='Russia'>Russia</a></td>
    <td>17098246
    </td></tr>
    <tr>
    <td>2</td>
    <td><a data-href='/wiki/Canada' title='Canada'>Canada</a></td>
    <td>9984670
    </td></tr>
    <tr>
    <td>3</td>
    <td><a data-href='/wiki/People%27s_Republic_of_China' title='People's Republic of China'>China</a></td>
    <td>9572900
    </td></tr>
    </tbody></table>

… used where we process a user Country (or Geographical) interaction Javascript code snippet where variable thisris is that user interaction result …


var pushfrom=[], pushto=[], pushag=[], selceqih='', saih='', oneistoosmall=false, oneisnotapplicable=false;

if (ourtzlist.indexOf(',' + thisris.toUpperCase() + ',') != -1 && thisris.length == 2) {
if (selceqih == '') { selceqih=document.getElementById('selceq').innerHTML; }
if (saih == '') { saih=document.getElementById('surface_area').innerHTML; }
pushfrom.push('[~' + thisris + '~');
pushto.push('[' + ourtzlist.split(',' + thisris.toUpperCase() + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisris.toUpperCase() + ',')[0].split(' data-geo=\"').length)].split(',')[0] + '|' + ourtzlist.split(',' + thisris.toUpperCase() + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisris.toUpperCase() + ',')[0].split(' data-geo=\"').length)].split(',')[1] + '|~' + thisris.toUpperCase() + '~');
if (selceqih.indexOf(' value=\"' + thisris.toUpperCase() + '\">') != -1) {
pushag.push('http.' + encodeURIComponent(selceqih.split(' value=\"' + thisris.toUpperCase() + '\">')[1].split('<')[0]));
} else {
pushag.push('');
}
if (saih.indexOf('>' + selceqih.split(' value=\"' + thisris.toUpperCase() + '\">')[1].split('<')[0]) != -1) {
thissa=saih.split('>' + selceqih.split(' value=\"' + thisris.toUpperCase() + '\">')[1].split('<')[0])[1].split('<td>')[1].split('<')[0].split(String.fromCharCode(10))[0];
if (eval('' + thissa) < 10000) {
oneistoosmall=true;
}
}
} else if (('' + thisris).trim() != '' && selceqih.toUpperCase().indexOf('>' + thisris.toUpperCase()) != -1) {
thisisocc=selceqih.toUpperCase().split('>' + thisris.toUpperCase())[0].split(' VALUE=\"')[eval(-1 + selceqih.toUpperCase().split('>' + thisris.toUpperCase())[0].split(' VALUE=\"').length)].split('\"')[0];
pushfrom.push('[~' + encodeURIComponent(thisris) + '~');
pushto.push('[' + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"').length)].split(',')[0] + '|' + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"').length)].split(',')[1] + '|~' + encodeURIComponent(thisris) + '~');
pushag.push('http.' + encodeURIComponent(thisris));
if (thisris.indexOf(' ') != -1) {
pushfrom.push('[~' + thisris + '~');
pushto.push('[' + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"').length)].split(',')[0] + '|' + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"')[eval(-1 + ourtzlist.split(',' + thisisocc + ',')[0].split(' data-geo=\"').length)].split(',')[1] + '|~' + encodeURIComponent(thisris) + '~');
pushag.push('http.' + encodeURIComponent(thisris));
}
if (saih.toUpperCase().indexOf('>' + thisris.toUpperCase()) != -1) {
thissa=saih.toUpperCase().split('>' + thisris.toUpperCase())[1];
thissa=thissa.split('<TD>')[1].split('<')[0].split(String.fromCharCode(10))[0];
if (eval('' + thissa) < 10000) {
oneistoosmall=true;
}
}
}

… and if remaining relevant just before the next navigation happens, where variable indatar represents the default “only Countries entered” mode of display value …


// var pushfrom=[], pushto=[], pushag=[], selceqih='', saih='', oneistoosmall=false, oneisnotapplicable=false;
function assess_small(indatar) {
var outsuffix='';
var outdatar=indatar;
if (pushfrom.length > 0 && !oneisnotapplicable && oneistoosmall) {
for (var ipl=0; ipl<pushfrom.length; ipl++) {
if (outdatar.indexOf(pushfrom[ipl]) != -1) {
if (outsuffix == '') {
outsuffix='&aregeographicals=' + pushag[ipl];
} else {
outsuffix+='%2C' + pushag[ipl];
}
while (outdatar.indexOf(pushfrom[ipl]) != -1) {
outdatar=outdatar.replace(pushfrom[ipl], pushto[ipl]);
}
}
}
}


return outdatar + outsuffix;
}

You can try the changed geo_chart.php Geo Chart interfacer at this live run link.


Previous relevant Window LocalStorage Client Versus Server Map Tutorial is shown below.

Window LocalStorage Client Versus Server Map Tutorial

Window LocalStorage Client Versus Server Map Tutorial

Get a good map, and a goodly number of times you’ll want a map of smaller or larger scale than the one you have. Murphy’s Law? This is probably why in the wonderful woooooooorrrrrrrrlllllld of Google Charts they have included …

  • Geo Chart topographic map of the world or of regions
  • Map Chart terrestrial/satellite map of your group of markers at a zoom level of your choosing

… and hope you can see that the latter can save the day for a Short Distance Trip (corner shop, anyone?!).

So we’ve added onto yesterday’s Window LocalStorage Client Versus Server Timeline Tutorial progress a new toggling button to view a scenario in either Google Chart scenario above.

You can see this integration work with our changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link supervising a tweaked geo_chart.php Geo Chart interfacer.


Previous relevant Window LocalStorage Client Versus Server Timeline Tutorial is shown below.

Window LocalStorage Client Versus Server Timeline Tutorial

Window LocalStorage Client Versus Server Timeline Tutorial

Up to yesterday’s Window LocalStorage Client Versus Server User Tutorial‘s progress, our Capital City Find Matching Country Report web application project was all about …

  • where (and capital of “what”) … but we often seek out a way to add into the mix that 4th dimension …
  • when (ie. time)

… and regarding the current project, a …

  • where “map” … can interface with a …
  • when “Trip Plan Itinerary”

… and for this purpose, we’re going to interface to the excellent Google Charts Annotated Timeline Chart, thanks, because it combines links of “time” to “user annotations” in a timeline way, that similar way you might describe the qualities of a Trip, even before you’ve gone on that trip. We’ve also added it so that an unordered places list can be turned into a Trip Plan Itinerary at the click/touch of a new map 🗺 &#128506; emoji button.

Again, see how these timeline amendments were achieved with our changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link and annotatedtimeline_chart.php which changed quite a lot.


Previous relevant Window LocalStorage Client Versus Server User Tutorial is shown below.

Window LocalStorage Client Versus Server User Tutorial

Window LocalStorage Client Versus Server User Tutorial

The inherent weakness with our current Capital City Find Matching Country Report web application project, to our minds, was that places of interest are not restricted to the Capital Cities of Countries, especially when “Trip Planning”. On the other hand, it would be impossible to cater for every “place” in the world. That is far too subjective for good web application applicability. What would be good though, is to allow in user defined …


Place name, Country name

… terms, the definitions of interest to a user. We can ask this …

  • flagged by the click/touch of an emoji button … and …
  • the interactive entry presented via a Javascript prompt window

. When thinking of data applicable to an individual, then that can be catered for by recording it in localStorage where it will be recalled on the next execution of that web application in the same web browser.

This, along with a Colour Wheel of the “nearest TimeZone place” onto the existing logic of yesterday’s Window SessionStorage Client Versus Server Order Tutorial progress could make for a more useful and practical tool for those Trip Planners out there!

See how this was achieved with our changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link.

Did you know?

To click/touch one of those Google Chart Geo Chart lines between Emoji Flag Markers will show a new Google Maps directions web page with transport times and detail, as well as an inhouse crow fly distance of that trip leg, as shown up the top right of today’s tutorial picture.


Previous relevant Window SessionStorage Client Versus Server Order Tutorial is shown below.

Window SessionStorage Client Versus Server Order Tutorial

Window SessionStorage Client Versus Server Order Tutorial

If we are to honour our thoughts of being able to use our current Capital City Find Matching Country Report web application as a Trip Planner …

Our primary integration today is to (software) integrate the great Weather Underground and its great API service for autocomplete name searches for weather (and hurricane) information. Why bother? Well, can you not envisage a user using that Ajax functionality of yesterday’s Window SessionStorage Client Versus Server Ajax Tutorial as a trip planner, perhaps, or as a “checking up on relatives overseas” tool, perhaps? And not all the capital cities are timezone places, and so for some of those we can use Weather integration to still show apt online information when click/touching a Countries Report row. Speaking of this “row”, we make an improvement whereby on a first click of a right hand (Country) row cell, that cell is not initially a contenteditable=”true” one (that may frustrate showing the keyboard on mobile, when most likely it was the row touch intended), but then becomes a contenteditable=”true” cell henceforth.

… then yesterday’s Window SessionStorage Client Versus Server Flags Tutorial “progress to now” needs to take notice of a user’s order of multiple select (dropdown) element click/touching of Capital City option (sub)elements, just as we did with the recent User Controlled Dynamic Javascript YouTube Embedded API Ordered Tutorial‘s web application project to allow for a user ordered YouTube video playlist.

Because what is a Trip Planner without an ordered trip? Well, that is debatable, but what isn’t (debatable), is that there will be people in the world who appreciate the “mapping out” of a proposed Trip Planning Itinerary. What could we call on here? We can think of the Google Chart Geo Chart work around about the time of Google Geo Chart Co-ordinate Emojis Tutorial, when we started using …

  • a world map … with …
  • emoji markers … and optionally …
  • joined up by straight lines

… an idea for a Trip Plan itinerary synopsis, perhaps?!

If you examined closely yesterday’s code changes you will have noticed our collecting of TimeZone Place geographical latitude and longitude information. Today, we start making use of that preparatory work with our changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link.

Stop Press

The “emoji markers” above (as of 2 January 2020) will be “country flags” (as per Window SessionStorage Client Versus Server Flags Tutorial ideas), as defined.


Previous relevant Window SessionStorage Client Versus Server Flags Tutorial is shown below.

Window SessionStorage Client Versus Server Flags Tutorial

Window SessionStorage Client Versus Server Flags Tutorial

Yes, there’s more to do onto yesterday’s Window SessionStorage Client Versus Server CSS Tutorial‘s Capital City Find Matching Country Report web application project, in our eyes. We have not even mentioned “Internationalization” as a concept up to now. In this line of thinking …

Did you know?

Emoji flags via ISO 2 character country codes are dead easy via Regional Indicator Symbol characters …


var lri="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var dri=["127462","127463","127464","127465","127466","127467","127468","127469","127470","127471","127472","127473","127474","127475","127476","127477","127478","127479","127480","127481","127482","127483","127484","127485","127486","127487"];

var thiscc='AU'; // ISO 2 character countrycode for Australia
var ccsuff='', ccchar=' ';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+='&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
}
document.getElementById('lastflag').innerHTML=ccsuff;

… to result in (via <span style=font-size:64px;>&#127462;&#127482;</span>) …


🇦🇺

… providing interest and general translatability to the changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link.


Previous relevant Window SessionStorage Client Versus Server CSS Tutorial is shown below.

Window SessionStorage Client Versus Server CSS Tutorial

Window SessionStorage Client Versus Server CSS Tutorial

Further to yesterday’s Window SessionStorage Client Versus Server Integration Tutorial we have a two pronged improvements set for you today with our current Capital City Find Matching Country Report web application project …

  • CSS styling changes … and …
  • additional functionality for Email and SMS links back to our current Capital City Find Matching Country Report web application project (to complete the cycle)

We use several modes of CSS application (the first and last of particular relevance to today’s “highlighting of workflow” improvements) …

… the “static” measures often helping to highlight the web application’s main workflow of user interaction and the “dynamic” measures helping to alert the user as to where to proceed with their “workflow”.

In terms of CSS styling work …

  1. for non-mobile platforms we allow for more columns to be applied to our Capitals select (dropdown) element (in order to reduce some user scrolling, as does our new additional A-Z letter basis sorting functionality) as per … the “dynamic” Javascript DOM “class” modifications

    if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    document.getElementById('lefttd').className='lefttd';
    }

    … dovetailing with the “static” internal CSS coding

    <style>
    .lefttd {
    column-count: 4;
    max-height: 35%;
    vertical-align: top;
    max-width: 70%;
    font-size: 8px;
    background-color: rgba(205,205,205,0.5);
    background-image: -webkit-gradient(
    linear,
    right bottom,
    left top,
    color-stop(0, rgba(205, 205, 205, 0.8)),
    color-stop(0.50, rgba(255, 255, 0, 0.2))
    );
    background-image: -o-linear-gradient(left top, rgba(205, 205, 205, 1) 0%, rgba(255, 255, 0, 0.2) 50%);
    background-image: -moz-linear-gradient(left top, rgba(205, 205, 205, 1) 0%, rgba(255, 255, 0, 0.2) 50%);
    background-image: -webkit-linear-gradient(left top, rgba(205, 205, 205, 1) 0%, rgba(255, 255, 0, 0.2) 50%);
    background-image: -ms-linear-gradient(left top, rgba(205, 205, 205, 1) 0%, rgba(255, 255, 0, 0.2) 50%);
    background-image: linear-gradient(to left top, rgba(205, 205, 205, 1) 0%, rgba(255, 255, 0, 0.2) 50%);

    }
    </style>

    … and please note that around here at RJM Programming we have a “far from hard and fast rule” (but a rule regardless) regarding HTML element ID and class attributes that they concern (and (usually) be compartmentalised into) Javascript (DOM) manipulations and CSS styling issues respectively … and add a linear-gradient background to the table cell when expecting the initial user interaction on non-mobile platforms
  2. a “dynamic” Javascript DOM “class” modification … document.getElementById(‘myrepsb’).className=’dglow’; … is made to the “Report…” button at the Capitals select (dropdown) onfocusout event so as to highlight (with “glow” inspired styling) where user interaction may flow to

As far as links go, you may expect to need serverside means to construct these in online Email and SMS message interfacing, but email (client program) products like Gmail parse your ascii text and convert http: or https: protocol URLs in your Email body to hyperlinks, as does the Messages SMS application here on this MacBook Pro using macOS Mojave. Cute, huh?! So to close the circle back from remote thar’ parts back to our web application is a simple matter of, in broad brush terms …

  • adding two new buttons called “Email Columns and Links …” and “SMS Columns and Links …” that …
  • set a global variable andlinkto = true; … setting in play, within the report writing code (that likes monospaced fonts) …
  • add a new links column to the right with URLs like …
    https://www.rjmprogramming.com.au/HTMLCSS/wls_vs_php.htm?andgo=y&countries=Belize&capitals=Belmopan
    … to tell your client programs to form the hyperlinks for us (if they are “of the mood”, that is!)

To improve user experience we use “dynamic” Javascript DOM HTML “style” attribute change means to easier close the “Colour Wheel” helper web application “above the fold” by changing the CSS z-index (Javascript DOM [element].style.zIndex) of elements accordingly, when the user clicks other elements. You can see all this with the first “the changed” link above, where all “glow” CSS styling will also feature prominently.


Previous relevant Window SessionStorage Client Versus Server Integration Tutorial is shown below.

Window SessionStorage Client Versus Server Integration Tutorial

Window SessionStorage Client Versus Server Integration Tutorial

We hope, when performing a “software integration” task, that the two or more components of that integration work with each other’s talents, rather than a big tussle like reinventing the wheel. This ideal makes the work …

  • sometimes difficult but rewarding because …
  • the differences between two independent software components can be quite large and daunting … and the programmer has to see that …
  • care is applied so as not to wreck previous functionality and integrations in making the current integration work

… and that is why we’ve made corollaries to “building from scratch” (when planning and design is a huge component) can be a lot simpler than a software integration “renovation”, in the past, here at this blog.

Our primary integration today is to (software) integrate the great Weather Underground and its great API service for autocomplete name searches for weather (and hurricane) information. Why bother? Well, can you not envisage a user using that Ajax functionality of yesterday’s Window SessionStorage Client Versus Server Ajax Tutorial as a trip planner, perhaps, or as a “checking up on relatives overseas” tool, perhaps? And not all the capital cities are timezone places, and so for some of those we can use Weather integration to still show apt online information when click/touching a Countries Report row. Speaking of this “row”, we make an improvement whereby on a first click of a right hand (Country) row cell, that cell is not initially a contenteditable=”true” one (that may frustrate showing the keyboard on mobile, when most likely it was the row touch intended), but then becomes a contenteditable=”true” cell henceforth.

As a user experience improvement for “trip planners” perhaps, we allow the user to alphabetically sort the presented select (dropdown) element entries …


var firstopt='';
var wasopts='';
var restopts='';

function readyitforsort(iselid) {
var optsare=[];
var huhisel=document.getElementById(iselid).innerHTML;
var huhsopts=huhisel.split('</option>');
for (var ihuh=0; ihuh<huhsopts.length; ihuh++) {
if (huhsopts[ihuh].trim() != '') {
if (firstopt == '') {
firstopt=huhsopts[ihuh] + '</option>';
} else {
wasopts+=huhsopts[ihuh].replace('option ','option data-ih="' + (huhsopts[ihuh].split('>')[eval(-1 + huhsopts[ihuh].split('>').length)] + '" ')) + '</option>';
optsare.push(huhsopts[ihuh].replace('option ','option data-ih="' + (huhsopts[ihuh].split('>')[eval(-1 + huhsopts[ihuh].split('>').length)] + '" ')) + '</option>');
}
}
}
optsare.sort();
for (var jhuh=0; jhuh<optsare.length; jhuh++) {
restopts+=optsare[jhuh];
}
}

… controlled by a new dropdown in the left hand column header cell.

We also allow the user to move the iframe element with some positioning emoji buttons near the “Close” button one (of yesterday’s work).

Into the future, too, we’ll have more to say regarding the germination of an idea “to allow a mobile onmouseover simulator (of sorts)” be to allow the user to perform a swipe across an individual HTML element of interest on mobile platforms (ie. harness ontouchmove event) as per (so far) … kicked off by “<body onload=” setTimeout(athn, 5000); “>” …


var last24='';
var rectdc;

function nodivalert() {
document.getElementById('divalert').style.display='none';
document.getElementById('divalert').style.zIndex='-456';
document.getElementById('divalert').style.left=('-' + rectdc.left).replace('px','') + 'px';
document.getElementById('divalert').style.top=('-' + rectdc.top).replace('px','') + 'px';
}

function ourdivalert(inmsg) {
document.getElementById('divalert').style.position='absolute';
document.getElementById('divalert').style.left=('' + rectdc.left).replace('px','') + 'px';
document.getElementById('divalert').style.top='' + eval(-80 + eval(('' + rectdc.top).replace('px',''))) + 'px';
document.getElementById('divalert').style.backgroundColor='#e0e0e0';
document.getElementById('divalert').style.display='block';
document.getElementById('divalert').style.zIndex='456';
document.getElementById('divalert').style.opacity='0.8';
document.getElementById('divalert').style.padding='5px 5px 5px 5px';
document.getElementById('divalert').innerHTML=inmsg + '<br><br><input type=button value=Close onclick=nodivalert();></input>';
setTimeout(nodivalert,9000);
}

function athn() {
rectdc=document.getElementById('dc').getBoundingClientRect();
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
document.getElementById('dc').ontouchmove=function(event) { if (last24.substring(0,eval(-1 + last24.length)) == event.target.title.substring(0,eval(-1 + event.target.title.length))) { last24=last24; } else { last24=event.target.title; ourdivalert(event.target.title); } }
} else {
document.getElementById('dc').onmousemove=function(event) { if (last24.substring(0,eval(-1 + last24.length)) == event.target.title.substring(0,eval(-1 + event.target.title.length))) { last24=last24; } else { last24=event.target.title; ourdivalert(event.target.title); } }
}
}

… working with the new HTML …


<div id=divalert></div>
</body>
</html>

… to try to allow the “explainer of an element” advantages non-mobile platforms have for hovering over an HTML element with a title attribute filled in.

And so, yet again, see the changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link’s new Weather integration functionality. It caused the changed colour_wheel.html‘s colour wheel (at this live run link) to be affected (by integrations “up”).


Previous relevant Window SessionStorage Client Versus Server Ajax Tutorial is shown below.

Window SessionStorage Client Versus Server Ajax Tutorial

Window SessionStorage Client Versus Server Ajax Tutorial

We have a few “clientside chestnuts” to use with our current Capital City Find Matching Country Report web application project today, those being …

  • Ajax functionality, kicked off by an “onclick” event set of logic, allowing mobile platforms to also have a look in (the look in that they miss when the event logic is off the “onmouseover” event)
  • iframe and its …
    1. srcdoc attribute (“content” alternative to src “url” attribute) … along with, and crucially needing (because srcdoc ignores its own document.body onload goings on, that we need the “Iframe Client Pre-Emptive” methods below to circumvent) the …
    2. onload event opportunity of an iframe element (we group into “Iframe Client Pre-Emptive” methods, here)

… adding onto yesterday’s Window SessionStorage Client Versus Server Canvas Tutorial.

It’s not that involved with the Ajax work today, given that there are no cross-domain issues, though there are cross-protocol (SSL https: versus non-SSL http:) issues to be careful about. Those can be addressed because the web application is recalled to present its “Country Report” and that is the opportunity to check on protocol navigation requirements.

Along the way, we also make this happen for the user on …

  • click/touching a table row … it sets off new “tr” (table row) element logic calling our (inhouse) Timezone and Wikipedia Place Information helper (HTML) via Ajax (so not leaving the webpage) … and because of place name oddities we allow for …
  • “td” (table cell) element user amendments by setting their contenteditable attributes to “true” (since fixed, but we found the Timezone Europe/Tirane pointing at Tirane in Albania used to be spelt “Tirana”)

… that latter methodology normally a technique we apply to “div” elements (so, there you are!)

Also used are “overlay” techniques, two of the “usual suspects” here coming into play, to present to the “Ajax content to srcdoc iframe arrangements” …

Yet again, see the changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link’s new “Ajax” functionality.


Previous relevant Window SessionStorage Client Versus Server Canvas Tutorial is shown below.

Window SessionStorage Client Versus Server Canvas Tutorial

Window SessionStorage Client Versus Server Canvas Tutorial

Yesterday’s Window SessionStorage Client Versus Server Share Tutorial dealt with ascii text clipboard copy assisted sharing options with our current Capital City Find Matching Country Report web application project. This suited both Email and SMS share options we coded for, but today’s extension of functionality from “ascii text” data to “graphical data” only suits Email sharing. The other caveat with our work is that no serverside (for us, PHP) help is allowed, so no PHP mail here.

What comes into play with a “graphical data” clientside (only) sharing approach? It will not surprise many readers that, for us, it involves …

  • canvas element … converting HTML table outerHTML “ascii text” data … via …
  • canvas drawing methods “[canvasContext].strokeRect()” and “[canvasContext].strokeText()” via “[cellElement].getBoundingClientRect()” … to convert that canvas element content via …
  • [canvasElement].toDataURL() … to an …
  • img element nested in a div contenteditable=true element … so as to hook in with today’s very useful helper link, thanks … use …

  • function tabletoclipboard(canvas) { // thanks to https://stackoverflow.com/questions/27863617/is-it-possible-to-copy-a-canvas-image-to-the-clipboard
    var img = document.createElement('img');
    img.src = canvas.toDataURL();

    var div = document.createElement('div');
    div.contentEditable = true;
    div.appendChild(img);
    document.body.appendChild(div);

    // do copy
    SelectText(div);
    document.execCommand('Copy');
    document.body.removeChild(div);
    }

    function SelectText(element) { // thanks to https://stackoverflow.com/questions/27863617/is-it-possible-to-copy-a-canvas-image-to-the-clipboard
    var doc = document;
    if (doc.body.createTextRange) {
    var range = document.body.createTextRange();
    range.moveToElementText(element);
    range.select();
    } else if (window.getSelection) {
    var selection = window.getSelection();
    var range = document.createRange();
    range.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(range);
    }
    }
  • to leave the user’s device’s clipboard containing a useful table (with linework) … ready to …
  • paste into an email body section

… sharing off to an emailee collaborator.

Again, see the changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link’s new “Email Table” button functionality.


Previous relevant Window SessionStorage Client Versus Server Share Tutorial is shown below.

Window SessionStorage Client Versus Server Share Tutorial

Window SessionStorage Client Versus Server Share Tutorial

Yesterday’s Window SessionStorage Client Versus Server Tutorial has been amended today for two new sharing and collaboration options, those being …

  • email
  • SMS

… but you may well be familiar with the restrictions on email and SMS client (program) approaches to this, coming from HTML “a” link “mailto:” and “sms:” href property prefixes respectively. We’re going to need help with the 800 odd character (length) restrictions with the (resultant) web address (bar) URL, but what? How about working off the great advice of this wonderful link, thanks, to copy what we’d have assembled into an ascii text Report into the characters contained by the user’s device’s clipboard?


function copytoclipboard(str) { // thanks to https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f
var el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}

An issue that springs up here using such clipboard ascii text content, whenever you get the Font choice given to you, pick a monospaced Font like Courier New or “Fixed Width”.

See the changed wls_vs_php.htm‘s Capital City Find Matching Country Report live run link’s new sharing functionality.


Previous relevant Window SessionStorage Client Versus Server Tutorial is shown below.

Window SessionStorage Client Versus Server Tutorial

Window SessionStorage Client Versus Server Tutorial

Sometimes it’s the case at this blog that we’d like to introduce a new topic, but do not do so, because we cannot show any real world (or real application) use of that concept. So it has been, up until now, with the concept of (web browser) window (object) sessionStorage property. But yesterday’s Window LocalStorage Client Versus Server Primer Tutorial represented an opportunity akin to when Haley’s Comet gets at its closest to the Earth … while you see a chance, take it … chance because of that nuance whereby we were not trying to store data for any other purpose than passing data onto …

  1. a known entity … ie. same web application … at …
  2. a known time … ie. immediately

… two conditions that make the code design “marginally” more ideal for the window object property concept of sessionStorage rather than localStorage, in that any …


localStorage.removeItem([knownLocalStorageName]);

… becomes superfluous as with sessionStorage data will disappear between web browser sessions, anyway.

We offer this new concept as a non-default option of a select (dropdown) element replacement to the h1 element hardcoding “localStorage” with the changed wls_vs_php.htm Capital City Find Matching Country Report live run. The other nuance of difference with sessionStorage usage is that in the document.body onload event logic, we may as well (as part of other changes) pre-emptively look for, and if there, respond to, any found sessionStorage data points, even without the user having flagged it specifically


var datamode='localStorage';

function checkforreport() {
var divcont='';
var dcaps, dctys, idis;
if (getcapitals == 'localStorage') {
if (window.localStorage) {
getcapitals=decodeURIComponent(localStorage.getItem('wls_vs_php_capitals')).replace(/\+/g,' ');
localStorage.removeItem('wls_vs_php_capitals');
} else {
getcapitals='';
}
} else if (getcapitals == 'sessionStorage') {
document.getElementById('smode').value=getcapitals;
datamode=getcapitals;
if (window.sessionStorage) {
getcapitals=decodeURIComponent(sessionStorage.getItem('wls_vs_php_capitals')).replace(/\+/g,' ');
} else {
getcapitals='';
}
}
else if (getcapitals == '' && window.sessionStorage) {
getcapitals=decodeURIComponent(('' + sessionStorage.getItem('wls_vs_php_capitals')).replace(/^null$/g,'')).replace(/\+/g,' ');
if (getcapitals != '') {
document.getElementById('smode').value='sessionStorage';
datamode='sessionStorage';
}
}

if (getcountries == 'localStorage') {
if (window.localStorage) {
getcountries=decodeURIComponent(localStorage.getItem('wls_vs_php_countries')).replace(/\+/g,' ');
if (getcapitals.replace('localStorage','') != '' && getcountries.replace('localStorage','') != '') { document.getElementById('myh1').innerHTML+=' <font size=1>... yes, it was needed</font>'; }
localStorage.removeItem('wls_vs_php_countries');
} else {
getcountries='';
}
} else if (getcountries == 'sessionStorage') {
if (window.sessionStorage) {
getcountries=decodeURIComponent(sessionStorage.getItem('wls_vs_php_countries')).replace(/\+/g,' ');
if (getcapitals.replace('sessionStorage','') != '' && getcountries.replace('sessionStorage','') != '') { document.getElementById('myh1').innerHTML+=' <font size=1>... yes, it was needed</font>'; }
} else {
getcountries='';
}
}
else if (getcountries == '' && document.getElementById('smode').value == 'sessionStorage' && window.sessionStorage) {
getcountries=decodeURIComponent(('' + sessionStorage.getItem('wls_vs_php_countries')).replace(/^null$/g,'')).replace(/\+/g,' ');
if (getcountries != '') {
document.getElementById('smode').value='sessionStorage';
datamode='sessionStorage';
}
}

if (getcapitals != '' && getcountries != '') {
divcont='<table border=5 style="width:95%;vertical-align:top;background-color:white;"><tr style=background-color:#f0f0f0;"><th>Capital</th><th>Country</th></tr></table>';
dcaps=getcapitals.split('|');
dctys=getcountries.split('|');
for (idis=0; idis<dcaps.length; idis++) {
divcont=divcont.replace('</table>', '<tr><td>' + dcaps[idis] + '</td><td>' + dctys[idis] + '</td></tr></table>');
}
document.getElementById('dreport').innerHTML=divcont;
}
document.getElementById('smode').value=datamode;
}

Which beggars the question “What are the differences between sessionStorage and localStorage?” A quick reading might surmise that “the latter has an expiration date”. We leave you with an open ended Google search so that you may extend your readings on this.


Previous relevant Window LocalStorage Client Versus Server Primer Tutorial is shown below.

Window LocalStorage Client Versus Server Primer Tutorial

Window LocalStorage Client Versus Server Primer Tutorial

Even though we rave on a lot about serverside PHP and its $_POST method=POST (versus HTML/Javascript recipient via ? and & argument $_GET method=GET scenario) data length advantages as the recipient of an HTML form method=POST set of data that could be sizeable, we’ve just realized that there is a client Javascript and window.localStorage methodology that may help alleviate the need to involve PHP (and any other serverside intervention) on occasions.

Hint: Yes, we’ve raved on about this too?! Does the blog posting title give it away? Okay, yes, it should read “localStorage”, but thought we’d gone past such juvenile finickiness since the Whac-A-Mole controversy of 1st December 2019 (or even The Great Tea Trolley Disaster of ’67, we daresay).

It can even use a “self-destruct” approach to the use of this “localStorage” on having used it because …

  • the web application knows who is using it (localStorage) … and on having accessed and read it …
  • the web application knows it (localStorage) is of no use to any other user (in this web application’s case, at least)

… which is very pleasing for a Land Surveyor who likes to leave cow paddocks as they’ve seen them so to speak. Except it’s like having a ten tonne truck worth of data access in amongst the cow pats when having access to “localStorage” (or PHP), rather than a little piddle of calf wee (wee Metcalfes know a thing or two about these things!) data access of ? and & HTML/Javascript URL arguments (or even if we were to use HTTP Cookies).

It’s not as if we all have access to serverside language usage, though we do, because we really like PHP and MAMP and Apache/PHP/MySql web servers (and have arranged our development environment accordingly), but what if you are starting out in web development, and still want to allow for sizeable chunks of data with your web applications? Huh? Huh?! See the possibilities? Try our proof of concept wls_vs_php.html Capital City Find Matching Country Report live run, and highlight a whole swathe of (multiple mode) dropdown option Capital Cities holding down the shift key before pressing the yellow “Report” button. If the URL ends up as …

https://rjmprogramming.com.au/HTMLCSS/wls_vs_php.html?capitals=localStorage&countries=localStorage

that’s because the web application’s …


function analyze() {
var purl=document.URL.split('#')[0].split('?')[0] + '?capitals=' + encodeURIComponent(document.getElementById('capitals').value) + '&countries=' + encodeURIComponent(document.getElementById('countries').value);
if (purl.length > 800) {
if (phpexists) {
document.getElementById('myform').method='POST';
document.getElementById('myform').action='./wls_vs_php.php';
} else if (window.localStorage) {
localStorage.setItem('wls_vs_php_countries', encodeURIComponent(document.getElementById('countries').value));
localStorage.setItem('wls_vs_php_capitals', encodeURIComponent(document.getElementById('capitals').value));
document.getElementById('capitals').value='localStorage';
document.getElementById('countries').value='localStorage';
location.href=document.URL.split('#')[0].split('?')[0] + '?capitals=' + encodeURIComponent(document.getElementById('capitals').value) + '&countries=' + encodeURIComponent(document.getElementById('countries').value);

return false;
}
}
return true;
}

… HTML form onsubmit event logic …

  1. discovered no PHP web application existant (via Client Pre-emptive Iframe techniques) … and …
  2. discovered (in a sanity check feeling way) that to go down the proposed HTML form method=GET approach was risking a …

    HTTP 414 "Request URI too long"

    … web browser error … and that …
  3. localStorage was a known web browser piece of functionality
  4. … and so as per our localStorage logic we …

  5. back out of the default HTML form method=GET navigation setup of the web application in favour of …
    • storing that data into localStorage
    • substituting into the URL ? and & arguments the hardcoding “localStorage” (and in so doing, getting back under the HTTP 414 “Request URI too long” limitation, piecing together (what amounts to) …
      location.href=document.URL.split(‘#’)[0].split(‘?’)[0] + ‘?capitals=localStorage&countries=localStorage’;)
      … that on a recall to this same web application a …
    • document.body onload event piece of Javascript logic checks the localStorage for its incoming Capital City Country Report data, as per …

      var phpexists=false;
      var getcapitals=location.search.split('capitals=')[1] ? decodeURIComponent(location.search.split('capitals=')[1].split('&')[0]).replace(/\+/g,' ') : '';
      var getcountries=location.search.split('countries=')[1] ? decodeURIComponent(location.search.split('countries=')[1].split('&')[0]).replace(/\+/g,' ') : '';

      function checkforreport() {
      var divcont='';
      var dcaps, dctys, idis;
      if (getcapitals == 'localStorage') {
      if (window.localStorage) {
      getcapitals=decodeURIComponent(localStorage.getItem('wls_vs_php_capitals')).replace(/\+/g,' ');
      localStorage.removeItem('wls_vs_php_capitals');
      } else {
      getcapitals='';
      }
      }
      if (getcountries == 'localStorage') {
      if (window.localStorage) {
      getcountries=decodeURIComponent(localStorage.getItem('wls_vs_php_countries')).replace(/\+/g,' ');
      if (getcapitals.replace('localStorage','') != '' && getcountries.replace('localStorage','') != '') { document.getElementById('myh1').innerHTML+=' <font size=1>... yes, it was needed</font>'; }
      localStorage.removeItem('wls_vs_php_countries');
      } else {
      getcountries='';
      }
      }

      if (getcapitals != '' && getcountries != '') {
      divcont='<table border=5 style="width:95%;vertical-align:top;background-color:white;"><tr style=background-color:#f0f0f0;"><th>Capital</th><th>Country</th></tr></table>';
      dcaps=getcapitals.split('|');
      dctys=getcountries.split('|');
      for (idis=0; idis<dcaps.length; idis++) {
      divcont=divcont.replace('</table>', '<tr><td>' + dcaps[idis] + '</td><td>' + dctys[idis] + '</td></tr></table>');
      }
      document.getElementById('dreport').innerHTML=divcont;
      }
      }

      … the localStorage.removeItem() representing that “self-destruct” nuance we were talking about before

We may well use this methodology in future projects, and hope it has been of some little interest to you as well?!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Tokeniser Primer Tutorial

PHP Tokeniser Primer Tutorial

PHP Tokeniser Primer Tutorial

Validation is a big subject area for programmers (we last discussed with XML Lint Validation Tutorial), and “when in a real pickle” I’ve turned to online HTML validators such as this one, but more often the web browser’s web inspector can help.

Here, changing from CentOS to AlmaLinux as the hosting Apache/PHP/MySql environment, we’ve been surprised by, even with PHP issues, the web browser web inspectors are by and large doing the job helping us debug issues. Nonetheless, we want to explore the Tokeniser PHP extension as a …

… best understood, we reckon, by trying it yourself …

Did you know?

For the first time we can remember we got over the perennial problem of form programming language code content encoding whereby a + equates to a space (on decoding) where we’d rather have %20 be used, as encodeURIComponent uses to encode the space character, by …

  1. on the way out, use (a form onsubmit event function incorporating) window.btoa
    <?php echo ”

    function btoait() {
    orig=document.getElementById('html').value;
    document.getElementById('html').value=window.btoa(orig);
    return true;
    }

    “; ?>

  2. teamed with, on the way in, incorporating base64_decode
    <?php

    $html_fragment=base64_decode($_POST['html']);

    ?>

… to get around that + character being misinterpreted. We find, though, that window.btoa can fail when there is a lot of data or complex data (or, it could have been a bad hair day?!)


Previous relevant XML Lint Validation Tutorial is shown below.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

Do you remember when we discussed the Sanitizer API, talked about at Sanitizer API Primer Tutorial, regarding it as a web application HTML (and more) validation tool?

Well, we’ve based a new “validator” of HTML or XML using the XML Lint web application on what we did then, but this code needing to be …

  • under the auspices of a serverside scenario … ie. PHP … for us … calling on …
  • underlying operating system call such as (for HTML qsall.htm incoming data file) …

    xmllint --html --valid --noout ./qsall.htm

    … via …
  • shell_exec

… there’s not much left of the original HTML and Javascript!

We had a fun time with HTML textarea elements and scrolling with the resultant “first draft” xmllint_validation.php you might want to try for yourself supplying an HTML or XML URL of intetest. Why, in particular? Well, it was the first time that we remember trying to make practically useful …

  • a table cell (ie. td element) (the left of two) hosted …
  • two textarea element arrangement whereby, ideally. they view …
    1. side by side
    2. if one is scrolled the two identically scroll the same amount … (document.body outerHTML) HTML …
      <?php echo ”

      <body onload="s1 = document.getElementById('preincoming'); s2 = document.getElementById('incoming'); s1.addEventListener('scroll', select_scroll_1, false); s2.addEventListener('scroll', select_scroll_2, false);" data-onload='onl();'>
      <h1>XML Lint Validation <!--button onclick='trythis();' title='Try your own'>Usage</button--></h1>
      <h3>RJM Programming - June, 2024</h3>
      <form action=./xmllint_validation.php method=POST target=_self>
      <table style=width:95%; border=5>
      <tr><th colspan=2 style=text-align:center;>XML Lint validation of <input style=width:70%; onblur="if (this.value.length > 0) { document.getElementById('mysub').click(); }" name=htmlfile id=myhxfile placeholder='Please enter either HTML or XML file to validate ...' value="<?php echo str_replace('>','>',str_replace('<','<',$prefn)); ?>"></input></th></tr>
      <tr><th>Data to validate</th><th>XML Lint results</th></tr>
      <tr><td style=vertical-align:top;><textarea style=font-size:8px;display:inline-block;overflow-x:clip;text-wrap:nowrap;text-align:right; id=preincoming><?php echo str_replace('>','>',str_replace('<','<',$precontents)); ?></textarea><textarea onblur="if (this.value.length > 0 && '<?echo $fn; ?>' == '') { document.getElementById('mysub').click(); }" style=font-size:8px;display:inline-block;overflow-x:clip;text-wrap:nowrap; name=content id=incoming><?php echo str_replace('>','>',str_replace('<','<',$contents)); ?></textarea></td><td style=vertical-align:top;><textarea id=outgoing><?php echo str_replace('>','>',str_replace('<','<',$results)); ?></textarea></td></tr>
      <tr><td></td><td><input type=submit id=mysub style=display:<?php echo $vsnone; ?> value=Validate></input></td></tr>
      </table>
      </form>
      </body>

      “; ?>
      … uses Javascript …
      <?php echo ”

      var s1=null, s2=null;

      // Thanks to https://stackoverflow.com/questions/7108270/scrolling-2-different-elements-in-same-time
      function select_scroll_1(e) { s2.scrollTop = s1.scrollTop; }
      function select_scroll_2(e) { s1.scrollTop = s2.scrollTop; }

      “; ?>
      … so that …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. the right hand textarea contains the code (HTML or XML) being validated by xmllint

    … while …

  • the right hand table cell contains the xmllint validation (of HTML or XML) results

… had us, in practice, thanking our lucky stars that …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

Today we’re roadtesting the Sanitizer API

The HTML Sanitizer API allow developers to take untrusted strings of HTML and Document or DocumentFragment objects, and sanitize them for safe insertion into a document’s DOM.

… as another validation idea for HTML to add to our previous HTML Online Validation Tidy Errors Tutorial efforts.

Perhaps you’d like to try the “Usage” button of the proof of concept web application below …

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Peer to Peer Locale Variants World Map Tutorial

PHP Intl Class Peer to Peer Locale Variants World Map Tutorial

PHP Intl Class Peer to Peer Locale Variants World Map Tutorial

Today, further to yesterday’s PHP Intl Class Peer to Peer Locale Variants Tutorial, we seek to answer questions such as …

Which countries in the world speak Arabic?

… and with a changed i_eg.js supporting a changed i_variant_eg.php and with the inhouse PHP intl class web application such questions are easier to answer on a Google Chart Geo Chart world map we start presenting.

And regarding “too thin” table cells hosting iframe hosting variant Current Datetimes, we also now offer onclick or oncontextmenu right click ways to show a “blow up view” of that same data in a table row below the top table row cells, which you can see and try for yourself below.

Now, in a data display sense, you might ask (via entering into yellow Locale textbox)

For a given Language can you show me Current Datetime in all the Countries of relevance using it?

Example below is for de German

For a given Script type can you show me Current Datetime in all the Countries of relevance using it?

Example below is for Latn script type

For a given Country can you show me Current Datetime in all the Languages of relevance to it?

Example below is for CY Cyprus


Previous relevant PHP Intl Class Peer to Peer Locale Variants Tutorial is shown below.

PHP Intl Class Peer to Peer Locale Variants Tutorial

PHP Intl Class Peer to Peer Locale Variants Tutorial

We’ve written a new member of “the peerage”, in other words, our inhouse PHP intl class web applications. It gathers variants of an entered Locale into a group we display Current Datetimes for in a series of HTML iframe hosting elements.

And if you’ve been keeping up with the goings on here, from yesterday’s PHP Intl Class Peer to Peer World Map Tutorial, you’ll know that we have code for the external Javascript to automatically change when a new member of “the peerage” is created, and we upload GETME files such as today’s i_variant_eg.php_GETME into place up at the RJM Programming domain as a web application

… with an updated peer to peer dropdown easily able to navigate the user to other web applications of its ilk.


Previous relevant PHP Intl Class Peer to Peer World Map Tutorial is shown below.

PHP Intl Class Peer to Peer World Map Tutorial

PHP Intl Class Peer to Peer World Map Tutorial

All the web applications in the suite of PHP intl class using web applications were capable of making a connection between …

Country Name and ISO-3166 2 letter Country Code suffixing a Locale … and … Emoji Flag

… setting our mind to an “across the board” improvement chance on top of progress up until yesterday’s PHP Intl Class Peer to Peer Serverside Tutorial.

And so, rather than change five members of “the peerage” …

  1. Sorting Words PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  2. Language Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  3. Region Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  4. Currency PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  5. Current Datetime PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript

… in any major way, rather we significantly changed the one i_eg.js as per


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php

var thisflagiso='', thisfemoji='';
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var herel=location.search.split('locale=')[1] ? decodeURIComponent(location.search.split('locale=')[1].split('&')[0]) : '';

if (document.head.innerHTML.indexOf('/i_eg.js?') != -1) {
var qs=document.head.innerHTML.split('/i_eg.js?')[1].split('"')[0].split("'")[0].split(' ')[0].split('>')[0];
if (qs.replace(/^rand\=/g,'').indexOf('=') != -1) {
candidates=decodeURIComponent(document.head.innerHTML.split('/i_eg.js?')[1].split('=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0]).replace(/\+/g,' ');
}
}

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function jorflag(thiscc) {
var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var dri=['127462','127463','127464','127465','127466','127467','127468','127469','127470','127471','127472','127473','127474','127475','127476','127477','127478','127479','127480','127481','127482','127483','127484','127485','127486','127487'];
var ccsuff='', ccchar=' ', cde='';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
cde='.';
}
if ((document.URL.split('#')[0] + '&').indexOf(encodeURIComponent('_') + thiscc.toUpperCase() + '&') != -1 && herel != '') {
if (thisfemoji == '' && thisflagiso != '') {
ccsuff=ccsuff;
} else {
thisflagiso=thiscc.toUpperCase();
thisfemoji=ccsuff;
setTimeout(geochartit, 20000);
}
}
return ccsuff;
}

function geochartit() {
var hostelt='', bighostelt='', resthostelt='', prefb='', ctynameisnow='';
//alert('0ccsuff');
if (thisfemoji == '' && thisflagiso != '') {
thisfemoji=jorflag(thisflagiso);
}
if (thisfemoji != '' && thisflagiso != '') {
//alert('1ccsuff');
if (!document.getElementById('ageoc') && document.getElementsByTagName('h1')[0].innerHTML.indexOf(thisfemoji) != -1) {
//alert('2ccsuff');
if (document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('<') != -1) {
prefb=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0];
ctynameisnow='%20in%20' + prefb.split('>')[eval(-1 + prefb.split('>').length)].trim() + '%20' + encodeURIComponent(thisfemoji);
//alert('ccsuff');
//bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
hostelt=bighostelt.split(' ')[0].split('>')[0];
resthostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[1].replace('</' + hostelt + '>', '').split('<')[0];
//alert('Resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
}
if (hostelt != '' && document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('</') == -1) {
//alert('resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
if (resthostelt.trim() != '') {
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a><' + bighostelt.split('>')[0] + '>' + resthostelt + '</' + hostelt + '>';
} else {
//alert(prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a>';
}
//alert('0:' + resthostelt + ' ... ' + document.getElementsByTagName('h1')[0].innerHTML);
} else {
document.getElementsByTagName('h1')[0].innerHTML=document.getElementsByTagName('h1')[0].innerHTML.replace(thisfemoji, "<a style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
thisfemoji='';
thisflagiso='';
//alert('1:' + document.getElementsByTagName('h1')[0].innerHTML);
}
}
}
}


function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');

if (herel != '') {
var piso=herel.split('_')[eval(-1 + herel.split('_').length)];
piso=piso.split('-')[eval(-1 + piso.split('-').length)];
if (eval('' + piso.length) == 2 && piso == piso.toUpperCase()) {
thisflagiso=piso;
setTimeout(geochartit, 22000);
}
}


if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}

hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… featuring an overridden function jorflag which explains our reordering of script tags we’ve talked about above.

And the benefits are that wherever you see an emoji flag in a heading tag of one of “the peerage” after a while the emoji flag can be clicked to create a popup window that shows the country relevant to the Locale involved shaded on a Google Chart Geo Chart world map.


Previous relevant PHP Intl Class Peer to Peer Serverside Tutorial is shown below.

PHP Intl Class Peer to Peer Serverside Tutorial

PHP Intl Class Peer to Peer Serverside Tutorial

Sometimes, in programming …

  • you’re stringent … especially regarding security matters, but most of the time, when we organize the programming rules, so to speak, we prefer it when …
  • you’re flexible

… and so, back with GraphViz via PHP on AlmaLinux Require Once Tutorial when we used a …

  • require_once … PHP calling paradigm (we’re not going to change it, because it is still fine) … we’re wondering now, why we didn’t use an …
  • include … paradigm, because the arrangement was optional

as per

The include (or require) statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement.

Including files is very useful when you want to include the same PHP, HTML, or text on multiple pages of a website.

… as with the optional nature of today’s PHP include paradigm call of a new i_eg_js.php piece of PHP we’ve decided should …

Can’t “when the need arises” be contentious?

… we hear you ask. Good question! We could jump the gun, before code is properly ready using PHP glob to look for files existant under the ./i_*eg.php file specification, and match them to what we have in the i_eg.js external Javascript, adding new entries when a mismatch is found. But that is where “local knowledge” can come into play (and the other aspect to “local knowledge” here is that the suite of PHP intl class using web applications all have a file specification suiting /i_*eg.php here). Genericity has it’s limits sometimes, in other words. Take a look at what we do to time this PHP rewrites external Javascript serverside intervention safely …

<?php

<?php
// i_eg_js.php
// RJM Programming - December, 2024
// Rewrite i_eg.js as needed

$iscand=false;
$pcont='';
$jscont='';
$phplistcomp='';
$desclistcomp='';
if (file_exists('./i_eg.js')) {
$jscont=file_get_contents('./i_eg.js');
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
if (sizeof($bitsphpa) > 1 && sizeof($bitsdesca) > 1) {
foreach (glob('./i_*eg.php') as $pfile) {
$iscand=false;
$pcont='';
if (strpos(' ' . explode('"', $bitsphpa[1])[0] . ' ', ' ' . basename($pfile) . ' ') === false) {
foreach (glob('./' . basename($pfile) . '*GETME') as $ppfile) {
$iscand=true;
}

}
if ($iscand) {
$pcont=file_get_contents('./' . basename($pfile));
if (strpos($pcont, '>Show ') === false) { $iscand=false; }
}
if ($iscand) {
$jscont=str_replace(' candidates="' . explode('"', $bitsphpa[1])[0] . '"', ' candidates="' . explode('"', $bitsphpa[1])[0] . ' ' . basename($pfile) . '"', $jscont);
$jscont=str_replace(' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . '"', ' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . ' ' . str_replace(' ','_',explode('"',explode('<', explode('>Show ', $pcont)[1])[0])[0]) . '"', $jscont);
file_put_contents('./i_eg.js', $jscont);
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
}
}
}
}

?>

Yes, we share via a GETME filename suffixing set of rules here at RJM Programming, and we only do that, and upload codefiles and GETME files to the RJM Programming web server via sftp means, when we’ve tested the code.

How is this new include paradigm PHP called in each PHP web application of …

  1. Sorting Words PHP code changed today this way and changed this way yesterday
  2. Language Name PHP code changed today this way and changed this way yesterday
  3. Region Name PHP code changed today this way and changed this way yesterday
  4. Currency PHP code changed today this way and changed this way yesterday
  5. Current Datetime PHP code changed today this way and changed this way yesterday

? As simple as now having …

<?php

include "i_eg_js.php";

?>

… up near the top of the PHP code and, unlike require_once these PHP suite web applications will not fall over should they not find i_eg_js.php in their same web server folder, and meaning the use of any of “the peerage” can look for new members without constantly having to update that external Javascript list, it flowing through to that dropdown, created via that external Javascript, updated, as required, by this new PHP include paradigm intervention.

Did you know?

If we’re not introducing any new PHP members of “the peerage” today, how did we test this thinking above, to our satisfaction? Simulating the scenario on our test Apache/PHP/MySql MAMP web server is how we tested it. We went, at the local macOS command line …


cp i_eg.php i_new_eg.php

… and tested, to be satisfied that the external Javascript remained unchanged, and then went …


cp i_eg.php i_new_eg.php_GETME

… to see that the external Javascript was appropriately changed, as you can see occurring in today’s tutorial picture. When happy, we undid all these changes, ready for when a new member of “the peerage” is really added, and then we’ll test further.


Previous relevant PHP Intl Class Peer to Peer Tutorial is shown below.

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

Today we’re implementing, on top of the progress of yesterday’s PHP Intl Class Word Sorting Primer Tutorial

  • a clientside (external Javascript called by the PHP) approach to gathering this PHP intl “Internationalization” class work into a suite of peer to peer web applications so that they can easily access each other rather than worrying about any web browser address bar (or bookmark) recalling of URLs in that group (once you get one under your belt, that is) … as maybe, another day, we’ll develop …
  • a serverside (PHP require/include) approach (helping out that clientside approach more generically and scientifically)

… meaning i_eg.js external Javascript …


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php
<>br>
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');
if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}


hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… is overseeing “the peerage” …

  1. Sorting Words
  2. Language Name
  3. Region Name
  4. Currency
  5. Current Datetime

… by constructing a new dropdown means of navigating into each …


<script type=text/javascript src=/i_eg.js></script>

… of the above PHP web applications.


Previous relevant PHP Intl Class Word Sorting Primer Tutorial is shown below.

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Peer to Peer Locale Variants Tutorial

PHP Intl Class Peer to Peer Locale Variants Tutorial

PHP Intl Class Peer to Peer Locale Variants Tutorial

We’ve written a new member of “the peerage”, in other words, our inhouse PHP intl class web applications. It gathers variants of an entered Locale into a group we display Current Datetimes for in a series of HTML iframe hosting elements.

And if you’ve been keeping up with the goings on here, from yesterday’s PHP Intl Class Peer to Peer World Map Tutorial, you’ll know that we have code for the external Javascript to automatically change when a new member of “the peerage” is created, and we upload GETME files such as today’s i_variant_eg.php_GETME into place up at the RJM Programming domain as a web application

… with an updated peer to peer dropdown easily able to navigate the user to other web applications of its ilk.


Previous relevant PHP Intl Class Peer to Peer World Map Tutorial is shown below.

PHP Intl Class Peer to Peer World Map Tutorial

PHP Intl Class Peer to Peer World Map Tutorial

All the web applications in the suite of PHP intl class using web applications were capable of making a connection between …

Country Name and ISO-3166 2 letter Country Code suffixing a Locale … and … Emoji Flag

… setting our mind to an “across the board” improvement chance on top of progress up until yesterday’s PHP Intl Class Peer to Peer Serverside Tutorial.

And so, rather than change five members of “the peerage” …

  1. Sorting Words PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  2. Language Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  3. Region Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  4. Currency PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  5. Current Datetime PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript

… in any major way, rather we significantly changed the one i_eg.js as per


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php

var thisflagiso='', thisfemoji='';
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var herel=location.search.split('locale=')[1] ? decodeURIComponent(location.search.split('locale=')[1].split('&')[0]) : '';

if (document.head.innerHTML.indexOf('/i_eg.js?') != -1) {
var qs=document.head.innerHTML.split('/i_eg.js?')[1].split('"')[0].split("'")[0].split(' ')[0].split('>')[0];
if (qs.replace(/^rand\=/g,'').indexOf('=') != -1) {
candidates=decodeURIComponent(document.head.innerHTML.split('/i_eg.js?')[1].split('=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0]).replace(/\+/g,' ');
}
}

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function jorflag(thiscc) {
var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var dri=['127462','127463','127464','127465','127466','127467','127468','127469','127470','127471','127472','127473','127474','127475','127476','127477','127478','127479','127480','127481','127482','127483','127484','127485','127486','127487'];
var ccsuff='', ccchar=' ', cde='';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
cde='.';
}
if ((document.URL.split('#')[0] + '&').indexOf(encodeURIComponent('_') + thiscc.toUpperCase() + '&') != -1 && herel != '') {
if (thisfemoji == '' && thisflagiso != '') {
ccsuff=ccsuff;
} else {
thisflagiso=thiscc.toUpperCase();
thisfemoji=ccsuff;
setTimeout(geochartit, 20000);
}
}
return ccsuff;
}

function geochartit() {
var hostelt='', bighostelt='', resthostelt='', prefb='', ctynameisnow='';
//alert('0ccsuff');
if (thisfemoji == '' && thisflagiso != '') {
thisfemoji=jorflag(thisflagiso);
}
if (thisfemoji != '' && thisflagiso != '') {
//alert('1ccsuff');
if (!document.getElementById('ageoc') && document.getElementsByTagName('h1')[0].innerHTML.indexOf(thisfemoji) != -1) {
//alert('2ccsuff');
if (document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('<') != -1) {
prefb=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0];
ctynameisnow='%20in%20' + prefb.split('>')[eval(-1 + prefb.split('>').length)].trim() + '%20' + encodeURIComponent(thisfemoji);
//alert('ccsuff');
//bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
hostelt=bighostelt.split(' ')[0].split('>')[0];
resthostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[1].replace('</' + hostelt + '>', '').split('<')[0];
//alert('Resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
}
if (hostelt != '' && document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('</') == -1) {
//alert('resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
if (resthostelt.trim() != '') {
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a><' + bighostelt.split('>')[0] + '>' + resthostelt + '</' + hostelt + '>';
} else {
//alert(prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a>';
}
//alert('0:' + resthostelt + ' ... ' + document.getElementsByTagName('h1')[0].innerHTML);
} else {
document.getElementsByTagName('h1')[0].innerHTML=document.getElementsByTagName('h1')[0].innerHTML.replace(thisfemoji, "<a style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
thisfemoji='';
thisflagiso='';
//alert('1:' + document.getElementsByTagName('h1')[0].innerHTML);
}
}
}
}


function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');

if (herel != '') {
var piso=herel.split('_')[eval(-1 + herel.split('_').length)];
piso=piso.split('-')[eval(-1 + piso.split('-').length)];
if (eval('' + piso.length) == 2 && piso == piso.toUpperCase()) {
thisflagiso=piso;
setTimeout(geochartit, 22000);
}
}


if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}

hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… featuring an overridden function jorflag which explains our reordering of script tags we’ve talked about above.

And the benefits are that wherever you see an emoji flag in a heading tag of one of “the peerage” after a while the emoji flag can be clicked to create a popup window that shows the country relevant to the Locale involved shaded on a Google Chart Geo Chart world map.


Previous relevant PHP Intl Class Peer to Peer Serverside Tutorial is shown below.

PHP Intl Class Peer to Peer Serverside Tutorial

PHP Intl Class Peer to Peer Serverside Tutorial

Sometimes, in programming …

  • you’re stringent … especially regarding security matters, but most of the time, when we organize the programming rules, so to speak, we prefer it when …
  • you’re flexible

… and so, back with GraphViz via PHP on AlmaLinux Require Once Tutorial when we used a …

  • require_once … PHP calling paradigm (we’re not going to change it, because it is still fine) … we’re wondering now, why we didn’t use an …
  • include … paradigm, because the arrangement was optional

as per

The include (or require) statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement.

Including files is very useful when you want to include the same PHP, HTML, or text on multiple pages of a website.

… as with the optional nature of today’s PHP include paradigm call of a new i_eg_js.php piece of PHP we’ve decided should …

Can’t “when the need arises” be contentious?

… we hear you ask. Good question! We could jump the gun, before code is properly ready using PHP glob to look for files existant under the ./i_*eg.php file specification, and match them to what we have in the i_eg.js external Javascript, adding new entries when a mismatch is found. But that is where “local knowledge” can come into play (and the other aspect to “local knowledge” here is that the suite of PHP intl class using web applications all have a file specification suiting /i_*eg.php here). Genericity has it’s limits sometimes, in other words. Take a look at what we do to time this PHP rewrites external Javascript serverside intervention safely …

<?php

<?php
// i_eg_js.php
// RJM Programming - December, 2024
// Rewrite i_eg.js as needed

$iscand=false;
$pcont='';
$jscont='';
$phplistcomp='';
$desclistcomp='';
if (file_exists('./i_eg.js')) {
$jscont=file_get_contents('./i_eg.js');
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
if (sizeof($bitsphpa) > 1 && sizeof($bitsdesca) > 1) {
foreach (glob('./i_*eg.php') as $pfile) {
$iscand=false;
$pcont='';
if (strpos(' ' . explode('"', $bitsphpa[1])[0] . ' ', ' ' . basename($pfile) . ' ') === false) {
foreach (glob('./' . basename($pfile) . '*GETME') as $ppfile) {
$iscand=true;
}

}
if ($iscand) {
$pcont=file_get_contents('./' . basename($pfile));
if (strpos($pcont, '>Show ') === false) { $iscand=false; }
}
if ($iscand) {
$jscont=str_replace(' candidates="' . explode('"', $bitsphpa[1])[0] . '"', ' candidates="' . explode('"', $bitsphpa[1])[0] . ' ' . basename($pfile) . '"', $jscont);
$jscont=str_replace(' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . '"', ' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . ' ' . str_replace(' ','_',explode('"',explode('<', explode('>Show ', $pcont)[1])[0])[0]) . '"', $jscont);
file_put_contents('./i_eg.js', $jscont);
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
}
}
}
}

?>

Yes, we share via a GETME filename suffixing set of rules here at RJM Programming, and we only do that, and upload codefiles and GETME files to the RJM Programming web server via sftp means, when we’ve tested the code.

How is this new include paradigm PHP called in each PHP web application of …

  1. Sorting Words PHP code changed today this way and changed this way yesterday
  2. Language Name PHP code changed today this way and changed this way yesterday
  3. Region Name PHP code changed today this way and changed this way yesterday
  4. Currency PHP code changed today this way and changed this way yesterday
  5. Current Datetime PHP code changed today this way and changed this way yesterday

? As simple as now having …

<?php

include "i_eg_js.php";

?>

… up near the top of the PHP code and, unlike require_once these PHP suite web applications will not fall over should they not find i_eg_js.php in their same web server folder, and meaning the use of any of “the peerage” can look for new members without constantly having to update that external Javascript list, it flowing through to that dropdown, created via that external Javascript, updated, as required, by this new PHP include paradigm intervention.

Did you know?

If we’re not introducing any new PHP members of “the peerage” today, how did we test this thinking above, to our satisfaction? Simulating the scenario on our test Apache/PHP/MySql MAMP web server is how we tested it. We went, at the local macOS command line …


cp i_eg.php i_new_eg.php

… and tested, to be satisfied that the external Javascript remained unchanged, and then went …


cp i_eg.php i_new_eg.php_GETME

… to see that the external Javascript was appropriately changed, as you can see occurring in today’s tutorial picture. When happy, we undid all these changes, ready for when a new member of “the peerage” is really added, and then we’ll test further.


Previous relevant PHP Intl Class Peer to Peer Tutorial is shown below.

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

Today we’re implementing, on top of the progress of yesterday’s PHP Intl Class Word Sorting Primer Tutorial

  • a clientside (external Javascript called by the PHP) approach to gathering this PHP intl “Internationalization” class work into a suite of peer to peer web applications so that they can easily access each other rather than worrying about any web browser address bar (or bookmark) recalling of URLs in that group (once you get one under your belt, that is) … as maybe, another day, we’ll develop …
  • a serverside (PHP require/include) approach (helping out that clientside approach more generically and scientifically)

… meaning i_eg.js external Javascript …


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php
<>br>
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');
if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}


hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… is overseeing “the peerage” …

  1. Sorting Words
  2. Language Name
  3. Region Name
  4. Currency
  5. Current Datetime

… by constructing a new dropdown means of navigating into each …


<script type=text/javascript src=/i_eg.js></script>

… of the above PHP web applications.


Previous relevant PHP Intl Class Word Sorting Primer Tutorial is shown below.

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Peer to Peer World Map Tutorial

PHP Intl Class Peer to Peer World Map Tutorial

PHP Intl Class Peer to Peer World Map Tutorial

All the web applications in the suite of PHP intl class using web applications were capable of making a connection between …

Country Name and ISO-3166 2 letter Country Code suffixing a Locale … and … Emoji Flag

… setting our mind to an “across the board” improvement chance on top of progress up until yesterday’s PHP Intl Class Peer to Peer Serverside Tutorial.

And so, rather than change five members of “the peerage” …

  1. Sorting Words PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  2. Language Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  3. Region Name PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  4. Currency PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript
  5. Current Datetime PHP code changed today this way only to reorder the external script call to be placed below the web application Javascript

… in any major way, rather we significantly changed the one i_eg.js as per


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php

var thisflagiso='', thisfemoji='';
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var herel=location.search.split('locale=')[1] ? decodeURIComponent(location.search.split('locale=')[1].split('&')[0]) : '';

if (document.head.innerHTML.indexOf('/i_eg.js?') != -1) {
var qs=document.head.innerHTML.split('/i_eg.js?')[1].split('"')[0].split("'")[0].split(' ')[0].split('>')[0];
if (qs.replace(/^rand\=/g,'').indexOf('=') != -1) {
candidates=decodeURIComponent(document.head.innerHTML.split('/i_eg.js?')[1].split('=')[1].split('&')[0].split('#')[0].split('"')[0].split("'")[0]).replace(/\+/g,' ');
}
}

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function jorflag(thiscc) {
var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var dri=['127462','127463','127464','127465','127466','127467','127468','127469','127470','127471','127472','127473','127474','127475','127476','127477','127478','127479','127480','127481','127482','127483','127484','127485','127486','127487'];
var ccsuff='', ccchar=' ', cde='';
for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
cde='.';
}
if ((document.URL.split('#')[0] + '&').indexOf(encodeURIComponent('_') + thiscc.toUpperCase() + '&') != -1 && herel != '') {
if (thisfemoji == '' && thisflagiso != '') {
ccsuff=ccsuff;
} else {
thisflagiso=thiscc.toUpperCase();
thisfemoji=ccsuff;
setTimeout(geochartit, 20000);
}
}
return ccsuff;
}

function geochartit() {
var hostelt='', bighostelt='', resthostelt='', prefb='', ctynameisnow='';
//alert('0ccsuff');
if (thisfemoji == '' && thisflagiso != '') {
thisfemoji=jorflag(thisflagiso);
}
if (thisfemoji != '' && thisflagiso != '') {
//alert('1ccsuff');
if (!document.getElementById('ageoc') && document.getElementsByTagName('h1')[0].innerHTML.indexOf(thisfemoji) != -1) {
//alert('2ccsuff');
if (document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('<') != -1) {
prefb=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0];
ctynameisnow='%20in%20' + prefb.split('>')[eval(-1 + prefb.split('>').length)].trim() + '%20' + encodeURIComponent(thisfemoji);
//alert('ccsuff');
//bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
bighostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].split('<')[eval(-1 + document.getElementsByTagName('h1')[0].innerHTML.split('</')[0].split(thisfemoji)[0].split('<').length)];
hostelt=bighostelt.split(' ')[0].split('>')[0];
resthostelt=document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[1].replace('</' + hostelt + '>', '').split('<')[0];
//alert('Resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
}
if (hostelt != '' && document.getElementsByTagName('h1')[0].innerHTML.split(thisfemoji)[0].indexOf('</') == -1) {
//alert('resthostelt=' + resthostelt + ' and hostelt=' + hostelt + ' and bighostelt=' + bighostelt);
if (resthostelt.trim() != '') {
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a><' + bighostelt.split('>')[0] + '>' + resthostelt + '</' + hostelt + '>';
} else {
//alert(prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
document.getElementsByTagName('h1')[0].innerHTML=prefb + "</" + hostelt + "><a id=ageoc style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives" + ctynameisnow + "&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=200,left=200,width=630,height=600');\">" + thisfemoji + '</a>';
}
//alert('0:' + resthostelt + ' ... ' + document.getElementsByTagName('h1')[0].innerHTML);
} else {
document.getElementsByTagName('h1')[0].innerHTML=document.getElementsByTagName('h1')[0].innerHTML.replace(thisfemoji, "<a style=cursor:pointer;text-decoration:none; title=GeoChart onclick=\"window.open('//www.rjmprogramming.com.au/PHP/GeoChart/geo_chart.php?title=Where%20Locale%20" + encodeURIComponent(herel) + "%20Lives&width=556&height=347&country=Country&popularity=Popularity&data=%20[~" + thisflagiso + '~,2]' + "','_blank','top=100,left=100,width=600,height=600');\">" + thisfemoji + '</a>');
thisfemoji='';
thisflagiso='';
//alert('1:' + document.getElementsByTagName('h1')[0].innerHTML);
}
}
}
}


function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');

if (herel != '') {
var piso=herel.split('_')[eval(-1 + herel.split('_').length)];
piso=piso.split('-')[eval(-1 + piso.split('-').length)];
if (eval('' + piso.length) == 2 && piso == piso.toUpperCase()) {
thisflagiso=piso;
setTimeout(geochartit, 22000);
}
}


if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}

hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… featuring an overridden function jorflag which explains our reordering of script tags we’ve talked about above.

And the benefits are that wherever you see an emoji flag in a heading tag of one of “the peerage” after a while the emoji flag can be clicked to create a popup window that shows the country relevant to the Locale involved shaded on a Google Chart Geo Chart world map.


Previous relevant PHP Intl Class Peer to Peer Serverside Tutorial is shown below.

PHP Intl Class Peer to Peer Serverside Tutorial

PHP Intl Class Peer to Peer Serverside Tutorial

Sometimes, in programming …

  • you’re stringent … especially regarding security matters, but most of the time, when we organize the programming rules, so to speak, we prefer it when …
  • you’re flexible

… and so, back with GraphViz via PHP on AlmaLinux Require Once Tutorial when we used a …

  • require_once … PHP calling paradigm (we’re not going to change it, because it is still fine) … we’re wondering now, why we didn’t use an …
  • include … paradigm, because the arrangement was optional

as per

The include (or require) statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement.

Including files is very useful when you want to include the same PHP, HTML, or text on multiple pages of a website.

… as with the optional nature of today’s PHP include paradigm call of a new i_eg_js.php piece of PHP we’ve decided should …

Can’t “when the need arises” be contentious?

… we hear you ask. Good question! We could jump the gun, before code is properly ready using PHP glob to look for files existant under the ./i_*eg.php file specification, and match them to what we have in the i_eg.js external Javascript, adding new entries when a mismatch is found. But that is where “local knowledge” can come into play (and the other aspect to “local knowledge” here is that the suite of PHP intl class using web applications all have a file specification suiting /i_*eg.php here). Genericity has it’s limits sometimes, in other words. Take a look at what we do to time this PHP rewrites external Javascript serverside intervention safely …

<?php

<?php
// i_eg_js.php
// RJM Programming - December, 2024
// Rewrite i_eg.js as needed

$iscand=false;
$pcont='';
$jscont='';
$phplistcomp='';
$desclistcomp='';
if (file_exists('./i_eg.js')) {
$jscont=file_get_contents('./i_eg.js');
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
if (sizeof($bitsphpa) > 1 && sizeof($bitsdesca) > 1) {
foreach (glob('./i_*eg.php') as $pfile) {
$iscand=false;
$pcont='';
if (strpos(' ' . explode('"', $bitsphpa[1])[0] . ' ', ' ' . basename($pfile) . ' ') === false) {
foreach (glob('./' . basename($pfile) . '*GETME') as $ppfile) {
$iscand=true;
}

}
if ($iscand) {
$pcont=file_get_contents('./' . basename($pfile));
if (strpos($pcont, '>Show ') === false) { $iscand=false; }
}
if ($iscand) {
$jscont=str_replace(' candidates="' . explode('"', $bitsphpa[1])[0] . '"', ' candidates="' . explode('"', $bitsphpa[1])[0] . ' ' . basename($pfile) . '"', $jscont);
$jscont=str_replace(' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . '"', ' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . ' ' . str_replace(' ','_',explode('"',explode('<', explode('>Show ', $pcont)[1])[0])[0]) . '"', $jscont);
file_put_contents('./i_eg.js', $jscont);
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
}
}
}
}

?>

Yes, we share via a GETME filename suffixing set of rules here at RJM Programming, and we only do that, and upload codefiles and GETME files to the RJM Programming web server via sftp means, when we’ve tested the code.

How is this new include paradigm PHP called in each PHP web application of …

  1. Sorting Words PHP code changed today this way and changed this way yesterday
  2. Language Name PHP code changed today this way and changed this way yesterday
  3. Region Name PHP code changed today this way and changed this way yesterday
  4. Currency PHP code changed today this way and changed this way yesterday
  5. Current Datetime PHP code changed today this way and changed this way yesterday

? As simple as now having …

<?php

include "i_eg_js.php";

?>

… up near the top of the PHP code and, unlike require_once these PHP suite web applications will not fall over should they not find i_eg_js.php in their same web server folder, and meaning the use of any of “the peerage” can look for new members without constantly having to update that external Javascript list, it flowing through to that dropdown, created via that external Javascript, updated, as required, by this new PHP include paradigm intervention.

Did you know?

If we’re not introducing any new PHP members of “the peerage” today, how did we test this thinking above, to our satisfaction? Simulating the scenario on our test Apache/PHP/MySql MAMP web server is how we tested it. We went, at the local macOS command line …


cp i_eg.php i_new_eg.php

… and tested, to be satisfied that the external Javascript remained unchanged, and then went …


cp i_eg.php i_new_eg.php_GETME

… to see that the external Javascript was appropriately changed, as you can see occurring in today’s tutorial picture. When happy, we undid all these changes, ready for when a new member of “the peerage” is really added, and then we’ll test further.


Previous relevant PHP Intl Class Peer to Peer Tutorial is shown below.

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

Today we’re implementing, on top of the progress of yesterday’s PHP Intl Class Word Sorting Primer Tutorial

  • a clientside (external Javascript called by the PHP) approach to gathering this PHP intl “Internationalization” class work into a suite of peer to peer web applications so that they can easily access each other rather than worrying about any web browser address bar (or bookmark) recalling of URLs in that group (once you get one under your belt, that is) … as maybe, another day, we’ll develop …
  • a serverside (PHP require/include) approach (helping out that clientside approach more generically and scientifically)

… meaning i_eg.js external Javascript …


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php
<>br>
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');
if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}


hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… is overseeing “the peerage” …

  1. Sorting Words
  2. Language Name
  3. Region Name
  4. Currency
  5. Current Datetime

… by constructing a new dropdown means of navigating into each …


<script type=text/javascript src=/i_eg.js></script>

… of the above PHP web applications.


Previous relevant PHP Intl Class Word Sorting Primer Tutorial is shown below.

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Peer to Peer Serverside Tutorial

PHP Intl Class Peer to Peer Serverside Tutorial

PHP Intl Class Peer to Peer Serverside Tutorial

Sometimes, in programming …

  • you’re stringent … especially regarding security matters, but most of the time, when we organize the programming rules, so to speak, we prefer it when …
  • you’re flexible

… and so, back with GraphViz via PHP on AlmaLinux Require Once Tutorial when we used a …

  • require_once … PHP calling paradigm (we’re not going to change it, because it is still fine) … we’re wondering now, why we didn’t use an …
  • include … paradigm, because the arrangement was optional

as per

The include (or require) statement takes all the text/code/markup that exists in the specified file and copies it into the file that uses the include statement.

Including files is very useful when you want to include the same PHP, HTML, or text on multiple pages of a website.

… as with the optional nature of today’s PHP include paradigm call of a new i_eg_js.php piece of PHP we’ve decided should …

Can’t “when the need arises” be contentious?

… we hear you ask. Good question! We could jump the gun, before code is properly ready using PHP glob to look for files existant under the ./i_*eg.php file specification, and match them to what we have in the i_eg.js external Javascript, adding new entries when a mismatch is found. But that is where “local knowledge” can come into play (and the other aspect to “local knowledge” here is that the suite of PHP intl class using web applications all have a file specification suiting /i_*eg.php here). Genericity has it’s limits sometimes, in other words. Take a look at what we do to time this PHP rewrites external Javascript serverside intervention safely …

<?php

<?php
// i_eg_js.php
// RJM Programming - December, 2024
// Rewrite i_eg.js as needed

$iscand=false;
$pcont='';
$jscont='';
$phplistcomp='';
$desclistcomp='';
if (file_exists('./i_eg.js')) {
$jscont=file_get_contents('./i_eg.js');
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
if (sizeof($bitsphpa) > 1 && sizeof($bitsdesca) > 1) {
foreach (glob('./i_*eg.php') as $pfile) {
$iscand=false;
$pcont='';
if (strpos(' ' . explode('"', $bitsphpa[1])[0] . ' ', ' ' . basename($pfile) . ' ') === false) {
foreach (glob('./' . basename($pfile) . '*GETME') as $ppfile) {
$iscand=true;
}

}
if ($iscand) {
$pcont=file_get_contents('./' . basename($pfile));
if (strpos($pcont, '>Show ') === false) { $iscand=false; }
}
if ($iscand) {
$jscont=str_replace(' candidates="' . explode('"', $bitsphpa[1])[0] . '"', ' candidates="' . explode('"', $bitsphpa[1])[0] . ' ' . basename($pfile) . '"', $jscont);
$jscont=str_replace(' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . '"', ' candidatesdesc="' . explode('"', $bitsdesca[1])[0] . ' ' . str_replace(' ','_',explode('"',explode('<', explode('>Show ', $pcont)[1])[0])[0]) . '"', $jscont);
file_put_contents('./i_eg.js', $jscont);
$bitsphpa=explode(' candidates="', $jscont);
$bitsdesca=explode(' candidatesdesc="', $jscont);
}
}
}
}

?>

Yes, we share via a GETME filename suffixing set of rules here at RJM Programming, and we only do that, and upload codefiles and GETME files to the RJM Programming web server via sftp means, when we’ve tested the code.

How is this new include paradigm PHP called in each PHP web application of …

  1. Sorting Words PHP code changed today this way and changed this way yesterday
  2. Language Name PHP code changed today this way and changed this way yesterday
  3. Region Name PHP code changed today this way and changed this way yesterday
  4. Currency PHP code changed today this way and changed this way yesterday
  5. Current Datetime PHP code changed today this way and changed this way yesterday

? As simple as now having …

<?php

include "i_eg_js.php";

?>

… up near the top of the PHP code and, unlike require_once these PHP suite web applications will not fall over should they not find i_eg_js.php in their same web server folder, and meaning the use of any of “the peerage” can look for new members without constantly having to update that external Javascript list, it flowing through to that dropdown, created via that external Javascript, updated, as required, by this new PHP include paradigm intervention.

Did you know?

If we’re not introducing any new PHP members of “the peerage” today, how did we test this thinking above, to our satisfaction? Simulating the scenario on our test Apache/PHP/MySql MAMP web server is how we tested it. We went, at the local macOS command line …


cp i_eg.php i_new_eg.php

… and tested, to be satisfied that the external Javascript remained unchanged, and then went …


cp i_eg.php i_new_eg.php_GETME

… to see that the external Javascript was appropriately changed, as you can see occurring in today’s tutorial picture. When happy, we undid all these changes, ready for when a new member of “the peerage” is really added, and then we’ll test further.


Previous relevant PHP Intl Class Peer to Peer Tutorial is shown below.

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

Today we’re implementing, on top of the progress of yesterday’s PHP Intl Class Word Sorting Primer Tutorial

  • a clientside (external Javascript called by the PHP) approach to gathering this PHP intl “Internationalization” class work into a suite of peer to peer web applications so that they can easily access each other rather than worrying about any web browser address bar (or bookmark) recalling of URLs in that group (once you get one under your belt, that is) … as maybe, another day, we’ll develop …
  • a serverside (PHP require/include) approach (helping out that clientside approach more generically and scientifically)

… meaning i_eg.js external Javascript …


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php
<>br>
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');
if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}


hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… is overseeing “the peerage” …

  1. Sorting Words
  2. Language Name
  3. Region Name
  4. Currency
  5. Current Datetime

… by constructing a new dropdown means of navigating into each …


<script type=text/javascript src=/i_eg.js></script>

… of the above PHP web applications.


Previous relevant PHP Intl Class Word Sorting Primer Tutorial is shown below.

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

PHP Intl Class Peer to Peer Tutorial

Today we’re implementing, on top of the progress of yesterday’s PHP Intl Class Word Sorting Primer Tutorial

  • a clientside (external Javascript called by the PHP) approach to gathering this PHP intl “Internationalization” class work into a suite of peer to peer web applications so that they can easily access each other rather than worrying about any web browser address bar (or bookmark) recalling of URLs in that group (once you get one under your belt, that is) … as maybe, another day, we’ll develop …
  • a serverside (PHP require/include) approach (helping out that clientside approach more generically and scientifically)

… meaning i_eg.js external Javascript …


// i_eg.js
// RJM Programming - December, 2024
// Allow for peer to peer access amongst i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php
<>br>
var candidates="i_eg.php i_cur_eg.php i_region_eg.php i_language_eg.php i_sort_eg.php";
var candidatesd=candidates;
var candidatesdesc="Current_Datetime Currency Region_Name Language_Name Sort_Words";
var candidatesdarr=candidates.replace(/\,/g,' ').split(' ');

var candidatesarr=candidates.replace(/\,/g,' ').split(' ');

function hthreesel() {
var icv=0, hthreesuffix='', curone='', curdesc='', compone=document.URL.split('?')[0].split('#')[0].split('/')[eval(-1 + document.URL.split('?')[0].split('#')[0].split('/').length)];
var hthreearr=document.getElementsByTagName('h3');
if (eval('' + hthreearr.length) > 0) {
if (hthreearr[0].outerHTML.indexOf('</select>') == -1 && candidates.trim() != '' && eval('' + candidatesarr.length) > 0) {
if ((' ' + candidatesd.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('1:' + compone + ' found at ' + candidatesdarr.indexOf(curone));
curdesc=candidatesdesc.split(' ')[candidatesdarr.indexOf(curone)].replace(/\_/g, ' ');
//alert(curdesc);
}
if (curone == '') {
if ((' ' + candidates.replace(/\+/g,' ') + ' ').indexOf(' ' + compone + ' ') != -1) {
curone=compone;
//alert('11:' + compone);
if (curone.indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
curdesc=curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + curone.split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase();
}
}
}


hthreesuffix='<select onchange="location.href=this.value;"><option value="' + document.URL.split('?')[0].split('#')[0] + '">Optionally select peer ' + ('to ' + curdesc).replace(/^to\ $/g, '') + ' web application below ...</option></select>';
for (icv=0; icv<candidatesarr.length; icv++) {
if (candidatesdarr.indexOf(candidatesarr[icv]) != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesdesc.split(' ')[candidatesdarr.indexOf(candidatesarr[icv])]).replace(/\_/g,' ') + '</option></select>');
} else if (candidatesarr[icv].indexOf('i_') == 0 && curone.indexOf('_eg.') != -1) {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + ('' + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(0,1).toUpperCase() + candidatesarr[icv].split('i_')[1].split('_eg.')[0].replace(/\_/g,' ').substring(1).toLowerCase()).replace(/\_/g,' ') + '</option></select>');
} else {
hthreesuffix=hthreesuffix.replace('</select>', '<option value="/' + candidatesarr[icv] + '">' + candidatesarr[icv] + '</option></select>');
}
}

if (hthreesuffix != '') {
if (curone != '' && curdesc != '') {
hthreearr[0].innerHTML+='  ' + hthreesuffix.replace('</select>', '<option value="/' + curone + '">' + curdesc + '</option></select>');
} else {
hthreearr[0].innerHTML+='  ' + hthreesuffix;
}
}
}
}
}

setTimeout(hthreesel, 2000);

… is overseeing “the peerage” …

  1. Sorting Words
  2. Language Name
  3. Region Name
  4. Currency
  5. Current Datetime

… by constructing a new dropdown means of navigating into each …


<script type=text/javascript src=/i_eg.js></script>

… of the above PHP web applications.


Previous relevant PHP Intl Class Word Sorting Primer Tutorial is shown below.

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

PHP Intl Class Word Sorting Primer Tutorial

The PHP intl “Internationalization” class can help with an issue that has haunted me for many years. When you sort words in my English biased way, will they be sorted the same way in other languages, given alphabets and diacritics (with thanks to this excellent link regarding an example we’re defaulting to in the web application) and emojis and non-ascii characters, in various keyboard configurations, which might happen with words expressing the human condition? Luckily, the PHP intl class has

<?php

function sortit($arr, $thisloc) {
global $dias, $dia, $tabis;
$coll = collator_create( $thisloc );
//$arr = array( 'at', 'às', 'as' );
//var_export( $arr );
if (!isset($_GET['sorttype']) && !isset($_POST['sorttype'])) {
collator_sort( $coll, $arr );
} else if (isset($_GET['sorttype'])) {
if (strpos($_GET['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_GET['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_GET['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
} else if (isset($_POST['sorttype'])) {
if (strpos($_POST['sorttype'], 'REGULAR') !== false) {
collator_sort( $coll, $arr, Collator::SORT_REGULAR );
} else if (strpos($_POST['sorttype'], 'NUMERIC') !== false) {
collator_sort( $coll, $arr, Collator::SORT_NUMERIC );
} else if (strpos($_POST['sorttype'], 'STRING') !== false) {
collator_sort( $coll, $arr, Collator::SORT_STRING );
} else {
collator_sort( $coll, $arr );
}
}
//var_export( $arr );
for ($ij=(-1 + sizeof($arr)); $ij>=0; $ij--) {
$tabis=str_replace('<td id="sorttd">', '<td id="sorttd">' . $arr[$ij] . '<br>', $tabis);
}
echo $tabis;
}

?>

… to verify, one way or the other, and thanks to a heads up from this useful link here, further to yesterday’s PHP Intl Class Language Names Primer Tutorial.

Again, feel free to try a new “proof of concept” i_sort_eg.php Word Sorting Internationalization web application, where you can test out these concepts yourself, using your own word lists, you can enter into textarea elements.


Previous relevant PHP Intl Class Language Names Primer Tutorial is shown below.

PHP Intl Class Language Names Primer Tutorial

PHP Intl Class Language Names Primer Tutorial

You might have noticed over the last week (further to yesterday’s PHP Intl Class Region Names Primer Tutorial) or so, how useful …

Locales

… are as a data item involved with PHP intl “Internationalization” class programming work.

As an example Locale …


pt_BR

… we’ve been making quite a lot out of the “BR” ISO-3166 2 letter Country Code as the suffix of such a Locale. But what about the prefix of Locales? That prefix maps to an ISO-639 Language Code, meaning any derivable (ie. via our keyboard onkeydown and oninput logics) set of Locales could tell us (at the very least) two types of information, exemplifying the case above …

List of Countries using pt Portuguese List of Languages used in BR Brazil
pt pt_AO pt_BR pt_CH pt_CV pt_GQ pt_GW pt_LU pt_MO pt_MZ pt_PT pt_ST pt_TL es_BR pt_BR

All “code talk” above, but what about some Language Names, because you are not likely to ask down at Copacabana Beach …

Ei, cara! Você falar es?

That’s where we thank https://www.php.net/manual/en/locale.getprimarylanguage.php for the “heads up” to use code as per the followup to $lochelper and $lochelpertwo data flows to help with these Language Name determinations …

<?php

$locsel='';
$altinlang='';
$locit=user_agent();
$arrl=ResourceBundle::getLocales('');
for ($df=0; $df<sizeof($arrl); $df++) {
$endih='';
$lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
$isalt=false;
if (isset($_GET['languagecode'])) {
if (strlen($_GET['languagecode']) > 0) {
if ($lastword == $_GET['languagecode']) { $isalt=true; }
}
} else if (isset($_POST['languagecode'])) {
if (strlen($_POST['languagecode']) > 0) {
if ($lastword == $_POST['languagecode']) { $isalt=true; }
}
}
$ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
if (sizeof($ends) > 1) {
$endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if (explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0] != '') {
$inlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
if ($isalt) { $altinlang=' is ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0]; }
}
}
if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
//echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
$interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
//exit;
//if ($isalt) { echo $interim; exit; }
$aintm=explode('>', str_replace('</a>','',$interim))[-1 + sizeof(explode('>', str_replace('</a>','',$interim) ))];
//if ($isalt) { echo $interim . '<br>' . $aintm . '<br>' . $endih; exit; }
if (strpos($endih, ' ' . $aintm) === false) {
if ($endih != '') {
$endih.=' (' . $aintm . ')';
$inlang=' is ' . $aintm;
if ($isalt) {
//echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
} else {
$endih.=' ' . $aintm;
if ($isalt) {
//echo "Yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
if ($altinlang != '') {
$altinlang.=' (' . $aintm . ')';
} else {
$altinlang=' is ' . $aintm;
}
}
}
}
}
if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
$endih.=' ' . orflag($lastword);
}
if ($endih != '') {
$endih="\t" . $endih . '';
}
if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
if ($locsel == '') {
$locsel="<select ontouchdown=ots(event); onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=(this.value); document.getElementById('justincase').src=document.URL.split('?')[0].split('#')[0] + '?ccode=' + this.value.split('_')[0].split('-')[0]; }\" id=locsel>
<option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
}
if ($locit != 'pc' && 1 == 1) {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . ' ' . $endih . "</option></select>", $locsel);
} else {
$locsel=str_replace("</select>", "
<option value='" . $arrl[$df] . "' translate=\"no\" data-ontouchstart=ots(event); title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
}
}
}

?>

So, feel free to try a new “proof of concept” i_language_eg.php Language Names Internationalization web application.


Previous relevant PHP Intl Class Region Names Primer Tutorial is shown below.

PHP Intl Class Region Names Primer Tutorial

PHP Intl Class Region Names Primer Tutorial

Apart from Ghostbusters who do you turn to when you want to know what a resident of a region calls their region?

Still, Ghostbusters, you must be pulling my leg?!

Anyway, further to yesterday’s PHP Intl Class Currency Primer Tutorial, we’ve turned to good ol’ PHP.net, as usual (when it comes to many matters PHP).

In amongst all the ISO code usage we seek when interfacing to the PHP intl “Internationalization” class, because they are definitive, even so, we feel we need to allow users to enter Country Names, as one concept, especially as Country Names have been there before any ISO codes even started. The trouble with Country Names is twofold …

  • it is not a reliable indexer, if you get my drift, because there are lots of forms, in any language you pick, for what a Country Name is
  • at least for an English representation of a Country Name we’d like consistency, and, happily, the PHP intl “Internationalization” class can provide it

… via PHP code of the ilk …

<?php

echo "<p id=pdfmt>" . locale_get_display_region(urldecode($_GET['locale']), urldecode($_GET['displaylocale'])) . "</p><br>";

?>

As you might imagine, this discovery can have mildly wide ranging implications … well, you had to be there … on …

…PHP intl class suite of web applications we’re not letting Ghostbusters anywhere near!


Previous relevant PHP Intl Class Currency Primer Tutorial is shown below.

PHP Intl Class Currency Primer Tutorial

PHP Intl Class Currency Primer Tutorial

We’re back with the PHP intl “Internationalization” class, today, last talked about with the recent PHP Intl Class Datetime Keyboard Events Tutorial, this time discussing …

Currency Internationalization

… topics. Again, we found the Locale data item, as with Datetimes, the main data item of interest. But, any one Country can use more than one Currency (defined by an ISO-4217 3 letter Currency Code) in this new PHP Intl using Currency web application we’ve started developing today, and on a Locale selection we choose the first such one, and leave it open to the user to be able to type in their own ISO-4217 three letter Currency Code, as required.

We got great help from https://stackoverflow.com/questions/76825595/php-format-currency-issue with codeline ideas, such as …

<?php

$formatter = new NumberFormatter(urldecode($_GET['locale']), NumberFormatter::CURRENCY);
if (isset($_GET['amount'])) {
echo "<p id=pdfmt>" . $formatter->formatCurrency(urldecode($_GET['amount']), urldecode($_GET['currency'])) . "</p><br>";
} else {
echo "<p id=pdfmt>" . $formatter->formatCurrency(76543.210, urldecode($_GET['currency'])) . "</p><br>";
}

?>

The work of Datetimes, ahead of all this, has meant it is easier to get “further down the track” for today’s “proof of concept” i_cur_eg.php PHP code start, that has keyboard event and dropdown logics all in there, and which you can try below …


Previous relevant PHP Intl Class Datetime Keyboard Events Tutorial is shown below.

PHP Intl Class Datetime Keyboard Events Tutorial

PHP Intl Class Datetime Keyboard Events Tutorial

As far as “user interaction” goes with our Current Datetime PHP web application of PHP Intl Class Datetime Google Translate Tutorial we’ve been thinking …

  • the user would be more likely to use the dropdown element selection methods … but supposing …
  • the user uses the keyboard to enter Locale and/or Timezone

… and, as of yesterday’s logic, that would have been quite unwieldy, especially regarding timezone entries.

And so, today, we’ve added keyboard onkeydown and oninput event logics to cater for several scenarios we can “shortcut” those user requirements, often down to the entry of a couple or a few characters, and from there click appropriate created links in …

<?php echo ”

var morechanges=true;
var lastwo='';
var woi=null;
var oko=null;
var nlastokn='';
var xokn='';
var xlastconto=[];
var xmorechanges=true;
var xlastwo='';
var xwoi=null;
var xoko=null;

function precval(iois) {
//okn=iois.value;
oko=iois;
lastokn=okn;
}

function xprecval(iois) {
//okn=iois.value;
xoko=iois;
xlastokn=xokn;
}

function cval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('2:' + eiois.which); }
//okn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
okn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
okn=okn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=okn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
okn='' + scs;
oko.value=okn;
lastokn=okn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
okn+=String.fromCharCode(47);
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(95);
} else {
okn+=String.fromCharCode(45);
}
if (eval('' + okn.length) > 1) { expandokn(); }
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
okn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
//document.title='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
if (eval('' + okn.length) > 1) { expandokn(); }
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
okn=okn;
} else if (1 == 3) {
okn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=1:' + okn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function xcval(eiois) {
//if (document.URL.indexOf('i0=') == -1) {
//if (eiois.which != 16) { alert('1:' + eiois.which); }
//xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
if ((eiois.which || eiois.keyCode) == 8) {
xokn='';
} else if ((eiois.which || eiois.keyCode) == 186 || (eiois.which || eiois.keyCode) == 900000016) {
xokn=xokn.replace(':','') + ':';
//document.title=okn + ' ' + (eiois.which || eiois.keyCode);
var cvi=xokn.split(':');
if (cvi.length > 1) {
var scs=0.0, factor=1.0;
for (var ij=eval(-1 + cvi.length); ij>=0; ij--) {
if (cvi[ij] == '') cvi[ij]='00';
scs+=eval(factor * eval(cvi[ij]));
factor*=60.0;
}
//alert(scs + ' ' + okn);
xokn='' + scs;
xoko.value=xokn;
xlastokn=xokn.replace(':','');
//document.title=okn + ' ' + (eiois.which || eiois.keyCode) + ' ' + oko.value;
//setTimeout(fixval,30);
}
} else if ((eiois.which || eiois.keyCode) == 191) {
if (!eiois.shiftKey) {
xokn+=String.fromCharCode(47);
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
} else if ((eiois.which || eiois.keyCode) == 189) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(95);
} else {
xokn+=String.fromCharCode(45);
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if (eiois.keyCode == 189 || (eiois.which || eiois.keyCode) >= 65 && (eiois.which || eiois.keyCode) <= 90) {
if (eiois.shiftKey) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
} else {
xokn+=String.fromCharCode(eval(32 + eval(eiois.which || eiois.keyCode)));
}
if (eval('' + xokn.length) > 1) { expandxokn(); }
//document.title='=2:' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
} else if ((eiois.which || eiois.keyCode) < 46 || (eiois.which || eiois.keyCode) > 58) {
xokn=xokn;
} else if (1 == 3) {
xokn+=String.fromCharCode(eiois.which || eiois.keyCode);
document.title+='=' + xokn + '+' + eiois.which + ' ' + eiois.keyCode + ' ... ';
}
//}
}

function expandokn() {
var iut=0, pls=[],firsttz='',tzsih='',xtzsih='',thatloc='', wds=[];
if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn != okn.toUpperCase()) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split('>' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + okn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
} else if (okn.substring(0,1) == okn.substring(0,1).toLowerCase() && okn == okn.toLowerCase()) {
xtzsih=document.getElementById('tzsel').innerHTML;
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split( value='\"' + okn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
thatloc=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0];
wds=thatloc.split('_');
if (eval('' + wds[eval(-1 + wds.length)].length) == 2 && wds[eval(-1 + wds.length)] == wds[eval(-1 + wds.length)].toUpperCase() && eval('' + wds.length) > 1) {
//alert('1:' + wds[eval(-1 + wds.length)]);
firsttz='';
if (xtzsih.indexOf(',' + wds[eval(-1 + wds.length)] + ',') != -1) {
firsttz=xtzsih.split(',' + wds[eval(-1 + wds.length)] + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
//alert('2:' + firsttz);
}
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + ' ' + jorflag(wds[eval(-1 + wds.length)]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"\"); style=cursor:pointer;text-decoration:underline;>' + thatloc + '</a>';
}
}
}

} else if (okn.substring(0,1) == okn.substring(0,1).toUpperCase() && okn == okn.toUpperCase() && eval('' + okn.length) == 2) {
document.getElementById('das').innerHTML='Country Name<br>';
pls=ctynames.split(\"'\" + okn + \"'>\");
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,0); title=' + okn + ' style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('<')[0] + ' ' + jorflag(okn) + '</a>';
}
}

tzsih=document.getElementById('tzsel').innerHTML;
if (tzsih.indexOf(',' + okn + ',') != -1) {
firsttz=tzsih.split(',' + okn + ',')[1].split('>')[1].split('<')[0].split(' ')[0];
}
document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + okn + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analr(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(okn) + '</a>';
}
}

}
}

function expandxokn() {
var iut=0, pls=[], tzsih='', thattz='';
if (xokn.substring(0,1) == xokn.substring(0,1).toUpperCase() && xokn != xokn.toUpperCase()) {
document.getElementById('das').innerHTML='TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('/' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut+=2) {
if (pls[iut].split('\"')[0].indexOf('/') == -1) {
thattz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0];
if (eval('' + tzsih.split(thattz)[1].split(' data-geo=')[1].split(',').length) > 3) {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + ' ' + jorflag(tzsih.split(thattz)[1].split(' data-geo=')[1].split(',')[3]) + '</a>';
} else {
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0].split('/' + xokn)[0] + '/' + xokn + pls[iut].split('\"')[0] + '</a>';
}
}
}
}
document.getElementById('das').innerHTML+='<br><br>Country Name<br>';
pls=ctynames.split('>' + xokn);
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analp(this,1); title=' + pls[eval(-1 + iut)].slice(-4) + ' style=cursor:pointer;text-decoration:underline;>' + xokn + pls[iut].split('<')[0] + ' ' + jorflag(pls[eval(-1 + iut)].slice(-3).substring(0,2)) + '</a>';
}
}
}
}

function analr(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
okn='';
}
}

function analq(ao,tzi) { // locale
if (ao.innerHTML.indexOf('_') != -1) {
document.getElementById('locsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('locale').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=tzi.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
okn='';
}
}

function analo(ao) { // timezone places
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
xokn='';
}
}

function analp(ao,isxokn) { // country names
var tzsih='',pls=[],iut=0, firsttz='', thattz='';
if (ao.innerHTML.indexOf('/') != -1) {
document.getElementById('tzsel').value=ao.innerHTML.split(' ')[0];
document.getElementById('timezone').value=ao.innerHTML.split(' ')[0];
document.getElementById('das').innerHTML='';
if (isxokn != 0) {
xokn='';
} else {
okn='';
}
} else {
document.getElementById('das').innerHTML+='<br><br>TimeZone Place Name<br>';
tzsih=document.getElementById('tzsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split(',' + ao.title.split(' ')[0] + ',');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
if (firsttz == '') { firsttz=pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0]; }
document.getElementById('das').innerHTML+=' <a onclick=analo(this); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

document.getElementById('das').innerHTML+='<br><br>Locale<br>';
tzsih=document.getElementById('locsel').innerHTML;
//alert(tzsih.length);
pls=tzsih.split('_' + ao.title.split(' ')[0] + '\"');
if (eval('' + pls.length) > 1) {
//alert('here');
for (iut=1; iut<pls.length; iut++) {
document.getElementById('das').innerHTML+=' <a onclick=analq(this,\"' + firsttz + '\"); style=cursor:pointer;text-decoration:underline;>' + pls[iut].split('>')[1].split('<')[0].split(' ')[0].split('+')[0] + ' ' + jorflag(ao.title.split(' ')[0]) + '</a>';
}
}

xokn='';
}
}

“; ?>

… in further changed latest draft PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Google Translate Tutorial is shown below.

PHP Intl Class Datetime Google Translate Tutorial

PHP Intl Class Datetime Google Translate Tutorial

The Internationalization improvements of yesterday’s PHP Intl Class Datetime Clock Tutorial get another boost today via the inclusion of some interfacing to the great …


Google Translate

… for those incidental translations regarding …

  • titles and headings
  • dropdown instructions

… while avoiding what might add confusion, that being any translation of user web application settings, as you might get … you being the user … that is!

But we ask first on this. And when it is the case for asking here, a useful mechanism can be the HTML input type=checkbox element which now feeds into the Javascript below …

<?php echo ”

function parhelp() {
" . $gone . "
}

function storeinnertexts() {
if (!document.getElementById('translate').checked) { return ''; }
if (!allowanyway) {
if (document.getElementById('locale').value == '') { return ''; }
if (document.getElementById('timezone').value == '') { return ''; }
}
var bcols=['yellow','yellow','white','#ffffff'];
var idcnt=0;
var seclet=['h translate=\"no\"','d','h translate=\"no\"','d','d translate=\"no\"','d','d','d'];
var inb='', ina='</span>';
var krow=0;
var itsare=['locale','loptone','timezone','toptone','calendar','calone','doneb','Clock'], thisrowis='';
var h1toform='<html><head><body>' + document.body.innerHTML.split('<form')[0] + '<br><table style=width:100%; border=2></table></body></html>';
for (var iuyt=0; iuyt<itsare.length; iuyt+=2) {
thisrowis='<tr style=background-color:' + bcols[krow] + ';></tr>';
thisrowis='<tr></tr>';
tdsuff='';
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:lightgreen;'
}
if (document.getElementById(itsare[iuyt]).value.trim() != '' || 1 == 1) {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[iuyt]).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
idcnt++;
if (bcols[krow] == '#ffffff') {
tdsuff=' style=background-color:#f0f0f0;'
}
inb='<span>';
if (eval('' + seclet[idcnt].length) > 1) {
inb='<span' + seclet[idcnt].substring(1) + '>';
}
if (itsare[eval(1 + iuyt)] == itsare[eval(1 + iuyt)].toLowerCase()) {
try {
if (document.getElementById(itsare[eval(1 + iuyt)]).innerText.trim() != '') {
//if (doseti == 1) { alert(document.getElementById(itsare[eval(1 + iuyt)]).innerText); }
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)]).innerText : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
} catch(erty) { alert(itsare[eval(1 + iuyt)]); }
} else {
if (document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value.trim() != '') {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).value : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
} else {
thisrowis=thisrowis.replace('</tr>', '<t' + seclet[idcnt].substring(0,1) + '>' + inb + (inb == '<span>' ? document.getElementById(itsare[eval(1 + iuyt)].toLowerCase()).placeholder : '') + ina + '</t' + seclet[idcnt].substring(0,1) + '></tr>');
}
}
idcnt++;
krow++;
h1toform=h1toform.replace('</table>', thisrowis + '</table>');
}
//if (doseti == 1) { alert(h1toform); }
h1toform=h1toform.replace(/Optionally\ select\ /g, '*');
h1toform=h1toform.replace(/Show\ Current\ Time/g, '@');
h1toform=h1toform.replace('RJM Programming - December, 2024', '$');
h1toform=h1toform.replace('As per (white background textboxes optional) ...', '!');
h1toform=h1toform.replace(/\<br\>/g, '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
h1toform=h1toform.replace('<span translate=\"no\"></span>', '');
//if (doseti == 1) { var tyr=prompt('' + (documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865)).length + ' ' + h1toform.replace(/\<\//g, String.fromCharCode(10) + '</'), h1toform.replace(/\<\//g, String.fromCharCode(10) + '</')); }
document.getElementById('setiif').src=documentURL.split('?')[0] + '?sra=' + encodeURIComponent(sra) + '&it=' + encodeURIComponent(h1toform) + '&rand=' + Math.floor(Math.random() * 1987865);
doseti++;
return '';
}

function setitranslate() {
if (doseti == 0) {
doseti=1;
setInterval(storeinnertexts, 2000);
}
}

“; ?>

… and the PHP …

<?php

$gtwo='';
$delthis='';
$optcnt=0;

if (isset($_GET['timezone'])) {
$_GET['timezone']=explode('%20',explode('+', $_GET['timezone'])[0])[0];
} else if (isset($_POST['timezone'])) {
$_POST['timezone']=explode('%20',explode('+', $_POST['timezone'])[0])[0];
}

function user_agent() { // thanks to https://stackoverflow.com/questions/6322112/check-if-php-page-is-accessed-from-an-ios-device/6322131
$iPod = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = strpos($_SERVER['HTTP_USER_AGENT'],"iPad");
$android = strpos($_SERVER['HTTP_USER_AGENT'],"Android");
//file_put_contents('./public/upload/install_log/agent',$_SERVER['HTTP_USER_AGENT']);
if ($iPad||$iPhone||$iPod) {
return 'ios';
} else if ($android) {
return 'android';
} else {
return 'pc';
}
}

function server_remote_addr() {
$rma = $_SERVER['REMOTE_ADDR'];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
// you can add different browsers with the same way ..
if (1 == 1) {
if(preg_match('/(chromium)[ \/]([\w.]+)/', $ua))
$rma = '000000'.$rma;
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $ua))
$rma = '00000'.$rma;
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $ua))
$rma = '0000'.$rma;
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $ua))
$rma = '000'.$rma;
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $ua))
$rma = '00'.$rma;
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $ua))
$rma = '0'.$rma;
}
return str_replace(':','_',str_replace('.','_',$rma));
}

if (isset($_GET['sra']) && isset($_GET['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_GET['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_GET['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
} else if (isset($_POST['sra']) && isset($_POST['it'])) {
//if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
// exec('rm -f ' . $_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html');
//}
$wopenit=false;
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html')) {
$wopenit=true;
}
$cont=str_replace('+',' ',urldecode($_POST['it']));
$cont=str_replace('*', 'Optionally select ', $cont);
$cont=str_replace('@', 'Show Current Time', $cont);
$cont=str_replace('$', 'RJM Programming - December, 2024', $cont);
$cont=str_replace('!', 'As per (white background textboxes optional) ...', $cont);
$cont=str_replace('</body>', '<style> th { background-color:yellow; } </style></body>', $cont);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/html_intl_' . str_replace('+',' ',urldecode($_POST['sra'])) . '.html', $cont);
if ($wopenit) {
echo "<html><body onload=\" parent.parhelp(); \"></body></html>";
}
exit;
}

$gone="\n setTimeout(function(){ if ((document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] != 'en') { gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=' + (document.getElementById('locale').value + document.getElementById('locale').placeholder).split('_')[0].split('-')[0] + '&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); } }, 7000); \n";

// https://www-rjmprogramming-com-au.translate.goog/PHP/GeoChart/image_chart.php?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=it&_x_tr_hl=en
if (isset($_GET['translate']) && isset($_GET['locale'])) {
if (strlen($_GET['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_GET['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_GET['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
} else if (isset($_POST['translate']) && isset($_POST['locale'])) {
if (strlen($_POST['locale']) > 0) {
$delthis=$_SERVER['DOCUMENT_ROOT'] . "/html_intl_" . server_remote_addr() . ".html";
if (explode('-',explode('_',urldecode($_POST['locale']))[0])[0] != 'en') {
$gtwo="\n setTimeout(function(){ gtwoo=window.open('https://www-rjmprogramming-com-au.translate.goog/html_intl_" . server_remote_addr() . ".html?_x_tr_sch=https&_x_tr_sl=en&_x_tr_tl=" . explode('-',explode('_',urldecode($_POST['locale']))[0])[0] . "&_x_tr_hl=en','_blank','top=200,left=' + eval(-500 + eval('' + screen.width)) + ',width=500,height=500'); }, 7000); \n";
}
}
}

?>

… to make this a possibility in a changed “fourth draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Clock Tutorial is shown below.

PHP Intl Class Datetime Clock Tutorial

PHP Intl Class Datetime Clock Tutorial

Yesterday’s PHP Intl Class Datetime Defaults Tutorial‘s PHP web application involves …

  • timezones … and, for us, whenever that happens, our eyes light up with “possibility” because …
  • “where” meets “when” … when you have timezones involved … and to our mind …
  • “where” and “when” are the best catered for “adverbs” in the I.T. wooooorrrrlllldddd

Invariably, too, the data is “full of possibility” regarding simple ideas of “internationalization” that are easy to deploy, such as …

  • emoji flags
  • Wikipedia lookups in the form of tabulated lists

And so, though our last web application is not totally disengageable from our English bias, we can help its “Internationalization Credentials” today, via …

  • emoji flag code …
    PHP
    <?php

    function orflag($incc) {
    $uretv='';
    $lri=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q","R","S","T","U","V","W","X","Y","Z"];
    $dri=["127462","127463","127464","127465","127466","127467","127468", "127469","127470","127471","127472","127473","127474","127475", "127476","127477","127478","127479","127480","127481", "127482","127483","127484","127485","127486","127487"];
    for ($jjm=0; $jjm<strlen($incc); $jjm++) {
    for ($jm=0; $jm<sizeof($lri); $jm++) {
    if (strtoupper(substr(substr($incc,$jjm),0,1)) == $lri[$jm]) {
    $uretv.='&#' . $dri[$jm] . ";";
    }
    }
    }
    return $uretv;
    }

    ?>
    Javascript
    <?php echo ”

    function jorflag(thiscc) {
    var lri='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var dri=['127462','127463','127464','127465','127466','127467','127468', '127469','127470','127471','127472','127473','127474', '127475','127476','127477','127478','127479','127480', '127481','127482','127483','127484','127485','127486','127487'];
    var ccsuff='', ccchar=' ', cde='';
    for (var iccsuff=0; iccsuff<thiscc.length; iccsuff++) {
    ccchar=thiscc.substring(iccsuff, eval(1 + eval('' + iccsuff))).toUpperCase();
    ccsuff+=String.fromCodePoint(dri[eval('' + lri.indexOf(ccchar))]); //'&#' + dri[eval('' + lri.indexOf(ccchar))] + ';';
    cde='.';
    }
    return ccsuff;
    }

    “; ?>
  • new clock functionality (using an Internationalization emoji usage regarding an SVG based button background image) and known timezone reasons to tabulate …
    <?php

    $tabp='';
    $tabs='';
    if (isset($_GET['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_GET['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    } else if (isset($_POST['timezone'])) {
    $tabp='<table style=width:100%;><tr><td style=vertical-align:top;>';
    $tabs='</td><td style=vertical-align:top;width:50%;><iframe src="/HTMLCSS/colour_wheel.html?mode=' . $_POST['timezone'] . '" style=width:100%;height:800px;></iframe></td></tr></table>';
    }
    $revealp='';
    $reveals='';
    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</text></svg>";

    if (isset($_GET['clock']) || isset($_POST['clock'])) {
    $revealp='<details title="Form you can use to display different time or different clock"><summary title="Form you can use to display different time or different clock"></summary>' . $tabp;
    $reveals=$tabs . '</details>';
    $clockcss="\n #pdfmt { border-radius: 50px; } \n";
    } else {
    $revealp=$tabp;
    $reveals=$tabs;
    }

    ?>

  • document.body onload emoji flag application (via Javascript) …
    <?php echo ”

    function onlit() {
    txils=parent.document.getElementById('tzsel').innerHTML.split(' value=\"' + thistz + '\"');
    if (eval('' + txils.length) > 1) {
    isov=txils[1].split('>')[0].split(',')[3];
    cnb='';
    if (ctynames.indexOf(\" value='\" + isov + \"'>\") != -1) {
    cnb=' in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('tzsel').title='Default is a Timezone in ' + ctynames.split(\" value='\" + isov + \"'>\")[1].split('<')[0];
    document.getElementById('myh1').innerHTML+=' for ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[1].replace(/\_/g,' ') + ' ' + (thistz + '/').replace(thistz.split('/')[0] + '/', '').split('/')[0].replace(/\_/g,' ').trim().replace('Argentina','');
    document.getElementById('myh1').innerHTML+=cnb + ' ' + jorflag(isov);
    }
    }
    }

    “; ?>
  • clock button styling …
    <?php

    $clockcss='';
    $clocksvg="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewport='0 0 100 100' style='font-family:Verdana;font-size:10px;'><text y='50%'>\\0023f0</svg>";

    ?>
    <?php echo ”

    <style>
    " . $clockcss . "
    input[type=\"text\"] { width: 250px; }
    #clock { border-radius: 50px; color:pink; text-shadow:-1px 1px 1px yellow; background-image: url('" . str_replace("'",'"',$clocksvg) . "'); }
    </style>

    “; ?>

  • clock recursive style functionality via an iframe onload event paradigm (with function clockif below) …
    <?php echo ”

    var documentURL=document.URL;
    var repcnt=0, cnb='', isov='', txils=[];
    var thistz=(location.search.split('timezone=')[1] ? (decodeURIComponent(location.search.split('timezone=')[1].split('&')[0]) + '') : '');

    function clockif(iois) {
    if (iois.src.indexOf('About_Us.') == -1) {
    repcnt++;
    setTimeout(function(){ iois.src=iois.src.split('&rand=')[0] + '&rand=' + repcnt; }, 1000);
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (aconto.getElementById('pdfmt') && parent.document.getElementById('pdfmt')) {
    parent.document.getElementById('pdfmt').innerHTML=aconto.getElementById('pdfmt').innerHTML;
    if (repcnt == 1) {
    parent.document.getElementById('pdfmt').style.border='5px dotted pink';
    parent.document.getElementById('pdfmt').style.padding='5 5 5 5';
    if (eval('' + txils.length) > 1) {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/') + txils[1].split('>')[0] + cnb;
    } else {
    parent.document.getElementById('pdfmt').title='Timestamp for ' + documentURL.split('?')[1].split('&cl')[0].replace(/\&/g,' ').replace(/\=/g,' ').replace(/\%2F/g,'/').replace(/\%2f/g,'/');
    }
    }
    }
    }
    }
    }
    }

    “; ?>
    … called into play via document.body onload Javascript …
    <?php echo ”

    <body onload="onlit(); if (documentURL.indexOf('clock=') != -1) { setTimeout(function(){ document.getElementById('justincase').src=documentURL=documentURL.replace('clock=','cloNOWAYck=') + '&rand=' + repcnt; }, 1000); } ">

    “; ?>
    … along with a new form submit button choice …
    <?php echo ”

    <input style=background-color:#f0f0f0; title=Clock type=submit id=clock name=clock value=Clock></input>

    “; ?>

  • dropdown option (subelement) emoji flag title …
    Locale
    <?php

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    $endih='';
    $lastword=explode('_',$arrl[$df])[-1 + sizeof(explode('_',$arrl[$df]))];
    $ends=explode("['" . explode('-',explode('_',$arrl[$df])[0])[0] . '-', $lochelper);
    if (sizeof($ends) > 1) {
    $endih.=' ' . explode("'", explode("['", $ends[0])[-1 + sizeof(explode("['", $ends[0]))])[0];
    }
    if (strpos($lochelpertwo, '>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>') !== false) {
    //echo "yes " . explode('-',explode('_',$arrl[$df])[0])[0] . "\n<br>";
    //echo substr(explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0], -250,250);
    $interim=explode('</a>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0])[-1 + sizeof(explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0]))])[0]; //)[-1 + sizeof(explode('>', explode('</td>', explode('<tr', explode('>' . explode('-',explode('_',$arrl[$df])[0])[0] . '</a>', $lochelpertwo)[0];
    //exit;
    $aintm=explode('>', $interim)[-1 + sizeof(explode('>', $interim))];
    if (strpos($endih, ' ' . $aintm) === false) {
    if ($endih != '') {
    $endih.=' (' . $aintm . ')';
    } else {
    $endih.=' ' . $aintm;
    }
    }
    }
    if ($lastword == strtoupper($lastword) && strlen($lastword) == 2) {
    $endih.=' ' . orflag($lastword);
    }
    if ($endih != '') {
    $endih="\t" . $endih . '';
    }

    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "' translate=\"no\" title=\"" . $endih . "\">" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>
    TimeZone
    <?php

    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    $yls=explode(" data-geo='", $yourtzlist);
    for ($iy=(-1 + sizeof($yls)); $iy>=1; $iy--) {
    if (sizeof(explode(',', $yls[$iy])) > 3) {
    $icp=explode(',', $yls[$iy])[3];
    //echo $icp;
    if ($icp == strtoupper($icp) && strlen($icp) == 2 && strpos($icp, '?') === false) {
    //echo $icp . ' data-geo="' . $yls[$iy] . ' becomes ' . ' title="' . orflag($icp) . '" data-geo="' . $yls[$iy];
    //exit;
    $yourtzlist=str_replace(" data-geo='" . $yls[$iy], ' title=' . "'" . orflag($icp) . "'" . " data-geo='" . $yls[$iy], $yourtzlist);
    }
    }
    }


    ?>

… in a changed “third draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Defaults Tutorial is shown below.

PHP Intl Class Datetime Defaults Tutorial

PHP Intl Class Datetime Defaults Tutorial

Onto the recent PHP Intl Class Datetime Tutorial start to a PHP Current Datetime Intl Using Internationalization web application we see a way forward improving …

  • default Locale and TimeZone presented …
    Locale
    <?php

    $defloc=Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

    ?>
    Timezone
    <?php

    $deficc=explode('_', str_replace('_posix','',$defloc))[-1 + sizeof(explode('_', str_replace('_posix','',$defloc)))];
    $yourtzlist="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('timezone').value=this.value; }\" id=tzsel><option id=\"toptone\" value=''>Optionally select a TimeZone below ...</option><option value='Africa/Abidjan' data-geo='5.31666,-4.03334,GMT,CI,+0'>Africa/Abidjan</option><option value='Africa/Accra' data-geo='5.55,-0.21667,GMT,GH,+0'>Africa/Accra</option><option value='Africa/Addis_Ababa' data-geo='9.03333,38.7,EAT,ET,+3'>Africa/Addis_Ababa</option><option value='Africa/Algiers' data-geo='36.78333,3.05,CET,DZ,+1'>Africa/Algiers</option> ... blah ... blah ... blah ... </select>";

    if (strpos($yourtzlist, ',' . $deficc . ',') !== false) {
    $ourtz=explode('<', explode('>', explode(',' . $deficc . ',', $yourtzlist)[1])[1])[0];
    } else {
    $ourtz="''"; //date.timezone; // ($_SERVER['TZ'] ?? (file_get_contents('/etc/timezone') ?: file_get_contents('/etc/localtime')))
    }

    ?>

  • add accompanying dropdown ways to select values from a list of what is available on Locale and TimeZone (as above) and Calendar …
    <?php

    $calsel='';
    if (1 == 1) {
    $bundle=new ResourceBundle('','ICUDATA');
    $cnames=[];
    $calendars=$bundle->get('calendar');
    foreach ($calendars as $n=>$v) {
    if ($calsel == '') {
    $calsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('calendar').value=this.value; }\" id=calsel><option value=''>Optionally select a Calendar system below ...</option></select>";
    }
    $calsel=str_replace("</select>", "<option value='" . $n . "'>" . $n . "</option></select>", $calsel);
    $cnames[]=$n;
    }
    }

    $locsel='';
    $arrl=ResourceBundle::getLocales('');
    for ($df=0; $df<sizeof($arrl); $df++) {
    if (strpos(($arrl[$df] . '_'), '_') !== false) { //} && strpos($arrl[$df], '0') === false) {
    if ($locsel == '') {
    $locsel="<select onchange=\"if (this.value.trim().length != 0) { document.getElementById('locale').value=tzdef(this.value); }\" id=locsel><option id=\"loptone\" value=''>Optionally select a Locale below ...</option></select>";
    }
    $locsel=str_replace("</select>", "<option value='" . $arrl[$df] . "'>" . $arrl[$df] . "</option></select>", $locsel);
    }
    }

    ?>

  • change input type=text placeholder reflect any previously selected Locale and TimeZone and/or Calendar …
    <?php echo ”

    echo "<h1>Show Current Time</h1><br><h3>RJM Programming - December, 2024</h3><br><h4>As per (white background textboxes optional) ...</h4><br><br><form method=GET onsubmit=\"if (document.getElementById('calendar').value.trim() != '') { document.getElementById('calendar').name='calendar'; } if (document.getElementById('locale').value.trim() == '' || document.getElementById('timezone').value.trim() == '') { return false; } return true;\" action=\"./i_eg.php\">
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=locale name=locale placeholder=" . (isset($_GET['locale']) ? urldecode($_GET['locale']) : (isset($_POST['locale']) ? urldecode($_POST['locale']) : $defloc)) . " value='' title=Locale></input> " . $locsel . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:yellow; id=timezone name=timezone placeholder=" . (isset($_GET['timezone']) ? urldecode($_GET['timezone']) : (isset($_POST['timezone']) ? urldecode($_POST['timezone']) : $ourtz)) . " value='' title=TimeZone></input> " . $yourtzlist . "
    <br><input type=text ondblclick=this.value=this.placeholder; style=background-color:white; id=calendar placeholder=" . (isset($_GET['calendar']) ? urldecode($_GET['calendar']) : (isset($_POST['calendar']) ? urldecode($_POST['calendar']) : "gregorian")) . " value='' title=Calendar></input> " . $calsel . "
    <br><br><input style=background-color:lightgreen; type=submit value=Display></input>
    </form>
    ";

    “; ?>

… and regarding Locale selections take the opportunity to gather up to the top of Locale and TimeZone dropdowns any options relevant to any Locale first selected …

<?php echo ”

<scri" . "pt type=text/javascript>
var ctynames=\"" . str_replace("\n","",$ctynames) . "\";
var canmakenothing=false, firstloc='';

function tzdef(inloc) { // wrapper around Locale dropdown selected value
var inicc=inloc.replace(/\-/g,'_').split('_')[eval(-1 + inloc.replace(/\-/g,'_').split('_').length)];
var jnicc=inicc;
var newtstuff='', newlstuff='', newts=0, newls=0, tvalis='';
if (ctynames.indexOf(\" value='\" + inicc + \"'>\") != -1) {
jnicc=ctynames.split(\" value='\" + inicc + \"'>\")[1].split('<')[0];
}
if (document.getElementById('timezone').value == '' && inicc.trim() != '' && inicc == inicc.toUpperCase() && eval('' + inicc.length) == 2) {
var tzoh=document.getElementById('tzsel').innerHTML;
var aftertopt=document.getElementById('toptone').outerHTML;
var tzloh=document.getElementById('locsel').innerHTML;
var afterlopt=document.getElementById('loptone').outerHTML;
var tzs=tzoh.split(',' + inicc + ',');
if (eval('' + tzs.length) > 1) {
//document.getElementById('timezone').value=tzs[1].split('>')[1].split('<')[0];
tvalis=tzs[1].split('>')[1].split('<')[0];
newtstuff+='<option value=\"' + tvalis + '\">' + tvalis + '</option>';
for (newts=1; newts<eval('' + tzs.length); newts++) {
if (tzs[newts].split('>')[1].split('<')[0] != tvalis) {
newtstuff+='<option value=\"' + tzs[newts].split('>')[1].split('<')[0] + '\">' + tzs[newts].split('>')[1].split('<')[0] + '</option>';
}
}
tzs=tzloh.split('_' + inicc + '\"');
if (eval('' + tzs.length) > 1) {
newlstuff+='<option value=\"' + inloc + '\">' + inloc + '</option>';
for (newls=1; newls<eval('' + tzs.length); newls++) {
if (tzs[newls].split('>')[1].split('<')[0] != inloc) {
newlstuff+='<option value=\"' + tzs[newls].split('>')[1].split('<')[0] + '\">' + tzs[newls].split('>')[1].split('<')[0] + '</option>';
}
}
}
}
if (tzoh.indexOf(aftertopt) != -1 && newtstuff != '') {
document.getElementById('tzsel').innerHTML=aftertopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Time', ' ' + jnicc + ' Time') + newtstuff + aftertopt + tzoh.split(aftertopt)[1];
}
if (tzloh.indexOf(afterlopt) != -1 && newlstuff != '') {
document.getElementById('locsel').innerHTML=afterlopt.replace(' id=', ' data-id=').replace(' value=\"', ' value=\" ').replace(' a Locale', ' ' + jnicc + ' Locale') + newlstuff + afterlopt + tzloh.split(afterlopt)[1];
}
if (tvalis != '') { document.getElementById('timezone').value=tvalis; }
document.getElementById('locsel').value=inloc;
firstloc=inicc;
canmakenothing=true;
}
if (document.getElementById('tzsel').value == ' ' && canmakenothing) {
if (inicc != firstloc) {
document.getElementById('tzsel').value='';
}
}
return inloc.replace(/\-/g,'_');
}
</scr" . "ipt>

“; ?>

… containing an ISO-3166 2 letter Country Code at it’s end, mentioning that country’s name in that first option of the TimeZone dropdown, so that some users will see a Country Name in the mix, adding to relatability, perhaps.

We feel this considerably improves the User Experience using a changed “second draft” PHP code offering here, as a PHP web application, you can also try below.


Previous relevant PHP Intl Class Datetime Tutorial is shown below.

PHP Intl Class Datetime Tutorial

PHP Intl Class Datetime Tutorial

We’re back revisiting the PHP intl “Internationalization” class mentioned in “the AlmaLinux install feeling” PHP Mbstring Multibyte String and Intl Class Tutorial

Reading a bit, we cottoned onto three data items being central to Datetime PHP intl usage being …

  1. locale
  2. timezone
  3. calendar … optional

… and, so, we’re starting our “learning curve” (we got great help from this excellent website developing …

<?php

if (isset($_GET['locale']) && isset($_GET['timezone']) && isset($_GET['calendar'])) {
$DateTime = new DateTime();
$IntlDateFormatter = new IntlDateFormatter(
urldecode($_GET['locale']) . '@calendar=' . urldecode($_GET['calendar']),
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
urldecode($_GET['timezone']),
IntlDateFormatter::TRADITIONAL);

echo '<p>' . $IntlDateFormatter->format($DateTime) . '</p><br><br>';
}

?>

…) in today’s “first draft” “proof of concept” offering here, as a PHP web application, you can also try below …


Previous relevant PHP Mbstring Multibyte String and Intl Class Tutorial is shown below.

PHP Mbstring Multibyte String and Intl Class Tutorial

PHP Mbstring Multibyte String and Intl Class Tutorial

We’re revisiting the PHP Mbstring Multibyte String Primer Tutorial of the past to see where we stand now with PHP 8 and …

  • mbstring “Multibyte String” extension … and …
  • intl “Internationalization Functions” extension

… and discovered that we can happily now have a chance incorporating these functionalities into PHP serverside logic into the future. We tested this with a tweaked mbstring_test.php “old way” live run and “new way” live run via the writing of a couple of “proof of concepts” …


Previous relevant PHP Mbstring Multibyte String Primer Tutorial is shown below.

PHP Mbstring Multibyte String Primer Tutorial

PHP Mbstring Multibyte String Primer Tutorial

Our (Mac OS X laptop) local MAMP web server is an Apache/PHP/MySql web server. In this environment you can find out a lot with some PHP code as per …

<?php phpinfo(); ?>

… and if, in doing this, you find a reference to the “mbstring” Multibyte String Information functionality existing, you are a lucky candidate to introduce some internationalization code into your PHP code, for those occasions where the destination language uses a UTF-8 character set where individual characters can not be described by the ascii character set from decimal 0 to decimal 255. In other words, it takes more than one byte to describe each character of the language. There are many languages like this, a few being the Chinese languages, Japanese and Korean.

We followed a lot of the advice of the very useful link (thanks) to create some PHP called …

… where we show what we always suspected but were too shy to ask, and didn’t flesh it out before … doh! … you can’t split a Chinese phrase’s characters into their individual characters and expect those characters individually translated bring you back to the sense of the Chinese phrase to start with.

So we take the Chinese phrase 火车票 (which translates into English as “Train tickets” … and we thank Google Translate for help with all this) and use PHP mbstring’s mb_str_split to properly split the Chinese into its constituent multibyte (UTF-8) characters (and along the way, show that PHP str_split messes up this same task, as you’d probably guess would happen), and then translate all these into English using Google Translate, as an intellectual exercise.

If this exercise makes you …

  • a) fall on the floor laughing
  • b) hit a gong with a huge hammer
  • c) cook up some deep fried dumplings
  • d) put the left chopstick in the right ear and the right chopstick in the left ear (please ask for adult supervision) … translation: do not do this
  • e) while reading you sweep the cat under the rug (no animals were harmed in the making of this blog posting)

… then we’re here to tell you that you need to take a Bex and have a lie down.

We are just showing in PHP that if the mbstring functionality is available to you, that the mbstring library of functionality can help with some Internationalization issues you may be grappling with and that this PHP code you could try via this live run link.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment