Problem/Motivation
Postponed on:
#3069442: Deprecate views_entity_field_label() in favor of EntityFieldManager->getFieldLabels
#3489415: Deprecate views_field_default_views_data and related functions
Here are the contrib uses that are documented: https://git.drupalcode.org/search?group_id=2&scope=blobs&search=%22Imple...
#1892574: Remove hook_hook_info_alter() was removed a long time ago already.
hook_hook_info() only exists for lazy-loading legacy hook implementation code.
hook_hook_info() has architectural problems causing code to not be loaded (see related issues).
Remaining implementations
- system_hook_info() (hook_token*())
- views_hook_info() (hook_views_*())
Steps to reproduce
N/A
Proposed resolution
We cannot deprecate hook_hook_info in the traditional manner, that would cause contrib that is implementing it to remove their implementations.
This in turn would break contrib utilizing those groups.
Instead we can update hook_hook_info docs that it will be removed in 12.x (modules supporting older drupal versions can keep it)
We then deprecate the files INCLUDED by the groups here:
if (isset($this->groupIncludes[$hook])) {
foreach ($this->groupIncludes[$hook] as $include) {
include_once $include;
}
}
This will push contrib that is using the hook group includes to move their code out of the groups.
Then in drupal 12 we can safely remove hook_hook_info.
Modules supporting lower versions of drupal can keep the hook_hook_info implementation.
It will work as it did prior to Drupal 12, and in Drupal 12+ it will do nothing. This deprecation will have already enforced moving that code for modules that want to support Drupal 12.
Modules implementing hook_hook_info should never use #[LegacyHook] we do not want to prevent the includes until we remove the functionality after the appropriate deprecation period for the includes.
Remaining tasks
Vet this plan
User interface changes
N/A
Introduced terminology
N/A
API changes
hook_hook_info will no longer take effect after drupal 12.
module.group.inc files will no longer autoload after drupal 12.
Data model changes
N/A
Release notes snippet
TBD
Issue fork drupal-2233261
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
sunClarifying summary that ModuleHandler maintains a separate cache item for hook_info.
Comment #2
sunCreated #2233353: Convert Token API into plugins
Comment #3
tim.plunkettPlease have a look at views_hook_info().
None of that is legacy. Until something like #1972304: Add a HookEvent or #2043653: Allow modules to implement hooks by nominating methods in a module.implements.yml goes in, I don't see how or why we should move forward here.
Comment #4
catch#1443308-97: Add static cache to module_load_include() shows that views_hook_info() is a net negative for performance. With an opcode cache, having the hook implementations in the module file has a negligible impact, vs. the discovery which is non-negligible.
Comment #5
catchAlso we can't nuke this until 9.x unfortunately, but we can discourage it before then.
Comment #6
David_Rothstein commentedI like the idea of killing it, although it would be nice for some of the code organization benefits that it provides to be retained (and in fact expanded).
But I guess that can still be done with require_once statements at the top of the .module file...
Comment #9
dpiShould we issue a deprecation notice?
Comment #10
joelpittet@dpi That sounds good but
8.3.xor8.4.xwould be the start were it was deprecated.Comment #12
mile23We're trying to figure out how to @trigger_error() for deprecated hooks here: #2870058: [policy, no patch] Document how to deprecate hooks
Comment #17
andypostPolicy accepted https://www.drupal.org/core/deprecation#how-hook
Still no replacement for the hook
Comment #19
donquixote commentedI don't understand why this is being suggested.
If we replace hooks completely, fine. But we are not there yet I think.
Until then, something like hook_hook_info() is useful for code organization, similar to autoloading for classes (not autoloading itself, but the PSR-4 file organization that is made necessary by autoloading).
To me, performance is not the main reason for not putting everything into the main *.module file.
Yes. Code organization +1.
Yes, but:
The issue summary contains some more arguments, which are quite old.
I don't know if these are still valid.
As long as we have hooks, it would be useful to be able to force a convention for file organization per hook.
I am not married to hook_hook_info() specifically, but we should find more convincing reasons to remove it, and/or suggest a good replacement.
Comment #26
andypostRemoved
field_hook_info()from IS as it was moved toviews_hook_info()in #2399931: Generic entity api field handler should live in views module not in field moduleSo only tokens and views using this hook but it needs to deprecate
\Drupal\Core\Extension\ModuleHandlerInterface::getHookInfo()as wellFiled follow-up to remove broken ref #3346614: Remove stray reference to field_hook_info()
Comment #27
andypostClosed as duplicates
- #1373884: [meta] Core does not use hook_hook_info()
- #1107528: Stop using magic functions and force modules to declare the hooks they want to implement
- #1029158: Let hook_hook_info() handle hooks in .install files (aka "rename MODULE.install to MODULE.install.inc")
Comment #28
catchJust to answer #19 - a lot of modules and some of core too already puts the logic of their hook implementations into classes, so that the hook implementation in .module is just three lines or so. This pattern is available for every hook, not just the ones that have hook_hook_info() implemented for them.
Comment #30
berdirDefinitely no reason to keep this now that #3442009: OOP hooks using attributes and event dispatcher landed.
But doing so is tricky and needs two layers. We can't just remove hook_hook_info() implementations, because that would immediately break hooks that live in those files. First we need to deprecate hook implementations that live in those files. I don't think we need to do that one-one and introduce a deprecated flag on the hook info, we can do it for everything. But to avoid moving the token hook implementations twice, we probably want to convert those in core to services first.
Comment #31
catchI wonder if we want to roll this into #3481555: [Plan] Determine how to deprecate procedural hooks..
First deprecate procedural hooks that don't have the @LegacyHook attribute.
This could still leave @LegacyHook hook implementation in hook_hook_info() files.
But then when we're ready to drop Drupal 10 support, we can deprecate @LegacyHook too. And at the same time, we can deprecate hook_hook_info().
Comment #32
ghost of drupal pastActually #3442009: OOP hooks using attributes and event dispatcher removed this functionality. That turned out to be a mistake.
I can already see the future thanks to test issue where nicxvan is testing converting everything everywhere all at once (or, in short, the Oscar patch). The views hooks can be converted without a problem and almost all *.views.inc becomes empty and is deleted. However, these includes not only contain hooks but helpers as well.:
datetime_type_field_views_data_helper,views_entity_field_label,views_field_default_views_dataSo for now, #3484105: Automatically included .inc files are no longer included restores this functionality. These three helpers will need to be deprecated manually before hook_hook_info can be laid to rest.
Comment #34
nicxvan commentedComment #35
nicxvan commentedAlso we'll have to deprecate this but keep the system and views one around since contrib uses those so much.
The views hook classes support both types, but contrib will have to move those LegacyHook calls into the .module files at the least.
Comment #36
nicxvan commentedComment #37
nicxvan commentedComment #38
berdirPer #31, we can't really deprecate this, not like we usually do.
> Also we'll have to deprecate this but keep the system and views one around since contrib uses those so much.
This doesn't just apply to system and views. It applies to all implementations. We can't tell modules to stop implementing this hook, because other modules that implement their hooks might still be in those files.
I think we should add a mention to hook_hook_info() docblock that this should no longer be implemented but existing implementations must be kept for BC.
And then we can just drop it in D12 (or whenever we remove the old hooks), no deprecation needed, it won't do anything anymore. It doesn't need to be converted, so no deprecation needed.
So IMHO, this task is actually not blocked on anything and it's just a documentation issue.
Comment #39
nicxvan commentedComment #40
nicxvan commentedComment #41
nicxvan commentedComment #42
nicxvan commented@berdir had a discussion in slack here about this: https://drupal.slack.com/archives/C079NQPQUEN/p1732497552707689
I copied my thoughts to the IS.
His approach is slightly different than mine, but I think they mesh well and will cause the least disruption.
The main issue with hook_hook_info is this:
If we deprecate it then modules will remove them.
Any modules that used the include files will no longer be autoloaded and broken, but they got no notice it was deprecated.
@berdir proposes that we update the documentation that it will be removed in 12.
When it's removed we'll have deprecated procedural hooks and modules will have already moved theirs hooks except hook hook info.
Modules that support 10, 11 and 12 can keep the hook hook info function since it provides the inc files (which presumably only have legacy hook implementations) This will break D12 sites that still have helpers in the .inc files.
The approach I propose in case the summary is updated.
We do what @berdir proposed, but also in 11.2 we deprecate the include files themselves.
This will force any modules that utilize for example mymodule.tokens.inc to move all of the functions out of the .inc, whether it's a hook or a helper.
Then when hook hook info is removed no modules will break because we've already deprecated the effect the hook hook info has.
The include files can be deprecated when we add them in module handler. This should also hit all custom modules as well.
Comment #43
nicxvan commentedI pushed up a POC, tons of tests should fail cause we have not removed the three helpers that core still has and this will trigger deprecations.
Comment #45
nicxvan commentedComment #46
nicxvan commentedComment #47
nicxvan commentedI pushed up a first attempt at documenting the expected lifecycle of hook_hook_info.
I also moved views.views.inc and datetime.views.inc so I could see which tests really fail.
Commit d23dd379163049272f855204ad92f5a0756766b0 will need to be reverted when the two issues postponing this one are in.
Comment #48
nicxvan commentedTurns out I missed content moderation views inc I'll add that to the deprecation issue.
I will likely combine the two issues postponing this one, since they really are about removing views.views.inc
Comment #49
nicxvan commentedThe only failure is the one we need to add an expect deprecation for because it tests the functionality we're deprecating.
Comment #50
nicxvan commentedComment #51
larowlanComment #52
nicxvan commentedTagging this for the deprecation method since this is a unique deprecation.
Comment #53
nicxvan commentedComment #57
nicxvan commentedOk the dependent issues got in, just waiting on tests.
Comment #58
nicxvan commentedComment #59
catchWe discussed this in slack - the 'soft' deprecation so that people don't jump the gun here is good.
I also wondered about a 'hard' (normal) deprecation in a future release so that we eventually tell people to remove it, but the risk of people still jumping the gun (e.g. breaking support with Drupal < 11.2 prematurely) will be there, and then when we finally get to a core release where that's not a problem, we might as well have just removed the supporting code anyway instead of formally deprecating the hook. That means some modules could still ship with crufty hook_hook_info() implementations, but when we eventually deprecate .module files altogether, it will get deleted with those.
Comment #60
nicxvan commentedRemoving release manager tag per discussion in slack and @catch's comment here.
Comment #61
berdirPosted a review on wording stuff.
This looks good otherwise and at this point, the actual changes in the MR are trivial. It will affect a large amount of modules though. https://git.drupalcode.org/search?group_id=2&scope=blobs&search=%22Imple... finds 1000 tokens.inc files, and https://git.drupalcode.org/search?group_id=2&scope=blobs&search=%22Imple... finds 2500 matches.
This also matches 7.x modules, likely a lot of false positives, but still, no way around the fact that a lot of modules will need to adjust for this one. The good thing is that the fix is trivial, anything can just be moved into the .module file and optionally converted to OOP hooks if desired, which resolves the "large hook implementations" concern. And as long as LegacyHook is used, it's fully backwards compatible.
CR looks pretty good to me. I'd explicitly link the Hook CR so people who are interested in that can find it.
Comment #62
nicxvan commentedI addressed your comments.
I didn't quite realize how many there are but thankfully it's an easy copy and paste, and there is the rector rule for converting.
Comment #63
berdirI think this is ready then, as mentioned above, this impacts a massive amount of modules, but the solution is trivial and fully backwards compatible, optionally with new hooks and LegacyHook, so you don't need to require 11.2 for this.
Comment #64
catchLooks great. Obviously we already moved all the core implementations but I temporarily forgot that so it was nice to see such a small diff.
Took a long time but got there in the end.
Committed/pushed to 11.x, thanks!
Comment #67
catchComment #69
nicxvan commented