You are here

function skinr_implements in Skinr 7.2

Same name and namespace in other branches
  1. 8.2 skinr.module \skinr_implements()

Determine which modules are implementing a hook.

Replacement for module_implements() that only invokes modules that implement the current version of Skinr API. It also supports $module.skinr.inc files in themes and custom paths.

Parameters

$hook: The name of the hook (e.g. "skinr_skin_info" or "skinr_theme_hooks").

Return value

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

See also

skinr_exit()

2 calls to skinr_implements()
SkinrApiTestCase::testSkinrImplements in tests/skinr.test
Test module_implements().
skinr_invoke_all in ./skinr.module
Invoke a hook in all enabled modules and themes that implement it.
2 string references to 'skinr_implements'
SkinrApiTestCase::testSkinrImplements in tests/skinr.test
Test module_implements().
skinr_exit in ./skinr.module
Implements hook_exit().

File

./skinr.module, line 424
Handles core Skinr functionality.

Code

function skinr_implements($hook) {
  $implementations =& drupal_static(__FUNCTION__, array());

  // Fetch implementations from cache.
  if (empty($implementations)) {
    $implementations = cache_get('skinr_implements', 'cache_bootstrap');
    if ($implementations === FALSE) {
      $implementations = array();
    }
    else {
      $implementations = $implementations->data;
    }
  }
  if (!isset($implementations[$hook])) {
    $implementations['#write_cache'] = TRUE;
    $extensions = skinr_implements_api();
    $implementations[$hook] = array();
    foreach ($extensions as $module => $extension) {
      if (isset($extension['include file'])) {

        // The module specified a custom path. module_implements() and
        // module_hook() only auto-load $module.skinr.inc in a module's
        // root folder.
        $include_file = skinr_load_include($extension['include file']);
        if (function_exists($module . '_' . $hook)) {
          $implementations[$hook][$module] = $include_file ? $extension['include file'] : FALSE;
        }
      }
      else {

        // Run through module_hook() to auto-load $module.skinr.inc from a
        // non-custom path.
        if (module_hook($module, $hook)) {
          $implementations[$hook][$module] = FALSE;
        }
      }
    }

    // Allow modules to change the weight of specific implementations but avoid
    // an infinite loop.
    if ($hook != 'skinr_implements_alter') {
      drupal_alter('skinr_implements', $implementations[$hook], $hook);
    }
  }
  else {
    foreach ($implementations[$hook] as $module => $file) {
      if ($file) {
        skinr_load_include($file);
      }
      else {
        module_hook($module, $hook);
      }

      // 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;
      }
    }
  }
  return array_keys($implementations[$hook]);
}