This tutorial demonstrates some advanced techniques in add-on development, like using hooks and post-controllers.
Note
Hooking is a very powerful technique, and we use it a lot in CS-Cart. PHP hooks can be used to perform additional pre- and post-processing of data, or to override default processing routines. TPL hooks are used to handle data on rendering, e.g. to display additional data with no need to modify the original template.
A pre- or post-controller is a special PHP file which (depending on its name and location in the add-on directory structure) are called before or after a particular standard controller is executed.
In this tutorial, we will create an add-on, which will utilize both PHP and TPL hooks.
The add-on will collect information about the categories being shown to a signed in user and store it in the database. This data will be then shown on the admin panel dashboard as a table of users and according number of viewed categories.
You will need an installed and functioning CS-Cart store to be able to follow this tutorial. You can download CS-Cart from our site and use it in the Free mode.
Basic knowledge of PHP, Smarty, and getting familiarized with the CS-Cart add-on directory structure is required. It is recommended that you follow the Hello World tutorial before proceeding with this one.
Go to the directory app/addons in your CS-Cart installation root directory and create the advanced_addon subdirectory. In this directory, create the file addon.xml with the following content (download
):
addons/advanced_addon/addon.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?xml version="1.0"?> <addon scheme="2.0"> <id>advanced_addon</id> <name>Advanced Add-on</name> <description>Advanced Add-on</description> <version>1.0</version> <priority>100500</priority> <status>active</status> <queries> <item for="install">DROP TABLE IF EXISTS ?:advanced_addon_data;</item> <item for="install"> CREATE TABLE `?:advanced_addon_data` ( `user_id` int(11) unsigned NOT NULL DEFAULT 0, `categories` text NOT NULL DEFAULT '', PRIMARY KEY (`user_id`) ) Engine=MyISAM DEFAULT CHARSET UTF8; </item> <item for="uninstall">DROP TABLE IF EXISTS ?:advanced_addon_data;</item> </queries> </addon>
In the same directory, create the file init.php with the following content (download
):
addons/advanced_addon/init.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php /*************************************************************************** * * * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev * * * * This is commercial software, only users who have purchased a valid * * license and accept to the terms of the License Agreement can install * * and use this program. * * * **************************************************************************** * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE * * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. * ****************************************************************************/ if ( !defined('AREA') ) { die('Access denied'); } fn_register_hooks( 'get_category_data_pre' ); ?>
Hint
Function names are usually self-explanatory in CS-Cart (e.g. get_products
to get products). Hooks are normally named after the function they are placed in, with the _pre
or _post
suffix for a pre- and post-processing hook accordingly (e.g. get_products_pre
and get_products_post
).
In this file, we declare that we are going to connect to the hook get_category_data_pre
, which is called before getting category data by a certain query. You can find the information about this and other hooks in our Hook base.
In the add-on directory (app/addons/advanced_addon), create the file func.php. It will contain the actual function to be embedded to the hook (download
):
addons/advanced_addon/func.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <?php /*************************************************************************** * * * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev * * * * This is commercial software, only users who have purchased a valid * * license and accept to the terms of the License Agreement can install * * and use this program. * * * **************************************************************************** * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE * * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. * ****************************************************************************/ if ( !defined('AREA') ) { die('Access denied'); } function fn_advanced_addon_get_category_data_pre($category_id, $field_list, $get_main_pair, $skip_company_condition, $lang_code) { //Getting authentication data to identify user $auth = $_SESSION['auth']; //Checking if the user is logged in and resides at the customer area if (!empty($auth['user_id']) && AREA == 'C') { //Checking if the database has data on the user. //Creating new record if necessary, appending existing data if possible. $viewed_categories = db_get_field('SELECT categories FROM ?:advanced_addon_data WHERE user_id = ?i', $auth['user_id']); if (!empty($viewed_categories)) { $viewed_categories = unserialize($viewed_categories); } $viewed_categories[$category_id] = true; $viewed_categories = serialize($viewed_categories); db_query('REPLACE INTO ?:advanced_addon_data VALUES (?i, ?s)', $auth['user_id'], $viewed_categories); } } ?>
The function fn_advanced_addon_get_category_data_pre
will get the currently displayed categories and store this data to the database linked with the user who is browsing the store.
Important
It is essential to follow the naming convention: fn_
+ [addon id] + _
+ [hook name].
A function named out ot this convention will be ignored.
In order to show the collected data in the admin panel, we are going to append a new data block to the TPL hook index
in the admin panel dashboard template (design/backend/templates/views/index/index.tpl).
Go to the directory design/backend/templates/addons and create a directory named advanced_addon. In this directory, create a subdirectory hooks and inside it another subdirectory index.
In this directory, create the file index.post.tpl with the following content (download
):
design/backend/templates/addons/advanced_addon/hooks/index/index.post.tpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <div class="statistics-box"> <div class="statistics-body"> <p class="strong">Viewed categories</p> <div class="clear"> {if $viewed_categories} <ul> {foreach from=$viewed_categories item="category_data"} <li><strong><a href="{"profiles.update?user_id=`$category_data.user_id`"|fn_url}">{$category_data.user_name}</a></strong>: {foreach from=$category_data.categories key="category_id" item="category_name"} <a href="{"categories.update?category_id=`$category_id`"|fn_url}">{$category_name}</a>, {/foreach} </li> {/foreach} </ul> {else} <ul> <li>No data found</li> </ul> {/if} </div> </div> </div>
Important
Unlike PHP hooks, TPL hooks should not be explicitly declared. It is sufficient to just place a properly named template in the properly named directory.
The location convention is as follows:
- design/backend/templates/addons/<addon name>/hooks for the admin panel template hooks
- var/themes_repository/basic/templates/addons/<addon name>/hooks for the customer area template hooks
- var/themes_repository/basic/mail/templates/addons/<addon name>/hooks for the customer area template hooks
Inside the hooks directory, the hooks should be located and named as follows: <template name>/<hook name>.[pre|post].tpl
The template cannot gather data from the database itself, this is performed by a post-controller for the index.php controller.
Go to the directory app/addons/advanced_addon and create the subdirectories controllers/backend. Switch to this directory and create the file index.post.php with the following content (download
):
app/addons/advanced_addon/controllers/backend/index.post.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?php /*************************************************************************** * * * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev * * * * This is commercial software, only users who have purchased a valid * * license and accept to the terms of the License Agreement can install * * and use this program. * * * **************************************************************************** * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE * * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. * ****************************************************************************/ if (!defined('BOOTSTRAP')) { die('Access denied'); } use Tygh\Registry; $viewed_categories = db_get_array('SELECT * FROM ?:advanced_addon_data'); if (!empty($viewed_categories)) { foreach ($viewed_categories as $key => $category_data) { $category_data['user_name'] = fn_get_user_name($category_data['user_id']); $category_data['categories'] = unserialize($category_data['categories']); $category_data['categories'] = fn_get_category_name(array_keys($category_data['categories'])); $viewed_categories[$key] = $category_data; } Registry::get('view')->assign('viewed_categories', $viewed_categories); } ?>
Double check all the file paths, names, and file contents to guarantee that the add-on will work properly.
To see the add-on in action, install it first. To do that, go to Add-ons → Manage add-ons in the CS-Cart admin panel. Find the item Advanced Add-on and click Install near the title. You should see a successful installation notification.
Now switch to the dashboard and to the bottom of the page. You should see a new section looking similar to this:
As you see, there are no data so far, but the section is shown properly.
Switch to the customer area, log in, and surf a bit around the store. Just go over some random categories. You can also try browsing under several different accounts.
Refresh the dashboard page of the admin panel and check the state of the Viewed categories section:
The section should now indicate the categories you have just surfed through, which is exactly as planned.
Questions & Feedback
Have any questions that weren't answered here? Need help with solving a problem in your online store? Want to report a bug in our software? Find out how to contact us.