protected function ExtensionDiscovery::scanDirectory

protected ExtensionDiscovery::scanDirectory($dir, $include_tests)

Recursively scans a base directory for the requested extension type.

Parameters

string $dir: A relative base directory path to scan, without trailing slash.

bool $include_tests: Whether to include test extensions. If FALSE, all 'tests' directories are excluded in the search.

Return value

array An associative array whose keys are extension type names and whose values are associative arrays of \Drupal\Core\Extension\Extension objects, keyed by absolute path name.

See also

\Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator

File

core/lib/Drupal/Core/Extension/ExtensionDiscovery.php, line 406

Class

ExtensionDiscovery
Discovers available extensions in the filesystem.

Namespace

Drupal\Core\Extension

Code

protected function scanDirectory($dir, $include_tests) {
  $files = array();

  // In order to scan top-level directories, absolute directory paths have to
  // be used (which also improves performance, since any configured PHP
  // include_paths will not be consulted). Retain the relative originating
  // directory being scanned, so relative paths can be reconstructed below
  // (all paths are expected to be relative to $this->root).
  $dir_prefix = ($dir == '' ? '' : "$dir/");
  $absolute_dir = ($dir == '' ? $this->root : $this->root . "/$dir");

  if (!is_dir($absolute_dir)) {
    return $files;
  }
  // Use Unix paths regardless of platform, skip dot directories, follow
  // symlinks (to allow extensions to be linked from elsewhere), and return
  // the RecursiveDirectoryIterator instance to have access to getSubPath(),
  // since SplFileInfo does not support relative paths.
  $flags = \FilesystemIterator::UNIX_PATHS;
  $flags |= \FilesystemIterator::SKIP_DOTS;
  $flags |= \FilesystemIterator::FOLLOW_SYMLINKS;
  $flags |= \FilesystemIterator::CURRENT_AS_SELF;
  $directory_iterator = new \RecursiveDirectoryIterator($absolute_dir, $flags);

  // Filter the recursive scan to discover extensions only.
  // Important: Without a RecursiveFilterIterator, RecursiveDirectoryIterator
  // would recurse into the entire filesystem directory tree without any kind
  // of limitations.
  $filter = new RecursiveExtensionFilterIterator($directory_iterator);
  $filter->acceptTests($include_tests);

  // The actual recursive filesystem scan is only invoked by instantiating the
  // RecursiveIteratorIterator.
  $iterator = new \RecursiveIteratorIterator($filter, 
  \RecursiveIteratorIterator::LEAVES_ONLY, 
  // Suppress filesystem errors in case a directory cannot be accessed.
  \RecursiveIteratorIterator::CATCH_GET_CHILD
  );

  foreach ($iterator as $key => $fileinfo) {
    // All extension names in Drupal have to be valid PHP function names due
    // to the module hook architecture.
    if (!preg_match(static::PHP_FUNCTION_PATTERN, $fileinfo->getBasename('.info.yml'))) {
      continue;
    }

    if ($this->fileCache && $cached_extension = $this->fileCache->get($fileinfo->getPathName())) {
      $files[$cached_extension->getType()][$key] = $cached_extension;
      continue;
    }

    // Determine extension type from info file.
    $type = FALSE;
    $file = $fileinfo->openFile('r');
    while (!$type && !$file->eof()) {
      preg_match('@^type:\s*(\'|")?(\w+)\1?\s*$@', $file->fgets(), $matches);
      if (isset($matches[2])) {
        $type = $matches[2];
      }
    }
    if (empty($type)) {
      continue;
    }
    $name = $fileinfo->getBasename('.info.yml');
    $pathname = $dir_prefix . $fileinfo->getSubPathname();

    // Determine whether the extension has a main extension file.
    // For theme engines, the file extension is .engine.
    if ($type == 'theme_engine') {
      $filename = $name . '.engine';
    }
    // For profiles/modules/themes, it is the extension type.
    else {
      $filename = $name . '.' . $type;
    }
    if (!file_exists($this->root . '/' . dirname($pathname) . '/' . $filename)) {
      $filename = NULL;
    }

    $extension = new Extension($this->root, $type, $pathname, $filename);

    // Track the originating directory for sorting purposes.
    $extension->subpath = $fileinfo->getSubPath();
    $extension->origin = $dir;

    $files[$type][$key] = $extension;

    if ($this->fileCache) {
      $this->fileCache->set($fileinfo->getPathName(), $extension);
    }
  }
  return $files;
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Extension!ExtensionDiscovery.php/function/ExtensionDiscovery::scanDirectory/8.1.x