Error message

You are browsing documentation for drupal 7.x, which is not supported anymore. Read the updated version of this page for drupal 11.x (the latest version).

function module_implements

Determines which modules are implementing a hook.

Lazy-loaded include files specified with "group" via hook_hook_info() or hook_module_implements_alter() will be automatically included by this function when necessary.

Parameters

string $hook: The name of the hook (e.g. "help" or "menu").

bool $sort: By default, modules are ordered by weight and filename, settings this option to TRUE, module list will be ordered by module name.

bool $reset: For internal use only: Whether to force the stored list of hook implementations to be regenerated (such as after enabling a new module, before processing hook_enable).

Return value

An array with the names of the modules which are implementing this hook.

See also

module_implements_write_cache()

Related topics

Hooks
Allow modules to interact with the Drupal core.
69 calls to module_implements()
aggregator_admin_form in modules/aggregator/aggregator.admin.inc
Form constructor for the aggregator system settings.
block_form_system_performance_settings_alter in modules/block/block.module
Implements hook_form_FORM_ID_alter().
boot_test_1_boot in modules/simpletest/tests/boot_test_1.module
Implements hook_boot().
DBLogTestCase::verifyCron in modules/dblog/dblog.test
Verifies that cron correctly applies the database log row limit.
DrupalDefaultEntityController::attachLoad in includes/entity.inc
Attaches data to entities upon loading.

... See full list

3 string references to 'module_implements'
ModuleUnitTest::testModuleImplements in modules/simpletest/tests/module.test
Test module_implements() caching.
module_implements_write_cache in includes/module.inc
Writes the hook implementation cache.
_drupal_bootstrap_full in includes/common.inc

File

includes/module.inc, line 727

Code

function module_implements ($hook, $sort = FALSE, $reset = FALSE) {
 // Use the advanced drupal_static() pattern, since this is called very often.
 static $drupal_static_fast;
 if (!isset($drupal_static_fast)) {
 $drupal_static_fast['implementations'] =& drupal_static (__FUNCTION__);
 $drupal_static_fast['verified'] =& drupal_static (__FUNCTION__ . ':verified');
 }
 $implementations =& $drupal_static_fast['implementations'];
 $verified =& $drupal_static_fast['verified'];
 // We maintain a persistent cache of hook implementations in addition to the
 // static cache to avoid looping through every module and every hook on each
 // request. Benchmarks show that the benefit of this caching outweighs the
 // additional database hit even when using the default database caching
 // backend and only a small number of modules are enabled. The cost of the
 // cache_get() is more or less constant and reduced further when non-database
 // caching backends are used, so there will be more significant gains when a
 // large number of modules are installed or hooks invoked, since this can
 // quickly lead to module_hook() being called several thousand times
 // per request.
 if ($reset) {
 $implementations = array();
 $verified = array();
 cache_set ('module_implements', array(), 'cache_bootstrap');
 drupal_static_reset ('module_hook_info');
 drupal_static_reset ('drupal_alter');
 cache_clear_all ('hook_info', 'cache_bootstrap');
 cache_clear_all ('system_cache_tables', 'cache');
 return;
 }
 // Fetch implementations from cache.
 // This happens on the first call to module_implements(*, *, FALSE) during a
 // request, but also when $implementations have been reset, e.g. after
 // module_enable().
 if (empty($implementations)) {
 $implementations = cache_get ('module_implements', 'cache_bootstrap');
 if ($implementations === FALSE) {
 $implementations = array();
 }
 else {
 $implementations = $implementations->data ;
 }
 // Forget all previously "verified" hooks, in case that $implementations
 // were cleared via drupal_static_reset('module_implements') instead of
 // module_implements(*, *, TRUE).
 $verified = array();
 }
 if (!isset($implementations[$hook])) {
 // The hook is not cached, so ensure that whether or not it has
 // implementations, that the cache is updated at the end of the request.
 $implementations['#write_cache'] = TRUE;
 // Discover implementations for this hook.
 $hook_info = module_hook_info ();
 $implementations[$hook] = array();
 $list = module_list (FALSE, FALSE, $sort);
 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;
 }
 }
 // Allow modules to change the weight of specific implementations, but avoid
 // an infinite loop.
 if ($hook != 'module_implements_alter') {
 // Remember the implementations before hook_module_implements_alter().
 $implementations_before = $implementations[$hook];
 drupal_alter ('module_implements', $implementations[$hook], $hook);
 // Verify implementations that were added or modified.
 foreach (array_diff_assoc ($implementations[$hook], $implementations_before) as $module => $group) {
 // If drupal_alter('module_implements') changed or added a $group, the
 // respective file needs to be included.
 if ($group) {
 module_load_include ('inc', $module, "{$module}.{$group}");
 }
 // If a new implementation was added, verify that the function exists.
 if (!function_exists ($module . '_' . $hook)) {
 unset($implementations[$hook][$module]);
 }
 }
 }
 // Implementations for this hook are now "verified".
 $verified[$hook] = TRUE;
 }
 elseif (!isset($verified[$hook])) {
 // Implementations for this hook were in the cache, but they are not
 // "verified" yet.
 foreach ($implementations[$hook] as $module => $group) {
 // If this hook implementation is stored in a lazy-loaded file, so include
 // that file first.
 if ($group) {
 module_load_include ('inc', $module, "{$module}.{$group}");
 }
 // It is possible that a module removed a hook implementation without the
 // implementations cache being rebuilt yet, so we check whether the
 // function exists on each request to avoid undefined function errors.
 // Since module_hook() may needlessly try to load the include file again,
 // function_exists() is used directly here.
 if (!function_exists ($module . '_' . $hook)) {
 // Clear out the stale implementation from the cache and force a cache
 // refresh to forget about no longer existing hook implementations.
 unset($implementations[$hook][$module]);
 $implementations['#write_cache'] = TRUE;
 }
 }
 $verified[$hook] = TRUE;
 }
 return array_keys ($implementations[$hook]);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.