Skip to content

Improve HookRegistry hook calling conventions #8083

@asmecher

Description

@asmecher

HookRegistry has some long-standing implementation quirks that make hook-based code hard to read and maintain:

  • Hook parameters are be passed through an array and must be unpacked in sequence
  • Type hinting is not possible within the parameter array
  • Named parameters are not available within the parameter array
  • The return value from a hook callback is perpetually confusing

Clean up these conventions (in a backwards-compatible way).

Proposal PR: #8084

Passing parameters to hook callbacks

The proposal deprecates HookRegistry::call and adds a new HookRegistry::execute to be preferred in its place.

HookRegistry::execute offers several new possibilities for callbacks:

Callback function parameters properly declared

Previously, callbacks had to pass parameters via an array:

HookRegistry::register('someHookName', function(string $hookName, array $args) {
    list($submission, $publication) = $args;
    ...
});

HookRegistry::call('someHookName', [$mySubmission, $myPublication]);

Using HookRegistry::execute instead, the parameters can be named directly, including type hinting:

HookRegistry::register('someHookName', function(string $hookName, Submission $submission, Publication $publication) {
    ...
});

HookRegistry::execute('someHookName', [$mySubmission, $myPublication]);

References are also supported; these can be declared in the callback parameter list as usual, and should be passed into the array as references as well (as before, even with objects):

HookRegistry::register('someHookName', function(string $hookName, Submission $submission, Publication &$publication) {
    ...
    $publication = $someOtherPublication;
});

HookRegistry::execute('someHookName', [$mySubmission, &$myPublication]);

Named arguments

HookRegistry::execute supports named arguments; this can help keep code readable when longer lists of parameters are provided or parameter ordering might be unclear.

HookRegistry::register('someHookName', function(string $hookName, Submission $submission, Publication $publication) {
    ...
});

HookRegistry::execute('someHookName', ['submission' => $mySubmission, 'publication' => $myPublication]);

Hook return conventions

In the past, hook callbacks returned true to interrupt later hooks, or false to continue. The meaning of these values was hard to remember. This change adds HookRegistry::HOOK_ABORT and HookRegistry::HOOK_CONTINUE constants to use instead. (This change is backwards compatible; the constants are equivalent to true and false.)

HookRegistry::register('someHookName', function(string $hookName) {
    return HookRegistry::HOOK_ABORT; // Stop processing subsequent hook registrants
});

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions