Problem/Motivation
The ordering of listeners defined by new Hook
attributes does not have a modern solution.
We needed to preserve hook_module_implements_alter
in it's current form to handle all current ordering scenarios.
#3485659: Remove HookOrder HookOrder was temporarily removed because it does not quite work with extras.
#3484754: Ordering of hooks needs some attention Resolves the BC break (this issue is the followup to address point 3)
#3479141: Implement FormAlter attribute. is related since it is the most common form (lol) of an alter with extra types.
Steps to reproduce
Try to order an OOP implementation of a hook. Observe there's only a very clumsy legacy mechanism.
Proposed resolution
There are CRs to address each piece of hook_module_implements_alter functionality needed to handle hook ordering.
There is also a section in the remaining tasks summarizing the deprecation specifically for framework and release managers.
Ordering own implementation
See this CR for more complete examples: https://www.drupal.org/node/3493962
Add order
parameter to the #[Hook]
attribute.
The order
parameter accepts the following simple ordering options.
Order::First
Order::Last
The order parameter also accepts the following complex ordering options which also accept parameters.
OrderBefore()
OrderAfter()
These can accept the following parameters:
modules:
an array of modules to order before or after.
classesAndMethods:
an array of arrays of classes and methods to order before or after.
groups:
an array of hooks this hook should be grouped with when extra types are involved.
Here is how it works for CKEditor5.
#[Hook('form_filter_format_form_alter',
order: new OrderAfter(
modules: ['editor', 'media'],
group: ['form_filter_format_add_form_alter', 'form_filter_format_edit_form_alter'],
)
)]
OrderAfter
specifies this hook should run after the parameters passed.
modules: ['editor', 'media'],
specifies this ordering cares about the editor
and media
modules.
group: ['form_filter_format_add_form_alter', 'form_filter_format_edit_form_alter'],
allows ordering relative to MediaHooks::formFilterFormatEditFormAlter
and MediaHooks::formFilterFormatAddFormAlter
-- these implement a different hook and so a grouping is necessary. This is the most complex case and most of the time group
is not necessary.
Removal
See this CR for more details: https://www.drupal.org/node/3496786
Add #[RemoveHook()]
attribute.
The #[RemoveHook()]
attribute accepts details about the implementation to remove.
#[RemoveHook('help', class: LayoutBuilderHooks::class, method: 'help')]
This will remove the layout builder hook_help implementation.
Ordering other implementations
See this CR for more details: https://www.drupal.org/node/3497308
Add #[ReOrderHook()]
attribute.
The #[ReOrderHook()]
attribute accepts details about the implementation to reorder.
class WorkspacesHooks {
#[ReOrderHook('entity_presave',
class: ContentModerationHooks::class,
method: 'entityPresave',
order: new OrderBefore(['workspaces'])
)]
public function entityPresave()
This allows the workspaces
module to move the entity_presave
implementation in content_moderation
before the implementation in workspaces
.
Remaining tasks
Review
Should the deprecation happen in this issue for release manager review.
HMIA is a special hook, we cannot deprecate it normally.
If we follow standard deprecation processes then a contributed module will remove it which requires them to drop support for Drupal < 11.2 because the ordering functionality here will not be available for older versions of Drupal.
Proposed BC deprecation process.
Deprecate HMIA calls without #[LegacyModuleImplementsAlter]
This allows modules that are on Drupal < 11.2 to still run HMIA ordering and modules newer than 11.2 to use the new functionality here and ignore the legacy ordering.
If we do not use a new attribute and use #[LegacyHook] there is a gap 11.1 - 11.2 where ordering will break since the ordering attributes are not available and LegacyHook will skip hook_module_implements_alter implementations.
Decide if we want to deprecate hmia here or in a follow up
Branch with deprecation and functionality: https://git.drupalcode.org/project/drupal/-/merge_requests/11233
Deprecation patch only: https://www.drupal.org/files/issues/2025-02-17/hmiadeprecationv9.patch
User interface changes
N/A
Introduced terminology
Order
OrderAfter
OrderBefore
RemoveHook
ReOrderHook
API changes
A new enum and two new classes assist with ordering, these replace hook_module_implements_alter:
Order
OrderAfter
OrderBefore
Two new attributes to assist with modifying other hook implementations.
#[RemoveHook()]
#[ReOrderHook()]
Do not delete hook_module_implements_alter
until you drop support for Drupal VERSION instead add the #[LegacyModuleImplementsAlter]
attribute to hook_module_implements_alter
once the module has set up the correct ordering attributes.
Data model changes
N/A
Release notes snippet
N/A