From drupal.org - Events:
Events are part of the Symfony framework: they allow for different components of the system to interact and communicate with each other. Each event has a unique string name. One system component dispatches the event at an appropriate time; many events are dispatched by Drupal core and the Symfony framework in every request. Other system components can register as event subscribers; when an event is dispatched, a method is called on each registered subscriber, allowing each one to react.
Drupal's default event dispatcher is \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
.
To alert the dispatcher about an event:
ContainerAwareEventDispatcher::dispatch($eventName, Event $event = null);
The base event class is \Symfony\Component\EventDispatcher\Event
.
You will probably need to extend this class to provide necessary data to event subscribers.
For example - core/lib/Drupal/Core/Render/PageDisplayVariantSelectionEvent.php
:
<?php
namespace Drupal\Core\Render;
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\EventDispatcher\Event;
/**
* Event fired when rendering main content, to select a page display variant.
*
* Subscribers of this event can call the following setters to pass additional
* information along to the selected variant:
* - self::setPluginConfiguration()
* - self::setContexts()
* - self::addCacheableDependency()
*
* @see \Drupal\Core\Render\RenderEvents::SELECT_PAGE_DISPLAY_VARIANT
* @see \Drupal\Core\Render\MainContent\HtmlRenderer
*/
class PageDisplayVariantSelectionEvent extends Event implements RefinableCacheableDependencyInterface {
// ...
/**
* The selected page display variant plugin ID.
*
* @var string
*/
protected $pluginId;
// ...
/**
* The selected page display variant plugin ID.
*
* @param string $plugin_id
* The ID of the page display variant plugin to use.
*
* @return $this
*/
public function setPluginId($plugin_id) {
$this->pluginId = $plugin_id;
return $this;
}
// ...
}
- Define a service in your module and tag it with
event_subscriber
.
For example - core/modules/block/block.services.yml
:
services:
# ...
block.page_display_variant_subscriber:
class: Drupal\block\EventSubscriber\BlockPageDisplayVariantSubscriber
tags:
- { name: event_subscriber }
# ...
- Define a class for your subscriber service that implements
Symfony\Component\EventDispatcher\EventSubscriberInterface
.
For example - core/modules/block/src/EventSubscriber/BlockPageDisplayVariantSubscriber.php
<?php
namespace Drupal\block\EventSubscriber;
use Drupal\Core\Render\PageDisplayVariantSelectionEvent;
use Drupal\Core\Render\RenderEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Selects the block page display variant.
*
* @see \Drupal\block\Plugin\DisplayVariant\BlockPageVariant
*/
class BlockPageDisplayVariantSubscriber implements EventSubscriberInterface {
// ...
}
- Return a list of events mapped to methods within the same class to call when the event is triggered.
For example - core/modules/block/src/EventSubscriber/BlockPageDisplayVariantSubscriber.php
:
<?php
// ...
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[RenderEvents::SELECT_PAGE_DISPLAY_VARIANT][] = ['onSelectPageDisplayVariant'];
return $events;
}
// ...
- Write the callback methods declared above.
For example - core/modules/block/src/EventSubscriber/BlockPageDisplayVariantSubscriber.php
:
<?php
// ...
/**
* Selects the block page display variant.
*
* @param \Drupal\Core\Render\PageDisplayVariantSelectionEvent $event
* The event to process.
*/
public function onSelectPageDisplayVariant(PageDisplayVariantSelectionEvent $event) {
$event->setPluginId('block_page');
}
// ...
You can also set priority for your subscribed events. Higher priority numbers are executed first.
Example from drupal.org - Events:
<?php
public static function getSubscribedEvents() {
// Subscribe to kernel terminate with priority 100.
$events[KernelEvents::TERMINATE][] = array('onTerminate', 100);
// Subscribe to kernel request with default priority of 0.
$events[KernelEvents::REQUEST][] = array('onRequest');
return $events;
}
If two event subscribers have the same priority the module with the lower weight fires first.
Symfony uses higher numbers as higher priority but Drupal uses the reverse. This is why for Event
priority it uses higher numbers, but for module handling the lower number receives priority.
If multiple subscribers exist in the same module, they are fired in the order they are defined, but if order is important, it's recommended to explicitly define a priority instead of relying on the default conventions in the event they ever change.