Module developer s tutorial Revision: May 29, 2011 1. Introduction In order to keep future updates and upgrades easy and simple, all changes to e-commerce websites built with LiteCommerce should be made as modules. Neither functions, nor design should ever be modified with direct hacks to the files of LiteCommerce or its modules. Even a bug-fixing patch should be distributed as a module until the bug is fixed in a newer LiteCommerce version. A LiteCommerce module is a collection of files that includes: PHP scripts, extending or replacing the default functionality of LiteCommerce Template files, extending or replacing the default look of the pages and blocks generated by LiteCommerce Resource files (images, styles, and so on) used by the above two groups YAML files with the data that is to be imported into the LiteCommerce database when the module is enabled Depending on the purpose of a certain module, it may miss some of the listed components: thus, a theme module is likely to miss scripts and data files, and a language module may include a single YAML file with the translation strings. Modules are distributed in the form of a single package that includes all the module files. There are three ways to install a module in LiteCommerce: 1. Unpack the module package manually and then copy the module files to the server. This is the most difficult (and least recommended) way, because here user must know which directories different groups of files are to be copied to. 2. Upload the module package in the LiteCommerce back-end. It will be unpacked and copied to the appropriate directories automatically. 3. We list popular modules in our Module Marketplace directory. LiteCommerce users can buy, install and update modules listed there directly from their LiteCommerce back-end. This is the easiest (and most recommended) way of installing LiteCommerce modules. The last chapter of this tutorial explains how you can submit your module to us for a review to be added to the Module Marketplace.
When a module is installed, it is listed in the LiteCommerce back-end and can be enabled by user. Until the module is enabled, it doesn t affect LiteCommerce functionality, design or database. If user disables a module, all of its classes, templates and database data become hidden from LiteCommerce. 2. Preparing for work Installing LiteCommerce Although you can develop modules directly over a regular LiteCommerce installation, we recommend you to get the most recent LiteCommerce version from our GitHub repositories, because it comes with multiple tools that may help you develop and test your module. Also, it makes sense to develop a module for a LC+Drupal version and then test it in a stand-alone LC version. 1. Install Git on the computer where you will be working on the module. If you aren t familiar with Git, there is a great book available free of charge 2. If this is a local computer, install web server applications as per LiteCommerce requirements 3. Create a single MySQL database for Drupal and LiteCommerce data 4. Download Drupal and LiteCommerce files from our GitHub repositories to your web directory by executing the following commands in a terminal window: cd <path_to_your_web_directory> git clone git://github.com/litecommerce/core.git xlite git clone git://github.com/litecommerce/drupal.git xlite_cms 5. Switch to the Git branches with the most recent (untested) version: cd xlite git checkout -b master-dev origin/master-dev cd../xlite_cms git checkout -b 7.x-master-dev origin/7.x-master-dev cd.. 6. Create configuration files: cp xlite/src/etc/config.php xlite/src/etc/config.local.php cp xlite_cms/sites/default/default.settings.php xlite_cms/sites/default/settings.php 7. Edit the configuration files (config.local.php and settings.php) and specify your database settings (set "prefix in the $databases variable to "drupal_"). In the config.local.php file, also specify your domain (in the "host_details" section) and set "web_dir" to "/xlite/src/". 8. Make sure the "xlite/src/var" and "xlite_cms/sites" directories have permissions that allow the web server to write files there. It really depends on your server environment, so please ask your server administrator how you can configure the permissions without opening a security breach. 9. Initialize the LiteCommerce database: cd xlite/src php -f restoredb demo cd../..
10. Rebuild the LC3 classes cache by opening the http://<domain>/<path>/xlite/src/admin.php script in a browser 11. Prepare for Drupal installation: cp xlite_cms/.dev/dev_install.php xlite_cms/dev_install.php 12. Run the Drupal installation script in a browser: http://<domain>/<path>/xlite_cms/ dev_install.php Locating LiteCommerce files Depending on how you installed LiteCommerce, you can find its files at the following locations: 1. LC+Drupal version from the pre-built Ecommerce CMS installation package: Drupal files are in the directory where the package is installed into LC files can be found under the modules/lc_connector/litecommerce/ subdirectory 2. LC+Drupal version from our GitHub repositories: Drupal files are in the directory where drupal.git repository is extracted into (more likely it is xlite_cms ) LC files are in the directory where core.git repository is extracted into (more likely it is xlite ) 3. A stand-alone version from an installation package: LC files are in the directory where the package is installed into 4. A stand-alone version from our GitHub repostiory: LC files are in the directory where core.git repository is extracted into (more likely it is xlite ) Further in the instructions, the directory with LiteCommerce files is referred to as xlite/, and the one with Drupal files - as xlite_cms/. Configuring developer-specific settings First of all, copy the etc/config.php file to etc/config.local.php (if you haven t copied it yet) and edit the config.local.php file. The settings that you are to look into are: 1. [log_details] section name - path to log file suppress_errors - disables showing errors in browser suppress_log_errors - disables recording errors to log file 2. [profiler_details] section enabled - enables profiler and displays profiler results at the bottom of the page process_widgets - counts time necessary to render every page template
xdebug_log_trace - enables Xdebug function traces show_messages_on_top - displays debug messages at the top of the page instead of using the profiler results section at the bottom (this option requires developer_mode option to be enabled). You can display a debug message by adding the following function call to your code: \XLite\Core\Profile::getInstance()->addMessage(<text>); 3. [debug] section mark_templates - displays debug information on LiteCommerce widgets and templates shown on the page 4. [decorator] section time_limit - sets time limit for the script that rebuilds LiteCommerce cache (in seconds) 5. [performance] section substitutional_skins_cache - when the option is enabled, LiteCommerce caches information on which templates files should be taken from which skin directories; this may boost the performance when you have a theme that extends another one. developer_mode - enables debug messages and the function of creating a module package from an installed module on the back-end page listing modules. You can display a debug message by adding the following function call to your code: \XLite\Core\Profile::getInstance()->addMessage(<text>); Also, in the LiteCommerce back-end, on the Performance page (top menu > Settings > General settings > Performance tab), there is a Check templates status in runtime option. When the option is disabled, LiteCommerce never checks whether a template file exists in the file system before opening it. That may increase the performance of a live shop, but in the development environment it is recommended to keep this option enabled. Also, in the developer mode, the option is always enabled. When done editing the settings file, open the LiteCommerce back-end and start rebuilding LiteCommerce cache by selecting the command on the top menu:
3. Creating blank module Choosing module name First of all, you need to choose unique identifiers for you (your company) and your module. Identifiers may contain maximum 64 letters/digits and must have an uppercase first character. It makes sense to make identifiers of your company name and the name of the module you are going to develop. Note: The CDev developer identifier is reserved for modules created and maintained by the LiteCommerce team. Although in your module you can use an identifier some other developer uses for his module, we do not recommend doing so because that may confuse LiteCommerce users, installed both the modules. Moreover, if you decide to list the module in our Module Marketplace, it is likely that we will ask you to rename it. Also, if it is a translation or a theme module, it would be a good idea to name it like <Language>Translation and <Name>Theme. Further in the tutorial, the module name may mean (depending on the context) either a display module name (the one that LiteCommerce users see in the back-end), a module identifier or a full module identifier, including the developer identifier, as: <Developer>/<Module>. Module structure When a module is installed, it has the following structure (paths are relative to the directory where LiteCommerce is installed; language is an ISO 639-1 language code): classes/<developer>/<module>/main.php - module descriptor class classes/<developer>/<module>/icon.png - optional module icon (can be.png,.jpg or.gif) classes/<developer>/<module>/install.yaml - data to be imported into the database when the module is enabled classes/<developer>/<module>/controller/... - new or modified controller classes classes/<developer>/<module>/view/... - new or modified view classes classes/<developer>/<module>/... - other classes added or modified by the module skins/admin/<language>/modules/<developer>/<module>/... - new and custom back-end templates/resources skins/default/<language>/modules/<developer>/<module>/... - new and custom store-front templates/resources Module descriptor class (Main.php script) The module descriptor class provides LiteCommerce with basic information on the module. Note: Although a disabled module doesn t affect LiteCommerce functionality, design and
database, a broken descriptor class can make it impossible to access pages generated by LiteCommerce. The descriptor class defines module version, made of 3 numbers; for example, 1.1.4. The first two numbers are the major version of the module that determines what LiteCommerce version the module is written for (1.1.x). The last number is the minor version of the module that indicates how many revisions of the module have been released till this one (4). A module shouldn t define the full module version directly; instead, it should define the major and the minor versions. On installing updates with the built-in automatic upgrade function, LiteCommerce follows this convention: it assumes that the most recent module revision is always compatible with the most recent LiteCommerce revision of the same major version, but may not work with earlier LiteCommerce revisions of that major version and is incompatible with other major LiteCommerce versions. That s why the automatic upgrade function always installs all available updates and never updates one module only when updates for the other modules are available. What you should remember is that it is the module author s responsibility to keep the module compatible with newer LiteCommerce revisions (and LiteCommerce modules the module depends on) and release newer module revisions when needed. Here is an example of the Main.php script: <?php // vim: set ts=4 sw=4 sts=4 et: <Your license notice> @category LiteCommerce @package XLite @subpackage <Name of your package> @author <Your name and contact e-mail> @copyright <Your copyright notice> @license <URL and your license> @version <File version in your version control system> / namespace XLite\Module\<Developer>\<Module>; <Brief information on what the module does>. @package XLite / abstract class Main extends \XLite\Module\AModule Return the developer name (company name).
@var string @access public / public static function getauthorname() return '<Your name or your company name>'; Return the module display name. @var string @access public / public static function getmodulename() return '<Module display name>'; Return the major module version. @return string / public static function getmajorversion() return '<Major module version>'; Return the minor module version (revision number). @return string / public static function getminorversion() return '<Module revision number>'; Return an URL to the module icon. If an empty string is returned icon.png from the module directory will be used. @return string / public static function geticonurl() return '<URL to your module icon>'; Return a brief module description. @return string
/ public static function getdescription() return '<Brief module description>'; Return a list of modules the module depends on. Each item should be a full module identifier: <Developer>\<Module>. @return array / public static function getdependencies() return array(); Determines whether the module has a settings form, or not. @return boolean / public static function showsettingsform() return false; Return a custom route to the module settings form. @return string / public static function getsettingsform() return 'admin.php?target=<target your module hooks>'; Enabling module in LiteCommerce When you have made any changes to a module, you should rebuild LiteCommerce cache in order to let LiteCommerce see the changes. Get into the LiteCommerce back-end and select the Re-build cache item on the top menu:
Select the Add-ons item on the menu and make sure your module is listed on the page. Now you can enable the module and start customizing LiteCommerce. Don t forget to rebuild cache every time you want to check the changes you have made to the module. 4. Customizing LiteCommerce appearance Modyfing LiteCommerce pages and widgets Exporting pages and widgets into Drupal 5. Extending the LiteCommerce functionality 6. Importing module data 7. Multilingual support Overview In LiteCommerce, you can translate both the messages shown from templates and PHP code and the data in your models.
When LiteCommerce is running in connection with Drupal, it uses the language selected by visitor in the Drupal language selector. Multilingual messages To enable translating a label/message, wrap it in a translation function as follows: 1. Inside LiteCommerce template files (it is a good practice to place all messages inside template files): t(#weight#) // translate to customer language t(#my name is name#,_array_(#name#^#test#)) // translation with replacement t(#weight#,_array_(),#de#) // translate to specified language 2. Inside common LiteCommerce scripts: \XLite\Core\Translation::lbl('Weight'); // translate to customer language \XLite\Core\Translation::lbl('My name is name', array('name' => 'test')); // translation with replacement \XLite\Core\Translation::lbl('Weight', array(), 'de'); // translate to specified language 3. Inside controllers and widget classes, you can use the short notation: $this->t('weight'); // translate to customer language $this->t('my name is name', array('name' => 'test')); // translation with replacement $this->('weight', array(), 'de'); // translate to specified language Messages, wrapped in a translation function like shown above, can be translated by any LiteCommerce module. In order to do so, the translating module should define the translations in its install.yaml file (it should be UTF-8; use 2 spaces for indentation) as follows (replace ru with a two-character ISO 639-1 code of the language you are translating to): directives: addmodel: 'XLite\Model\LanguageLabelTranslation' - name: 'Weight', translations: [ code: ru, label: 'Weight (russian)' ] - name: 'Add to cart', translations: [ code: ru, label: 'Add to Cart (russian)' ] - name: 'Other LC3 message', translations: [ code: ru, label: 'Your translation' ]... You can use \n for inserting line breaks into translations. The addmodel directive forces LiteCommerce to import translations for existing labels and messages only. You may remove the directive to have all the records from your YAML file imported. Although it is not recommended for a translation module, it is possible to store multiple translations in one YAML file as follows: - name: 'Weight', translations: [ code: nl, label: 'Weight (dutch)', code: sv, label: 'Weight (swedish)' ]
Also, you may write YAML files as follows (recommended to avoid mixing different notations in one file): - name: 'Weight' translations: - code: nl label: 'Weight (dutch)' - code: sv label: 'Weight (swedish)' Note: Since LiteCommerce v3 is based on the LiteCommerce v2 code, some labels and message are not passed through the translation functions and cannot be translated through YAML files. So, if you notice a label/message of such kind, you can fix it as follows: 1. Submit a ticket at https://bt.litecommerce.com/ and ask us to fix the labels you have found. 2. Fix it in your forked GitHub repository (in a separate branch) and then submit us a Pull Request on adding your changes to the core LiteCommerce repository. Please note that by doing so you grant us the right to use your code in other software we develop (both open-source and proprietary) without any restrictions on your side and any obligations on our side. Multilingual model fields 8. Creating a module package 9. Submitting your module to Module Marketplace Overview Coding standards