You are here

function skinr_implements in Skinr 8.2

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

Determine which modules are implementing a hook.

Replacement for ModuleHandler::getImplementations() 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()

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

File

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

Code

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

  // Fetch implementations from cache.
  if (empty($implementations)) {

    // @todo Fix cache bin.
    $implementations = \Drupal::cache('bootstrap')
      ->get('skinr_implements');
    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.
        // ModuleHandler::getImplementations() and
        // ModuleHandler::implementsHook() 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 ModuleHandler::implementsHook() to auto-load
        // $module.skinr.inc from a non-custom path.
        if (\Drupal::moduleHandler()
          ->implementsHook($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::moduleHandler()
        ->alter('skinr_implements', $implementations[$hook], $hook);
    }
  }
  else {
    foreach ($implementations[$hook] as $module => $file) {
      if ($file) {
        skinr_load_include($file);
      }
      else {
        \Drupal::moduleHandler()
          ->implementsHook($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 ModuleHandler::implementsHook() 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]);
}