Les mécanisme d'Event Observer sous Magento2

Aujourd'hui on va voir comment fonctionne le mécanise si bien connu d'event / observer sous magento2. Ce tutoriel fait partie d'une formation magento2, si vous ne l'avez pas encore fait, je vous invite par démarrer par les premiers article avant de vous attaquer à celui ci. Pour ce tutoriel, nous repartirons du code du tutoriel précédent.

Présentation du mécanisme d'Events / Observers

Le mécanisme d'évent observer est un des mécanismes de base qu'on retrouve réguliérement en Programation Orienté Objet (POO). On défini un object "observeur" dont le role est de regarder en permanence ce qu'il se passe sur magento et d'exécuter une function précise lorsqu'un événement est déclenché. L'"Event" lui on l'apelle via une méthode qui s'apelle displatch. Quand on fait un dispatch d'un événement, tous les observers associé à cet événement vont se délencher.

Déclarer un événement sous magento2

Un Evénement magento2 est déclenché en utilisant l'EventManager (classe Magento\Framework\Event\Manager), cette classe est obtenue automatiquement dans nos contrôleurs quand on étend la classe \Magento\Framework\App\Action\Action* une fois ajouté à votre classe, vous pouvez maintenant utiliser cet objet pour déclencher un événement via la méthode dispatch :

$this->eventManager->dispatch('pfay_contacts_event_test');

Vous remarquez qu'on passe une variable de type string à la méthode dispatch, c'est le nom de l'événément. En effet, chaque événement à un nom ici "pfay_contacts_event_test1" qui permettra de lui attacher un ou plusieurs observers. On va créer une nouvelle action pour déclencher notre événement. Créez donc le fichier /app/code/Pfay/Contacts/Controller/Test/Myevent.php comme ceci :

<?php
namespace Pfay\Contacts\Controller\Test;

use Magento\Framework\App\Action\Action;

class Myevent extends Action
{
    public function execute()
    {

        $this->_eventManager->dispatch('pfay_contacts_event_test');
        die('test');
    }
}

Théoriquement si vous commentez la ligne avec l'évent manager, vous devriez pour le moment voir "test" s'afficher lorsque vous allez sur http://www.magento2.lan/contacts/test/myevent. Vous pouvez ensuite décommenter la ligne apres votre test.

Créer un Observer sous magento2

Sous magento, un Observer est une classe qui va implémenter l'interface Magento\Framework\Event\ObserverInterface c'est à dire qu'il prend une méthode exécute avec un argument de type \Magento\Framework\Event\Observer. On va donc créer notre classe comme ceci :

<?php
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

/**
 * Class TestObserver
 */
class TestObserver implements ObserverInterface
{

    /**
     * @param Observer $observer
     * @return void
     */
    public function execute(Observer $observer)
    {
        die('test observer');
    }
}

Pour le moment si vous retournez sur votre action, il ne se passe toujours rien mais l'observer va théoriquement s'éxécuter et vous afficher "test observer" à la place de "test". Il reste une chose à faire pour que ce la fonctionne...lier l'évent et l'observer.

Associer un Observer à un event sous magento2

Les Observers sont donc des éléments qui permettent de déclencher des fonctions lors de l'appel à la méthode dispatch() d'un évent. Un observer est associé à event via le nom de l'évent. Cette association est géré dans le fichier events.xml. Créons donc notre fichier events.xml comme ceci :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="pfay_contacts_event_test">
        <observer name="pfay_contacts_observer_test" instance="Pfay\Contacts\Observer\TestObserver" />
    </event>
</config>

Dans ce fichier, on déclare un nouvel élément "event" dans "events", cet event s'apellera "pfay_contacts_event_test" et déclenchera l'observer qu'il nomera "pfay_contacts_observer_test" et qui sera représenté par la classe "Pfay\Contacts\Observer\TestObserver". Donc maintenant lors du dispatch("pfay_contacts_observer_test"), notre observer ca se délencher.
Effectivement si on retourne sur notre page http://www.magento2.lan/contacts/test/myevent, on voit bien "test observer" apparaitre donc notre Observer s'est bien délenché.

Utiliser les événements natifs de magento2

Pour utiliser lest events natifs de magento rien de plus simple c'est exactement pariel. Vous pouvez télécharger la "cheat sheet magento2" PDF en bas de ce tutoriel, cette feuille que vous pouvez imprimer facilement liste tous les Events natifs magento2. Prenon un exemple, vous voulez éxécuter votre Observer Pfay\Contacts\Controller\Test\Myevent à l'ajout d'un produit. Je regarde donc dans ma "cheat sheet" et je vois qu'il y a un événement natif qu s'apelle "checkout_cart_add_product_complete" Je vais donc éditer mon fichier events.xml afin de rajouter mon observer dans l'event. J'édites donc mon fichier events.xml comme ceci :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_add_product_complete">
        <observer name="pfay_contacts_observer_test" instance="Pfay\Contacts\Observer\TestObserver" />
    </event>
</config>

Je vais ensuite sur une fiche produit et j'ajoute mon produit au panier. Je suis redirigé vers une page blanche avec "test observer" donc mon observeur a bien été pris en compte.

Surcharger un Observer sous magento

Pour surcharger un Observer sur Magento c'est comme d'habitude, il vous suffit d'ajouter une préférence dans di.xml. Surchargons notre Observer. j'édites donc mon fichier /app/code/Pfay/Contacts/etc/di.xml pour rajouter cette ligne :

<preference for="Pfay\Contacts\Observer\TestObserver" type="Pfay\Contacts\Observer\SurchargeObserver" />

Et je créer mon objet SurchargeObserver (/app/code/Pfay/Contacts/Observer/SurchargeObserver.php) comme ceci :

<?php
namespace Pfay\Contacts\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

/**
 * Class TestObserver
 */
class SurchargeObserver implements ObserverInterface
{
    /**
     * @param Observer $observer
     * @return void
     */
    public function execute(Observer $observer)
    {
        die('surcharge observer');
    }
}

Je retourne sur une fiche produit et j'ajoute mon produit...j'ai bien "surcharge observer" qui s'affiche donc ma surcharge à fonctionner. Voilà c'est la fin de ce tutoriel, si vous n'arrivez pas à le faire fonctionner n'hésitez pas à télécharger le code via le liens juste en dessous. Si apres avoir analysé ce code vous n'y arrivez toujours pas laissez moi un message en bas dans les commentaire et je vous répondrai rapidement. N'hésitez pas si vous avez des questions.
Les livres qui peuvent vous aider :
  • Livre Magento 2 Developer's Guide by Branko
  • Livre Magento 2 Cookbook
  • Livre Mastering Magento2 Second Edition
Questions sur cette leçon
2838 days ago :

Le fichier events.xml va dans le dossier etc de votre module, sinon ça ne marchera pas^^ Pour le TestObserver.php, mettez-le dans un dossier Observer de votre module, pour être organisé de la même manière que ce tutoriel (ça évitera les erreurs lors de la copie du code).

Vous devez etre connecté pour demander de l'aide sur une leçon.