diff --git a/core/includes/common.inc b/core/includes/common.inc index 966fc36..f9cea6e 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -17,7 +17,6 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Routing\GeneratorNotInitializedException; -use Drupal\Core\SystemListingInfo; use Drupal\Core\Template\Attribute; use Drupal\Core\Render\Element; @@ -3177,19 +3176,6 @@ function drupal_page_set_cache(Response $response, Request $request) { } /** - * This function is kept only for backward compatibility. - * - * @see \Drupal\Core\SystemListing::scan(). - */ -function drupal_system_listing($mask, $directory, $key = 'name') { - // As SystemListing is required to build a dependency injection container - // from scratch and SystemListingInfo only extends SystemLising, this - // class needs to be hardwired. - $listing = new SystemListingInfo(); - return $listing->scan($mask, $directory, $key); -} - -/** * Sets the main page content value for later use. * * Given the nature of the Drupal page handling, this will be called once with diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 8519961..5a4b1eb 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -13,7 +13,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; use Drupal\Core\StringTranslation\Translator\FileTranslation; -use Drupal\Core\SystemListing; +use Drupal\Core\SystemListingInfo; use Drupal\Core\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; @@ -497,7 +497,7 @@ function install_begin_request(&$install_state) { $module_handler->loadAll(); // Add list of all available profiles to the installation state. - $listing = new SystemListing(); + $listing = new SystemListingInfo(); $install_state['profiles'] += $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); // Prime drupal_get_filename()'s static cache. diff --git a/core/includes/install.inc b/core/includes/install.inc index 991136b..1465504 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; +use Drupal\Core\SystemListingInfo; /** * Requirement severity -- Informational message only. @@ -570,8 +571,10 @@ function drupal_verify_profile($install_state) { $info = $install_state['profile_info']; // Get a list of modules that exist in Drupal's assorted subdirectories. + $profile_directories = array(dirname($profile_file)); + $listing = new SystemListingInfo($profile_directories); $present_modules = array(); - foreach (drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules') as $present_module) { + foreach ($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules') as $present_module) { $present_modules[] = $present_module->name; } diff --git a/core/includes/module.inc b/core/includes/module.inc index a208877..ebd0cca 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -5,6 +5,7 @@ * API for loading and interacting with Drupal modules. */ +use Drupal\Core\SystemListingInfo; /** * Builds a list of bootstrap modules and enabled modules and themes. @@ -285,7 +286,8 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE) * Returns an array of modules required by core. */ function drupal_required_modules() { - $files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'modules'); + $listing = new SystemListingInfo(); + $files = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); $required = array(); // An installation profile is required and one must always be loaded. @@ -295,7 +297,11 @@ function drupal_required_modules() { } foreach ($files as $name => $file) { - $info = \Drupal::service('info_parser')->parse($file->uri); + $info_file = dirname($file->uri) . '/' . $file->name . '.info.yml'; + if (!file_exists($info_file)) { + continue; + } + $info = \Drupal::service('info_parser')->parse($info_file); if (!empty($info) && !empty($info['required']) && $info['required']) { $required[] = $name; } diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index eb6ea97..e6ec3dc 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -304,7 +304,7 @@ protected function moduleData($module) { // If a module is within a profile directory but specifies another // profile for testing, it needs to be found in the parent profile. $settings = $this->configStorage->read('simpletest.settings'); - $parent_profile = isset($settings['parent_profile']) ? $settings['parent_profile'] : FALSE; + $parent_profile = !empty($settings['parent_profile']) ? $settings['parent_profile'] : FALSE; if ($parent_profile && !isset($profiles[$parent_profile])) { // In case both profile directories contain the same extension, the // actual profile always has precedence. diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php index 4c8a1ea..bffa9d5 100644 --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -245,7 +245,7 @@ public function reset() { public function rebuildThemeData() { // Find themes. $listing = $this->getSystemListingInfo(); - $themes = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'); + $themes = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes'); // Allow modules to add further themes. if ($module_themes = $this->moduleHandler->invokeAll('system_theme_info')) { foreach ($module_themes as $name => $uri) { @@ -259,7 +259,6 @@ public function rebuildThemeData() { } // Find theme engines. - $listing = $this->getSystemListingInfo(); $engines = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines'); // Set defaults for theme info. diff --git a/core/lib/Drupal/Core/SystemListing.php b/core/lib/Drupal/Core/SystemListing.php index 8034fa0..3c00e62 100644 --- a/core/lib/Drupal/Core/SystemListing.php +++ b/core/lib/Drupal/Core/SystemListing.php @@ -17,21 +17,14 @@ class SystemListing { /** - * Previously discovered files keyed by extension type. - * - * @var array - */ - protected static $files = array(); - - /** - * Previously scanned list of dynamic search directories. + * Previously discovered files keyed by dynamic directory hash and extension type. * * Dynamic directories are the site directory and the installation profile - * directories. + * directories. The hash is a simple concatention of the directory paths. * * @var array */ - protected static $searchDirs = array(); + protected static $files = array(); /** * List of installation profile directories to additionally scan. @@ -110,19 +103,22 @@ function scan($mask, $directory, $key = 'name') { $key = 'uri'; } $config = conf_path(); - $profileDirectories = $this->getProfileDirectories(); - if (isset($profileDirectories[0]) && $profileDirectories[0] === '') { - throw new \RuntimeException('drupal_get_profile() can return an empty string. Please adjust your code.'); + $profileDirectories = array(); + if ($directory != 'profiles') { + $profileDirectories = $this->getProfileDirectories(); + + if (isset($profileDirectories[0]) && $profileDirectories[0] === '') { + throw new \RuntimeException('drupal_get_profile() can return an empty string. Please adjust your code.'); + } } // Check static cache. // The static cache is valid unless the dynamic directories have changed. - $dynamic_dirs = array($config => $config) + $profileDirectories; - if ($dynamic_dirs == static::$searchDirs && isset(static::$files[$directory][$mask])) { - return static::$files[$directory][$mask]; + $dynamic_dirs_hash = implode('|', array($config => $config) + $profileDirectories); + if (isset(static::$files[$dynamic_dirs_hash][$directory])) { + return static::$files[$dynamic_dirs_hash][$directory]; } - static::$searchDirs = $dynamic_dirs; // Search for the directory in core. $searchdir = array('core/' . $directory); @@ -147,7 +143,7 @@ function scan($mask, $directory, $key = 'name') { foreach ($searchdir as $dir) { $files = array_merge($files, $this->process($files, $this->scanDirectory($dir, $key, $mask, $nomask))); } - static::$files[$directory][$mask] = $files; + static::$files[$dynamic_dirs_hash][$directory] = $files; return $files; } diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php index c940422..b4a9672 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestInstallStorage.php @@ -8,6 +8,7 @@ namespace Drupal\config_test; use Drupal\Core\Config\InstallStorage; +use Drupal\Core\SystemListingInfo; /** * Tests configuration of profiles, modules and themes. @@ -22,9 +23,10 @@ class TestInstallStorage extends InstallStorage { */ protected function getAllFolders() { if (!isset($this->folders)) { - $this->folders = $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); - $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0))); - $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'))); + $listing = new SystemListingInfo(); + $this->folders = $this->getComponentNames('profile', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); + $this->folders += $this->getComponentNames('module', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'))); + $this->folders += $this->getComponentNames('theme', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes'))); } return $this->folders; } diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php index 8d240b0..efe56d7 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/TestSchemaStorage.php @@ -8,6 +8,7 @@ namespace Drupal\config_test; use Drupal\Core\Config\Schema\SchemaStorage; +use Drupal\Core\SystemListingInfo; /** * Tests configuration schemas of profiles, modules and themes. @@ -29,10 +30,11 @@ public function __construct() { */ protected function getAllFolders() { if (!isset($this->folders)) { + $listing = new SystemListingInfo(); $this->folders = $this->getBaseDataTypeSchema(); - $this->folders += $this->getComponentNames('profile', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); - $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0))); - $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'))); + $this->folders += $this->getComponentNames('profile', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'))); + $this->folders += $this->getComponentNames('module', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'))); + $this->folders += $this->getComponentNames('theme', array_keys($listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes'))); } return $this->folders; } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index b284941..be6d457 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -777,7 +777,7 @@ protected function setUp() { // Set 'parent_profile' of simpletest to add the parent profile's // search path to the child site's search paths. - // @see drupal_system_listing() + // @see \Drupal\Core\SystemListingInfo::getProfileDirectories() \Drupal::config('simpletest.settings')->set('parent_profile', $this->originalProfile)->save(); // Collect modules to install. diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index c6b53bf..4670493 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -2,6 +2,7 @@ use Drupal\Core\Database\Database; use Drupal\Core\Page\HtmlPage; +use Drupal\Core\SystemListingInfo; use Drupal\simpletest\TestBase; use Symfony\Component\Process\PhpExecutableFinder; @@ -464,7 +465,8 @@ function simpletest_test_get_all($module = NULL) { $classes = array(); $module_data = system_rebuild_module_data(); $all_data = $module_data + system_rebuild_theme_data(); - $all_data += drupal_system_listing('/\.profile$/', 'profiles', 'name'); + $listing = new SystemListingInfo(); + $all_data += $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); // If module is set then we keep only that one module. if (isset($module)) { $all_data = array( @@ -550,14 +552,15 @@ function simpletest_classloader_register() { $types = array( 'theme_engine' => array('dir' => 'themes/engines', 'extension' => 'engine'), 'module' => array('dir' => 'modules', 'extension' => 'module'), - 'theme' => array('dir' => 'themes', 'extension' => 'info'), + 'theme' => array('dir' => 'themes', 'extension' => 'info\.yml'), 'profile' => array('dir' => 'profiles', 'extension' => 'profile'), ); $classloader = drupal_classloader(); + $listing = new SystemListingInfo(); foreach ($types as $type => $info) { - $matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']); + $matches = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']); foreach ($matches as $name => $file) { drupal_classloader_register($name, dirname($file->uri)); $classloader->add('Drupal\\' . $name . '\\Tests', DRUPAL_ROOT . '/' . dirname($file->uri) . '/tests'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php index ee1f12b..4b2306d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Common; +use Drupal\Core\SystemListingInfo; use Drupal\simpletest\WebTestBase; /** @@ -55,7 +56,8 @@ function testDirectoryPrecedence() { // Now scan the directories and check that the files take precedence as // expected. - $files = drupal_system_listing('/\.module$/', 'modules'); + $listing = new SystemListingInfo(); + $files = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); foreach ($expected_directories as $module => $directories) { $expected_directory = array_shift($directories); $expected_filename = "$expected_directory/$module/$module.module"; diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 2c9f63a..62c2126 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -8,6 +8,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Language\Language; +use Drupal\Core\SystemListingInfo; use Drupal\Core\Utility\ModuleInfo; use Drupal\menu_link\MenuLinkInterface; use Drupal\user\UserInterface; @@ -2579,11 +2580,12 @@ function system_get_module_info($property) { * An associative array of module information. */ function _system_rebuild_module_data() { + $listing = new SystemListingInfo(); // Find modules - $modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); + $modules = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules'); // Find installation profiles. - $profiles = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); + $profiles = $listing->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles'); // Include the installation profile in modules that are loaded. if ($profile = drupal_get_profile()) { diff --git a/core/modules/update/update.module b/core/modules/update/update.module index adf6ba3..7a227bb 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -629,7 +629,7 @@ function theme_update_last_check($variables) { * an .info.yml file which claims that the code is compatible with the current * version of Drupal core. * - * @see drupal_system_listing() + * @see \Drupal\Core\SystemListingInfo::process() * @see _system_rebuild_module_data() */ function update_verify_update_archive($project, $archive_file, $directory) {