Огляд системи подій в Magento 2
Події в Magento 2 – це дуже гнучкий спосіб розширити логіку програми. У сьогоднішній статті ми зробимо короткий огляд системи подій, а також побачимо, як це працює в Magento 2.
Шаблон спостерігача (observer)
Основна концепція системи подій така ж, як у старого доброго шаблону програмування для спостерігачів: з її допомогою реалізується у класі механізм, що дозволяє об’єкту цього класу отримувати оповіщення про зміну стану інших об’єктів і тим самим спостерігати за ними. Шаблон Обсервер (Observer) визначає залежність “один-до-багатьох” між об’єктами так, що при зміні стану одного об’єкта, всі залежні від нього об’єкти сповіщаються і оновлюються автоматично.
Зазвичай шаблон представлений двома об’єктами: Спостерігачем і Суб’єктом. Сутність Observer (спостерігача) прослуховує повідомлення Суб’єкта і виконує деякі дії після отримання повідомлення. А Суб’єкт відповідає за повідомлення Спостерігача: він інкапсулює інформацію про зареєстрованих Спостерігачів і інформує їх, коли повідомлення було запущено.
Це була загальна інформація для розуміння того, як працює шаблон обсервера. А тепер давайте подивимося, як це працює на практиці в Magento 2.
Система подій в Magento 2
Давайте для практики створимо базову структуру нашого модуля для обсервера наступним чином:
/{ПАКЕТ_МОДУЛІВ}/{МОДУЛЬ}/etc/events.xml /{ПАКЕТ_МОДУЛІВ}/{МОДУЛЬ}/Observer/ObserverClass.php
Потім для спостереження за подіями нам потрібно оголосити нашого спостерігача. Оголосіть спостерігачів і подію у файлі events.xml. У новій версії Magento завантаження конфігурації може відноситись до різних областей. Всі області представлені у вигляді папок в каталозі etc
, і можна вказати конфігурацію events.xml для наступних областей:
adminhtml
– конфігурація буде застосована для панелі адміністратора.frontend
– конфігурація буде застосована для вітрини.crontab
– конфігурація буде застосована для дій CRON.webapi_rest
– конфігурація буде застосована, коли Magento використовується як додаток REST.webapi_soap
– конфігурація буде застосована до викликів SOAP.
Всі файли конфігурації, які знаходяться в папці etc
, використовуються в глобальній області. Глобальні зміни завантажуються перед конфігурацією конкретних областей і скасовують їх. Для прикладу ми створимо конфігурацію events.xml в глобальній області.
Давайте подивимося, як спостерігачі оголошуються в events.xml
:
<?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="unique_name_of_event"> <observer name="global_event_observer_name" instance="{ПАКЕТ_МОДУЛІВ}\{МОДУЛЬ}\Observer\ObserverClass" shared="true" /> </event> </config>
Налаштування подій починається з вузла <config>
. Тут атрибути задають визначення XML схеми, яка повинна перевіряти вузли, вкладені в <config>
. Вузли подій <event>
вкладені в вузол <config>
. У вузлі <event>
оголошуються спостерігачі (Обсервери), і цей вузол може містити наступні атрибути:
name
– обов’язковий атрибут, який ідентифікує вузол. Він повинен бути унікальним, щоб запобігти перевизначення вузла.instance
– обов’язковий атрибут, який вказує повне ім’я класу, який повинен бути підписаний на повідомлення про події.shared
– необов’язковий атрибут, який визначає спосіб створення класу. Якщо ця опція не вказана (або вона маєfalse
в якості значення), клас буде створюватися кожен раз, коли відбувається подія. В іншому випадку клас буде розділений між подіями: він буде створений тільки один раз і збережений в кеші.disabled
– необов’язковий атрибут, який дає можливість відключити спостерігача, якщо він зазначений якtrue
.
Отже, ми оголосили наш обсервер. Тепер давайте подивимося, як він може бути реалізований:
<?php namespace {ПАКЕТ_МОДУЛІВ}\{МОДУЛЬ}\Observer; use Magento\Framework\Event\ObserverInterface; class ObserverClass implements ObserverInterface { public function __construct() { // оголошення залежностей } public function execute(\Magento\Framework\Event\Observer $observer) { // Код, який потрібно виконати при події, наприклад: $request = $observer->getRequest(); … return $this; } }
Зверніть увагу, що є одна важлива вимога: всі спостерігачі повинні реалізувати інтерфейс \Magento\Framework\Event\ObserverInterface
. Відповідно до цього в методі ObserverInterface::execute()
повинна бути тільки одна логіка спостереження. У подальшій логіці метод отримує всю інформацію про подію з параметрів. Одним з параметрів є об’єкт класу \Magento\Framework\Event\Observer
. Він може повернути інформацію про подію, використовуючи магічні методи (наприклад, гетери або сетери).
Нарешті, як Magento 2 запускає події? Всі менеджери подій повинні бути реалізовані з класу Magento\Framework\Event\ManagerInterface
:
interface ManagerInterface { /** * Відправка події (dispatch event) * Викликає всі зворотні виклики спостерігачів, зареєстрованих для цієї події * Та інших спостерігачів, що відповідають шаблону імені події * * @param string $eventName * @param array $data * @return void */ public function dispatch($eventName, array $data = []); }
Нижче ви можете побачити логіку запуску подій для методу Magento\Framework\Event\Manager::dispatch()
:
class Manager implements ManagerInterface { /** * @param InvokerInterface $invoker * @param ConfigInterface $eventConfig */ public function __construct(InvokerInterface $invoker, ConfigInterface $eventConfig) { $this->_invoker = $invoker; $this->_eventConfig = $eventConfig; } public function dispatch($eventName, array $data = []) { $eventName = mb_strtolower($eventName); foreach ($this->_eventConfig->getObservers($eventName) as $observerConfig) { $event = new \Magento\Framework\Event($data); $event->setName($eventName); $wrapper = new Observer(); $wrapper->setData(array_merge(['event' => $event], $data)); $this->_invoker->dispatch($observerConfig, $wrapper); } } }
Підводячи підсумок, клас менеджера делегує обробку конфігурацій, а спостерігач делегує обов’язки реалізацій інтерфейсів ConfigInterface
та InvokerInterface
відповідно. Крім того, можна запускати користувацькі події (так само, як і в Magento 1.x). Для цього просто запровадьте менеджер подій в свій клас і викличте метод dispatch()
менеджера, коли подію має бути запущено. Ось приклад:
class MyClass { public function __construct(ManagerInterface $eventManager) { // ін'єкція залежностей менеджера подій $this->_eventManager = $eventManager; } public function someMethod() { // тут подію має бути запущено $this->_eventManager->dispatch('my_event', array('context' => $this)); } }
У цій статті ми коротко розглянули, як працює система подій в Magento 2. На прикладі базової структури модуля побачили, як це робиться на практиці.
Не соромтеся ділитися своєю думкою або ставити запитання в розділі коментарів нижче.
Дякуємо, що читаєте нас!