You are here

class PluginTypeManager in Plugin 8.2

Provides a plugin type manager.

Hierarchy

Expanded class hierarchy of PluginTypeManager

1 file declares its use of PluginTypeManager
PluginTypeManagerTest.php in tests/src/Unit/PluginType/PluginTypeManagerTest.php
1 string reference to 'PluginTypeManager'
plugin.services.yml in ./plugin.services.yml
plugin.services.yml
1 service uses PluginTypeManager
plugin.plugin_type_manager in ./plugin.services.yml
Drupal\plugin\PluginType\PluginTypeManager

File

src/PluginType/PluginTypeManager.php, line 14

Namespace

Drupal\plugin\PluginType
View source
class PluginTypeManager implements PluginTypeManagerInterface {

  /**
   * The service container.
   *
   * @var \Symfony\Component\DependencyInjection\ContainerInterface
   */
  protected $container;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The known plugin types.
   *
   * @var \Drupal\plugin\PluginType\PluginTypeInterface[]|null
   *   An array of plugin types or NULL if plugin type discovery has not been
   *   executed yet.
   */
  protected $pluginTypes;

  /**
   * Creates a new instance.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The service container.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(ContainerInterface $container, ModuleHandlerInterface $module_handler) {
    $this->container = $container;
    $this->moduleHandler = $module_handler;
  }

  /**
   * {@inheritdoc}
   */
  public function hasPluginType($id) {
    return isset($this
      ->getPluginTypes()[$id]);
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginType($id) {
    $plugin_types = $this
      ->getPluginTypes();
    if (isset($plugin_types[$id])) {
      return $plugin_types[$id];
    }
    else {
      throw new \InvalidArgumentException(sprintf('Plugin type "%s" is unknown.', $id));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginTypes() {

    // Return immediately if all data is available in the static cache.
    if (is_array($this->pluginTypes)) {
      return $this->pluginTypes;
    }
    $this->pluginTypes = [];

    // List the available plugin type providers.
    $providers = array_map(function (Extension $module) {
      return $module
        ->getName();
    }, $this->moduleHandler
      ->getModuleList());
    $providers[] = 'core';

    // \Drupal\Component\Discovery\YamlDiscovery::findAll() caches raw file
    // contents, but we want to cache plugin types for better performance.
    $files = $this
      ->findFiles();
    $providers_by_file = array_flip($files);
    $file_cache = FileCacheFactory::get('plugin:plugin_type:' . hash('sha256', serialize($providers)));

    // Try to load from the file cache first.
    foreach ($file_cache
      ->getMultiple($files) as $file => $plugin_types_by_file) {
      $this->pluginTypes = array_merge($this->pluginTypes, $plugin_types_by_file);
      unset($providers_by_file[$file]);
    }

    // If there are files left that were not returned from the cache, load and
    // parse them now. This list was flipped above and is keyed by filename.
    foreach ($providers_by_file as $file => $provider) {

      // If a file is empty or its contents are commented out, return an empty
      // array instead of NULL for type consistency.
      $plugin_type_definitions = Yaml::decode(file_get_contents($file)) ?: [];

      // Set the plugin type definitions' default values.
      $plugin_type_definition_defaults = [
        'class' => PluginType::class,
        'provider' => $provider,
      ];
      $plugin_type_definitions = array_map(function ($plugin_type_id, array $plugin_type_definition) use ($plugin_type_definition_defaults) {
        $plugin_type_definition['id'] = $plugin_type_id;
        return $plugin_type_definition + $plugin_type_definition_defaults;
      }, array_keys($plugin_type_definitions), $plugin_type_definitions);

      // Remove definitions from uninstalled providers.
      $plugin_type_definitions = array_filter($plugin_type_definitions, function (array $plugin_type_definition) use ($providers) {
        return in_array($plugin_type_definition['provider'], $providers);
      });

      // Create plugin types from their definitions.
      $file_plugin_types = [];
      foreach ($plugin_type_definitions as $plugin_type_definition) {

        /** @var \Drupal\plugin\PluginType\PluginTypeInterface $class */
        $class = $plugin_type_definition['class'];
        $plugin_type = $class::createFromDefinition($this->container, $plugin_type_definition);
        $file_plugin_types[$plugin_type
          ->getId()] = $plugin_type;
      }

      // Store the plugin types in the static and file caches.
      $this->pluginTypes += $file_plugin_types;
      $file_cache
        ->set($file, $file_plugin_types);
    }
    return $this->pluginTypes;
  }

  /**
   * Returns an array of file paths, keyed by provider.
   *
   * @return string[]
   */
  protected function findFiles() {
    $files = [];
    foreach ($this->moduleHandler
      ->getModuleDirectories() as $provider => $directory) {
      $file = $directory . '/' . $provider . '.plugin_type.yml';
      if (file_exists($file)) {
        $files[$provider] = $file;
      }
    }
    return $files;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PluginTypeManager::$container protected property The service container.
PluginTypeManager::$moduleHandler protected property The module handler.
PluginTypeManager::$pluginTypes protected property The known plugin types.
PluginTypeManager::findFiles protected function Returns an array of file paths, keyed by provider.
PluginTypeManager::getPluginType public function Gets a known plugin type. Overrides PluginTypeManagerInterface::getPluginType
PluginTypeManager::getPluginTypes public function Gets the known plugin types. Overrides PluginTypeManagerInterface::getPluginTypes
PluginTypeManager::hasPluginType public function Checks whether a plugin type is known. Overrides PluginTypeManagerInterface::hasPluginType
PluginTypeManager::__construct public function Creates a new instance.