66
27 THE ULTIMATE GUIDE TO DRUPAL 8, REVISED AND UPDATED FOR DRUPAL 8.1
Drupal 8: Events
Although hooks are definitely still prevalent in Drupal 8 for most event-driven
behavior (though info-style hooks have largely moved to YAML or Plugin
annotations), the portions of Drupal 8 that are more closely aligned to Symfony (for
example, bootstrap/exit, routing system) as well as brand new code in Drupal 8
like Migrate have largely moved to Symfony’s Event Dispatcher system . In this
system, events are dispatched at runtime when certain logic occurs, and modules
can subscribe classes to the events to which they want to react.
To demonstrate this, let’s take a look at Drupal 8’s configuration API, located
in core/lib/Drupal/Core/Config/Config.php. It defines a variety of CRUD
methods such as save(), delete(), and so on. Each method dispatches an event
when finished with its work, so other modules can react. For example, here’s
Config::save():
<?php
public function save() {
// <snip>Validate the incoming information.</snip>
// Save data to Drupal, then tell other modules this was
// just done so they can react.
$this->storage->write($this->name, $this->data);
// ConfigCrudEvent is a class that extends from Symfony’s
// “Event” base class.
$this->eventDispatcher->dispatch(ConfigEvents::SAVE, new
ConfigCrudEvent($this));
}
?>
As it turns out, at least one module needs to react when the configuration is saved:
the core Language module. Because if the configuration setting that was just
changed was the default site language, it needs to clear out compiled PHP files so
the change can take effect.
To do this, Language module does three things:
1. Registers an event subscriber class in its language.services.yml file (this
is a configuration file for the Symfony Service Container for registering
reusable code):
language.config_subscriber:
class: Drupal\language\EventSubscriber\ConfigSubscriber
tags:
- { name: event_subscriber }
2. In the referenced class, it implements the EventSubscriberInterface and
declares a getSubscribedEvents() method, which itemizes the events that it
should be alerted to and provides each with one or more callbacks that should
be triggered when the event happens, along with a “weight” to ensure certain
modules that need to can get the first/last crack at the object can (heads-up:
Symfony’s priority scoring is the opposite of Drupal’s weight system—higher-
numbered methods are called first):
<?php
class ConfigSubscriber implements EventSubscriberInterface {
static function getSubscribedEvents() {
$events[ConfigEvents::SAVE][] = array(‘onConfigSave’, 0);
return $events;
}
}
?>
3. Defines the callback method, which contains the logic that should happen when
the configuration is saved:
<?php
public function onConfigSave(ConfigCrudEvent $event) {
$saved_config = $event->getConfig();
if ($saved_config->getName() == ‘system.site’ &&
$event- >isChanged(‘langcode’)) {
// Trigger a container rebuild on the next request.
PhpStorageFactory::get(‘service_container’)
->deleteAl();
}
}
?>