Enabling modules one at a time works differently than enabling them all at once

Created on 27 February 2010, over 14 years ago
Updated 7 August 2023, about 1 year ago

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:

  1. Invoke hook_disable() on the first module that will be disabled.
  2. 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.
  3. Update the database and caches to actually disable the module.
  4. (repeat steps 1-3 for other modules)
  5. 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. -->
πŸ“Œ Task
Status

Closed: outdated

Version

9.5

Component
InstallΒ  β†’

Last updated 2 days ago

No maintainer
Created by

πŸ‡ΊπŸ‡ΈUnited States David_Rothstein

Live updates comments and jobs are added and updated live.
  • Needs backport to D7

    After being applied to the 8.x branch, it should be considered for backport to the 7.x branch. Note: This tag should generally remain even after the backport has been written, approved, and committed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024