Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Events and subscribers

An event is a message saying "this has just happened" that core sends to everyone interested. A subscriber is a class that listens to the events it needs and runs its own code. Next to hooks, it is the second way to step into the work of Drupal. Events are used by the part of core that came from Symfony: handling the request and response, routes, saving configuration.

Where a subscriber lives

Subscribers go to the src/EventSubscriber folder of the module by convention. Create the folder and the file by hand.

The subscriber class

Let us add a header to every response of the site:

// web/modules/custom/blog/src/EventSubscriber/HeaderSubscriber.php
namespace Drupal\blog\EventSubscriber;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
 
class HeaderSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::RESPONSE => 'onResponse'];
    }
 
    public function onResponse(ResponseEvent $event): void
    {
        $event->getResponse()->headers->set('X-Blog', 'Drupal course');
    }
}

The getSubscribedEvents() method says which events to listen to and which method to call. KernelEvents::RESPONSE happens when the response is ready to be sent. The method receives the event object — the response is taken from it and changed.

Registering

A subscriber is a service with a special tag. Add it to blog.services.yml:

# web/modules/custom/blog/blog.services.yml
services:
  blog.header_subscriber:
    class: Drupal\blog\EventSubscriber\HeaderSubscriber
    tags:
      - { name: event_subscriber }

The event_subscriber tag in the tags section tells Drupal to connect the service to event dispatching. If the file already has a services section, the new entry is added to it without repeating the word services.

Checking

vendor/bin/drush cr
curl -I http://127.0.0.1:8888/blog

The response headers now contain the line X-Blog: Drupal course. It is also visible in the browser developer tools on the Network tab.

Frequent events

EventWhen it happens
KernelEvents::REQUESTThe request has arrived, the controller is not chosen yet
KernelEvents::RESPONSEThe response is ready to be sent
KernelEvents::EXCEPTIONAn exception was thrown during handling
ConfigEvents::SAVEA configuration object was saved
RoutingEvents::ALTERThe list of routes is built: another module's route can be changed

The ConfigEvents and RoutingEvents classes are in the Drupal\Core\Config and Drupal\Core\Routing namespaces.

Priority

If several classes subscribe to an event, the order is set by the priority — a number next to the method name:

// web/modules/custom/blog/src/EventSubscriber/HeaderSubscriber.php
public static function getSubscribedEvents(): array
{
    return [KernelEvents::RESPONSE => ['onResponse', 100]];
}

The larger the number, the earlier the subscriber is called. Without a number the priority is zero.

Hook or event

You do not have to choose: core decides. Entities, forms and templates are extended with hooks, while the request, response, routes and configuration use events. The documentation of each place says what exactly it offers.

Common mistake

The subscriber class is written, but the method is not called. The cause is that the subscriber is not registered: Drupal does not look for such classes by folder, as it does for plugins. You need an entry in blog.services.yml with the event_subscriber tag and then drush cr. Check the YAML indentation too: tags is on the same level as class.

Thanks for reading!

Donate to the site — we work hard for you.