Office Hours
Day Hours (GMT)
Bank Holidays Closed
Monday 9:00 - 17:30
Tuesday 9:00 - 17:30
Wednesday 9:00 - 17:30
Thursday 9:00 - 17:30
Friday 9:00 - 17:30
Saturday Closed
Sunday Closed
Knowledgebase: Developer Articles
How can I create a plugin using the code hooks system?
Posted by Al Brookbanks on 12 April 2012 04:43 PM

CubeCart has a unique system of "code hooks" which allow you to pull external code into the main application. This is one major benefit is that you can upgrade your store without having to redo all your code customisations. For this reason we urge developers to integrate new code following the directions outlined in this article. This also allows you to easily distribute CubeCart plugins that are very simple for the store owner to install without having to manually edit the source code.

The best way to go about this is to look at a series of simple example plugins. We will look at two examples followed by an appendix of available code hooks. This developer guide assumes that you have a fair level of experience developing object orientated PHP code. However if you don't it is definitely time to learn so don't shy away...

Example 1 Overview: Creating the modules structure and admin interface
This example explains the minimum requirements for a plugin so that it has an admin configuration interface and deals with language strings. This example doesn't cover working with code hook which we come onto in example 2.  

Example 2 Overview: Creating a simple Visitor Statistics Plugin
This example moves a step forward from example one. It explores how code hooks work in order for you to be able to add external code into the core CubeCart source code all from your plugins 'hooks' folder. This example explores a simple visitor counter with the following useful features;

- How custom database table(s) can be installed automatically and setting default configuration settings.
- Creating a custom admin navigation menu link with a new admin page to view the counter statistics.
- Using a front end hook to log page views into the newly created database table and setting a macro so that the counter can be places into the skins main template.

Example 1 - Creating the modules structure and admin interface

This example plugin has been designed to show how the admin interface of a plugin can be configured by the end user allowing the store administrator to input text, select values from drop down menus and select radio buttons. Please download the following zip archive, extract it and upload it to the modules/plugins directory of your CubeCart v5 installation.

Once uploaded please navigate to the Modules >> Plugins screen where you should see the new example module.

Example Module Showing in Plugins Section of Admin Control Panel

Click though to the module to view the example configuration paremeters.

Configuration Screen on Example Plugin

Ok so how did we get here:

1. We created a folder in the modules/plugins folder called "example".

2. We created a file called config.xml this has the following content:

<?xml version="1.0" encoding="UTF-8" ?>
<installer version="1.0"> 
    <uid>[email protected]</uid>
    <description><![CDATA[Example Plugin]]></description>
    <creator><![CDATA[Example Company]]></creator>

  <hooks> <!-- Please see plugin example2 for more information on this -->  </hooks>

Parameter Explanation
uid  This needs to be a unique identifier for the module. It doesn't need to be an working email account. 
type This needs to be set to plugins. Other module types will have a different value e.g. gateway, social, shipping etc..
folder This must be set to the exact value of the plugin folder. So in this case "example" (case sensitive!)
name This is the name of the module. Any value is accepted.
description A short description of the plugin.
version This again is up to you. Most would probably start with 1.0.0 depending on how you like to specify versioning. The module shows 2.0.0 but strictly speaking probably should have a value of 1.0.0.
minVersion This is the minimum version of CubeCart the module can be used with.
maxVersion  This is the maximum version the module can be used with.
creator Put your company name here to take credit fo your work.
homepage This is the URL to your plugin or company homepage.

3. We created a folder called language containing the file module.definitions.xml. CubeCart can handle multiple languages for plugins but we won't cover this now. An example of this can be found in the Canada Post shipping module which has English and French languages.

The basic structure of this file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<definitions version="1.0"> 
  <group name="example"> 
    <string name="module_title"><![CDATA[Example Module Title]]></string>

The group name needs to match the module folder name. After this any key values can be set with any phrase between the unparsed CDATA fields.

4. We then need to create a folder called admin which will contain a logo file (png, gif or jpg). This automatically shows on the plugins module list once it exists. If no image exists the folder name as a text hyperlink will show instead.

5. In the admin folder we also need an file. This is basically a controller file that loads the module configuration settings and loads the admin configuration file that we will come onto in a moment. The contents in the example plugin is suitable for any plugin and can be used exactly as it is for any new module. If you do need to add custom code to validate post variable, install database tables or whatever feel free to do so. 

6. Create a folder called "skin" and then inside this another folder called "admin" which will contains the template files of the admin control panel. We used "index.tpl" but you can use any value so long as it matches the value in the Module construct of the admin/ file we discussed in step 5.

Please have a look at the contents of the index.tpl file of the example module. On first submit CubeCart will automatically save the configuration data and update it on subsequent submissions. You can have textboxes, checkboxes, select boxes and radio boxes here. Looking at the code should give you an idea of how it automatically sets these values. 

Using the smarty template system variables can be accessed with standard MODULE macro.

e.g. {$MODULE.status} - This will output the value of the module key 'status'.

Radio and select boxes are a bit different however. The HTML attributes selected="selected" or checked="checked" will only be assigned to the template if the macros are set correctly. For a select box with key module[example_drop_down] and value 'key1' it is crucial that the option tag has the attribute:

<select name="module[example_drop_down]">
  <option value="key1"{$SELECT_example_drop_down_key1}>{$LANG.example.key1}</option>

Broken down this translated to the format encapsulated with an underscore:

SELECT - This tells the HTML template if it should be outputting selected="selected" or checked="checked" (CHECKED) depending if it is a radio or select box.
example_drop_down - this is the fields key name. 
key1 - This is the value. 

So if the module key "example_drop_down" exists with the value "key1" the macro {$SELECT_example_drop_down_key1} will have a value of selected="selected". If not it will have no value.

The index.tpl file can take language strings from any section of CubeCart. To obtain the language strings specified in the plugins language definitions file (language/module.definitions.xml) it is possible to do this with the macro {$LANG.example.key_name}. Broken down "example" is the group name specified in the language definitions file followed by the string key. 

Example 2 - Creating a simple Visitor Statistics Plugin

Disclaimer: This module has not been developed to be used in a production environment. The plugin may put heavy loads on the MySQL server and some of the coding practices may not be perfect. It has been designed as a quick learning tool for experienced PHP developers.  

This example moves forward assuming that example 1 is understood. As outlined in the example overview we will explore the way new database tables can be automatically installed, default configurations can be set, including custom code in the store front and creating an admin navigation link to admin statistics page. This is just one example of what can be done with the plugins system however there are a huge amount of code hooks available which can be found in the appendix section of this document. 

Please download the following zip archive, extract it and upload it to the modules/plugins directory of your CubeCart v5 installation.

Once uploaded please navigate to the Modules >> Plugins screen where you should see the new example module.

Screenshot of example 2 on module list

Click though to the module to view the example configuration parameters.

Example 2 Admin Configuration Screen

So without going over the documentation in example 1 we can see the plugins admin configuration screen which is parsed from the template file in the skin/admin/index.tpl file.

When the link from the plugin list page is clicked the code in the admin/ file is loaded. This instantly created the database table "plugin_visitor_stats" and builds the default module configuration settings. It also loads a class file specific to the plugin to display a preview of the front end counter so we can keep most of the core module functions in one nice tidy file. The class file can take any name you wish. Yup, the counter looks REALLY crappy but its only a quick example. The code in this file is well documented so please refer to that for further information about how the database table is created etc...

You may prefer to create a splash page with install button before showing the module configuration page instead of checking the database exists on every page load.

Working with Code Hooks

For this plugin to be able to do anything at all we need to be able to create code for inclusion into the core CubeCart code files. To do this we use hooks which have already been added thought the CubeCart application. These code hooks literally are a means to include code from the /hooks folder of your plugin by means of specific indentifiers. 

This module takes advantage of three code hooks:

admin.navigation - This hook is found at around line 71 of the admin/sources/element.navigation.php file which loads the admin navigation menu.

admin.visitor_stats - This is a dynamic hook based on the plugin folder name which is found in the controllers/ file at around line 132. We use this hook to load the plugins custom admin page to view the recorded stats from the link in the admin.navigation menu link.

controller.index - This hook is loaded on every page load of the front end of the store and can be found at around line 84 of the controllers/ file. 

Before we can use these code hooks we have to specify them in the plugins config file. Please have a look at the config.xml file where we can see:

<hook trigger="admin.navigation" enabled="1"><![CDATA[Navigation Menu Item]]></hook>
<hook trigger="admin.visitor_stats" enabled="1"><![CDATA[Admin Visitor Statistics Page]]></hook>
<hook trigger="controller.index" enabled="1"><![CDATA[Front end page view logger]]></hook>

As you can see each hook needs the correct trigger identifier and enabled set to 1. If you wish to disable part of a plugin this can be done by setting this value to 0 or from the "Settings" >> "Manage Hooks" section of the stores admin control panel which we will explore in a moment. You can use then set a brief description of what each hook is used for. 

Once the plugin is enabled for the first time CubeCart will automatically register the hooks in the system so that the plugin can take advantage of them. As briefly mentioned before there is a interface in the admin control panel of your store which allows you to see what hooks each enabled plugin is using and edit/delete if necessary. It is unlikely that this will ever need to be dealt with. 

The screenshot below shows the registered hooks for our plugin:

Hook List Screenshot

The last thing to consider is where to create the files the code hooks include. These need to reside in the /hooks folder of your plugin. In our example we have three hook files of which all are named according to the hook identifier. These literally take the hook identifier as the file name but of course with the .php extension. 

e.g. admin.navigation.php

Code Hooks Appendix

For the latest list of available code hooks please refer to the modules/plugins/hooks.xml file of your CubeCart v5 installation as the list below may be missing some. Our developers add more code hooks from time to time. If you are a developer creating a CubeCart plugin and find that there is a code hook missing that you would like to see added please contact us and we will see about getting it release into the next maintenance version release. 

Hook Identifier Location
controller.admin  controllers/
admin.category.addedit_display  admin/sources/
admin.category.delete  admin/sources/
admin.category.pre_display  admin/sources/  admin/sources/  admin/sources/  admin/sources/  admin/sources/
admin.customer.add  admin/sources/
admin.customer.delete  admin/sources/
admin.customer.group_add  admin/sources/
admin.customer.group_edit  admin/sources/
admin.customer.group_delete  admin/sources/
admin.customer.group_list  admin/sources/  admin/sources/  admin/sources/  admin/sources/
admin.customer.list  admin/sources/
admin.customer.update  admin/sources/
admin.dashboard.quick_tasks  admin/sources/
admin.documents.delete  admin/sources/
admin.documents.pre_display  admin/sources/  admin/sources/  admin/sources/
admin.documents.status  admin/sources/
admin.navigation  admin/sources/
admin.order.index.display  admin/sources/
admin.order.index.post_display  admin/sources/
admin.order.index.post_process  admin/sources/
admin.order.index.pre_display  admin/sources/
admin.order.index.pre_process  admin/sources/
admin.order.index.transaction  admin/sources/
admin.product.delete  admin/sources/
admin.product.pre_display  admin/sources/  admin/sources/  admin/sources/
admin.product.manufacturer.delete  admin/sources/
admin.product.manufacturer.pre_display  admin/sources/  admin/sources/  admin/sources/  admin/sources/  admin/sources/  admin/sources/  admin/sources/  admin/sources/
admin.settings.admins.sections  admin/sources/
admin.tabs  classes/acp.class.php
offline  includes/
controller.index  controllers/
class.admin.get_section_id  classes/admin.class.php
class.ajax.load  classes/ajax.class.php
class.cart.add.pre  classes/cart.class.php  classes/cart.class.php
class.cart.clear  classes/cart.class.php
class.cart.discount_add  classes/cart.class.php
class.cart.get  classes/cart.class.php
class.cart.update  classes/cart.class.php
class.catalogue.category_product_list  classes/catalogue.class.php
class.cubecart.display_product  classes/catalogue.class.php
class.catalogue.product_data  classes/catalogue.class.php
class.catalogue.product_options  classes/catalogue.class.php
class.cubecart.account.list  classes/cubecart.class.php
class.cubecart.construct  classes/cubecart.class.php
class.cubecart.construct.addressbook  classes/cubecart.class.php
class.cubecart.construct.callback.gateway  classes/cubecart.class.php
class.cubecart.construct.cancel  classes/cubecart.class.php
class.cubecart.construct.certificates  classes/cubecart.class.php
class.cubecart.construct.confirm  classes/cubecart.class.php  classes/cubecart.class.php
class.cubecart.construct.gateway  classes/cubecart.class.php
class.cubecart.construct.logout  classes/cubecart.class.php
class.cubecart.construct.register  classes/cubecart.class.php  classes/cubecart.class.php
class.cubecart.display_basket  classes/cubecart.class.php
class.cubecart.display_category  classes/cubecart.class.php
class.cubecart.display_content  classes/cubecart.class.php
class.cubecart.display_gateways  classes/cubecart.class.php
class.cubecart.display_homepage  classes/cubecart.class.php
class.cubecart.display_basket.alternate  classes/cubecart.class.php
class.cubecart.display_basket.related  classes/cubecart.class.php
class.cubecart.login  classes/cubecart.class.php
class.cubecart.product_price  classes/cubecart.class.php
class.gui.css  classes/gui.class.php
class.gui.display  classes/gui.class.php
class.gui.display_currency_switch  classes/gui.class.php
class.gui.display_documents  classes/gui.class.php
class.gui.display_language_switch  classes/gui.class.php
class.gui.display_mailing_list  classes/gui.class.php
class.gui.display_navigation.make_tree  classes/gui.class.php
class.gui.display_navigation.pre_cache  classes/gui.class.php
class.gui.display_navigation  classes/gui.class.php
class.gui.display_popular_products  classes/gui.class.php
class.gui.display_random_product  classes/gui.class.php
class.gui.display_sale_items  classes/gui.class.php
class.gui.display_search_box  classes/gui.class.php
class.gui.display_skin_select  classes/gui.class.php
class.gui.display_session_box  classes/gui.class.php
class.gui.javascripts  classes/gui.class.php
class.order.order_status  classes/order.class.php
class.order.place_order  classes/order.class.php
class.order.place_order.basket  classes/order.class.php
class.user.load  classes/user.class.php
class.user.load.user  classes/user.class.php
class.user.logout  classes/user.class.php
class.user.get_session_data  classes/user.class.php
class.user.register_user  classes/user.class.php
class.user.register_user.insert  classes/user.class.php
class.user.register_user.inserted  classes/user.class.php