Comment surcharger le core de Magento (v 1.3.0)

Last modified by Anthony Charrex on Wed, June 23, 2010 17:51
Source|Old Revisions  

This is an old revision of the document!


Objectif

Afin d’étendre les fonctionnalités natives de Magento, nous allons nous intéresser ici au mécanisme de surcharge du noyau de Magento.

Cette pratique consiste à surcharger une partie d’un module (contrôleur, modèle, helper...) afin de modifier son comportement par défaut et de rendre possible les mises à jours futures de Magento sans risquer la perte des modifications qui auraient pu être codées en dur dans son core.

Configuration de base

Afin d’effectuer une surcharge, nous devons tout d’abord créer un nouveau module. Pour ce faire, ajoutez un nouveau répertoire dans le dossier ./app/code/local en vous basant sur l’architecture suivante :

`-- Mynamespace
    `-- Mymodule
        `-- etc
            `-- config.xml

(où Mynamespace et Mymodule peuvent être remplacés respectivement par le nom de votre société et par le nom du module que vous souhaitez surcharger)

Puis, configurez le fichier config.xml de cette manière :

  1. <?xml version="1.0"?>
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <version>0.1.0</version>
  6.         </Mynamespace_Mymodule>
  7.     </modules>
  8. </config>

Et, afin d’informer Magento de l’existence de ce nouveau module, créez un nouveau fichier nommé Mynamepsace_Mymodule.xml dans le répertoire ./app/etc/modules :

  1. <?xml version="1.0"?> 
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <active>true</active>
  6.             <codePool>local</codePool>
  7.         </Mynamespace_Mymodule>
  8.     </modules>
  9. </config>

Surcharger une classe

Pour surcharger un contrôleur, un modèle, un bloc ou un helper, tous basés sur des classes PHP, nous aurons besoin de créer une ou plusieurs classes étendants les fonctionnalités “par défaut” du core de Magento.

Cette extension se fera à l’aide du mot-clé “extends” de PHP et du fichier config.xml permettant d’indiquer à Magento le type de surcharge à effectuer.

Les différents types de surcharge

Afin de vous présenter au mieux les différents types de surcharge, nous allons à chaque fois nous baser sur plusieurs exemples différents représentant certaines subtilités qui peuvent souvent poser beaucoup de problèmes.

Surcharge d'un contrôleur

Dans ce document, nous allons nous intéresser à deux types de contrôleur : les contrôleurs dits “accessibles” et les contrôleurs “d’arrière-plan”.

Le premier type représente les contrôleurs auxquels on accède directement grâce à leur URL. Par exemple, le contrôleur Customer_Account est appelé à l’adresse http://www.mymagentostore.com/customer/account/.

Quant au deuxième type, il représente les contrôleurs qui sont appelés de façon indirecte. Prenez l’exemple du contrôleur Cms_Index ou Cms_Page qui sont respectivement appelés lors de la visualisation de la page d’accueil (ex. http://www.mymagentostore.com/) et d’une page du CMS, par exemple http://www.mymagentostore.com/mycmspage.

Cas 1 : le contrôleur dit "accessible"

Pour ce cas, nous allons nous pencher sur le contrôleur Customer_Account en partant sur l’arborescence suivante :

`-- Mynamespace
    `-- Mymodule
        |-- controllers
        |   `-- Customer
        |       `-- AccountController.php
        `-- etc
            `-- config.xml

Comme vous pouvez le voir, nous avons ajouter un répertoire controllers à notre configuration de base dans lequel se trouve un dossier Customer puis un fichier AccountController.php. C’est dans ce fichier que nous surchargerons les diverses méthodes du contrôleur Customer_Account (fichier ./app/code/Mage/Customer/controllers).

Pour commencer, nous allons réécrire la méthode _loginPostRedirect du fichier AccountController.php afin que l’utilisateur soit redirigé sur la page d’accueil après s’être connecté à son compte :

  1. <?php
  2.  
  3. require_once 'Mage/Customer/controllers/AccountController.php';
  4.  
  5. class Mynamespace_Mymodule_Customer_AccountController extends Mage_Customer_AccountController
  6. {
  7.  
  8.     /**
  9.      * Redirects user to home page...
  10.      */
  11.     protected function _loginPostRedirect()
  12.     {
  13.         $this->_redirectUrl(Mage::getBaseUrl());
  14.     }
  15.  
  16. }

(notez bien qu’il vous faudra obligatoirement inclure la classe Mage_Customer_AccountController au travers d’un appel à l’instruction require_once)

Ensuite, nous allons rajouter une règle rewrite à notre fichier config.xml :

  1. <?xml version="1.0"?>
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <version>0.1.0</version>
  6.         </Mynamespace_Mymodule>
  7.     </modules>
  8.     <global>
  9.         <rewrite>
  10.             <mynamespace_mymodule_customer_account>
  11.                 <from><![CDATA[#^/customer/account/#]]></from> <!-- traduit par http://www.mymagentostore.com/customer/account/ -->
  12.                 <to>/mymodule/customer_account/</to> <!-- traduit par /Mynamespace/Mymodule/controllers/Customer/AccountController.php -->
  13.             </mynamespace_mymodule_customer_account>
  14.         </rewrite>
  15.     </global>
  16.     <frontend>
  17.         <routers>
  18.             <Mynamespace_Mymodule>
  19.                 <use>standard</use>
  20.                 <args>
  21.                     <module>Mynamespace_Mymodule</module>
  22.                     <frontName>mymodule</frontName>
  23.                 </args>
  24.             </Mynamespace_Mymodule>
  25.         </routers>
  26.     </frontend>
  27. </config>

Cas 2 : le contrôleur "d'arrière-plan"

Dans ce deuxième cas, nous allons surcharger le contrôleur Mage_Cms_IndexController (fichier ./app/code/core/Mage/Cms/controllers/IndexController.php).

Commençons par définir notre nouvelle arborescence :

`-- Mynamespace
    `-- Mymodule
        |-- controllers
        |   `-- Cms
        |       `-- PageController.php
        `-- etc
            `-- config.xml

Ensuite, éditons le fichier PageController.php et ajoutons-y le code suivant :

  1. <?php
  2.  
  3. require_once 'Mage/Cms/controllers/PageController.php';
  4.  
  5. class Mynamespace_Mymodule_Cms_PageController extends Mage_Cms_PageController
  6. {
  7.  
  8.     public function viewAction()
  9.     {
  10.         $pageId = $this->getRequest()->getParam('page_id', $this->getRequest()->getParam('id', false));
  11.         if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
  12.             $this->_forward('noRoute');
  13.         }
  14.     }
  15.  
  16. }

Enfin, configurons une nouvelle règle de rewrite dans le fichier config.xml :

  1. <?xml version="1.0"?>
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <version>0.1.0</version>
  6.         </Mynamespace_Mymodule>
  7.     </modules>
  8.     <global>
  9.         <routers>
  10.             <cms>
  11.                 <rewrite>
  12.                     <page>
  13.             <to>/mymodule/cms_page</to>
  14.             <override_action>true</override_action>
  15.             <actions>
  16.                             <view><to>mymodule/cms_page/view</to></view>
  17.             </actions>
  18.                     </page>
  19.                 </rewrite>
  20.             </cms>
  21.         </routers>
  22.     </global>
  23.     <frontend>
  24.         <routers>
  25.             <Mynamespace_Mymodule>
  26.                 <use>standard</use>
  27.                 <args>
  28.                     <module>Mynamespace_Mymodule</module>
  29.                     <frontName>mymodule</frontName>
  30.                 </args>
  31.             </Mynamespace_Mymodule>
  32.         </routers>
  33.     </frontend>
  34. </config>

Surcharge d'un modèle

Pour surcharger un modèle, nous allons nous baser sur l’exemple du modèle Cms_Page (fichier ./app/code/core/Mage/Cms/Model/Page.php).

Pour commencer, reprenons notre arborescence de base et ajoutons-y un répertoire Model, un dossier Cms puis un fichier Page.php :

`-- Mynamespace
    `-- Mymodule
        |-- etc
        |   `-- config.xml
        `-- Model
            `-- Cms
                 `-- Page.php

Ensuite, dans le fichier Page.php, étendons la classe Mage_Cms_Model_Page de cette façon :

  1. <?php
  2.  
  3. class Mynamespace_Mymodule_Model_Cms_Page extends Mage_Cms_Model_Page
  4. {
  5.  
  6.     // ...
  7.  
  8. }

Puis, dans le fichier config.xml, indiquons à Magento que nous souhaitons surcharger ce modèle :

  1. <?xml version="1.0"?>
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <version>0.1.0</version>
  6.         </Mynamespace_Mymodule>
  7.     </modules>
  8.     <global>
  9.         <models>
  10.             <cms>
  11.                 <rewrite>
  12.                     <page>Mynamespace_Mymodule_Model_Cms_Page</page>
  13.                 </rewrite>
  14.             </cms>
  15.         </models>
  16.     </global>
  17.     <frontend>
  18.         <routers>
  19.             <Mynamespace_Mymodule>
  20.                 <use>standard</use>
  21.                 <args>
  22.                     <module>Mynamespace_Mymodule</module>
  23.                     <frontName>mymodule</frontName>
  24.                 </args>
  25.             </Mynamespace_Mymodule>
  26.         </routers>
  27.     </frontend>
  28. </config>

Vous remarquerez qu’au sein de la balise models nous retrouvons les balises cms et page, qui représentent respectivement le nom du module et le nom du bloc. Pour illustrer au mieux ce mécanisme, voici d’autres exemples de configuration :

  1.     <global>
  2.  
  3.         <models>
  4.  
  5.             <!-- Surcharge du modèle Mage_Cms_Page -->
  6.             <cms>
  7.                 <rewrite>
  8.                     <page>Mynamespace_Mymodule_Model_Cms_Page</page>
  9.                 </rewrite>
  10.             </cms>
  11.  
  12.             <!-- Surcharge du modèle Mage_Adminhtml_Model_Customer_Renderer_Region -->
  13.             <adminhtml>
  14.                 <rewrite>
  15.                     <customer_renderer_region>Mynamespace_Mymodule_Model_Adminhtml_Customer_Renderer_Region</customer_renderer_region>
  16.                 </rewrite>
  17.             </adminhtml>       
  18.  
  19.             <!-- Surcharge du modèle Mage_Customer_Model_Entity_Customer_Collection -->
  20.             <customer_entity>
  21.                 <rewrite>
  22.                     <customer_collection>Mynamespace_Mymodule_Model_Customer_Entity_Customer_Collection</customer_collection>
  23.                 </rewrite>
  24.             </customer_entity>       
  25.  
  26.             <!-- Surcharge du modèle Mage_CatalogInventory_Model_Stock_Item_Api_V2 -->
  27.             <cataloginventory_stock>
  28.                 <rewrite>
  29.                     <item_api_v2>Mynamespace_Mymodule_Model_CatalogInventory_Stock_Item_Api_V2</item_api_v2>
  30.                 </rewrite>
  31.             </cataloginventory_stock>
  32.  
  33.             <!-- Surcharge du modèle Mage_Cms_Model_Mysql4_Page -->
  34.             <cms_mysql4>
  35.                 <rewrite>
  36.                     <page>Mynamespace_Mymodule_Model_Cms_Mysql4_Page</page>
  37.                 </rewrite>
  38.             </cms_mysql4>
  39.  
  40.             <!-- Surcharge du modèle Mage_Cms_Model_Mysql4_Page_Collection -->
  41.             <cms_mysql4>
  42.                 <rewrite>
  43.                     <page_collection>Mynamespace_Mymodule_Model_Cms_Mysql4_Page_Collection</page_collection>
  44.                 </rewrite>
  45.             </cms_mysql4>
  46.  
  47.             <!-- Surcharge du modèle Mage_CatalogSearch_Model_Mysql4_Advanced_Collection -->
  48.             <catalogsearch_mysql4>
  49.                 <rewrite>
  50.                     <advanced_collection>Mynamespace_Mymodule_Model_CatalogSearch_Mysql4_Advanced_Collection</advanced_collection>
  51.                 </rewrite>
  52.             </catalogsearch_mysql4>
  53.  
  54.             <!-- Surcharge du modèle Mage_Tax_Model_Mysql4_Calculation_Rate_Title_Collection -->
  55.             <tax_mysql4>
  56.                 <rewrite>
  57.                     <calculation_rate_title_collection>Mynamespace_Mymodule_Model_Tax_Mysql4_Calculation_Rate_Title_Collection</calculation_rate_title_collection>
  58.                 </rewrite>
  59.             </tax_mysql4>
  60.  
  61.             <!-- Surcharge du modèle Mage_Catalog_Model_Resource_Eav_Mysql4_Product -->
  62.             <catalog_resource_eav_mysql4>
  63.                 <rewrite>
  64.                     <product>Mynamespace_Mymodule_Model_Catalog_Resource_Eav_Mysql4_Product</product>
  65.                 </rewrite>
  66.             </catalog_resource_eav_mysql4>
  67.  
  68.         </models>
  69.        
  70.     </global>

Remarque : un modèle basé sur une classe abstraite ne peut pas être surchargé.

Surcharge d'un bloc

Dans cette section, nous allons nous baser sur l’exemple du bloc Mage_Cms_Page. Dans un premier temps, nous allons donc mettre en place l’arborescence suivante :

`-- Mynamespace
    `-- Mymodule
        |-- Block
        |   `-- Cms
        |       `-- Page.php
        `-- etc
            `-- config.xml

Dans le fichier Page.php, nous allons étendre la classe Mage_Cms_Block_Page et redéfinir la méthode _toHtml afin d’ajouter au contenu des pages du CMS affiché sur le frontend leur titre (qui par défaut n’est affiché que dans la barre de titre du navigateur) :

  1. <?php
  2.  
  3. class Mynamespace_Mymodule_Block_Cms_Page extends Mage_Cms_Block_Page
  4. {
  5.     protected function _toHtml()
  6.     {
  7.         $processor = Mage::getModel('core/email_template_filter');
  8.         $html = $processor->filter($this->getPage()->getContent());
  9.         $html = $this->getMessagesBlock()->getGroupedHtml() . $html;
  10.         return $this->getPage()->getTitle() . $html; // ajout du titre au contenu
  11.     }
  12. }

Ensuite, nous allons déclarer la surcharge dans le fichier config.xml :

  1. <?xml version="1.0"?>
  2. <config>
  3.     <modules>
  4.         <Mynamespace_Mymodule>
  5.             <version>0.1.0</version>
  6.         </Mynamespace_Mymodule>
  7.     </modules>
  8.     <global>
  9.         <blocks>
  10.             <cms>
  11.                 <rewrite>
  12.                     <page>Mynamespace_Mymodule_Block_Cms_Page</page>
  13.                 </rewrite>
  14.             </cms>
  15.         </blocks>
  16.     </global>
  17.     <frontend>
  18.         <routers>
  19.             <Mynamespace_Mymodule>
  20.                 <use>standard</use>
  21.                 <args>
  22.                     <module>Mynamespace_Mymodule</module>
  23.                     <frontName>mymodule</frontName>
  24.                 </args>
  25.             </Mynamespace_Mymodule>
  26.         </routers>
  27.     </frontend>
  28. </config>

Vous remarquerez qu’au sein de la balise blocks nous retrouvons les balises cms et page, qui représentent respectivement le nom du module et le nom du bloc. Mais que faire lorsque le bloc à surcharger se trouve dans un sous-répertoire du dossier Blocks ?

Et bien il suffira de remplacer le nom du bloc par son chemin à partir du dossier Blocks. Afin d’illustrer ce propos, prenons comme exemple le bloc Customer_Form_Login (fichier ./app/code/core/Mage/Customer/Blocks/Form/Login.php) dont voici le paramétrage du fichier config.xml :

  1.     <global>
  2.         <blocks>
  3.             <customer>
  4.                 <rewrite>
  5.                     <form_login>Mynamespace_Mymodule_Block_Customer_Form_Login</form_login>
  6.                 </rewrite>
  7.             </customer>   
  8.         </blocks>
  9.     </global>

Et pour compléter ce propos, voici un autre exemple avec le bloc Customer_Account_Dashboard_Address (fichier ./app/code/core/Mage/Customer/Blocks/Account/Dashboard/Address.php) :

  1.     <global>
  2.         <blocks>
  3.             <customer>
  4.                 <rewrite>
  5.                     <account_dashboard_address>Mynamespace_Mymodule_Block_Customer_Account_Dashboard_Address</account_dashboard_address>
  6.                 </rewrite>
  7.             </customer>
  8.         </blocks>
  9.     </global>
  

Enfin, lorsqu’il s’agit d’un bloc appelé dans le backend (situé dans le répertoire ./app/code/core/Mage/Adminhtml/Block), voici la configuration à utiliser dans le fichier config.xml :

  1.     <blocks>
  2.         <!-- Surcharge du bloc Mage_Adminhtml_Block_Cms_Page_Grid -->
  3.         <adminhtml>
  4.             <rewrite>
  5.                 <cms_page_grid>Mynamespace_Mymodule_Block_Adminhtml_Cms_Page_Grid</cms_page_grid>
  6.             </rewrite>
  7.         </adminhtml>
  8.     </blocks>

Surcharge d'un helper

Tous les principes évoqués dans la section Surcharge d’un bloc sont également valables pour les helpers, à l’exception près qu’il faudra utiliser la balise helpers à la place de la balise blocks dans le fichier de configuration config.xml, et copier les helpers à surcharger dans le répertoire Helper.

Dans cette section, nous n’allons donc pas re-détailler les différents cas pouvant se présenter à vous.

Références




 

Magento 2 GitHub Repository

Magento Job Board - Some sort of tag line goes here

Latest Posts| View all Jobs