You are here

function ctools_get_plugins in Chaos Tool Suite (ctools) 7

Same name and namespace in other branches
  1. 6 includes/plugins.inc \ctools_get_plugins()

Fetch a group of plugins by name.

Parameters

string $module: The name of the module that utilizes this plugin system. It will be used to get more data about the plugin as defined on hook_ctools_plugin_type().

string $type: The type identifier of the plugin.

string $id: If specified, return only information about plugin with this identifier. The system will do its utmost to load only plugins with this id.

Return value

array An array of information arrays about the plugins received. The contents of the array are specific to the plugin.

25 calls to ctools_get_plugins()
ctools_cache_find_plugin in includes/cache.inc
Take a mechanism and return a plugin and data.
ctools_get_access_plugin in includes/context.inc
Fetch metadata on a specific access control plugin.
ctools_get_access_plugins in includes/context.inc
Fetch metadata for all access control plugins.
ctools_get_argument in includes/context.inc
Fetch metadata for a specific argument plugin.
ctools_get_arguments in includes/context.inc
Fetch metadata for all argument plugins.

... See full list

File

includes/plugins.inc, line 215
Contains routines to organize and load plugins. It allows a special variation of the hook system so that plugins can be kept in separate .inc files, and can be either loaded all at once or loaded only when necessary.

Code

function ctools_get_plugins($module, $type, $id = NULL) {

  // Store local caches of plugins and plugin info so we don't have to do full
  // lookups every time.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['plugins'] =& drupal_static('ctools_plugins', array());
  }
  $plugins =& $drupal_static_fast['plugins'];
  $info = ctools_plugin_get_plugin_type_info();
  if (!isset($info[$module][$type])) {

    // If we don't find the plugin we attempt a cache rebuild before bailing out.
    $info = ctools_plugin_get_plugin_type_info(TRUE);

    // Bail out noisily if an invalid module/type combination is requested.
    if (!isset($info[$module][$type])) {
      watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array(
        '@module' => $module,
        '@type' => $type,
      ), WATCHDOG_ERROR);
      return array();
    }
  }

  // Make sure our plugins array is populated.
  if (!isset($plugins[$module][$type])) {
    $plugins[$module][$type] = array();
  }

  // Attempt to shortcut this whole piece of code if we already have the
  // requested plugin:
  if ($id && array_key_exists($id, $plugins[$module][$type])) {
    return $plugins[$module][$type][$id];
  }

  // Store the status of plugin loading. If a module plugin type pair is true,
  // then it is fully loaded and no searching or setup needs to be done.
  $setup =& drupal_static('ctools_plugin_setup', array());

  // We assume we don't need to build a cache.
  $build_cache = FALSE;

  // If the plugin info says this can be cached, check cache first.
  if ($info[$module][$type]['cache'] && empty($setup[$module][$type])) {
    $cache = cache_get("plugins:{$module}:{$type}", $info[$module][$type]['cache table']);
    if (!empty($cache->data)) {

      // Cache load succeeded so use the cached plugin list.
      $plugins[$module][$type] = $cache->data;

      // Set $setup to true so we know things where loaded.
      $setup[$module][$type] = TRUE;
    }
    else {

      // Cache load failed so store that we need to build and write the cache.
      $build_cache = TRUE;
    }
  }

  // Always load all hooks if we need them. Note we only need them now if the
  // plugin asks for them. We can assume that if we have plugins we've already
  // called the global hook.
  if (!empty($info[$module][$type]['use hooks']) && empty($plugins[$module][$type])) {
    $plugins[$module][$type] = ctools_plugin_load_hooks($info[$module][$type]);
  }

  // Then see if we should load all files. We only do this if we want a list of
  // all plugins or there was a cache miss.
  if (empty($setup[$module][$type]) && ($build_cache || !$id)) {
    $setup[$module][$type] = TRUE;
    $plugins[$module][$type] = array_merge($plugins[$module][$type], ctools_plugin_load_includes($info[$module][$type]));

    // If the plugin can have child plugins, and we're loading all plugins,
    // go through the list of plugins we have and find child plugins.
    if (!$id && !empty($info[$module][$type]['child plugins'])) {

      // If a plugin supports children, go through each plugin and ask.
      $temp = array();
      foreach ($plugins[$module][$type] as $name => $plugin) {

        // The strpos ensures that we don't try to find children for plugins
        // that are already children.
        if (!empty($plugin['get children']) && function_exists($plugin['get children']) && strpos($name, ':') === FALSE) {
          $temp = array_merge($plugin['get children']($plugin, $name), $temp);
        }
        else {
          $temp[$name] = $plugin;
        }
      }
      $plugins[$module][$type] = $temp;
    }
  }

  // If we were told earlier that this is cacheable and the cache was empty,
  // give something back.
  if ($build_cache) {
    cache_set("plugins:{$module}:{$type}", $plugins[$module][$type], $info[$module][$type]['cache table']);
  }

  // If no id was requested, we are finished here:
  if (!$id) {

    // Use array_filter because looking for unknown plugins could cause NULL
    // entries to appear in the list later.
    return array_filter($plugins[$module][$type]);
  }

  // Check to see if we need to look for the file.
  if (!array_key_exists($id, $plugins[$module][$type])) {

    // If we can have child plugins, check to see if the plugin name is in the
    // format of parent:child and break it up if it is.
    if (!empty($info[$module][$type]['child plugins']) && strpos($id, ':') !== FALSE) {
      list($parent, $child) = explode(':', $id, 2);
    }
    else {
      $parent = $id;
    }
    if (!array_key_exists($parent, $plugins[$module][$type])) {
      $result = ctools_plugin_load_includes($info[$module][$type], $parent);

      // Set to either what was returned or NULL.
      $plugins[$module][$type][$parent] = isset($result[$parent]) ? $result[$parent] : NULL;
    }

    // If we are looking for a child, and have the parent, ask the parent for the child.
    if (!empty($child) && !empty($plugins[$module][$type][$parent]) && function_exists($plugins[$module][$type][$parent]['get child'])) {
      $plugins[$module][$type][$id] = $plugins[$module][$type][$parent]['get child']($plugins[$module][$type][$parent], $parent, $child);
    }
  }

  // At this point we should either have the plugin, or a NULL.
  return $plugins[$module][$type][$id];
}