class DirectoryWithMetadataDiscovery

Same name in this branch
  1. 10 core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataDiscovery.php \Drupal\sdc\Plugin\Discovery\DirectoryWithMetadataDiscovery
Same name and namespace in other branches
  1. 11.x core/modules/sdc/src/Plugin/Discovery/DirectoryWithMetadataDiscovery.php \Drupal\sdc\Plugin\Discovery\DirectoryWithMetadataDiscovery
  2. 11.x core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataDiscovery.php \Drupal\Core\Plugin\Discovery\DirectoryWithMetadataDiscovery

Does the actual finding of the directories with metadata files.

Hierarchy

Expanded class hierarchy of DirectoryWithMetadataDiscovery

File

core/lib/Drupal/Core/Plugin/Discovery/DirectoryWithMetadataDiscovery.php, line 11

Namespace

Drupal\Core\Plugin\Discovery
View source
class DirectoryWithMetadataDiscovery extends YamlDirectoryDiscovery {
  
  /**
   * Constructs a DirectoryWithMetadataDiscovery object.
   *
   * @param array $directories
   *   An array of directories to scan, keyed by the provider. The value can
   *   either be a string or an array of strings. The string values should be
   *   the path of a directory to scan.
   * @param string $file_cache_key_suffix
   *   The file cache key suffix. This should be unique for each type of
   *   discovery.
   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
   *   The file system service.
   */
  public function __construct(array $directories, string $file_cache_key_suffix, protected FileSystemInterface $fileSystem) {
    parent::__construct($directories, $file_cache_key_suffix);
  }
  
  /**
   * Gets an iterator to loop over the files in the provided directory.
   *
   * This method exists so that it is easy to replace this functionality in a
   * class that extends this one. For example, it could be used to make the scan
   * recursive.
   *
   * @param string $directory
   *   The directory to scan.
   *
   * @return \RecursiveIteratorIterator
   *   A \RecursiveIteratorIterator object or array where the values are
   *   \SplFileInfo objects.
   */
  protected function getDirectoryIterator($directory) : \RecursiveIteratorIterator {
    // Use FilesystemIterator to not iterate over the . and .. directories.
    $flags = \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS;
    $directory_iterator = new \RecursiveDirectoryIterator($directory, $flags);
    // Detect "my_component.component.yml".
    $regex = '/^([a-z0-9_-])+\\.component\\.yml$/i';
    $filter = new RegexRecursiveFilterIterator($directory_iterator, $regex);
    return new \RecursiveIteratorIterator($filter, \RecursiveIteratorIterator::LEAVES_ONLY, $flags);
  }
  
  /**
   * {@inheritdoc}
   *
   * The IDs can collide in two different scenarios:
   *
   * 1. Because one component is overriding another one via "weight".
   * 2. Because the same component exists in different themes.
   */
  protected function getIdentifier($file, array $data) : string {
    $id = $this->fileSystem
      ->basename($file, '.component.yml');
    $provider_paths = array_flip($this->directories);
    $provider = $this->findProvider($file, $provider_paths);
    // We use the provider to dedupe components because it does not make sense
    // for a single provider to fork itself.
    return sprintf('%s:%s', $provider, $id);
  }
  
  /**
   * Finds the provider of the discovered file.
   *
   * The approach here is suboptimal because the provider is actually set in
   * the plugin definition after the getIdentifier is called. So we either do
   * this, or we forego the base class.
   *
   * @param string $file
   *   The discovered file.
   * @param array $provider_paths
   *   The associative array of the path to the provider.
   *
   * @return string
   *   The provider
   */
  private function findProvider(string $file, array $provider_paths) : string {
    $parts = explode(DIRECTORY_SEPARATOR, $file);
    array_pop($parts);
    if (empty($parts)) {
      return '';
    }
    $provider = $provider_paths[implode(DIRECTORY_SEPARATOR, $parts)] ?? '';
    return empty($provider) ? $this->findProvider(implode(DIRECTORY_SEPARATOR, $parts), $provider_paths) : $provider;
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
DirectoryWithMetadataDiscovery::findProvider private function Finds the provider of the discovered file.
DirectoryWithMetadataDiscovery::getDirectoryIterator protected function Gets an iterator to loop over the files in the provided directory. Overrides YamlDirectoryDiscovery::getDirectoryIterator
DirectoryWithMetadataDiscovery::getIdentifier protected function The IDs can collide in two different scenarios: Overrides YamlDirectoryDiscovery::getIdentifier
DirectoryWithMetadataDiscovery::__construct public function Constructs a DirectoryWithMetadataDiscovery object. Overrides YamlDirectoryDiscovery::__construct
YamlDirectoryDiscovery::$directories protected property An array of directories to scan, keyed by the provider.
YamlDirectoryDiscovery::$fileCacheKeySuffix protected property The suffix for the file cache key.
YamlDirectoryDiscovery::$idKey protected property The key contained in the discovered data that identifies it.
YamlDirectoryDiscovery::FILE_KEY constant Defines the key in the discovered data where the file path is stored.
YamlDirectoryDiscovery::findAll public function Returns an array of discoverable items. Overrides DiscoverableInterface::findAll
YamlDirectoryDiscovery::findFiles protected function Returns an array of providers keyed by file path.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.