diff -u b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php --- b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php @@ -7,7 +7,8 @@ namespace Drupal\language\Config; -use Drupal\Core\Config\ConfigCollectionNamesEvent; +use Drupal\Component\Utility\String; +use Drupal\Core\Config\ConfigCollectionInfoEvent; use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\TypedConfigManagerInterface; @@ -149,6 +150,14 @@ } /** + * {@inheritdoc} + */ + public function getConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) { + $langcode = $this->getLangcodeFromCollectionName($collection); + return $this->getOverride($langcode, $name); + } + + /** * Creates a configuration collection name based on a langcode. * * @param string $langcode @@ -162,17 +171,40 @@ } /** + * Converts a configuration collection name to a langcode. + * + * @param $collection + * The configuration collection name. + * + * @return string + * The langcode of the collection. + * + * @throws \InvalidArgumentException + * Exception thrown if the provided collection name is not in the format + * "language.LANGCODE". + * + * @see self::createConfigCollectionName() + */ + protected function getLangcodeFromCollectionName($collection) { + preg_match('/^language\.(.*)$/', $collection, $matches); + if (!isset($matches[1])) { + throw new \InvalidArgumentException(String::format('!collection is not a valid language override collection', array('!collection' => $collection))); + } + return $matches[1]; + } + + /** * Reacts to the ConfigEvents::COLLECTION_NAMES event. * - * @param \Drupal\Core\Config\ConfigCollectionNamesEvent $event + * @param \Drupal\Core\Config\ConfigCollectionInfoEvent $event * The configuration collection names event. */ - public function addCollectionNames(ConfigCollectionNamesEvent $event) { + public function addCollectionNames(ConfigCollectionInfoEvent $event) { $collections = array(); foreach (\Drupal::languageManager()->getLanguages() as $language) { $collections[] = $this->createConfigCollectionName($language->getId()); } - $event->addCollectionNames($collections); + $event->addCollectionNames($collections, $this); } /** only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigCollectionInfoEvent.php @@ -0,0 +1,82 @@ + 0) { + $collections_to_add = array_combine($collections, array_fill(0, count($collections), $override_service)); + $this->collections = array_merge($this->collections, $collections_to_add); + } + } + + /** + * Adds a name to the list of possible collections. + * + * @param string $collection + * Collection name to add. + * @param \Drupal\Core\Config\ConfigFactoryOverrideInterface + * (optional) The configuration factory override service responsible for the + * collection. + */ + public function addCollectionName($collection, ConfigFactoryOverrideInterface $override_service = NULL) { + $this->addCollectionNames(array($collection), $override_service); + } + + /** + * Gets the list of possible collection names. + * + * @return array + * The list of possible collection names. + */ + public function getCollectionNames($include_default = TRUE) { + $collection_names = array_keys($this->collections); + sort($collection_names); + if ($include_default) { + array_unshift($collection_names, StorageInterface::DEFAULT_COLLECTION); + } + return $collection_names; + } + + /** + * Gets the config factory override service responsible for the collection. + * + * @param string $collection + * The configuration collection. + * + * @return \Drupal\Core\Config\ConfigFactoryOverrideInterface|NULL + * The override service responsible for the collection if one exists. NULL + * if not. + */ + public function getOverrideService($collection) { + return isset($this->collections[$collection]) ? $this->collections[$collection] : NULL; + } + +} only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/ConfigCollectionNamesEvent.php +++ /dev/null @@ -1,59 +0,0 @@ -collections = array_merge($this->collections, $collections); - } - - /** - * Adds a name to the list of possible collections. - * - * @param string $collection - * Collection name to add. - */ - public function addCollectionName($collection) { - $this->addCollectionNames(array($collection)); - } - - /** - * Gets the list of possible collection names. - * - * @return array - * The list of possible collection names. - */ - public function getCollectionNames($include_default = TRUE) { - sort($this->collections); - $collections = array_unique($this->collections); - if ($include_default) { - array_unshift($collections, StorageInterface::DEFAULT_COLLECTION); - } - return $collections; - } - -} only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php @@ -32,4 +32,17 @@ public function loadOverrides($names); */ public function getCacheSuffix(); + /** + * Gets a configuration object for the override. + * + * @param string $name + * The configuration object name. + * @param string $collection + * The configuration collection. + * + * @return \Drupal\Core\Config\StorableConfigBase + * The configuration object for the provided name and collection. + */ + public function getConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION); + } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -156,6 +156,13 @@ class ConfigImporter extends DependencySerialization { protected $totalConfigurationToProcess = 0; /** + * The ConfigCollectionInfoEvent after dispatch. + * + * @var \Drupal\Core\Config\ConfigCollectionInfoEvent + */ + protected $configCollectionInfo; + + /** * Constructs a configuration import object. * * @param \Drupal\Core\Config\StorageComparerInterface $storage_comparer @@ -896,7 +903,13 @@ protected function checkOp($collection, $op, $name) { * The name of the configuration to process. */ protected function importConfig($collection, $op, $name) { - $config = new Config($name, $this->storageComparer->getTargetStorage($collection), $this->eventDispatcher, $this->typedConfigManager); + $overrider = $this->getConfigCollectionInfo()->getOverrideService($collection); + if ($overrider) { + $config = $overrider->getConfigObject($name, $collection); + } + else { + $config = new Config($name, $this->storageComparer->getTargetStorage($collection), $this->eventDispatcher, $this->typedConfigManager); + } if ($op == 'delete') { $config->delete(); } @@ -1043,4 +1056,28 @@ protected function reInjectMe() { $this->stringTranslation = \Drupal::service('string_translation'); } + /** + * Gets available collection information using the event. + * + * @return \Drupal\Core\Config\ConfigCollectionInfoEvent + * The event which collects information about all the available collections. + */ + protected function getConfigCollectionInfo() { + if (!isset($this->configCollectionInfo)) { + $this->configCollectionInfo = new ConfigCollectionInfoEvent(); + $this->eventDispatcher->dispatch(ConfigEvents::COLLECTION_NAMES, $this->configCollectionInfo); + } + return $this->configCollectionInfo; + } + + /** + * {@inheritdoc} + */ + public function __sleep() { + // Unset the collection information since this can contain references to + // services. + $this->configCollectionInfo = NULL; + return parent::__sleep(); + } + } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -97,7 +97,7 @@ public function installDefaultConfig($type, $name) { } // Gather all the supported collection names. - $event = new ConfigCollectionNamesEvent(); + $event = new ConfigCollectionInfoEvent(); $this->eventDispatcher->dispatch(ConfigEvents::COLLECTION_NAMES, $event); $collections = $event->getCollectionNames(); @@ -113,7 +113,7 @@ public function installDefaultConfig($type, $name) { foreach ($collections as $collection) { $config_to_install = $this->listDefaultConfigCollection($collection, $type, $name, $enabled_extensions); if (!empty($config_to_install)) { - $this->createConfiguration($collection, $config_to_install); + $this->createConfiguration($collection, $config_to_install, $event); } } $this->configFactory->setOverrideState($old_state); @@ -169,8 +169,10 @@ protected function listDefaultConfigCollection($collection, $type, $name, array * The configuration collection. * @param array $config_to_install * A list of configuration object names to create. + * @param \Drupal\Core\Config\ConfigCollectionInfoEvent $event + * The event which holds information about configuration collections. */ - protected function createConfiguration($collection, array $config_to_install) { + protected function createConfiguration($collection, array $config_to_install, ConfigCollectionInfoEvent $event) { // Order the configuration to install in the order of dependencies. $data = $this->getSourceStorage($collection)->readMultiple($config_to_install); $config_entity_support = $this->configManager->supportsConfigurationEntities($collection); @@ -185,7 +187,13 @@ protected function createConfiguration($collection, array $config_to_install) { $config_to_install = array_diff($config_to_install, $this->getActiveStorage($collection)->listAll()); foreach ($config_to_install as $name) { - $new_config = new Config($name, $this->getActiveStorage($collection), $this->eventDispatcher, $this->typedConfig); + $overrider = $event->getOverrideService($collection); + if ($overrider) { + $new_config = $overrider->getConfigObject($name, $collection); + } + else { + $new_config = new Config($name, $this->getActiveStorage($collection), $this->eventDispatcher, $this->typedConfig); + } if ($data[$name] !== FALSE) { $new_config->setData($data[$name]); } @@ -238,9 +246,13 @@ public function installCollectionDefaultConfig($collection) { return in_array($provider, $enabled_extensions); }); if (!empty($config_to_install)) { + // Gather information about all the collection names. + $event = new ConfigCollectionInfoEvent(); + $this->eventDispatcher->dispatch(ConfigEvents::COLLECTION_NAMES, $event); + $old_state = $this->configFactory->getOverrideState(); $this->configFactory->setOverrideState(FALSE); - $this->createConfiguration($collection, $config_to_install); + $this->createConfiguration($collection, $config_to_install, $event); $this->configFactory->setOverrideState($old_state); // Reset all the static caches and list caches. $this->configFactory->reset(); only in patch2: unchanged: --- a/core/modules/config/tests/config_collection_install_test/lib/Drupal/config_collection_install_test/EventSubscriber.php +++ b/core/modules/config/tests/config_collection_install_test/lib/Drupal/config_collection_install_test/EventSubscriber.php @@ -7,7 +7,7 @@ namespace Drupal\config_collection_install_test; -use Drupal\Core\Config\ConfigCollectionNamesEvent; +use Drupal\Core\Config\ConfigCollectionInfoEvent; use Drupal\Core\Config\ConfigEvents; use Drupal\Core\State\StateInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -34,10 +34,10 @@ public function __construct(StateInterface $state) { /** * Reacts to the ConfigEvents::COLLECTION_NAMES event. * - * @param \Drupal\Core\Config\ConfigCollectionNamesEvent $event + * @param \Drupal\Core\Config\ConfigCollectionInfoEvent $event * The configuration collection names event. */ - public function addCollectionNames(ConfigCollectionNamesEvent $event) { + public function addCollectionNames(ConfigCollectionInfoEvent $event) { $event->addCollectionNames($this->state->get('config_collection_install_test.collection_names', array())); } only in patch2: unchanged: --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\ConfigFactoryOverrideInterface; use Drupal\Core\Config\ConfigModuleOverridesEvent; +use Drupal\Core\Config\StorageInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -40,5 +41,12 @@ public function getCacheSuffix() { return 'ConfigOverrider'; } + /** + * {@inheritdoc} + */ + public function getConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) { + return NULL; + } + } only in patch2: unchanged: --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php @@ -41,5 +41,12 @@ public function getCacheSuffix() { return 'ConfigOverriderLowPriority'; } + /** + * {@inheritdoc} + */ + public function getConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) { + return NULL; + } + }