diff --git a/core/lib/Drupal/Core/Extension/ExtensionList.php b/core/lib/Drupal/Core/Extension/ExtensionList.php index e50cda5..fee4048 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ExtensionList.php @@ -91,6 +91,13 @@ protected $addedFileNames = []; /** + * Static version of the added file names during the installer. + * + * @var string + */ + protected static $staticAddedFileNames; + + /** * The state. * * @var \Drupal\Core\State\StateInterface @@ -140,7 +147,15 @@ public function reset() { $this->extensionInfo = NULL; $this->cache->delete($this->getInfoCacheId()); $this->fileNames = NULL; - $this->state->delete($this->getFilenameCacheId()); + + try { + $this->state->delete($this->getFilenameCacheId()); + } + catch (\Exception $e) { + // Ignore exceptions caused by a non existing {key_value} table in the + // early installer. + } + $this->cache->delete($this->getFilenameCacheId()); // We explicitly don't reset the addedFileNames as its sort of a static // cache. @@ -442,9 +457,19 @@ protected function recalculateFilenames() { * than by consulting the dynamic extension listing. * * @internal + * + * @see ::getFilename */ public function setFilename($extension_name, $filename) { $this->addedFileNames[$extension_name] = $filename; + + // In the early installer the container is rebuilt multiple times. Therefore + // we have to keep the added filenames across those rebuilds. This is not a + // final design, but rather just a workaround resolved at some point, + // hopefully. + if (!empty($GLOBALS['install_state'])) { + static::$staticAddedFileNames[$extension_name] = $filename; + } } /** @@ -489,7 +514,10 @@ public function getFilename($extension_name) { elseif (isset($this->fileNames[$extension_name])) { return $this->fileNames[$extension_name]; } - elseif ($file_names = $this->getFilenames() && isset($file_names[$extension_name])) { + elseif (isset(static::$staticAddedFileNames[$extension_name])) { + return static::$staticAddedFileNames[$extension_name]; + } + elseif (($file_names = $this->getFilenames()) && isset($file_names[$extension_name])) { return $file_names[$extension_name]; } throw new \InvalidArgumentException("The {$this->type} $extension_name does not exist."); diff --git a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php index 7be828a..7d30840 100644 --- a/core/lib/Drupal/Core/Extension/ModuleExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ModuleExtensionList.php @@ -73,32 +73,44 @@ protected function getExtensionDiscovery() { $discovery = parent::getExtensionDiscovery(); if ($active_profile = $this->getActiveProfile()) { - // First, find profiles. - $discovery = new ExtensionDiscovery($this->root); - $discovery->setProfileDirectories([]); - $all_profiles = $discovery->scan('profile'); - $profiles = array_intersect_key($all_profiles, $this->configFactory->get('core.extension')->get('module') ?: [$active_profile->getName() => 0]); - - // 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->configFactory->get('simpletest.settings')->get(); - $parent_profile = !empty($settings['parent_profile']) ? $settings['parent_profile'] : NULL; - if ($parent_profile && !isset($profiles[$parent_profile])) { - // In case both profile directories contain the same extension, the - // actual profile always has precedence. - $profiles = [$parent_profile => $all_profiles[$parent_profile]] + $profiles; - } - - $profile_directories = array_map(function (Extension $profile) { - return $profile->getPath(); - }, $profiles); - $discovery->setProfileDirectories($profile_directories); + $discovery->setProfileDirectories($this->getProfileDirectories($discovery)); } return $discovery; } /** + * Finds all installation profile paths. + * + * @param \Drupal\Core\Extension\ExtensionDiscovery $discovery + * The extension discovery. + * + * @return array + * Paths to all installation profiles. + */ + protected function getProfileDirectories(ExtensionDiscovery $discovery) { + $discovery->setProfileDirectories([]); + $all_profiles = $discovery->scan('profile'); + $profiles = array_intersect_key($all_profiles, $this->configFactory->get('core.extension')->get('module') ?: [$active_profile->getName() => 0]); + + // 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->configFactory->get('simpletest.settings')->get(); + $parent_profile = !empty($settings['parent_profile']) ? $settings['parent_profile'] : NULL; + + if ($parent_profile && !isset($profiles[$parent_profile])) { + // In case both profile directories contain the same extension, the + // actual profile always has precedence. + $profiles = [$parent_profile => $all_profiles[$parent_profile]] + $profiles; + } + + $profile_directories = array_map(function (Extension $profile) { + return $profile->getPath(); + }, $profiles); + return $profile_directories; + } + + /** * Gets the processed active profile object, or null. * * @return \Drupal\Core\Extension\Extension|null diff --git a/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php b/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php index c65dac9..77f24c1 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ExtensionListTest.php @@ -253,9 +253,7 @@ protected function getInstalledExtensionsNames() { * {@inheritdoc} */ protected function getExtensionDiscovery() { - return NULL !== $this->extensionDiscovery - ? $this->extensionDiscovery - : parent::getExtensionDiscovery(); + return $this->extensionDiscovery ?: parent::getExtensionDiscovery(); } }