Créer un module sous Magento - Partie 6 - Administration

On entre ici dans une partie assez conséquente. L'objectif ici est de créer une partie administrative de notre module. Pour le moment, nous allons faire en sorte de créer la partie "administration", pour qu'au final, on ait la liste des commerciaux qui s'affiche en intégrant le design du backoffice de Magento. Pour ce faire, il va aussi falloir comprendre comment fonctionne le backoffice de Magento.

Introduction

Pour cette partie, nous allons garder le même module créé dans les parties précédentes. Nous allons simplement faire en sorte de lister nos commerciaux dans une nouvelle page du backoffice. Nous allons aussi créer une autre page pour afficher une chaine de caractère basique pour un premier exemple. Nous avons déjà fait ça pour le frontoffice, mais on va voir que c'est un peu plus complexe pour le backoffice. 

Pour toute la partie administration d'un module, il est préférable de séparer le code d'administration du code concernant le front. Pour cela, on va ajouter un répertoire Adminhtml/ dans les répertoires controllers/, Block/, et Helper/ (pas dans Model/ car les modèles vont être les mêmes pour le frontoffice et le backoffice). Ce n'est pas obligatoire, on va plutôt dire que c'est une façon conventionnelle de faire. De même, si on a une modification du design du backoffice, le plus simple est de créer un nouveau thème pour le backoffice. Si vous ne savez pas comment faire, sachez que je vais créer rapidement un tuto pour vous l'apprendre. 

Le fichier de configuration

La première chose à faire est d'ajouter un nouveau menu dans le backoffice. Pour cela, on va modifier le fichier etc/config.xml de notre module, et ajouter le code XML suivant dans la balise <config>, en dehors des balises <frontend> et <global> :

Extrait du fichier /app/code/local/Ns/Thorleif/etc/config.xml
  1. <admin>
  2.     <routers>
  3.         <routeuradmin>
  4.             <use>admin</use>
  5.             <args>
  6.                 <module>Ns_Thorleif</module>
  7.                 <frontName>thorleifadmin</frontName>
  8.             </args>
  9.         </routeuradmin>
  10.     </routers>
  11. </admin>

Comme pour le front, on a créé un nouveau routeur nommé ici "routeuradmin", qui est configuré de la même manière que le routeur de notre front, donc pas besoin d'y revenir. On va maintenant ajouter une nouvelle balise qui va nous permettre de créer un nouvel onglet et de nouveaux menus dans le backoffice. Cette balise se nomme <adminhtml> et nous allons la placer juste après la balise <admin> pour bien regrouper tout ce qui concerne le backoffice : 

Extrait du fichier /app/code/local/Ns/Thorleif/etc/config.xml
  1. <adminhtml>
  2.     <menu>
  3.         <thorleif_menu translate="title" module="thorleif">
  4.             <title>Thorleif</title>
  5.             <sort_order>100</sort_order>
  6.             <children>
  7.                 <index>
  8.                     <title>Commerciaux</title>
  9.                     <sort_order>1</sort_order>
  10.                     <action>thorleifadmin/adminhtml_index/index</action>
  11.                 </index>
  12.                 <test>
  13.                     <title>Test</title>
  14.                     <sort_order>2</sort_order>
  15.                     <action>thorleifadmin/adminhtml_index/test</action>
  16.                 </test>
  17.             </children>
  18.         </thorleif_menu>
  19.     </menu>
  20. </adminhtml>

Dans ce fichier, on a créé un nouvel onglet "Thorleif", contenant les liens "Commerciaux" et "Test". Le nouvel onglet va se nommer "thorleif_menu", qui aura pour titre le contenu de la balise <title>, et sera positionné tout à la fin de la liste des onglets puisqu'on a précisé la position 100 dans la balise <sort_order>. Ensuite chaque lien de cet onglet sera listé dans une balise <children>. On a ici deux liens, qu'on a nommé "index" et "test", et à qui on donne un titre et une position, comme pour la création de l'onglet, mais on ajoute aussi une action, qui précise à Magento, quelle action exécuter.

Pour le lien "Commerciaux", on va donc exécuter l'action IndexAction() du contrôleur IndexController.php situé dans le répertoire Adminhtml/ du répertoire controllers/. Le nom de l'action est important. Par exemple, si votre contrôleur IndexController.php se situe dans le répertoire controllers/coucou/admin/test/, l'action sera thorleifadmin/coucou_admin_test_index/index pour l'action indexAction(). On va créer notre contrôleur par la suite, mais pour le moment, regardons notre nouveau menu dans le backoffice (si ça ne fonctionne pas, continuez ce tuto, c'est qu'il manque un helper quelque part, et nous allons le créer par la suite) : 

creer-un-module-sous-magento-partie-6-administration-1

Contrôle des accès

Nous arrivons maintenant à un point facultatif, mais qui peut s'avérer important : les ACL pour Access Control Lists. Pour faire simple, il s'agit d'un contrôle de droit sur les liens du module : avec ces options, on peut faire en sorte d'afficher les liens pour certains types d'utilisateurs, mais pas pour d'autres. Dans un Magento de base, on n'a qu'un seul rôle de créé, celui d'administrateur. Mais il se peut qu'un jour vous vouliez créer un rôle qui permettra seulement de créer des produits, et du coup, il va falloir configurer ce rôle pour que les utilisateurs ne puissent avoir accès qu'aux pages produits. 

Pour faire ces configurations, il faut se rendre dans le backoffice, onglet "System" et cliquer sur le lien Permissions > Roles, et sélectionner dans l'onglet "Role resources" les pages à afficher ou non. Pour ajouter la liste des liens que nous venons de créer, il faut ajouter une balise <acl> dans le fichier de configuration du module, dans la balise <adminhtml> après la balise <menu> de préférence (la configuration ressemblant à celle de la balise <menu>). Pour notre exemple, voici ce que ça donne : 

Extrait du fichier /app/code/local/Ns/Thorleif/etc/config.xml
  1. <acl>
  2.     <resources>
  3.         <admin>
  4.             <children>
  5.                 <thorleif_menu translate="title" module="thorleif">
  6.                     <title>Thorleif</title>
  7.                     <sort_order>100</sort_order>
  8.                     <children>
  9.                         <index> 
  10.                             <title>Commerciaux</title>
  11.                             <sort_order>1</sort_order>
  12.                         </index>
  13.                         <test>  
  14.                             <title>Test</title>
  15.                             <sort_order>2</sort_order>
  16.                         </test> 
  17.                     </children>
  18.                 </thorleif_menu>
  19.             </children>
  20.         </admin>
  21.     </resources>
  22. </acl>

C'est assez facile à comprendre ici : on ajoute, à la liste déjà existante, un enfant qui va être notre onglet défini dans la balise <menu>, on lui dit qu'il sera placé à la fin, puis, on ajoute nos liens dans une autre balise <children>. Au final, dans la gestion de nos rôles, on peut voir nos nouvelles ressources : 

creer-un-module-sous-magento-partie-6-administration-3

Le contrôleur

Notre menu est créé, mais il ne va pas fonctionner, puisque notre contrôleur n'existe pas encore. On va donc créer un répertoire Adminhtml/ dans le répertoire controllers/ de notre module. Dans ce répertoire, on ajoute un fichier IndexController.php qui sera le contrôleur de notre module pour la gestion du backoffice. Dans un premier temps, et comme pour la partie sur le frontoffice, on va simplement afficher une chaine de caractères.

/app/code/local/Ns/Thorleif/controllers/Adminhtml/IndexController.php
  1. <?php
  2. class Ns_Thorleif_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
  3. {
  4.     public function indexAction()
  5.     {
  6.         echo 'index action';
  7.     }
  8.  
  9.     public function testAction()
  10.     {
  11.         echo 'test action';
  12.     }
  13.  
  14. }

Ce contrôleur a la même tête que celui du frontoffice, à la différence près qu'il hérite du contrôleur d'administration par défaut de Magento, à savoir, la classe Mage_Adminhtml_Controller_Action. On peut donc maintenant cliquer sur un des deux liens de notre menu, et voir... qu'on a une erreur !

En regardant dans nos logs d'erreurs on s'aperçoit qu'il manque un Helper pour que ça fonctionne. On va donc le créer sans trop s'attarder sur les explications qui viendront dans une prochaine partie. Ce fichier se nomme Data.php et se situe dans le répertoire Helper/ de notre module (pas besoin de créer de répertoire Adminhtml/ ici) :

/app/code/local/Ns/Thorleif/Helper/Data.php
  1. <?php
  2. class Ns_Thorleif_Helper_Data extends Mage_Core_Helper_Abstract
  3. {}

Et pour que notre module prenne en compte ce helper, il va falloir modifier le fichier etc/config.xml de notre module et y ajouter une balise <helpers> dans la balise <global> (la configuration est la même que pour celle des blocks) : 

Extrait du fichier /app/code/local/Ns/Thorleif/etc/config.xml
  1. <helpers>
  2.     <thorleif>
  3.         <class>Ns_Thorleif_Helper</class>
  4.     </thorleif>
  5. </helpers>

On peut maintenant tester nos liens pour vérifier qu'ils fonctionnent bien.

Le design

On veut maintenant intégrer tout ça dans le design du backoffice de Magento, et, ô surprise, ça se passe comme pour le front ! Il va donc falloir créer un layout, un template, et configurer le module pour qu'il prenne tout ça en compte. Pour la configuration, on va ouvrir le fichier etc/config.xml et ajouter une balise <layout> à la suite de notre balise <menu> dans la balise <adminhtml>

Extrait du fichier /app/code/local/Ns/Thorleif/etc/config.xml
  1. <layout>
  2.     <updates>               
  3.         <thorleif>
  4.             <file>thorleif.xml</file>
  5.         </thorleif>
  6.     </updates>      
  7. </layout>

Ensuite, on va modifier l'action indexAction() de notre contrôleur pour qu'au lieu de nous afficher un simple texte, il charge et lance le layout :

Extrait du fichier /app/code/local/Ns/Thorleif/controllers/Adminhtml/IndexController.php
  1. public function indexAction()
  2. {
  3.     $this->loadLayout()
  4.          ->_setActiveMenu('thorleif_menu')
  5.          ->_title('Commerciaux');
  6.     $this->renderLayout();
  7. }

Il y a ici une différence par rapport au frontoffice : on ajoute un titre à la page (fonction _title()), et on rend actif l'onglet "Thorleif" grâce à la fonction _setActiveMenu(). Le nom de l'onglet est précisé dans le fichier de configuration. Malgré le fait que le layout n'existe pas encore, on peut afficher la page, et on a bien une intégration du backoffice Magento avec un contenu vide. On peut donc créer notre layout. Pour cela, on peut copier celui qu'on a pour le frontoffice, dans le répertoire layout/ de notre thème backoffice (pour ma part ce thème se situe dans le répertoire /app/design/adminhtml/default/montheme/). Après avoir copié ce fichier on y apporte quelques modifications que nous allons analyser par la suite : 

/app/design/adminhtml/default/montheme/layout/thorleif.xml
  1. <?xml version="1.0"?>
  2. <layout version="0.1.0">
  3.     <routeuradmin_adminhtml_index_index>
  4.         <reference name="content">
  5.             <block type="thorleif/blocktest" name="blocktest" template="thorleif/index.phtml" />
  6.         </reference>
  7.     </routeuradmin_adminhtml_index_index>
  8. </layout>

Par rapport au frontoffice, il n'y a que la route à modifier, ici la route est routeuradmin_adimnhtml_index_index : on prend le nom du routeur, on précise que le contrôleur est adminhtml_index, et que le nom de l'action est index. Concernant le block, c'est exactement le même que pour le frontoffice (en effet, on a mis notre balise <blocks> dans <global> dans le fichier de configuration, et de toute façon, on veut utiliser ce qu'on a déjà codé pour le front). 

Voici maintenant le contenu du template : on appelle simplement la méthode afficher() de notre block : 

/app/design/adminhtml/default/montheme/template/thorleif/index.phtml
  1. <h3>Liste des commerciaux</h3>
  2. <p>
  3.     <?php echo $this->afficher(); ?>
  4. </p>

Voici la méthode afficher() en question : 

Extrait du fichier /app/code/local/Ns/Thorleif/Block/Blocktest.php
  1. public function afficher()
  2. {
  3.     $retour = '';
  4.     $data = Mage::getModel('thorleif/commerciaux')->getCollection();
  5.     foreach($data as $row)
  6.     {
  7.         $retour .= $row->getData('name').' ('.$row->getData('city').')<br />';
  8.     }
  9.     return $retour;
  10. }

Dernière chose à savoir sur les templates du backoffice : si on a un formulaire, il va falloir ajouter un nouveau champ de type "hidden" qui contiendra la clé de sécurité du backoffice. Pas besoin d'en dire plus, voici l'input qu'il faudra placer dans votre formulaire : 

Extrait du fichier /app/design/adminhtml/default/montheme/template/thorleif/index.phtml
  1. <input name="form_key" type="hidden" value="<?php echo Mage::getSingleton('core/session')->getFormKey() ?>"  />

Conclusion

Au final, après autant d'effort, on arrive (enfin ! ) au résultat que l'on voulait.

creer-un-module-sous-magento-partie-6-administration-2

Bien évidemment, on peut designer tout ça comme on le désire. On aurait pu aussi ajouter le formulaire d'ajout de commerciaux, mais, dans Magento, il existe des classes et fonctions qui le font presque tout seul grâce aux grids ! Nous verrons comment ça fonctionne dans la prochaine partie.