L'arborescence d'un module Magento 2
Dans un précédent article, nous avons étudiés les bases d'un module Magento 2. Dans cet article, nous allons expliquer l'arborescence d'un module.
Les dossiers et fichiers de base
Pour cet article, j'ai cloné le dépôt de mon modèle de base dans le dossier app/code/NicolasBejean/Master
.
Une fois le dépôt cloné, vous devez avoir l'arborescence suivante :
.
├─ app/
| └─ code/
| └─ NicolasBejean/
| └─ Master/
| └─ etc/
| └─ module.xml
| └─ .gitignore
| └─ .gitlab-ci.yml
| └─ CHANGELOG.md
| └─ LICENCE
| └─ README.md
| └─ composer.json
| └─ registration.php
Dans ce dossier, les éléments obligatoires sont etc/module.xml
, composer.json
et registration.php
. Voici une brève explication des autres fichiers que j'ai intégrés à mon module de base :
.gitignore
: Quand je développe un module, je lui crée un dépôt Git. Ce fichier me permet de spécifier les fichiers que je souhaite ignorer dans le dépôt du module. Lien vers la documentation Git..gitlab-ci.yml
: Pour mettre en place une CI/CD, j'utilise Gitlab CI. Ce fichier est donc très utile pour tester et déployer mon module. Un article sera prochainement consacré au test et au déploiement d'un module Magento 2.CHANGELOG.md
: Un module évolue constamment. Il est donc important de noter les changements réalisés au fur et à mesure que des versions sont créées. Pour cela, j'utilise ce fichier en me basant le plus possible sur ce modèle.LICENCE
: L'ensemble des modules que je développe personnellement sont sous licence GNU GPL 3.README.md
: Ce fichier est présent pour présenter, expliquer le module et ses fonctionnalités.
Les dossiers que l'on peut retrouver
Suivant les fonctionnalités de notre module, nous allons avoir une arborescence différente. Un module peut donc avoir une multitude de dossiers :
.
├─ app/
| └─ code/
| └─ NicolasBejean/
| └─ Master/
| └─ Api/
| └─ Block/
| └─ Console/
| └─ Controller/
| └─ Cron/
| └─ CustomerData/
| └─ etc/
| └─ Helper/
| └─ i18n/
| └─ Model/
| └─ Observer/
| └─ Plugin/
| └─ Setup/
| └─ Test/
| └─ Ui/
| └─ view/
| └─ ViewModel/
Le dossier Api
Le dossier Api
va comporter l'ensemble des interfaces ainsi que leurs implémentations. Chaque interface est déclarée dans le fichier di.xml
du dossier etc
comme une preference
, par exemple :
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation=" urn:magento:framework:ObjectManager/etc/config.xsd">
...
<preference for="NicolasBejeanContentManagerApiDataContentManagerInterface" type="NicolasBejeanContentManagerModelContentManager" />
...
</config>
La classe PHP ...\Model\ContentManager
implémente l'interface ...\Api\Data\ContentManagerInterface
. L'implémentation d'une interface nécessite d'être renseignée dans le fichier di.xml
car Magento 2 utilise l'injection de dépendances comme modèle de conception.
Voici le lien vers la documentation des interfaces publics et des API de Magento 2 ainsi que le lien vers la documentation PHP sur les interfaces.
Les dossiers Block
, Controller
et Model
Magento 2 utilise le modèle de conception (Design Pattern) MVC, qui signifie Modèle - Vue - Contrôleur.
Le dossier Block
contient toutes les classes PHP nécessaires à la vue, le dossier Controller
contient toutes les classes PHP nécessaire à la logique et le dossier Model
contient toutes les classes permettant d'aller récupérer les informations dans la base de données.
Le dossier Console
Ce dossier va contenir toutes les classes PHP permettant l'utilisation des commandes CLI. Les commandes CLI sont basées le framework Symfony.
Un module peut comporter une multitude de commandes. Chaque commande est définie dans le fichier di.xml
du dossier etc
, par exemple :
<?xml version="1.0" encoding="utf-8" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
...
<type name="Magento\Framework\Console\CommandListInterface">
<arguments>
<argument name="commands" xsi:type="array">
<item name="nicolasbejean_rabbitmq_defaultmessage" xsi:type="object">NicolasBejean\RabbitMq\Console\Command\DefaultMessage</item>
</argument>
</arguments>
</type>
...
</config>
Dans cet exemple, la commande NicolasBejean\RabbitMq\Console\Command\DefaultMessage
est du type Magento\Framework\Console\CommandListInterface
. Chaque commande doit être nommée, dans notre exemple : nicolasbejean_rabbitmq_defaultmessage
.
Voici le lien vers la documentation des commandes CLI de Magento 2.
Le dossier Cron
Sous Magento 2, les crons utilisent le planificateur de tâches UNIX nommé crontab
. Beaucoup de fonctionnalités utilisent les crons : les règles de prix catalogue, l'envoi des emails, la réindexation...
Il est possible de définir un ou plusieurs crons par module. Chaque cron est déclaré dans le fichier crontab.xml
du dossier etc
, par exemple :
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
...
<group id="nicolasbejean">
<job name="nb_sales_exported_data_order" instance="NicolasBejean\Sales\Cron\ExportOrderData" method="execute">
<schedule>* * * * *</schedule>
</job>
</group>
...
</config>
Dans cet exemple, le cron d'exportation de commande nommé nb_sales_exported_data_order
exécutera toutes les minutes * * * * *
la méthode execute
de la classe NicolasBejean\Sales\Cron\ExportOrderData
associée au cron.
On remarque également dans l'exemple que le job est défini dans un groupe nommé nicolasbejean
. Magento offre la possibilité de créer des groupes de crons. Ces derniers peuvent être configurés différemment des groupes par défaut. De plus, il est possible de créer plusieurs crons par groupe.
Voici le lien vers la documentation des crons et voici le lien vers la documentation des groupes de crons.
Le dossier Helper
Magento ne recommande pas la création de classes, dites d'assistances. Elles sont considérées comme un anti-pattern. Pour Magento, il faut éviter de créer des Helpers.
Voici le lien vers les bonnes pratiques de Magento 2.
Le dossier i18n
Au sein de ce dossier, nous allons retrouver des fichiers CSV contenant les dictionnaires de traduction de votre module. Chaque fichier est nommé dans la langue cible et comporte au minimum 2 colonnes, une première comprenant la clé de traduction et/ou la phrase d'origine et une seconde comprenant la traduction, par exemple :
"Add to cart", "Ajouter au panier"
Dans ce fichier, nous traduisons, en français, la phrase Add to cart
par Ajouter au panier
. Le fichier de traduction doit se nommer fr_FR.csv
.
Voici le lien vers la documentation des fichiers de traduction.
Le dossier Observer
Les observateurs permettent d'étendre les fonctionnalités de Magento 2. Le modèle publication-abonnement est le modèle de conception (Design Pattern) utilisé.
Les événements sont distribués lorsque certaines actions sont déclenchées et les observateurs sont exécutés lorsqu'un événement, sur lequel l'observateur est configuré, est déclenché.
Chaque Observers
doit être déclaré dans le fichier events.xml
du dossier etc
, par exemple :
<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
...
<event name="sales_order_save_after">
<observer name="nicolasbejean_sales_exportorder" instance="NicolasBejean\Sales\Observer\ExportOrder"/>
</event>
...
</config>
Dans cet exemple, la classe NicolasBejean\Sales\Observer\ExportOrder
est rattaché à l'événement sales_order_save_after
.
Voici le lien vers la documentation des observateurs.
Le dossier Plugin
Un plugin permet d'intercepter le code, en amont, en aval ou autour d'une fonction, en utilisant les méthodes before
, after
ou around
suivi du nom de la méthode ciblée. Le plugin est limité aux fonctions publiques.
Chaque plugin est déclaré dans le fichier di.xml
comme une type
, par exemple :
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
...
<type name="Magento\Customer\Model\AccountManagement">
<plugin name="NicolasBejeanAccountManagement" type="NicolasBejean\Customer\Plugin\AccountManagement" sortOrder="1" disabled="false" />
</type>
...
</config>
Dans l'exemple ci-dessus, le plugin NicolasBejean\Customer\Plugin\AccountManagement
nommé NicolasBejeanAccountManagement
est configuré pour intercepter le code de la classe Magento\Customer\Model\AccountManagement
où il sera possible de modifier le comportement de Magento 2 soit à la création d'un compte client, soit à l'authentification.
Il est possible de créer plusieurs plugins pour un seul type, dans ce cas, il sera nécessaire de les ordonner. De plus, il est possible de les désactiver sans les supprimer.
Voici le lien vers la documentation des plugins.
Le dossier Setup
Depuis la version 2.3 de Magento, le processus d'installation et de mise à jour de la base de données a été revu. Auparavant, il était nécessaire de créer des scripts PHP pour installer ou mettre à jour sa base de données, voir ci-dessous. Désormais, cela est réalisé par le biais de fichiers XML situé dans le dossier etc
.
Voici le lien vers la documentation du schéma déclaratif.
Cependant, il est possible que vous ayez un dossier Setup
à la racine d'un module. Ce dossier contient les fichiers nécessaires pour définir la structure des tables dans la base de données ainsi que leur configuration que ce soit pour l'installation ou la mise à jour du module. Ces fichiers sont appelés lorsque la commande bin/magento setup:upgrade
est exécutée.
Voici le lien vers la documentation du cycle de vie d'un module Magento 2.
Le dossier Test
Magento propose plusieurs stratégies de test pour garantir la qualité du code. Il y a les tests d'intégration, les tests unitaires JS et PHP, les tests statiques et le vérificateur de version sémantique.
Dans ce dossier Test
, nous allons principalement retrouver les dossiers Unit
, Integration
et Mftf
.
Les tests unitaires présents dans le dossier Test/Unit
permettent de tester et de vérifier que chaque méthode soit bien appelée et que la valeur retournée est bien la valeur attendue.
Les tests d'intégration nécessite un environnement Magento 2 fonctionnelle avec une base de données vierge. Ils permettent de vérifier et de contrôler la comptabilité d'un module dans un environnement complet.
Pour terminer, le dossier Mftf
comportera l'ensemble des tests fonctionnels de votre application. Magento Functional Testing Framework est un projet open-source souvent nommé MFTF. Il permet de développer rapidement des tests fonctionnels pour votre application.
Voici le lien vers le guide de tests de Magento 2 et le lien vers la documentation de Magento Functional Testing Framework.
Le dossier Ui
Ce dossier contient l'ensemble des classes des composants de l'interface utilisateur de votre module. On peut retrouver différentes actions dans une liste déroulante située dans une grille de données.
Il existe plusieurs UI Components au sein de Magento 2, voici le lien vers la documentation.
Le dossier ViewModel
Les modèles de vues sont disponibles depuis Magento 2.2. Ils sont à privilégier lorsqu'il est nécessaire d'injecter des fonctionnalités dans des fichiers de rendu.
Voici le lien vers la documentation des View Models.