Are hooks a thing in their own right, or are they actually implemented as events under the hood?
3 Answers
Hooks aren't Symfony events. They are PHP functions with a specific name that Drupal calls in very specific cases.
For example, hook_cron()
is invoked when Drupal cron tasks are executed, from Cron::invokeCronHandlers()
, which uses the following code.
// Iterate through the modules calling their cron handlers (if any):
foreach ($this->moduleHandler
->getImplementations('cron') as $module) {
if (!$module_previous) {
$logger
->notice('Starting execution of @module_cron().', [
'@module' => $module,
]);
}
else {
$logger
->notice('Starting execution of @module_cron(), execution of @module_previous_cron() took @time.', [
'@module' => $module,
'@module_previous' => $module_previous,
'@time' => Timer::read('cron_' . $module_previous) . 'ms',
]);
}
Timer::start('cron_' . $module);
// Do not let an exception thrown by one module disturb another.
try {
$this->moduleHandler
->invoke($module, 'cron');
} catch (\Exception $e) {
watchdog_exception('cron', $e);
}
Timer::stop('cron_' . $module);
$module_previous = $module;
}
A module whose machine name is spam_checker could implement this hook adding the following function to its code.
function spam_checker_cron() {
// Delete the nodes from the list of nodes to check after 96 hours are passed.
Drupal::database()
->delete('spam_checker_list')
->condition('timestamp', REQUEST_TIME - 3600 * 96, '<')
->execute();
}
To put it simply, I would say the hook system is a naming convention that allows you to extend the Drupal functionalities.
The core of the implementation is something like this:
// $vars is an array with the basic page variables that Drupal provides.
$hook = 'preprocess_page';
for ($modules as $module) {
call_user_func_array("${module}_${hook}", $vars);
}
// Now, $vars could have new variables or a number of modifications.
// You have effectively tampered the default workflow,
// without changing the code in the Drupal Core.
Hooks as a Software Engineering Design Pattern
According to the Drupal 4 Documentation (Programming from an Object-Oriented Perspective) Hooks are the procedural equivalents of the Abstraction and Inheritance OOP Concepts and the Decorator, Observer and Command Design Patterns.
This view seems to be well accepted:
Other sources say the Hooks are an implementation of the Mediator pattern. Mediator pattern Hooks vs. Events
Object Oriented Programming is the Future, not Hooks
Implementing a Form, Block or Content Entity is easier and cleaner with the new Object Oriented model in Drupal 8. The related hooks were removed.
Some other removed hooks are: hook_watchdog, hook_boot, hook_init, and hook_exit.
Related Issues and links:
- Use Symfony EventDispatcher for hook system (issue 1509164)
- Add a HookEvent (Issue 1972304)
- Dispatch the PREPARE_ROW event. Deprecate prepare_row_alter hooks (Issue 2952291)
- Hook Event Dispatcher Contrib module
- Drupal 8 Hooks Unravelled
They're not events (think you have symfony in mind), they are called like here in EntityStoreBase:
// Call hook_TYPE_load().
foreach ($this->moduleHandler()->getImplementations($this->entityTypeId . '_load') as $module) {
$function = $module . '_' . $this->entityTypeId . '_load';
$function($entities);
}