You are here

function skinr_implements_api in Skinr 8.2

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

Returns a list of extensions that implement this API version of Skinr.

Return value

An associative array whose keys are system names of extensions and whose values are again associative arrays containing:

  • type: Either 'module' or 'theme'.
  • name: The system name of the extension.
  • path: The path to the extension.
  • directory: (optional) The sub-directory holding Skinr plugin files.
  • ...: Any other properties defined by the module or theme.
7 calls to skinr_implements_api()
DefaultController::skinr_test_skinr_implements_api in tests/modules/skinr_test/src/Controller/DefaultController.php
SkinrApiTest::testSkinrImplementsAPI in src/Tests/SkinrApiTest.php
Tests skinr_implements().
SkinrApiTestCase::testSkinrImplementsAPI in src/Tests/skinr.test
Tests skinr_implements().
skinr_hook in ./skinr.module
Determine whether a module implements a hook.
skinr_implements in ./skinr.module
Determine which modules are implementing a hook.

... See full list

1 string reference to 'skinr_implements_api'
skinr_cache_reset in ./skinr.module
Clears cached Skinr information.

File

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

Code

function skinr_implements_api() {

  // All themes are disabled while running update script so theme skins are not
  // cached. Don't cache to prevent this.
  if (defined('MAINTENANCE_MODE')) {
    return array();
  }
  $cache =& drupal_static(__FUNCTION__);
  if (!isset($cache)) {
    if ($cached = \Drupal::cache()
      ->get('skinr_implements_api')) {
      $cache = $cached->data;
      return $cache;
    }
    $cache = array();

    // Collect hook_skinr_api_VERSION() module implementations. This will also
    // auto-load $module.skinr.inc files, which may contain skin/group hook
    // implementations (when not using the plugin system).
    $module_info = system_get_info('module');
    foreach (\Drupal::moduleHandler()
      ->getImplementations('skinr_api_' . SKINR_VERSION) as $module) {

      // Ensure that $module and the extension type is registered.
      $cache[$module] = array(
        'type' => 'module',
        'name' => $module,
        'version' => isset($module_info[$module]['version']) ? $module_info[$module]['version'] : NULL,
      );

      // Check whether the hook returns any information.
      $function = $module . '_skinr_api_' . SKINR_VERSION;
      $info = $function();
      if (isset($info) && is_array($info)) {
        $cache[$module] += $info;
      }

      // If the module specified a custom path, check whether it contains a
      // $module.skinr.inc file and auto-load it.
      // ModuleHandler::getImplementations() only auto-loads $module.skinr.inc
      // in a module's root folder.
      if (isset($cache[$module]['path'])) {
        $file = $cache[$module]['path'] . '/' . $module . '.skinr.inc';
        if (file_exists(DRUPAL_ROOT . '/' . $file)) {
          $cache[$module]['include file'] = $file;
        }
      }
      else {

        // If there is a $module.skinr.inc in the module's root, it gets
        // auto-loaded for any hooks. But if a skin defined thering contains a
        // custom 'form callback' function, we'll need to load it manually. So
        // store the file's info.
        $file = drupal_get_path('module', $module) . '/' . $module . '.skinr.inc';
        if (file_exists(DRUPAL_ROOT . '/' . $file)) {
          $cache[$module]['include file'] = $file;
        }
      }

      // Populate defaults.
      $cache[$module] += array(
        'path' => drupal_get_path('module', $module),
        'directory' => NULL,
      );
    }

    // Collect the equivalent of hook_skinr_api_VERSION() implementations in
    // themes. The theme system only initializes one theme (and optionally its
    // base themes) for the current request, and the phptemplate engine only
    // loads template.php during theme initialization. Furthermore, template.php
    // is a custom concept of the phptemplate engine and does not exist for
    // other theme engines. Since we are interested in all existing
    // implementations of all enabled themes, the equivalent of the module hook
    // is a theme .info file property 'skinr' that has the sub-keys 'api' and
    // optionally 'directory' defined.
    // Account for all enabled themes and (any recursive) base themes of them,
    // regardless of whether base themes are enabled.
    $theme_handler = \Drupal::service('theme_handler');
    $all_themes = $theme_handler
      ->listInfo();
    $themes = array();

    // Additionally record the base themes and sub themes of each theme, in
    // order to apply inheritance rules elsewhere. Do not assign these variables
    // as properties on the theme objects themselves, since all objects are
    // pointers (much like references) in PHP 5, so our properties would be
    // visible for everyone else who calls
    // \Drupal::service('theme_handler')->listInfo().
    $base_themes = array();
    $sub_themes = array();
    foreach ($all_themes as $name => $theme) {

      // If the theme is enabled, add it to the stack.
      if (!empty($theme->status)) {
        $themes[$name] = $theme;

        // Find and add all base themes of the enabled theme to the stack.
        // @see drupal_theme_initialize()
        // @see \Drupal::theme()->getActiveTheme()
        $sub_theme_name = $name;
        while ($name && isset($all_themes[$name]->base_theme)) {

          // Record the sub theme for the base theme.
          $sub_themes[$all_themes[$name]->base_theme][$name] = $name;

          // Add the base theme to the stack.
          $name = $all_themes[$name]->base_theme;
          $themes[$name] = $all_themes[$name];

          // Record the base theme for the original sub theme.
          $base_themes[$sub_theme_name][$name] = $name;
        }
      }
    }
    foreach ($themes as $name => $theme) {
      if (isset($theme->info['skinr']['api']) && $theme->info['skinr']['api'] == SKINR_VERSION) {

        // Ensure that the theme name and the extension type is registered.
        $cache[$name] = array(
          'type' => 'theme',
          'name' => $name,
          'version' => isset($theme->info['version']) ? $theme->info['version'] : NULL,
          'base themes' => isset($base_themes[$name]) ? $base_themes[$name] : array(),
          'sub themes' => isset($sub_themes[$name]) ? $sub_themes[$name] : array(),
        );

        // Add any additional information that has been registered.
        $cache[$name] += $theme->info['skinr'];

        // Populate defaults.
        $cache[$name] += array(
          'path' => drupal_get_path('theme', $name),
          // Since themes cannot do anything else than registering skins and
          // groups, we default to the sub-directory 'skins'.
          'directory' => 'skins',
        );

        // Lastly, for API consistency with modules, check whether the theme
        // contains a $theme.skinr.inc file and auto-load it, if any.
        $file = $cache[$name]['path'] . '/' . $name . '.skinr.inc';
        if (file_exists(DRUPAL_ROOT . '/' . $file)) {
          $cache[$name]['include file'] = $file;
        }
      }
    }
    \Drupal::cache()
      ->set('skinr_implements_api', $cache);
  }
  return $cache;
}