How to Write Custom Modules for PHP-based E-Commerce Systems (2011)
1. How to write Custom
Modules for PHP-based E-
Commerce Systems
Dr. Roman Zenner
2. Roman Zenner
• Working as freelance trainer, author and
developer since 2004
• Has written two books on Magento
• Is in the process of writing a book on
OXID eShop
• Publishes in various magazines
3. Initial thoughts
• Modularity a no-brainer in today’s
ecommerce software
• There must be a way of extending
classes or an event-listener system in
order to integrate custom functionalities
4. Types of modules
• Encapsulate graphical (template)
changes
• Provide additional information (e.g. for
an article
• Special calculations
• Payment and shipping
• Other interfaces (ImpEx, etc.
9. Brief History
• First stable version released in spring 2008
• Community Edition under OSL
• Professional and Enterprise Editions
• Based on Zend Framework and MySQL
• Relies heavily on EAV structure
• XML definitions
• Bought by eBay in 2011 (X.commerce)
• Current stable version: 1.6.1
29. Drilling down (3)
public function render()
{
$myConfig = $this->getConfig();
$oProduct = $this->getProduct();
}
public function getProduct()
{
$sOxid = oxConfig::getParameter( 'anid' );
$this->_oProduct = oxNew( 'oxarticle' );
if ( !$this->_oProduct->load( $sOxid ) ) {
...
}
}
30. Drilling down (4)
public function load( $oxID)
{
$blRet = parent::load( $oxID);
public function load( $sOXID)
{
//getting at least one field before lazy loading the object
$this->_addField('oxid', 0);
$sSelect = $this->buildSelectString( array( $this->getViewName().".oxid" => $sOXID));
return $this->_isLoaded = $this->assignRecord( $sSelect );
}
/core/oxarticle.php
/core/oxbase.php
31. Custom classes (1)
• Most view- and core classes can be overloaded
• Module are registered in backend
• Object instantiation via oxNew(): core/oxutilsobject.php
oxArticle
my_oxArticle
our_oxArticle
class my_oxArticle extends oxArticle
class our_oxArticle extends my_oxArticle
32. Custom classes (2)
• This procedure becomes problematic when there is more
than one new module wanting to extend a specific class.
• Solution: oxNew() dynamically creates transparent
classes in the form of: [class-name]_parent
• This means that by means of the following structure,
module classes can be chained:
– oxArticle => my_oxArticle&our_oxArticle
33. Plugins (1)
• Task: Write a module that displays the remaining time until
X mas with each article.
1. New module directory: /modules/xmas/
2. Publishing it via Admin:
34. Plugins (2)
class xmasArticle extends xmasArticle_parent
{
public function getDaysLeft()
{
$time = mktime(0, 0, 0, 12, 25, 2011, 1) - time();
$days = floor($time/86400);
return $days;
}
}
<div>Only [{$oDetailsProduct->getDaysLeft()}] days left until Xmas!</div>
/modules/xmas/xmasArticle.php
/out/azure/tpl/page/details/inc/productmain.tpl
36. Brief History
• First stable version released in 2007.
• OS-Edition since October 2010.
• Since v.3.5 based on Enlight Framework
(based on ZF) & MySQL
• MVC-Model
• Backend based on ExtJS 4
• Templates based on Smarty 3
• Recent version: 3.5.5
37. Enlight-Framework
• Basis functionalities are inherited from Zend
Framework:
• Syntax and Workflow
• Request- and Response-Objects
• Action-Controller Design
• Rewritten Router / Dispatcher and View-
Object optimised for performance and
expandability
• Own plugin system based on events and
hooks
43. Drilling down (2)
• Article detail page: templates_defaultfrontenddetailindex.tpl
• Part that displays article name in frontend
• Template-Path (frontend/detail/index.tpl) tells us where to find the
corresponding controller. In this case: Shopware/Controllers/
Frontend/Detail.php – indexAction.
• Get article information from Model and assign to template
• Shopware()->Modules()->Articles() is a service locator to access the
main article object that could be found at /engine/core/class/
sArticles.php
• sGetArticleById fetches a certain article by id from database and
returns the result as an array for further processing
47. Plugins: Hooks
<?php
class Shopware_Plugins_Frontend_myHook_Bootstrap extends Shopware_Components_Plugin_Bootstrap
{
public function install()
{
$hook = $this->createHook(
'sArticles',
'sGetArticleById',
'onArticle',
Enlight_Hook_HookHandler::TypeAfter,
0
);
$this->subscribeHook($hook);
return true;
}
static function onArticle(Enlight_Hook_HookArgs $args)
{
}
}
48. Summary
• Each system employs a slightly different method of
inserting custom functionalities
• Layout and functional files are more or less
encapsulated
• No core-hacking required – still a need for testing!