Lee RowlandsSenior Developer
To Alter or Dispatch: Drupal 8 Events versus Alter Hooks
Drupal 8 comes with two extension points for module developers to allow other modules to interact with their code.
The trusty alter hook, the linchpin of Drupal versions past is still there - allowing other modules to interact and intervene in the behaviour of your module.
But there is a new kid on the block, the event system.
So as a module developer how do you decide whether to use the alter system or the event system.
To alter or to fire an event?
This was the premise of a recent IRC conversation between myself, dawehner and bojanz, so for posterity I present to you the pros and cons we came up with.
Pros of events
- Object oriented. Hooks still rely on procedural code meaning unit-testing is possible, but more involved. As events are object-oriented and support dependency injection, you could unit-test your event. Although in practise your events should be thin, like your controllers, with your logic deferred to the larger parts of your application. Either way, Object oriented code presents a nicer developer experience than working with procedural functions.
- Stopping propagation. Like a JavaScript event, the event dispatcher allows any single event to stop propagation, preventing subsequent event listeners from firing. This can't be done with an alter hook.
- Firing twice on the one event. By default with the hook system, your hook is fired based on alphabetical sorting. i.e. barfoo_some_hook will go before foobar_some_hook because barfoo comes before foobar in the alphabet. If you want to alter the order in which the hooks fire, you can alter the module's weight in the system table - which applies globally for all hooks, or implement hook_module_implements_alter to re-order on a per-hook basis. What you can't do however is fire your hook twice. With the event system, you can register two listeners for the one event, from the one module. This means you can have your event listener fire first and last when the event is dispatched.
Pros of alter hooks
- One thing the event system doesn't easily allow is for one module to remove another module's implementation. This can be done with hook_module_implements_alter in the hook system. So for your particular site-build you may find one module's implementation of a hook problematic or even broken. With the hook system, you can implement hook_module_implements_alter and remove a particular implementation and re-implement it in your own way. To do something similar in the event-dispatcher system, would require you to alter the container definition and remove the event listener you don't want.
Code sample for hooks
<?php
function mymodule_dosomething() {
$data = mymodule_get_some_data();
return \Drupal::moduleHandler()->alter('my_module_hook', $data);
}
?>
Code sample for events
<?php
namespace Drupal\mymodule;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Drupal\mymodule\Events\SomethingEvent;
/**
* Defines a class for doing stuff.
*/
class MyModuleSomething {
protected $eventDispatcher;
/**
* Constructs a MyModuleSomething.
*/
public function __construct(EventDispatcherInterface $event_dispatcher) {
$this->eventDispatcher = $event_dispatcher;
}
/**
* Does something.
*/
public function doSomething($with_this) {
$event = new SomethingEvent($with_this);
$this->eventDispatcher->dispatch(SomethingEvent::JUST_DO_IT, $event);
return $event->showMeTheDoneStuff();
}
}
?>
So what will it be?
Are you building a module for Drupal 8 and have already decided to use events instead of alter hooks? Let us know what influenced your decision in the comments - let's keep the conversation going and build out a resource to help others make their decision.