Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 297608

Add a HookEvent

$
0
0

Problem/Motivation

Module authors converting their procedural code to services would like to implement hooks in said services without procedural code.

Proposed resolution

One, the event bridge. In ModuleHandler:

public function invokeAll($hook, $args = array()) {
  $event = new HookEvent("hook.$hook", $args)
  \Drupal::service('event_dispatcher')->dispatch($event);
  $return = $event->getResults();
// ... the rest of the function is unchanged.
}

this way people can write dependency injected services implementing a hook instead of procedural code. As we hope to attract new developers more accustomed to OOP, this is sort of important.

Alternatively we could put the hook definitions in a class like Drupal\System\HookDefinition\System, one method per hook with the doxygen and with empty bodies. Classes would extend these definitions, register themselves into the service container with the tag hook. On container compile, we could parse the classes of these services with existing Doctrine code to find the methods defined by them and store the hook => array-of-services list into the container and then invokeAll:

public function invokeAll($hook, $args = array()) {
  $result = array();
  $hook_method_name = Camelize($hook_name);
  foreach (\Drupal::container()->getParameter("hook.$hook_name") as $service) {
     // We could do something with the return value as well.
     call_user_func_array(array(\Drupal::service($service), $hook_method_name), $args);
  }
// ... the rest of the function is unchanged.
}

This would have the advantage of a) we could retire hooks even for D8 because we have a place where we can put the hook doxygen B) we never need to load all the hook definitions, unlike with the event bridge. It's a regression to load all that code, in D7 we added groups to hooks to avoid that. The main "against" here is that this not the familiar (?) event dispatcher but then again, the only difference here is that instead of tagging as 'event_subscriber' we need to tag with 'hook' and then subscription is automatic. Already the event_subscriber tag is a Drupalism, this isn't a big step ahead.

Remaining tasks

Update module handler as required
Create HookEvent
Convert remaining hook invocations that do not use ModuleHandler::invokeAll ie where module_implements is used instead. There are two kinds: one that wants to pass around references, these are easy to convert because invokeAll takes an array of arguments instead of a variable number of arguments and the array simply can contain the references. Those that want to record the module that returned certain information will need some consideration (permissions do this for uninstall). The problematic cases will likely be handled in a followup.

User interface changes

None

API changes

Module maintainers can implement hooks in their service classes.
ModuleHandler::moduleImplements likely becomes a protected method.

#1972300: Write a more scalable dispatcher


Viewing all articles
Browse latest Browse all 297608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>