You are here

public function ExtensionDiscovery::scan in Zircon Profile 8.0

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Extension/ExtensionDiscovery.php \Drupal\Core\Extension\ExtensionDiscovery::scan()

Discovers available extensions of a given type.

Finds all extensions (modules, themes, etc) that exist on the site. It searches in several locations. For instance, to discover all available modules:

$listing = new ExtensionDiscovery(\Drupal::root());
$modules = $listing
  ->scan('module');

The following directories will be searched (in the order stated):

  • the core directory; i.e., /core
  • the installation profile directory; e.g., /core/profiles/standard
  • the legacy site-wide directory; i.e., /sites/all
  • the site-wide directory; i.e., /
  • the site-specific directory; e.g., /sites/example.com

The information is returned in an associative array, keyed by the extension name (without .info.yml extension). Extensions found later in the search will take precedence over extensions found earlier - unless they are not compatible with the current version of Drupal core.

Parameters

string $type: The extension type to search for. One of 'profile', 'module', 'theme', or 'theme_engine'.

bool $include_tests: (optional) Whether to explicitly include or exclude test extensions. By default, test extensions are only discovered when in a test environment.

Return value

\Drupal\Core\Extension\Extension[] An associative array of Extension objects, keyed by extension name.

File

core/lib/Drupal/Core/Extension/ExtensionDiscovery.php, line 152
Contains \Drupal\Core\Extension\ExtensionDiscovery.

Class

ExtensionDiscovery
Discovers available extensions in the filesystem.

Namespace

Drupal\Core\Extension

Code

public function scan($type, $include_tests = NULL) {

  // Determine the installation profile directories to scan for extensions,
  // unless explicit profile directories have been set. Exclude profiles as we
  // cannot have profiles within profiles.
  if (!isset($this->profileDirectories) && $type != 'profile') {
    $this
      ->setProfileDirectoriesFromSettings();
  }

  // Search the core directory.
  $searchdirs[static::ORIGIN_CORE] = 'core';

  // Search the legacy sites/all directory.
  $searchdirs[static::ORIGIN_SITES_ALL] = 'sites/all';

  // Search for contributed and custom extensions in top-level directories.
  // The scan uses a whitelist to limit recursion to the expected extension
  // type specific directory names only.
  $searchdirs[static::ORIGIN_ROOT] = '';

  // Simpletest uses the regular built-in multi-site functionality of Drupal
  // for running web tests. As a consequence, extensions of the parent site
  // located in a different site-specific directory are not discovered in a
  // test site environment, because the site directories are not the same.
  // Therefore, add the site directory of the parent site to the search paths,
  // so that contained extensions are still discovered.
  // @see \Drupal\simpletest\WebTestBase::setUp()
  if ($parent_site = Settings::get('test_parent_site')) {
    $searchdirs[static::ORIGIN_PARENT_SITE] = $parent_site;
  }

  // Find the site-specific directory to search. Since we are using this
  // method to discover extensions including profiles, we might be doing this
  // at install time. Therefore Kernel service is not always available, but is
  // preferred.
  if (\Drupal::hasService('kernel')) {
    $searchdirs[static::ORIGIN_SITE] = \Drupal::service('site.path');
  }
  else {
    $searchdirs[static::ORIGIN_SITE] = $this->sitePath ?: DrupalKernel::findSitePath(Request::createFromGlobals());
  }

  // Unless an explicit value has been passed, manually check whether we are
  // in a test environment, in which case test extensions must be included.
  // Test extensions can also be included for debugging purposes by setting a
  // variable in settings.php.
  if (!isset($include_tests)) {
    $include_tests = Settings::get('extension_discovery_scan_tests') || drupal_valid_test_ua();
  }
  $files = array();
  foreach ($searchdirs as $dir) {

    // Discover all extensions in the directory, unless we did already.
    if (!isset(static::$files[$dir][$include_tests])) {
      static::$files[$dir][$include_tests] = $this
        ->scanDirectory($dir, $include_tests);
    }

    // Only return extensions of the requested type.
    if (isset(static::$files[$dir][$include_tests][$type])) {
      $files += static::$files[$dir][$include_tests][$type];
    }
  }

  // If applicable, filter out extensions that do not belong to the current
  // installation profiles.
  $files = $this
    ->filterByProfileDirectories($files);

  // Sort the discovered extensions by their originating directories.
  $origin_weights = array_flip($searchdirs);
  $files = $this
    ->sort($files, $origin_weights);

  // Process and return the list of extensions keyed by extension name.
  return $this
    ->process($files);
}