diff --git a/core/core.services.yml b/core/core.services.yml index 59d17aa..6dd5b16 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -482,10 +482,10 @@ services: lazy: true extension.list.module: class: Drupal\Core\Extension\ModuleExtensionList - arguments: ['@app.root', 'module', '@cache.default', '@info_parser', '@module_handler', '@config.factory', '@extension.list.profile'] + arguments: ['@app.root', 'module', '@cache.default', '@info_parser', '@module_handler', '@state', '@config.factory', '@extension.list.profile'] extension.list.profile: class: Drupal\Core\Extension\ProfileExtensionList - arguments: ['@app.root', 'profile', '@cache.default', '@info_parser', '@module_handler'] + arguments: ['@app.root', 'profile', '@cache.default', '@info_parser', '@module_handler', '@state'] content_uninstall_validator: class: Drupal\Core\Entity\ContentUninstallValidator tags: diff --git a/core/lib/Drupal/Core/Extension/ExtensionList.php b/core/lib/Drupal/Core/Extension/ExtensionList.php index 7797cfd..05338c6 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ExtensionList.php @@ -3,6 +3,7 @@ namespace Drupal\Core\Extension; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\State\StateInterface; /** * Provides available extensions. @@ -90,6 +91,13 @@ protected $addedFileNames = []; /** + * The state. + * + * @var \Drupal\Core\State\StateInterface + */ + protected $state; + + /** * Constructs a new instance. * * @param string $root @@ -102,13 +110,16 @@ * The info parser. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. + * @param \Drupal\Core\State\StateInterface $state + * The state. */ - public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler) { + public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler, StateInterface $state) { $this->root = $root; $this->type = $type; $this->cache = $cache; $this->infoParser = $info_parser; $this->moduleHandler = $module_handler; + $this->state = $state; } /** @@ -129,6 +140,7 @@ public function reset() { $this->extensionInfo = NULL; $this->cache->delete($this->getInfoCacheId()); $this->fileNames = NULL; + $this->state->delete($this->getFilenameCacheId()); $this->cache->delete($this->getFilenameCacheId()); $this->addedFileNames = []; return $this; @@ -380,8 +392,13 @@ public function getFilenames() { if ($cache = $this->cache->get($cache_id)) { $file_names = $cache->data; } + elseif ($file_names = $this->state->get($this->getFilenameCacheId())) { + } else { $file_names = $this->recalculateFilenames(); + // Store filenames to allow drupal_get_filename() to retrieve them without + // having to rebuild or scan the filesystem. + $this->state->set($cache, $file_names); $this->cache->set($cache_id, $file_names); } $this->fileNames = $file_names; diff --git a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php index 454d1f9..20c4cfa 100644 --- a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php @@ -4,6 +4,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\State\StateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; /** @@ -51,13 +52,15 @@ class ModuleExtensionList extends ExtensionList { * The info parser. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. + * @param \Drupal\Core\State\StateInterface $state + * The state. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. * @param \Drupal\Core\Extension\ExtensionList $profile_list * The site profile listing. */ - public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, ExtensionList $profile_list) { - parent::__construct($root, $type, $cache, $info_parser, $module_handler); + public function __construct($root, $type, CacheBackendInterface $cache, InfoParserInterface $info_parser, ModuleHandlerInterface $module_handler, StateInterface $state, ConfigFactoryInterface $config_factory, ExtensionList $profile_list) { + parent::__construct($root, $type, $cache, $info_parser, $module_handler, $state); $this->configFactory = $config_factory; $this->profileList = $profile_list; diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php index a083805..a2e38f8 100644 --- a/core/modules/simpletest/src/KernelTestBase.php +++ b/core/modules/simpletest/src/KernelTestBase.php @@ -100,7 +100,7 @@ function __construct($test_id = NULL) { protected function beforePrepareEnvironment() { // Copy/prime extension file lists once to avoid filesystem scans. if (!isset($this->moduleFiles)) { - $this->moduleFiles = \Drupal::cache('default')->get('system.module.files') ?: array(); + $this->moduleFiles = \Drupal::state()->get('system.module.files') ?: array(); $this->themeFiles = \Drupal::state()->get('system.theme.files') ?: array(); } } diff --git a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php index 2c92f74..d0396a4 100644 --- a/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php +++ b/core/modules/system/src/Tests/Bootstrap/GetFilenameUnitTest.php @@ -20,7 +20,7 @@ function testDrupalGetFilename() { global $install_state; $install_state['parameters']['profile'] = 'testing'; - // Rebuild system.module.files state data. + // Rebuild the filename data. system_rebuild_module_data(); // Retrieving the location of a module. diff --git a/core/modules/system/system.module b/core/modules/system/system.module index e8acdb7..b8aa83c 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -915,11 +915,13 @@ function system_check_directory($form_element, FormStateInterface $form_state) { */ function system_get_info($type, $name = NULL) { if ($type == 'module') { + /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */ + $module_list = \Drupal::service('extension.list.module'); if (isset($name)) { - return \Drupal::service('extension.list.module')->getInfo($name); + return $module_list->getExtensionInfo($name); } else { - return \Drupal::service('extension.list.module')->getAllInfo(); + return $module_list->getAllInstalledInfo(); } } else { diff --git a/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php b/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php index a90e91c..c65dac9 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Extension\ExtensionList; use Drupal\Core\Extension\InfoParserInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\State\StateInterface; use Drupal\Tests\UnitTestCase; use org\bovigo\vfs\vfsStream; use Prophecy\Argument; @@ -24,8 +25,8 @@ class ExtensionListTest extends UnitTestCase { * @expectedException \InvalidArgumentException */ public function testGetNameWithNonExistingExtension() { - list($cache, $info_parser, $module_handler) = $this->getMocks(); - $test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal()); + list($cache, $info_parser, $module_handler, $state) = $this->getMocks(); + $test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal()); $extension_discovery = $this->prophesize(ExtensionDiscovery::class); $extension_discovery->scan('test_extension')->willReturn([]); @@ -48,8 +49,8 @@ public function testGetName() { * @expectedException \InvalidArgumentException */ public function testGetExtensionWithNonExistingExtension() { - list($cache, $info_parser, $module_handler) = $this->getMocks(); - $test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal()); + list($cache, $info_parser, $module_handler, $state) = $this->getMocks(); + $test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal()); $extension_discovery = $this->prophesize(ExtensionDiscovery::class); $extension_discovery->scan('test_extension')->willReturn([]); @@ -191,12 +192,12 @@ protected function setupTestExtensionList($extension_names = ['test_name']) { touch("vfs://drupal_root/example/$extension_name/$extension_name.info.yml", 123456789); } - list($cache, $info_parser, $module_handler) = $this->getMocks(); + list($cache, $info_parser, $module_handler, $state) = $this->getMocks(); $info_parser->parse(Argument::any())->will(function($args) { return Yaml::decode(file_get_contents($args[0])); }); - $test_extension_list = new TestExtension('vfs://drupal_root', 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal()); + $test_extension_list = new TestExtension('vfs://drupal_root', 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal()); $extension_discovery = $this->prophesize(ExtensionDiscovery::class); $extension_scan_result = []; @@ -212,7 +213,8 @@ protected function getMocks() { $cache = $this->prophesize(CacheBackendInterface::class); $info_parser = $this->prophesize(InfoParserInterface::class); $module_handler = $this->prophesize(ModuleHandlerInterface::class); - return [$cache, $info_parser, $module_handler]; + $state = $this->prophesize(StateInterface::class); + return [$cache, $info_parser, $module_handler, $state]; } }