Module Magento: Créer son propre controller

Respect my authoritahMagento profite largement du modèle MVC. Cela lui permet ainsi de définir ses modèles, vues (layout + templates) et ses controllers. Malgré le grand nombre de modules Magento disponibles par défaut dans Magento et sur Magento Connect vous pouvez être amené à vouloir créer le votre et y définir votre propre controller pour votre site Magento. Pas de problème, nous allons voir comment créer son propre controller et comment faire en sorte qu'il fasse respecter son autorité aux layouts et templates.

Dans cet exemple, nous allons voir comment créer un controller dont l'intérêt sera de retourner le résultat d'une multiplication de deux entiers (pratique si on ne retrouve plus sa calculatrice). Les entiers à multiplier seront fournis grâce à un formulaire. Le résultat sera affiché dans une notification Magento.

Avant de commencer à créer votre extension, veuillez vous assurer que votre cache est désactivé afin de pouvoir constater immédiatement les modifications apportées.

Création du module

Notre extension s'appellera arithmetic. On crée tout d'abord les dossiers pour cette extension.

$ mkdir -p app/code/local/Baobaz/Arithmetic/controllers
$ mkdir -p app/code/local/Baobaz/Arithmetic/etc

On crée le fichier app/code/local/Baobaz/Arithmetic/etc/config.xml, afin de déclarer cette extension

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <baobaz_arithmetic>
            <version>0.0.1</version>
        </baobaz_arithmetic>
    </modules>
</config>

Plus un fichier app/etc/modules/Baobaz_Arithmetic.xml afin de l'activer:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Baobaz_Arithmetic>
            <active>true</active>
            <codePool>local</codePool>
        </Baobaz_Arithmetic>
    </modules>
</config>

N'hésitez pas à consulter le post de Wojtek "Tutoriel - Développer un module pour Magento - Où commencer ? [Partie 1]" pour plus de détails concernant la création d'un nouveau module.

Création d'un controller

Il faut maintenant créer un fichier app/code/local/Baobaz/Arithmetic/controllers/IntegerController.php et y déclarer une méthode qui sera utilisée pour la multiplication.

Les fichiers des controllers doivent toujours être de la forme xxxxxController.php (xxxxx va être utilisé ensuite dans l'url pour appeler ce controller) et être mis dans le dossier controllers.
Les noms des méthodes des controllers doivent avoir un nom de la forme yyyyyAction (yyyyy sera aussi utilisé dans l'url pour appeler ce controller). Notre fichier contient donc pour le moment

class Baobaz_Arithmetic_IntegerController extends Mage_Core_Controller_Front_Action
{
    public function multiplyAction(){
    }
}

Il faut déclarer que des controllers sont disponibles avec le module Arithmetic. On ajoute pour cela dans le fichier app/code/local/Baobaz/Arithmetic/etc/config.xml

<config>
    ...
    <frontend>
        <routers>
            <arithmetic>
                <use>standard</use>
                <args>
                    <module>Baobaz_Arithmetic</module>
                    <frontName>arithmetic</frontName>
                </args>
            </arithmetic>
        </routers>  
    </frontend>
</config>

Voyons comment fonctionne cette déclaration de route vers le controller :

  • <frontend> indique que cette route sera utilsée pour la partie front du site
  • <routers> est l'endroit où l'on déclare les routes
  • <arithmetic> est l'identifiant de cette route
  • <use>standard</use> peut prendre les valeurs standard (pour la partie front office) ou admin (pour la partie admin)
  • <module>Baobaz_Arithmetic</module> indique dans quel module se trouve le controller pour gérer cette route
  • <frontName>arithmetic</frontName> indique le nom de la route dans l'url

On peut désormais modifier la méthode multiplyAction afin qu'elle affiche un message:

public function multiplyAction(){
    echo "Respect my authoritah";
}

En appelant l'url http://monsitemagento/arithmetic/integer/multiply le message "Respect my authoritah" s'affiche. Décortiquons un peu cette url :

  • arithmetic indique que le controller se trouve dans l'estension Baobaz_Arithmetic
  • integer indique qu'il faut regarder le fichier controllers/integerController.php
  • multiply indique qu'il faut choisir la méthode multiplyAction dans ce fichier

Afficher une template

On définit le fichier de layout à utiliser en le déclarant dans l'extension

<config>
    ...
    <frontend>
        ...
        <layout>
            <updates>
                <arithmetic>
                    <file>arithmetic.xml</file>
                </arithmetic>
            </updates>
        </layout>
    </frontend>
</config>

On crée le fichier app/design/frontend/default/default/layout/arithmetic.xml afin d'y déclarer les blocs que l'on va utiliser pour le controller que l'on vient de créer.

<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
    <arithmetic_integer_multiply>
        <reference name="root">
            <action method="setTemplate">
                <template>page/1column.phtml</template>
            </action>
        </reference>
        <reference name="content">
            <block type="core/template" name="arithmetic_integer_multiply" template="arithmetic/integer/multiply.phtml"></block>
        </reference>
    </arithmetic_integer_multiply>
</layout>

La template principale utilisée par arithmetic/integer/multiply est page/1column.phtml. Pour la partie "content" de cette template on affiche juste le bloc arithmetic_integer_multiply. Ce bloc ne nécessite pas de traitement particulier. On le déclare donc du type core/template qui est le type par défaut. Le fichier de template utilisé sera arithmetic/integer/multiply.phtml.

Notre template est défini, il faut donc créer le fichier app/design/frontend/default/default/template/arithmetic/integer/multiply.phtml qui sera vide pour le moment.

Pour faire en sorte que le layout s'affiche correctement, il faut le charger dans le controller

public function multiplyAction(){
    $this->loadLayout();
    $this->renderLayout();
}

Interaction entre le template et le controller

Notre template Magento est simplement constitué d'un formulaire qui doit fournir les deux entiers à multiplier

<form action="<?php echo Mage::getUrl('arithmetic/integer/multiply') ?>" method="post">
    <fieldset>
        <ul>
            <li>
                <label for="int1">Integer 1</label>
                <input type="text" id="int1" name="int1" />
            </li>
            <li>
                <label for="int2">Integer 2</label>
                <input type="text" id="int2" name="int2" />
            </li>
            <li><input type="submit" value="Multiply" /></li>
        </ul>
    </fieldset>
</form>

L'url appelée par le formulaire est toujours arithmetic/integer/multiply. On doit donc désormais modifier l'action du controller pour prendre en compte le formulaire et retourner le résultat.

public function multiplyAction(){
    if ($this->getRequest()->isPost()){
        $int1 = $this->getRequest()->getPost('int1');
        $int2 = $this->getRequest()->getPost('int2');
        $result = $int1 * $int2;
    Mage::getSingleton('customer/session')->addSuccess("$int1 * $int2 = $result");
    }
    $this->loadLayout();
    $this->_initLayoutMessages('customer/session');
    $this->renderLayout();
}

Pour savoir si le controller est appelé après utilisation du formulaire on utilise :

$this->getRequest()->isPost()

Le résultat est placé dans la session 'customer/session'. Pour pouvoir afficher ces message dans les templates pensez bien à charger la template des messages dans la méthode multiplyAction avec

$this->_initLayoutMessages('customer/session');

Rajouter dans votre template la ligne

echo $this->getMessagesBlock()->getGroupedHtml();

à l'endroit où vous désirez afficher ces messages.

Et voilà, nous avons désormais un tout nouveau controller qui nous affiche le résultat d'une multiplication. Elle est pas belle la vie ?

L'ensemble des fichiers utilisés pour ce tuto sont disponible dans l'archive baobaz_arithmetic.tar.gz

Ce post est inpiré du post d'Alan Storm Magento Front Controller. Pensez à visiter son blog très instructif.

4 comments on "Module Magento: Créer son propre controller"

Portrait de Metal3d
Metal3d (visiteur) - ven, 11/12/2009 - 15:45:

Erreur dans la page:
* <frontend> est l'endroit où l'on déclare les routes

Il fallait lire
* <routers> est l'endroit où l'on déclare les routes

Portrait de Laurent Clouet
Laurent Clouet - ven, 11/12/2009 - 18:20:

J'ai corrigé l'article.
Merci d'avoir signalé cette erreur.

Portrait de Leonard
Leonard (visiteur) - ven, 22/06/2012 - 08:11:

That is good use of PR and does drive more traffic to your site, with the ultimate goal of increasing sales. We missed that boat the last time but will be all over it if we win again.
technical translation services

Portrait de Eric
Eric (visiteur) - dim, 26/08/2012 - 13:13:

Bjr merci pour ce tuto j'aimerai vous continue et je veux comprendre comment va afficher le resultat?