Diese Präsentation wurde erfolgreich gemeldet.

Modul-Entwicklung für Magento, OXID eShop und Shopware (2013)

1

Teilen

1 von 47
1 von 47

Weitere Verwandte Inhalte

Ähnliche Bücher

Kostenlos mit einer 14-tägigen Testversion von Scribd

Alle anzeigen

Ähnliche Hörbücher

Kostenlos mit einer 14-tägigen Testversion von Scribd

Alle anzeigen

Modul-Entwicklung für Magento, OXID eShop und Shopware (2013)

  1. 1. How  to  write  Custom   Modules  for  PHP-­based  E-­ Commerce  Systems   Roman  Z.  
  2. 2. Roman  Zenner   •  Working  as  freelance  trainer,  author  and   consultant  since  2004   •  Has  written  three  books  on  Magento  and   OXID  eShop   •  Is  in  the  process  of  writing  a  “cookbook”   on  OXID  eShop  with  Joscha  Krug   •  Publishes  in  various  magazines  
  3. 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. 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.)  
  5. 5. Today‘s  candidates   •  Magento   •  OXID  eShop   •  Shopware  
  6. 6. http://www.flickr.com/photos/exey/3815327201
  7. 7. 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  de^initions   •  Bought  by  eBay  in  2011  (X.commerce)   •  Current  stable  version:  1.7.0.2  
  8. 8. Structure  
  9. 9. Templates  (1)  
  10. 10. Templates  (2)  
  11. 11. Templates  (2)   <block type="page/html“ name="root" output="toHtml“ template="page/3columns.phtml"> <block type="page/html_header" name="header" as="header"> <block type="page/switch" name="store_language" as="store_language" template="page/switch/languages.phtml"/></block> </block> Template: /layout/page.xml <?php if(count($this->getStores())>1): ?> <div class="form-language“> <?php foreach ($this->getStores() as $_lang): ?> <?php $_selected = ($_lang->getId() == $this->getCurrentStoreId()) ? ' selected="selected"' : '' ?> <option value="<?php echo $_lang->getCurrentUrl() ?>"<?php echo $_selected ?>> <?php endforeach; ?> </div> <?php endif; ?> Template: /template/page/switch/languages.phtml
  12. 12. Drilling  down  (1)   Example: How to get from the article name in the template to the database field?
  13. 13. Drilling  down  (2)   1.  Block: <block type="catalog/product_view" name="product.info" template="catalog/ product/view.phtml"> 2.  Template: /app/design/frontend/base/default/template/catalog/product/view.phtml 3.  Block class: Mage_Catalog_Block_Product_View 4.  Model: Mage_Catalog_Model_Product: public function getProduct() { if (!Mage::registry('product') && $this->getProductId()) { $product = Mage::getModel('catalog/product')->load($this->getProductId()); Mage::register('product', $product); } return Mage::registry('product'); }
  14. 14. Drilling  down  (3)   1.  Abstract class: Mage_Core_Model_Abstract 2.  Resource model: Mage_Core_Model_Mysql4_Abstract public function load($id, $field=null) { $this->_beforeLoad($id, $field); $this->_getResource()->load($this, $id, $field); $this->_afterLoad(); $this->setOrigData(); $this->_hasDataChanges = false; return $this; }
  15. 15. Modules  
  16. 16. Brief  History   •  OS-­‐Edition  since  late  2008.   •  Based  on  own  PHP-­‐Framework  &  MySQL   •  Recent  version:  4.7.3  
  17. 17. Features   •  ADODB  database  abstraction  layer   •  Uses  Smarty  2  (but  Template  Inheritance  by   Smarty  3)   •  Block  Inheritance   •  Autoloader  
  18. 18. Structure  
  19. 19. Template  Inheritance  (1)  
  20. 20. Template  Inheritance  (2)   [{capture append="oxidBlock_content"}] [{assign var="oFirstArticle" value=$oView->getFirstArticle()}] [{/capture}] [{include file="layout/page.tpl" sidebar="Right"}] /out/azure/tpl/page/shop/start.tpl
  21. 21. Template  Inheritance  (3)   <div id="content"> [{include file="message/errors.tpl"}] [{foreach from=$oxidBlock_content item="_block"}] [{$_block}] [{/foreach}] </div> [{include file="layout/footer.tpl"}] /out/azure/tpl/layout/page.tpl
  22. 22. Drilling  down  (1)   Example:     How  to  get  from  the  article  name  in   the  Smarty-­‐Template  to  the  database  ^ield?  
  23. 23. Drilling  down  (2)   •  Article  detail  page:  /out/azure/tpl/page/details/inc/productmain.tpl   [{block name="details_productmain_title"}] <h1 id="productTitle"><span itemprop="name"> [{$oDetailsProduct->oxarticles__oxtitle->value}] [{$oDetailsProduct->oxarticles__oxvarselect->value}]</span></h1> [{/block}] Scheme: [Object name]->[Table name]__[Field name]->value •  View controller: /application/controller/details.php
  24. 24. 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 ) ) { ... } }
  25. 25. 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 ); } /application/models/oxarticle.php /core/oxbase.php
  26. 26. 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
  27. 27. Custom  classes  (2)   •  This  procedure  becomes  problematic  when  there  is  more   than  one  new  module  wanting  to  extend  a  speci^ic  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  
  28. 28. 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  metadata.php  (used  to   be  via  Admin)   'extend' => array( 'oxarticle' => ‘xmas/xmasArticle' )
  29. 29. Plugins  (2)     class  xmasArticle  extends  xmasArticle_parent   {          public  function  getDaysLeft()          {                  $time  =  mktime(0,  0,  0,  12,  25,  2011,  1)  -­‐  time();                  $days  =  ^loor($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
  30. 30. 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:  4.0.7  
  31. 31. Enlight-­‐Framework   •  Basis  functionalities  are  inherited  from  Zend   Framework:     •  Syntax  and  Work^low   •  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  
  32. 32. Template-­‐Structure  
  33. 33. index.tpl   {* Content section *} <div id="content"> <div class="inner”> {* Content top container *} {block name="frontend_index_content_top"}{/block} {* Sidebar left *} {block name='frontend_index_content_left'} {include file='frontend/index/left.tpl'} {/block} {* Main content *} {block name='frontend_index_content'}{/block} {* Sidebar right *} {block name='frontend_index_content_right'}{/block} <div class="clear">&nbsp;</div> </div> </div>
  34. 34. Template-­‐Inheritance   {extends file=”../_default/frontend/home/index.tpl} {block name=’frontend_index_content’ prepend} <h1>Hallo Welt</h1> {/block} SMARTY: Append – Prepend - Replace
  35. 35. Plugin-­‐Directory  Structure  
  36. 36. Drilling  down   Example:     How  to  get  from  the  article  name  in   the  Smarty-­‐Template  to  the  database  ^ield?  
  37. 37. 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  ^ind  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  
  38. 38. Plugins:  Bootstrap   <?php class Shopware_Plugins_Frontend_IPCDEMO_Bootstrap extends Shopware_Components_Plugin_Bootstrap { public function install() { // return true; } public static function onPostDispatch(Enlight_Event_EventArgs $args) { // Still empty } }
  39. 39. Plugins:  Event   public function install() { $event = $this->createEvent('Enlight_Controller_Action_PostDispatch','onPostDispatch'); $this-> subscribeEvent($event); $form = $this->Form(); $form->setElement('textarea', ’yourtext', array('label'=>’Text for left column’,'value'=>’Hello World')); $form->save(); return true; }
  40. 40. Plugins:  Listener   !public static function onPostDispatch(Enlight_Event_EventArgs $args) { $view = $args->getSubject()->View(); $config = Shopware()->Plugins()->Frontend()->IPCDEMO()->Config(); $view->pluginText = $config->yourtext; $view->addTemplateDir(dirname(__FILE__)."/Views/"); $view->extendsTemplate('plugin.tpl'); }
  41. 41. 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) { } }
  42. 42. Summary   •   Each  system  employs  a  slightly  different  method  of          inserting  custom  functionalities   •   Layout  and  functional  ^iles  are  more  or  less   encapsulated   •   No  core-­‐hacking  required  –  still  a  need  for  testing!  
  43. 43. Thank  you!   Blog:  romanzenner.com   Skype:  roman_zenner   XING:  xing.com/pro^ile/Roman_Zenner   Twitter:  twitter.com/rzenner  
  44. 44. MVC-­‐Model  (extended)  

×