Sunday, November 20, 2016

Drupal 8, Modules, Composer JSON, Platform.sh

In Drupal CMS we can integrate Modules in different ways like uploading module via module manager/ extent, manually copy pasting module folders, via Drush command, Drupal consol and Composer.

Most preferable ways are either via Drush or by Composer. Now we are sometimes confused what is best way to do that actually. My personal opinion is whatever procedure/ technique u've applied must reach the  requirement properly. I also prefer by Dursh or by Composer.
Now some modules has dependency on third party libraries. Drush is unable to load those vendor libraries.
Better explain through an example.
Lets consider about Address Module. Address has third party vendor/ library dependency and if we execute command like

$drush cr --continue-with-error/ --no-halt-on-error
$drush en Address -y

It'll successfully download the Address module but will throw error about Vendor dependency i.e. Address Module will not be enabled.

So, drush fails to enable Address module. Here we need Composer extensively. Composer checks the Module and its Vendors defined in composer.json file. So we need to execute commands like this -

$composer config repositories.drupal composer https://packages.drupal.org/8
$composer require "drupal/address ~1.0"

Similarly to add geoip Module we can execute this command.

 $composer config repositories.drupal composer https://packages.drupal.org/8
$composer require "drupal/geoip 2.x-dev"

Now what should we do when we are on Platform.sh ?
To be continued ...

Wednesday, November 16, 2016

Update Day - Date Time based on systems local time-zone of Website Visitor.

The headline is not quiet clear itself. Definitely it needs some explanation what it actually want to tell. Going through with an example will be a good approach for me to clarify.

Say, there is a WebInar as "What CSS3 can do?" is going to happen at January 16, 2017 10.00 PM
And  considering this WebInar is going to happen on IST time i.e. GMT+5:30 or UTC+5:30

Lets say HTML tag structure is like below
<ul class="webinar-info">
 <li><i class="fa fa-calendar"></i> January 16, 2017</li>
 <li><i class="fa fa-clock-o"></i> 10:00 PM</li>
</ul>

Now our JavaScript code will follow these flowchart to convert this IST to another time zone based on website visitors local system. i.e. If some is browsing this site from EST zone this IST will appear to the visitor on EST time.
  • Read Date Time from the html tag and convert this to time-stamp.
  • Converting this IST time-stamp to UTC-GMT time-stamp.
  • Get time offset of the Visitor's timezone.
  • Calculate the Visitor's local time-stamp based on GMT time-stamp and time offset.
  • Now, generate local date, time, year based on the calculated local time-stamp.
  • Display in the required format by over-writing it.
Here is a sample code that does this same thing above.

var pageInitialized = false;
Drupal.behaviors.webinar_upcomingevent = {
    attach: function(context) {
    if(pageInitialized) return;
    pageInitialized = true;
        ;(function($){
            //return ;
            if($("ul.webinar-info li:first").text().trim().length > 1 ){
                var wInarDateText    = $("ul.webinar-info li:first").text().trim();
                var wInarDate     = wInarDateText.split(" ");    //alert(wInarDate[1].replace(/^,|,$/g,''));

                var wInarTimeText    = $("ul.webinar-info li:last").text().trim();   
                var hours = Number(wInarTimeText.match(/^(\d+)/)[1]);
                var minutes = Number(wInarTimeText.match(/:(\d+)/)[1]);
                var AMPM = wInarTimeText.match(/\s(.*)$/)[1];
                var AMPM = AMPM.toUpperCase();
                if(AMPM == "PM" && hours<12) {
                     hours = hours+12;
                }
                if(AMPM == "AM" && hours==12) {
                     hours = hours-12;
                }
                var sHours = hours.toString();
                var sMinutes = minutes.toString();
                if(hours<10) sHours = "0" + sHours;
                if(minutes<10) sMinutes = "0" + sMinutes;

                var monthNumber = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"].indexOf(wInarDate[0].toLowerCase());
                //var monthNumber = monthNumber + 1;
                var wInarIST    = new Date(wInarDate[2],monthNumber,wInarDate[1].replace(/^,|,$/g,''),sHours,sMinutes).getTime();
                // Perfect timestamp has been calculated "wInarIST"
                //alert(new Date(wInarIST).toUTCString());
                //Considering TimeZone = IST = +5Hrs30mins = +330Mins to milliseconds
                var utcGmtTStamp    = wInarIST - 330*60*1000;
                var offset             = new Date().getTimezoneOffset()*60*1000;
                var localTimeStamp    = utcGmtTStamp - offset;
                //Local timestamp calculation is perfect
                //alert('ist='+wInarIST+'utcGmtTStamp='+utcGmtTStamp+'offset='+offset+'localTimeStamp='+localTimeStamp);
                var localDate    = new Date(localTimeStamp);
                var yearL    = localDate.getFullYear();
                var monthL   = localDate.getMonth();
                var dayL     = localDate.getDate();
                var hourL    = localDate.getHours();
                var minuteL  = localDate.getMinutes();
                //var secondsL = localDate.getSeconds(); 
                var amPmLocal    = hourL >= 12 ? 'PM' : 'AM';
                hourL = hourL % 12;
                hourL = hourL ? hourL : 12; // the hour '0' should be '12'
                minuteL = minuteL < 10 ? '0'+minuteL : minuteL;

                var monthArray = new Array();
                monthArray[0] = "January";
                monthArray[1] = "February";
                monthArray[2] = "March";
                monthArray[3] = "April";
                monthArray[4] = "May";
                monthArray[5] = "June";
                monthArray[6] = "July";
                monthArray[7] = "August";
                monthArray[8] = "September";
                monthArray[9] = "October";
                monthArray[10] = "November";
                monthArray[11] = "December";
                //alert('monthNumber='+monthNumber+'year='+year+'month='+month+'day='+day+'hour='+hour+'minute='+minute);
                $("ul.webinar-info li:first").html('<i class="fa fa-calendar"></i> '+monthArray[monthL]+' '+dayL+', '+yearL);
                $("ul.webinar-info li:last").html('<i class="fa fa-clock-o"></i> '+hourL+':'+minuteL+' '+amPmLocal);
            }
        })(jQuery);
    }
};

This code is based on Drupal 8 behaviour along with some jQuery dependency.
This code also checks whether this it's executing more then once.