Как в Magento 2 подписаться на событие и обработать его

  1. Выясните перечень доступных в Вашем сценарии системных событий.
  • Определитесь, на какое из доступных событий Вы намерены подписаться.

  • Подписка на событие осуществляется в одном из файлов events.xml модуля (их может быть несколько, читайте ниже).

  • Определитесь, нужно ли обрабатывать событие глобально, или же данное событие достаточно обрабатывать только для витрины или только для административной части:

    • Если на событие нужно подписаться глобально, то подписывайтесь в файле etc/events.xml.
    • Если на событие нужно подписаться только для витрины, то подписывайтесь в файле etc/frontend/events.xml.
    • Если на событие нужно подписаться только для административной части, то подписывайтесь в файле etc/adminhtml/events.xml.
  • Формат файла events.xml можно посмотреть в системных модулях Magento 2, например, в файле app/code/Magento/AdminNotification/etc/adminhtml/events.xml

  • Подписка описывается так:

    <event name='core_app_init_current_store_after'>
        <observer
            name='rm_core' 
            instance='Rm\Core\Model\Dispatcher'
            method='coreAppInitCurrentStoreAfter' 
        />
    </event>
    
  • В атрибуте instance указываете класс-обработчик.

  • Пример обработки события:

    <?php
    namespace Rm\Core\Model;
    class Dispatcher {
        /**
         * @param \Magento\Framework\Event\Observer $observer
         * @return void
         */
        public function coreAppInitCurrentStoreAfter(\Magento\Framework\Event\Observer $observer) {
            \Magento\Framework\App\ObjectManager::getInstance()
                ->get('Psr\Log\LoggerInterface')
                    ->debug(__METHOD__)
            ;
        }
    }
    

С октября 2015 года порядок подписки на события и обработки событий изменились:

Шаг1

Объявите обработчики событий в файле events.xml модуля.
У модуля может быть несколько файлов events.xml:

Перечень возможных файлов `events.xml` модуля
Расположение В каких случаях будут задействованы объявленные в файле обработчики событий Пример из ядра
`etc/events.xml` Всегда. [`Magento/CatalogInventory`][1]
`etc/adminhtml/events.xml` Только в административном интерфейсе. [`Magento/Catalog`][2]
`etc/frontend/events.xml` Только на витрине. [`Magento/Catalog`][3]
`etc/crontab/events.xml` Только при выполнении задач планировщиком ([cron][4]). [`Magento/CatalogRule`][5]
`etc/setup/events.xml` Только при [установке][6] и [обновлении][7] Magento и модулей. [`Magento/CatalogUrlRewrite`][8]
`etc/webapi_rest/events.xml` Только при обработке запросов по протоколу [REST][9] [API][10]. [`Magento/CatalogRule`][11]
`etc/webapi_soap/events.xml` Только при обработке запросов по протоколу [SOAP][12] [API][13]. [`Magento/CatalogRule`][14]

Пример описания обработчика события в файле events.xml:

<?xml version='1.0'?>
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd'>
	<event name='controller_action_predispatch'>
		<observer
			name='Df\Core\Observer\ControllerActionPredispatch'
			instance='Df\Core\Observer\ControllerActionPredispatch'
		/>
	</event>
</config>

Step 2

Пример класса-обработчика собатия.
Класс должен реализовывать интерфейм \Magento\Framework\Event\ObserverInterface.
Этот интерфейс состоит из единственного метода execute, и этот метод должен быть реализован, например:

<?php
namespace Df\Core\Observer;
use Magento\Framework\Event\ObserverInterface;
class ControllerActionPredispatch implements ObserverInterface {
	/**
	 * @override
	 * @see ObserverInterface::execute()
	 * @used-by \Magento\Framework\Event\Invoker\InvokerDefault::_callObserverMethod()
	 * @see \Magento\Framework\App\Action\Action::dispatch()
	 * https://github.com/magento/magento2/blob/dd47569249206b217e0a9f9a9371e73fd7622724/lib/internal/Magento/Framework/App/Action/Action.php#L91-L92
		$eventParameters = ['controller_action' => $this, 'request' => $request];
		$this->_eventManager->dispatch('controller_action_predispatch', $eventParameters)
	 * @param \Magento\Framework\Event\Observer $observer
	 * @return void
	 */
	public function execute(\Magento\Framework\Event\Observer $observer) {
		rm_state()->controllerSet($observer['controller_action']);
	}
}