Création d'un module sous Magento 2 - Partie 6 - Les événements

Qu'est-ce qu'un événement ? Comment doivent-ils être mis en place dans un module ? C'est ce que nous allons voir dans cette nouvelle partie. Dans un premier temps nous allons créer un observer récupérant un événement déjà existant, puis, par la suite, nous allons créer notre propre événement.

Introduction

Qu'est-ce qu'un événement ? Pour comprendre cela, voyons un exemple simple : nous sommes sur notre site e-commerce, et nous nous connectons en tant que client. L'action de se connecter est un événement, et il en existe beaucoup dans Magento, comme la validation d'un nouveau compte client, le paiement d'une commande, ... Ces événements vont être détectés par un observer, pour exécuter une action. 

Nous pouvons utiliser tous les événements déjà présents dans Magento. Mais nous pouvons aussi en créer de nouveaux. Nous allons donc voir un cas où l'événement sera l'action de se connecter, et nous allons créer un nouvel événement qui exécutera une action lors de l'affichage de la liste des commerciaux dans le backoffice.

Événement existant

Pour déclarer un observer, on doit créer un fichier events.xml. On doit placer ce fichier dans le répertoire etc/frontend/ de notre module pour qu'il ne soit disponible que dans le frontend. Pour qu'il soit disponible partout, il faut ajouter ce fichier dans le répertoire etc/

app/code/Ns/Thorleif/etc/frontend/events.xml
  1. <?xml version="1.0"?>
  2. <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
  3.     <event name="customer_login">
  4.         <observer name="nsthorleif_customer_login" instance="Ns\Thorleif\Observer\CustomerLogin"/>
  5.     </event>
  6. </config>

Dans la balise <event> on va préciser le nom de l'événement que notre observer va gérer. Dans la balise <observer>, on va préciser quelle classe contient notre observer. Magento va donc comprendre qu'à chaque client qui se connecte, la méthode execute() de l'observer CustomerLogin doit être exécuté. On peut utiliser une méthode particulière en ajoutant un attribut "method" dans la balise <observer>.

Voyons maintenant comment implémenter notre classe CustomerLogin

app/code/Ns/Thorleif/Observer/CustomerLogin.php
  1. <?php
  2.  
  3. namespace Ns\Thorleif\Observer;
  4.  
  5. use Magento\Framework\Event\ObserverInterface;
  6. use Magento\Framework\Message\ManagerInterface;
  7. use Magento\Framework\Event\Observer;
  8.  
  9. class CustomerLogin implements ObserverInterface
  10. {
  11.  
  12.     protected $messageManager;
  13.  
  14.     public function __construct(ManagerInterface $messageManager)
  15.     {
  16.         $this->messageManager = $messageManager;
  17.     }
  18.  
  19.     public function execute(Observer $observer)
  20.     {
  21.         $event = $observer->getEvent();
  22.         $customer = $event->getCustomer();
  23.         $this->messageManager->addSuccess(__('Bienvenue %1 !', $customer->getName()));
  24.     }
  25. }

Un observer est une implémentation de l'interface ObserverInterface, et la méthode obligatoire à instancier est la méthode execute(). Dans cette méthode, on récupère les informations sur le client. Pour connaître les données récupérées par l'observer, il faut faire une recherche sur le nom de l'événement, et regarder où l'événement est appelé. Dans notre cas, l'événement "customer_login" est appelé dans le fichier vendor/magento/module-customer/Model/Session.php, et on peut voir qu'il n'envoie à l'observer qu'un objet customer

Après avoir récupéré cet objet, on peut faire ce qu'on veut ici. Dans notre exemple, on ajoute simplement un message souhaitant la bienvenue à l'utilisateur qui vient de se connecter. Faites bien attention aux classes à utiliser dans notre observer. Une fois que tout ceci est fait, connectez-vous sur le frontend de votre Magento, et vous devriez avoir votre message de bienvenue affiché : 

Création d'un module sous Magento 2 - partie 6 - Les événements

Pour l'exemple, on a utilisé l'événement "customer_login", mais il existe dans Magento 2, de nombreux autres événements. Vous pourrez trouver une liste sur le net, ça serait vraiment long de tous les noter ici. Si aucun événement n'existe pour votre problématique, il est possible d'en créer de nouveaux !

Créer un nouvel événement

Pour créer un nouvel événement, rien de plus simple ! Vous savez déjà comment créer un nouvel observer, et comment le déclarer dans un fichier events.xml. Maintenant, il ne reste plus qu'à dire à Magento qu'on déclenche cet événement. Pour cela, on va ajouter la ligne suivante à l'endroit où on veut que l'événement soit déclenché : 

Exemple de déclanchement d'un événement
  1. $this->_eventManager->dispatch('nom_evenement', ['data' => $data]);

Et c'est tout ! On va quand même faire les choses jusqu'au bout et créer un nouvel événement exemple qui va faire en sorte d'afficher un message d'avertissement au-dessus de la liste de nos commerciaux dans le backoffice. Dans un premier temps, on va ajouter le déclenchement de notre événement dans le fichier Controller/Adminhtml/Index/Index.php qui correspond au contrôleur qui va afficher la liste de nos commerciaux : 

app/code/Ns/Thorleif/Controller/Adminhtml/Index/Index.php
  1. <?php
  2. namespace Ns\Thorleif\Controller\Adminhtml\Index;
  3.  
  4. use Magento\Framework\View\Result\PageFactory;
  5. use Magento\Backend\App\Action\Context;
  6.  
  7. class Index extends \Magento\Backend\App\Action
  8. {
  9.     protected $resultPageFactory;
  10.  
  11.     public function __construct(Context $context, PageFactory $resultPageFactory)
  12.     {
  13.         $this->resultPageFactory = $resultPageFactory;
  14.         parent::__construct($context);
  15.     }
  16.  
  17.     public function execute()
  18.     {
  19.         $resultPage = $this->resultPageFactory->create();
  20.         $resultPage->setActiveMenu('Ns_Thorleif::index'); // Notez bien l'identifiant de votre menu !
  21.         $resultPage->addBreadcrumb(__('Gestion des commerciaux'), __('Gestion des commerciaux'));
  22.         $resultPage->getConfig()->getTitle()->prepend(__('Gestion des commerciaux'));
  23.  
  24.         $this->_eventManager->dispatch('commerciaux_index_view', ['username' => $this->_session->getName()]);
  25.  
  26.         return $resultPage;
  27.     }
  28. }

C'est vraiment tout simple, on ajoute juste au code existant le ligne de déclenchement de l'événement. On a précisé le nom de notre événement (commerciaux_index_view),  et les données à transférer à l'observer (ici le nom de l'utilisateur). Ensuite, on va déclarer notre nouvel observer. Il va donc falloir créer un fichier events.xml dans le répertoire etc/adminhtml/ de notre module (rappelez-vous que l'événement n'est disponible que dans le backoffice) : 

app/code/Ns/Thorleif/etc/adminhtml/events.xml
  1. <?xml version="1.0"?>
  2. <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
  3.     <event name="commerciaux_index_view">
  4.         <observer name="nsthorleif_commerciaux_index_view" instance="Ns\Thorleif\Observer\CommerciauxView"/>
  5.     </event>
  6. </config>

Dernière chose à faire, créer notre observer. Comme pour le frontoffice, on ajoute notre observer CommerciauxView.php dans le répertoire Observer/ de notre module, comme indiqué dans notre fichier events.xml. Normalement, vous devriez avoir implémenté cet observer tout seul, puisque vous savez déjà comment faire : 

app/code/Ns/Thorleif/Observer/CommerciauxView.php
  1. <?php
  2.  
  3. namespace Ns\Thorleif\Observer;
  4.  
  5. use Magento\Framework\Event\ObserverInterface;
  6. use Magento\Framework\Message\ManagerInterface;
  7. use Magento\Framework\Event\Observer;
  8.  
  9. class CommerciauxView implements ObserverInterface
  10. {
  11.  
  12.     protected $messageManager;
  13.  
  14.     public function __construct(ManagerInterface $messageManager)
  15.     {
  16.         $this->messageManager = $messageManager;
  17.     }
  18.  
  19.     public function execute(Observer $observer)
  20.     {
  21.         $event = $observer->getEvent();
  22.         $username = $event->getUsername();
  23.         $this->messageManager->addNotice(__('Attention vous allez gérer les commerciaux en tant que %1 !', $username));
  24.     }
  25. }

Et voilà, c'est terminé. Les événements sous Magento 2 n'ont plus de secret pour vous. Le résultat obtenu pour notre exemple sera le suivant : 

Création d'un module sous Magento 2 - Partie 6 - Les événements