World Clock

This example will walk you through the steps of developing a simple “World Clock” extension on Vtiger 7 Framework. It introduces you to the way of injecting client-side libraries & JSON APIs.

Pre-requisites

  • Vtiger 7 installed on your server (assuming it would be used for development).

  • PHP CLI is setup to be invoked from the command prompt or terminal.

  • Gone through module development docs: Develop Extensions For Vtiger

Terminology

  • <vtigercrm> - root-directory / document root where Vtiger 7 is installed.

  • http://<vtigercrm> - web entry access.

Note

You can download “WorldClock-v1.zip” from here.

Step 1: Create files

Switch to your working directory (say.. Desktop) and create the following files.

manifest.xml
modules/WorldClock/WorldClock.php
modules/WorldClock/views/List.php
layouts/v7/modules/WorldClock/ListViewContents.tpl
layouts/v7/modules/WorldClock/ListViewSidebar.tpl
layouts/v7/modules/WorldClock/resources/List.js
layouts/v7/modules/WorldClock/resources/lib/
languages/en_us/WorldClock.php

Step 2: jQuery Clock Plugin

Download jquery-clock-plugin and unzip into layouts/v7/modules/WorldClock/resources/lib/

Step 3: manifest.xml

Edit manifest.xml and fill in basic information required for getting the extension installed in Vtiger.

<?xml version="1.0"?>
<module>
        <type>extension</type>
        <name>WorldClock</name>
        <label>World Clock</label>
        <parent>Tools</parent>
        <version>1.0</version>
        <dependencies>
                <vtiger_version>7.0.0</vtiger_version>
                <vtiger_max_version>7.*</vtiger_max_version>
        </dependencies>
</module>

Step 4: Module Class

Update the module class file (modules/WorldClock/WorldClock.php).

<?php
class WorldClock {}

Note

It is recommended to have this file - although its blank will be useful later.

Step 5: View Class

Edit modules/WorldClock/views/List.php

<?php

class WorldClock_List_View extends Vtiger_Index_View {

        public function process(Vtiger_Request $request) {
                $viewer = $this->getViewer($request);
                $viewer->view('ListViewContents.tpl', $request->getModule());
        }

        // Register loading client-scripts for the UI
        public function getHeaderScripts(Vtiger_Request $request) {
                $allJS = parent::getHeaderScripts($request);
                $moduleName = $request->getModule();

                // dot.separated paths will be resolved with respect to active layout
                // example: layouts/v7/...
                $jsFileNames = array(
                        "modules.Vtiger.resources.List",
                        "modules.$moduleName.resources.List"
                );

                $newJS = $this->checkAndConvertJsScripts($jsFileNames);
                $allJS = array_merge($allJS, $newJS);
                return $allJS;
        }

}

Note

Default entry for the module from the menu is set to List View. We can customize this for every module.

Step 6: View template

Edit layouts/v7/modules/WorldClock/ListViewContents.tpl

<!-- Direct inclusion of library files with reference to layout -->

<link rel="stylesheet" href="layouts/v7/modules/WorldClock/resources/lib/jquery-clock-plugin/css/analog.css" type="text/css" />
<script src="layouts/v7/modules/WorldClock/resources/lib/jquery-clock-plugin/js/jquery.clock.js"></script>

<div style="text-align: center">
        <ul id="worldclock-on-sidebar" class="analog" data-tz="{$CURRENT_USER->name}">
          <li class="hour"></li>
          <li class="min"></li>
          <li class="sec"></li>
          <li class="meridiem"></li>
        </ul>
</div>

<div style="text-align: center;" id="timezone-clocks" class="row-fluid"></div>

Step 7: View Javascript

Edit layouts/v7/modules/WorldClock/resources/List.js - (extend Vtiger List jQuery Class)

Vtiger_List_Js.extend('WorldClock_List_Js', {}, {

        // Default function invoked by Vtiger Client Framework on specific View
        registerEvents: function() {
                var self = this;
                this.initializeSidebarClock(function(){
                        self.initializeTimezoneClocks();
                });
        },

        initializeSidebarClock: function(next) {
                var offset = (new Date()).getTimezoneOffset() * -1 / 60.0;
                jQuery('#worldclock-on-sidebar').clock({offset: offset});
                next();
        },

        initializeTimezoneClocks: function() {
                var self = this;

                jQuery.ajax({
                        dataType: 'jsonp',
                        url: 'http://gomashup.com/json.php?fds=geo/timezone/locations&jsoncallback=?',
                        success: function(response) {
                                var timezones = response.result;
                                self._createClockUIForTimezones(timezones);
                        }
                });
        },

        _createClockUIForTimezones: function(timezones) {
                var self = this;
                if (timezones.length) {
                        self._createClockUIForTimezone(timezones.shift(), function(){
                                self._createClockUIForTimezones(timezones);
                        });
                }
        },

        _createClockUIForTimezone: function(timezone, next) {
                var clockUI = jQuery(
                        '<div class="span4 marginLeftZero"><ul class="analog"><li class="hour"></li><li class="min"></li><li class="sec"></li><li class="meridiem"></li></ul><label></label></div>'
                );
                var container = jQuery('#timezone-clocks');
                jQuery('label', clockUI).html(timezone.TimeZoneId.replace('-', '/'));
                container.append(clockUI);

                clockUI.clock({offset: timezone.GMT});
                next();
        }
});

Step 8: Default i18n

Edit languages/en_us/HelloWorld.php

<?php

$languageStrings = array(
        'World Clock' => 'World Clock'
);

Note

Add all the string constants used by the module - required for i18n support.

Step 9: Package files

zip -r WorldClock-v1.zip manifest.xml modules/WorldClock/WorldClock.php modules/WorldClock/views/List.php layouts/v7/modules/WorldClock/ListViewContents.tpl layouts/v7/modules/WorldClock/ListViewSidebar.tpl layouts/v7/modules/WorldClock/resources/List.js layouts/v7/modules/WorldClock/resources/lib languages/en_us/WorldClock.php

Refer to Package Structure

Step 10: Install in Vtiger

You can import through Module Manager UI.

The module is now installed and ready, you can find it under All > Tools section.