Surcharger un contrôleur Magento

Dans la mesure où il est interdit de modifier le CORE de Magento, la plate-forme propose plusieurs options pour surcharger son code natif. Les options de surcharge d'un contrôleur sont différentes de celles des autres classes Magento.
Nous allons les décrire.

Surcharge d'un contrôleur :

Nous allons prendre comme exemple le panier Magento. Le module se nomme Mage_Checkout et le contrôleur qui nous intéresse est CartController.

Il existe 2 méthodes pour surcharger un contrôleur Magento :

  • La première (la plus contraignante) est une méthode qui existe depuis la première version de Magento.
  • La deuxième (la meilleure) est disponible depuis la version 1.3

Pré-requis

Vous avez déjà créé un module perso et celui-ci est activé. Ce module se nomme Netapsys_Moduleperso et se trouve dans le répertoire app/code/local/Netapsys/Moduleperso/

Pour les besoins de ce billet nous considérerons le contrôleur suivant :


require_once 'Mage/Checkout/controllers/CartController.php';

class Netapsys_Moduleperso_Checkout_CartController extends Mage_Checkout_CartController
{
    /**
     * Shopping cart display action
     */
    public function indexAction()
    {
        $this->_getCart()->getCheckoutSession()->addSuccess('Rewrite OK');
        parent::indexAction();
    }
}

Le fichier se trouvera physiquement dans app/code/local/Netapsys/Moduleperso/controllers/Checkout/CartController.php

Les différentes méthodes de surcharge

1. Méthode historique

Éditez le fichier config.xml de votre module (répertoire app/code/local/Netapsys/Moduleperso/etc) :

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Netapsys_Moduleperso>
            <version>0.1.0</version>
        </Netapsys_Moduleperso>
    </modules>
    <global>
        <rewrite>
            <netapsys_moduleperso_checkout_cart>
                <from><![CDATA[#^/checkout/cart/#]]></from>
                <to>/moduleperso/checkout_cart/</to>
            </netapsys_moduleperso_checkout_cart>
        </rewrite>
    </global>
    <frontend>
        <routers>
            <netapsys_moduleperso>
                <use>standard</use>
                <args>
                    <module>Netapsys_Moduleperso</module>
                    <frontName>moduleperso</frontName>
                </args>
            </netapsys_moduleperso>
        </routers>
    </frontend>
</config>

Parlons d'abord de la partie <frontend>. A l'intérieur se trouve un noeud <routers> qui va permettre de définir de quelle manière notre module sera appelé via une URL. C'est ce qui est défini à l'intérieur du noeud <frontName>, ici moduleperso. Nous pourrons donc appeler notre module avec une URL du type http://www.monsite.fr/moduleperso/ même si nous ne l'utiliserons pas dans le cadre de ce billet.

La surcharge à proprement parlé se trouve dans le noeud <rewrite>. Le noeud suivant <netapsys_moduleperso_checkout_cart> est l'identifiant unique de votre surcharge. Suivent ensuite les noeuds <from> et <to>. Le premier correspond au controller/action du core de Magento. Le deuxième correspond au controller/action qui vient surcharger le core.

<from><![CDATA[#^/checkout/cart/#]]></from>
<to>/moduleperso/checkout_cart/</to>

Comment comprendre cette partie ?

Dès qu'une URL du type checkout/cart (Module Checkout / contrôleur Cart) sera appelée, Magento va détecter qu'une surcharge est en place grâce au noeud <from>. Il analyse ensuite la donnée <to> et dans notre cas va traduire ”/moduleperso/checkout_cart/” par l'utilisation du fichier ”/Netapsys/Moduleperso/controllers/Checkout/CartController.php”

On peut se contenter de surcharger une action en particulier en procédant comme suit :

<from><![CDATA[#^/checkout/cart/index/#]]></from>
<to>/moduleperso/checkout_cart/index/</to>

2. Méthode disponible depuis Magento 1.3 (recommandée)

Depuis la version 1.3 de Magento il existe une méthode plus simple et plus efficace qui permet d'ajouter votre module perso au routeur du module Magento.

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Netapsys_Moduleperso>
            <version>0.1.0</version>
        </Netapsys_Moduleperso>
    </modules>
    
    <frontend>
        <routers>
            <checkout>
                <args>
                    <modules>
                        <Netapsys_Moduleperso before="Mage_Checkout">Netapsys_Moduleperso_Checkout</Netapsys_Moduleperso>
                    </modules>
                </args>
            </checkout>
        </routers>
    </frontend>
</config>

Dans l'exemple ci-dessus, à chaque fois qu'une URL du module Checkout de Magento sera appelée, le système va d'abord vérifier s'il y a dans votre module personnel un couple controller/action correspondant. Si c'est le cas il utilisera celui de votre module.

Comme vous pouvez le constater la syntaxe est beaucoup plus simple que la méthode n°1. Cette méthode n°2 est donc à privilégier car elle évite de devoir rentrer dans le détail des URL à rewriter ce qui était source d'erreur.

Ajouter une nouvelle action

Pour ajouter une nouvelle action au contrôleur d'un module Magento, rien de plus simple, il nous suffit de partir sur la 2ème méthode de surcharge et d'ajouter à notre contrôleur l'action voulue.

Par exemple nous allons ajouter une action appelée new. Notre contrôleur ressemblera donc à cela :

require_once 'Mage/Checkout/controllers/CartController.php';
class Netapsys_Moduleperso_Checkout_CartController extends Mage_Checkout_CartController
{
    /**
     * Shopping cart display action
     */
    public function indexAction()
    {
        $this->_getCart()->getCheckoutSession()->addSuccess('Rewrite OK');
        parent::indexAction();
    }
    
    /**
     * Customer login form page
     */
    public function newAction()
    {
        $this->_getCart()->getCheckoutSession()->addSuccess('Nouvelle fonction "new"');
        $this->_forwarde('index');
    }
}

Notre action sera appelée via une URL du type checkout/cart/new et même si celle-ci n'existe pas dans le module du core, Magento la trouvera dans notre contrôleur personnel.

Mise en garde

“J'ai appliqué à la lettre la méthode recommandée et la surcharge ne fonctionne pas”.

C'est possible !

Il arrive que plusieurs modules surchargent le même contrôleur du core Magento, par exemple une extension de la communauté (répertoire app/code/community) et un module personnel. Il est donc nécessaire de faire une recherche pour détecter l'extension en question.

Admettons que nous ayons détecté que l'extension Namespace_Extension (répertoire app/code/community/Namespace/Extension) surcharge également le controleur CartController du module Checkout. Pour que notre surcharge soit prise en compte nous devons, dans ce cas précis, surcharger non pas le module du core mais l'extension Namespace_Extension, en procédant comme suit :

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Netapsys_Moduleperso>
            <version>0.1.0</version>
        </Netapsys_Moduleperso>
    </modules>
    
    <frontend>
        <routers>
            <checkout>
                <args>
                    <modules>
                        <Netapsys_Moduleperso before="Namespace_Extension_Checkout">Netapsys_Moduleperso_Checkout</Netapsys_Moduleperso>
                    </modules>
                </args>
            </checkout>
        </routers>
    </frontend>
</config>

Magento va donc procéder en cascade. Si une URL du type checkout/cart/new est appelée il va d'abord regarder la surcharge de notre module, puis si l'action new n'existe pas il va regarder dans l'extension Namespace_Extension et enfin s'il ne trouve rien il utilisera le module du core.

Et Magento 2 dans tout ça ?

Dans Magento 2 la syntaxe relative aux surcharges sera grandement simplifiée, pour le bonheur de tous les développeurs !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.