What Ties a Drupal Hook to a Particular Module?
In Drupal 7, every core module has an "api" file
$ ls modules/*/*.api.php
modules/aggregator/aggregator.api.php modules/openid/openid.api.php
modules/block/block.api.php modules/overlay/overlay.api.php
modules/comment/comment.api.php modules/path/path.api.php
modules/contextual/contextual.api.php modules/rdf/rdf.api.php
modules/dashboard/dashboard.api.php modules/search/search.api.php
modules/field/field.api.php modules/shortcut/shortcut.api.php
modules/field_ui/field_ui.api.php modules/simpletest/simpletest.api.php
modules/file/file.api.php modules/system/system.api.php
modules/filter/filter.api.php modules/system/theme.api.php
modules/help/help.api.php modules/taxonomy/taxonomy.api.php
modules/image/image.api.php modules/trigger/trigger.api.php
modules/locale/locale.api.php modules/update/update.api.php
modules/menu/menu.api.php modules/user/user.api.php
modules/node/node.api.php
Each of these files contains a function that's never (?) called, but documents the existence of a hook that other modules (including 3rd party) can implement.
File: modules/path/path.api.php
function hook_path_delete($path) {
db_delete('mytable')
->condition('pid', $path['pid'])
->execute();
}
My question: What ties a particular hook to a particular module? Why is the path_delete
hook included in the path.api.php
file? Why is the entity_view
hook included in the system.api.php
file? Is this just arbitrary, after the fact organization, or is there something in the Drupal system that ties a particular hook to a particular module? Or something else?
Hooks are invoked using
module_invoke()
andmodule_invoke_all()
: if you look at the code for those two functions, you might be able to piece together how it works, but basically, if I add this to my module's code:Drupal will invoke every implementation of
hook_foo_bar($var1, $var2)
it finds in enabled modules. Based on this, you should see that only thing that ties a particular hook to a particular module is a naming convention: if I call my modulefoo
, my hook functions should begin withhook_foo_
.You are correct about nothing in
*.api.php
being called: since a module invocation is just a function call, module authors includefoo.api.php
merely for documentation purposes to inform implementors how to implement the hook.For example, in the case above,
foo.api.php
would include a sample function like:But as a module implementor, I could implement
hook_foo_bar()
in a different fashion:And when
module_invoke_all()
gets called, Drupal will craft a function using the implementing module's short name (mymodule
) and the hook name passed tomodule_invoke_all()
(foo_bar
), thus calling the functionmymodule_foo_bar()
I just defined.The
system
module in core is a bit of a catch-all: one task for Drupal 8 is to kill it off and delegate its functionality to other modules.