I tried implementing hook_menu()
in an foo.admin.inc
file for reasons that aren't important, and discovered that hooks are not checked in said file. However, in the past, I have seen include files with hooks defined in them (e.g. rules.inc), so I was wondering what the default core rule is for this, and how one can specify files outside of the defaults. Does extending where hooks can be checked have a nice Drupal way of doing this, or have module developers used PHP to achieve this end?
2 Answers
What files will Drupal poll for hooks by default?
There's no "polling" happening really, at the core, this is what happens:
function module_hook($module, $hook) {
return function_exists($module .'_'. $hook);
}
And this is simply called with $module
being the name of each enabled module. So essentially, if the hook is declared in any file that is loaded, PHP will find it, and the function above will return TRUE
.
If one, for one reason or another, wants to declare hooks elsewhere, it is possible to explicitly tell Drupal to load up other modules by using hook_hook_info. The documentation says:
Normally hooks do not need to be explicitly defined. However, by declaring a hook explicitly, a module may define a "group" for it. Modules that implement a hook may then place their implementation in either $module.module or in $module.$group.inc. If the hook is located in $module.$group.inc, then that file will be automatically loaded when needed. In general, hooks that are rarely invoked and/or are very large should be placed in a separate include file, while hooks that are very short or very frequently called should be left in the main module file so that they are always available.
Another low tech option, or the only option in D6, looks like this:
[module].module:
function module_menu() {
require_once "module.menu.inc";
return _module_menu();
}
[module].menu.inc:
function _module_menu() {
return array();
}
If hook module is large, this moves the majority of the code outside of the module, requiring less RAM on most page loads to run the module. As above, this makes little sense if the module is invoked on (nearly) every page load.
An include file will be scanned if the hook is within a group. For example, the rules module defines a group called 'rules' and so Drupal will scan the file foo.rules.inc for implementations of rules hooks.
The hook where groups are defined is hook_hook_info. See: https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_hook_info/7
Also, look at the function module_implements that finds modules implementing a hook: https://api.drupal.org/api/drupal/includes!module.inc/function/module_implements/7