Issue description updated: comment #22
This issue started with me trying to follow up on
#620298: Schema not available in hook_install() β
, where among other things we removed node access specific code from module_enable() and put it in node_modules_enabled() instead. I was trying to do the same thing here with the node access code in module_disable(), and quickly ran into the following problem.
As per the "Invoke hook_modules_disabled" comment in the below excerpt from module_disable():
if (!empty($invoke_modules)) {
// Refresh the module list to exclude the disabled modules.
system_list_reset();
module_list(TRUE);
module_implements('', FALSE, TRUE);
// Invoke hook_modules_disabled before disabling modules,
// so we can still call module hooks to get information.
module_invoke_all('modules_disabled', $invoke_modules);
// Update the registry to remove the newly-disabled module.
registry_update();
_system_update_bootstrap_status();
}
the intention is that disabled modules hooks are still available when hook_modules_disabled() is called.
However, as can easily be seen from the code order, this does not actually happen. It's not hard to fix by moving the code around, but this then has some odd side effects. For example, any API function call you make from inside hook_modules_disabled() that invokes hooks of its own will then invoke that hook on the disabled module as well, which could lead to unexpected results.
In order to preserve the ability indicated in the code comment, the only way I can think of to do this is to add a new hook, and then do an overall rewrite of module_disable() to make it more sane and make it work similarly to the way we made module_enable() work in
#620298: Schema not available in hook_install() β
. In particular, the function should work like this:
- Invoke hook_disable() on the first module that will be disabled.
- Invoke a new hook, something like "hook_module_disabling", which allows other modules to respond to that module alone, before it is disabled - i.e., fulfilling the actual intended functionality of the code comment above.
- Update the database and caches to actually disable the module.
- (repeat steps 1-3 for other modules)
- Invoke hook_modules_disabled() to inform all modules about the list of modules that were disabled. This should happen after the module's hooks can no longer be called, so it is safe to call API functions and know that the disabled modules are really disabled and won't still be hanging around. In other words, I think this hook should work as it does work now, not as it is documented to work.
It's possible that steps 1 and 2 in my above list should actually be switched around - would need to think more about that.
Beta phase evaluation
<!--Uncomment the relevant rows for the issue. -->