Categories: Мадженто 2

Обзор системы событий в 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. На примере базовой структуры модуля увидели, как это делается на практике. Не стесняйтесь делиться своим мнением или задавать вопросы в разделе комментариев ниже.

Спасибо, что читаете нас!

 

Share
Published by
SebWeo
Tags: Magento2

Recent Posts

Как выбрать мастера для перетяжки мебели?

Выбор мастера для ремонта и перетяжки мебели — задача, которая требует вдумчивого подхода. Ведь от…

2 дня ago

Что лучше выбрать для хостинга: сервер VPS Windows или VPS Linux?

Выбор идеального хостинга под свой сайт может быть довольно запутанным делом, особенно когда существует так…

1 неделя ago

Лоуренс Питер

Чтобы избегать ошибок, нужно набираться опыта; чтобы набираться опыта, надо делать ошибки Лоуренс Питер  

2 недели ago

Что такое Черное СЕО (Black Hat SEO) — вся нужная информация

Краткое определение Черного SEO Черное СЕО (или Черная оптимизация) — это любая практика, целью которой…

2 недели ago

Права категории C: кому они нужны и как их получить?

Получение водительских прав категории C открывает двери к профессиональной деятельности, связанной с управлением грузовыми автомобилями.…

3 недели ago

Уилл Смит

Хорошие люди принесут вам счастье, плохие люди наградят вас опытом, худшие — дадут вам урок,…

3 недели ago