4

I have a module that should replace the implementation of a hook done by another module.
Is it possible to do it, with Drupal 7? If it is possible, under which conditions is possible?

By replacing the implementation of a hook done by another module, I mean using a function that is automatically called by Drupal when that module is enabled. For example, if the Poll module is enabled, then Drupal should call the poll_user_restriction_info() or the poll_metatags_info() (where hook_user_restriction_info() and hook_metatags_info() are custom hooks used by my module) function present in my module files.
I could use a function in my module that loads some include files from my module directory (e.g. poll_custom_hooks.inc) basing on the enabled modules, but I am looking for a system that would allow Drupal to automatically load such files.

7

You can use hook_module_implements_alter() to alter the list of modules which implement a given hook. So just implement the hook in your module too and then remove the one from the module you want to replace.

Note that this hook should be used very carefully, you can do really weird stuff with it which will make it very hard to maintain and understand, among other things.

5

It is only possible when the module is implementing the hook in a file that is not the module file, and the module that wants to override that hook implementation is implementing it in its module file. In this case, it is possible to implement hook_module_implements_alter() to report to Drupal that the hook implementation is not contained in an external file (i.e., the hook implementation is contained in the module file).

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'token_info') {
    $implementations['poll']['group'] = FALSE;
  }
}

In the case the module for which the hook implementation is being overwritten implements it in the module file, then it is impossible to do anything without altering the files used by that module, or adding a new file in the directory containing the module that needs to be "overwritten." The reason is that:

  • module_hook(), the function called from module_invoke() is using the following code.

    function module_hook($module, $hook) {
      $function = $module . '_' . $hook;
      if (function_exists($function)) {
        return TRUE;
      }
    
      // If the hook implementation does not exist, check whether it may live in an
      // optional include file registered via hook_hook_info().
      $hook_info = module_hook_info();
      if (isset($hook_info[$hook]['group'])) {
        module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']);
        if (function_exists($function)) {
          return TRUE;
        }
      }
      // ...
    }
    

    This code calls module_hook_info() only when the hook implementation is not in a file already loaded from Drupal, for example the module file. Since hook_module_implements_alter() is invoked by module_hook_info(), this means that in this case my implementation of hook_module_implements_alter() would not be invoked.

  • module_implements(), the function called by module_invoke_all() executes the following code.

    foreach ($list as $module) {
      $include_file = isset($hook_info[$hook]['group']) && module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']);
      // Since module_hook() may needlessly try to load the include file again,
      // function_exists() is used directly here.
      if (function_exists($module . '_' . $hook)) {
        $implementations[$hook][$module] = $include_file ? $hook_info[$hook]['group'] : FALSE;
      }
      // ...
    }
    

    The code is looking for the file to load in the directory containing the module implementing the hook. My code cannot tell Drupal where to look for the file containing the hook, so I could just put it in a file Drupal automatically loads, such as the module file of my module.

Overriding a module hook implemented in a module file with a function implemented in another module file does not work, as PHP would complain about a function defined twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.