Події в Magento 2 – це дуже гнучкий спосіб розширити логіку програми. У сьогоднішній статті ми зробимо короткий огляд системи подій, а також побачимо, як це працює в Magento 2.
Основна концепція системи подій така ж, як у старого доброго шаблону програмування для спостерігачів: з її допомогою реалізується у класі механізм, що дозволяє об’єкту цього класу отримувати оповіщення про зміну стану інших об’єктів і тим самим спостерігати за ними. Шаблон Обсервер (Observer) визначає залежність “один-до-багатьох” між об’єктами так, що при зміні стану одного об’єкта, всі залежні від нього об’єкти сповіщаються і оновлюються автоматично.
Зазвичай шаблон представлений двома об’єктами: Спостерігачем і Суб’єктом. Сутність Observer (спостерігача) прослуховує повідомлення Суб’єкта і виконує деякі дії після отримання повідомлення. А Суб’єкт відповідає за повідомлення Спостерігача: він інкапсулює інформацію про зареєстрованих Спостерігачів і інформує їх, коли повідомлення було запущено.
Це була загальна інформація для розуміння того, як працює шаблон обсервера. А тепер давайте подивимося, як це працює на практиці в 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. На прикладі базової структури модуля побачили, як це робиться на практиці.
Не соромтеся ділитися своєю думкою або ставити запитання в розділі коментарів нижче.
Дякуємо, що читаєте нас!
У нашій подорожі світом сокетів ми почали з "верхнього поверху" — WebSocket у браузері, потім…
У попередній статті ми говорили про WebSockets — технологію, що дозволяє створювати інтерактивні чати в…
Шкіра немовляти – тонка та ніжна. Ще не справляється із захистом організму від зовнішніх факторів.…
Уявіть собі телефонну розмову. Ви дзвоните другу, він піднімає слухавку, і ви можете говорити одночасно,…
Довгий час планшети сприймалися виключно як пристрої для споживання контенту: подивитися YouTube, погортати стрічку новин…
Ви внесли правки в CSS, виправили критичний баг у JavaScript, завантажили файли на сервер і…