diff -u b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php --- b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php @@ -33,16 +33,6 @@ public function getCacheSuffix(); /** - * Reacts to default configuration installation during extension install. - * - * @param string $type - * The type of extension being installed. Either 'module' or 'theme'. - * @param string $name - * The name of the extension. - */ - public function install($type, $name); - - /** * Reacts to configuration removal during extension uninstallation. * * @param string $type reverted: --- b/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ a/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -87,18 +87,25 @@ /** * {@inheritdoc} */ + public function installDefaultConfig($type, $name) { - public function getConfigToInstall($type, $name, $collection = StorageInterface::DEFAULT_COLLECTION) { // Get all default configuration owned by this extension. + $source_storage = $this->getSourceStorage(); - $source_storage = $this->getSourceStorage($collection); $config_to_install = $source_storage->listAll($name . '.'); $extension_path = drupal_get_path($type, $name); + // If the extension provides configuration schema clear the definitions. + if (is_dir($extension_path . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY)) { + // Refresh the schema cache if installing default configuration and the + // extension has a configuration schema directory. + $this->typedConfig->clearCachedDefinitions(); + } + // If not installing the core base system default configuration, work out if // this extension provides default configuration for any other enabled // extensions. if ($type !== 'core' && is_dir($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY)) { $enabled_extensions = $other_module_config = array(); + $default_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY); - $default_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY, $collection); $other_module_config = array_filter($default_storage->listAll(), function ($value) use ($name) { return !preg_match('/^' . $name . '\./', $value); }); @@ -116,26 +123,10 @@ $config_to_install = array_merge($config_to_install, $other_module_config); } - return $config_to_install; - } - - /** - * {@inheritdoc} - */ - public function installDefaultConfig($type, $name) { - $extension_path = drupal_get_path($type, $name); - // If the extension provides configuration schema clear the definitions. - if (is_dir($extension_path . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY)) { - // Refresh the schema cache if installing default configuration and the - // extension has a configuration schema directory. - $this->typedConfig->clearCachedDefinitions(); - } - - $config_to_install = $this->getConfigToInstall($type, $name); if (!empty($config_to_install)) { // Order the configuration to install in the order of dependencies. + $data = $source_storage->readMultiple($config_to_install); - $data = $this->getSourceStorage()->readMultiple($config_to_install); $dependency_manager = new ConfigDependencyManager(); $sorted_config = $dependency_manager ->setData($data) @@ -147,12 +138,12 @@ // Remove configuration that already exists in the active storage. $sorted_config = array_diff($sorted_config, $this->activeStorage->listAll()); + foreach ($sorted_config as $name) { + $new_config = new Config($name, $this->activeStorage, $this->eventDispatcher, $this->typedConfig); + if ($data[$name] !== FALSE) { + $new_config->setData($data[$name]); - foreach ($sorted_config as $config_name) { - $new_config = new Config($config_name, $this->activeStorage, $this->eventDispatcher, $this->typedConfig); - if ($data[$config_name] !== FALSE) { - $new_config->setData($data[$config_name]); } + if ($entity_type = $this->configManager->getEntityTypeIdByName($name)) { - if ($entity_type = $this->configManager->getEntityTypeIdByName($config_name)) { // If we are syncing do not create configuration entities. Pluggable // configuration entities can have dependencies on modules that are @@ -168,8 +159,8 @@ ->getStorage($entity_type); // It is possible that secondary writes can occur during configuration // creation. Updates of such configuration are allowed. + if ($this->activeStorage->exists($name)) { + $id = $entity_storage->getIDFromConfigName($name, $entity_storage->getEntityType()->getConfigPrefix()); - if ($this->activeStorage->exists($config_name)) { - $id = $entity_storage->getIDFromConfigName($config_name, $entity_storage->getEntityType()->getConfigPrefix()); $entity = $entity_storage->load($id); foreach ($new_config->get() as $property => $value) { $entity->set($property, $value); @@ -188,12 +179,6 @@ } $this->configFactory->setOverrideState($old_state); } - - // Allow configuration factory overrides to respond to installation. - foreach ($this->configFactory->getOverrides() as $config_override) { - $config_override->install($type, $name); - } - // Reset all the static caches and list caches. $this->configFactory->reset(); } @@ -215,16 +200,16 @@ } /** + * Gets the configuration storage that provides the default configuration. + * + * @return \Drupal\Core\Config\StorageInterface + * The configuration storage that provides the default configuration. - * {@inheritdoc} */ + public function getSourceStorage() { - public function getSourceStorage($collection = StorageInterface::DEFAULT_COLLECTION) { if (!isset($this->sourceStorage)) { // Default to using the ExtensionInstallStorage which searches extension's // config directories for default configuration. + $this->sourceStorage = new ExtensionInstallStorage($this->activeStorage); - $this->sourceStorage = new ExtensionInstallStorage($this->activeStorage, ExtensionInstallStorage::CONFIG_INSTALL_DIRECTORY, $collection); - } - if ($this->sourceStorage->getCollectionName() != $collection) { - $this->sourceStorage = $this->sourceStorage->createCollection($collection); } return $this->sourceStorage; } reverted: --- b/core/lib/Drupal/Core/Config/ConfigInstallerInterface.php +++ a/core/lib/Drupal/Core/Config/ConfigInstallerInterface.php @@ -13,28 +13,6 @@ interface ConfigInstallerInterface { /** - * Gets a list of configuration object names to install. - * - * It searches all the default configuration directories for all installed - * extensions to locate any configuration with its name prefix. Additionally, - * the default configuration directory for the extension being installed is - * searched to discover if it contains default configuration that is owned by - * other enabled extensions. - * - * @param string $type - * The extension type; e.g., 'module' or 'theme'. - * @param string $name - * The name of the module or theme to install default configuration for. - * @param string $collection - * (optional) The configuration collection. Defaults to the default - * collection. - * - * @return array - * The list of configuration object names to install. - */ - public function getConfigToInstall($type, $name, $collection = StorageInterface::DEFAULT_COLLECTION); - - /** * Installs the default configuration of a given extension. * * When an extension is installed, it searches all the default configuration @@ -70,17 +48,6 @@ public function setSourceStorage(StorageInterface $storage); /** - * Gets the configuration storage that provides the default configuration. - * - * @param string $collection - * The configuration collection. - * - * @return \Drupal\Core\Config\StorageInterface - * The configuration storage that provides the default configuration. - */ - public function getSourceStorage($collection = StorageInterface::DEFAULT_COLLECTION); - - /** * Resets the configuration storage that provides the default configuration. * * @return self reverted: --- b/core/lib/Drupal/Core/Config/ConfigManager.php +++ a/core/lib/Drupal/Core/Config/ConfigManager.php @@ -160,11 +160,6 @@ foreach ($config_names as $config_name) { $this->configFactory->get($config_name)->delete(); } - // Allow configuration factory overrides to respond to uninstallation. - foreach ($this->configFactory->getOverrides() as $config_override) { - $config_override->uninstall($type, $name); - } - $schema_dir = drupal_get_path($type, $name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY; if (is_dir($schema_dir)) { // Refresh the schema cache if uninstalling an extension that provides reverted: --- b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php +++ a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php @@ -32,10 +32,9 @@ * The directory to scan in each extension to scan for files. Defaults to * 'config'. */ + public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY) { - public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = self::DEFAULT_COLLECTION) { $this->configStorage = $config_storage; $this->directory = $directory; - $this->collection = $collection; } /** @@ -74,17 +73,5 @@ } return $this->folders; } - - /** - * {@inheritdoc} - */ - public function createCollection($collection) { - return new static( - $this->configStorage, - $this->directory, - $collection - ); - } - } reverted: --- b/core/lib/Drupal/Core/Config/InstallStorage.php +++ a/core/lib/Drupal/Core/Config/InstallStorage.php @@ -53,9 +53,8 @@ * The directory to scan in each extension to scan for files. Defaults to * 'config'. */ + public function __construct($directory = self::CONFIG_INSTALL_DIRECTORY) { - public function __construct($directory = self::CONFIG_INSTALL_DIRECTORY, $collection = self::DEFAULT_COLLECTION) { $this->directory = $directory; - $this->collection = $collection; } /** @@ -199,7 +198,7 @@ * The configuration folder name for this component. */ protected function getComponentFolder($type, $name) { + return drupal_get_path($type, $name) . '/' . $this->directory; - return drupal_get_path($type, $name) . '/' . $this->getCollectionDirectory(); } /** 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,18 +7,19 @@ namespace Drupal\language\Config; -use Drupal\Component\Utility\Unicode; -use Drupal\Core\Config\ExtensionInstallStorage; +use Drupal\Core\Config\ConfigCollectionNamesEvent; +use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageDefault; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Provides language overrides for the configuration factory. */ -class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInterface { +class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInterface, EventSubscriberInterface { /** * The configuration storage. @@ -141,46 +142,10 @@ /** * {@inheritdoc} */ - public function install($type, $name) { - $config_installer = \Drupal::service('config.installer'); - // Work out if this extension provides default language overrides. - foreach (\Drupal::languageManager()->getLanguages() as $language) { - $collection = $this->createConfigCollectionName($language->getId()); - $config_to_install = $config_installer->getConfigToInstall($type, $name, $collection); - $storage = $this->getStorage($language->getId()); - // Remove configuration that already exists in the active storage. - $config_to_install = array_diff($config_to_install, $storage->listAll()); - $data = $config_installer->getSourceStorage($collection)->readMultiple($config_to_install); - foreach ($data as $config_name => $config_data) { - $config = new LanguageConfigOverride($config_name, $storage, $this->typedConfigManager); - $config->setData($config_data)->save(); - } - } - } - - /** - * {@inheritdoc} - */ public function installLanguageOverrides($langcode) { - $enabled_extensions = array(); - $extension_config = $this->baseStorage->read('core.extension'); - $enabled_extensions += array_keys($extension_config['module']); - $enabled_extensions += array_keys($extension_config['theme']); - - $install_storage = new ExtensionInstallStorage($this->baseStorage, ExtensionInstallStorage::CONFIG_INSTALL_DIRECTORY, $this->createConfigCollectionName($langcode)); - $storage = $this->getStorage($langcode); - - $config_to_install = $install_storage->listAll(); - // Only install language overrides for enable modules. - $config_to_install = array_filter($config_to_install, function ($config_name) use ($enabled_extensions) { - $provider = Unicode::substr($config_name, 0, strpos($config_name, '.')); - return in_array($provider, $enabled_extensions); - }); - foreach ($config_to_install as $config_name) { - $data = $install_storage->read($config_name); - $config = new LanguageConfigOverride($config_name, $storage, $this->typedConfigManager); - $config->setData($data)->save(); - } + /** @var \Drupal\Core\Config\ConfigInstallerInterface $config_installer */ + $config_installer = \Drupal::service('config.installer'); + $config_installer->installCollectionDefaultConfig($this->createConfigCollectionName($langcode)); } /** @@ -208,2 +173,24 @@ + /** + * Reacts to the ConfigEvents::COLLECTION_NAMES event. + * + * @param \Drupal\Core\Config\ConfigCollectionNamesEvent $event + * The configuration collection names event. + */ + public function addCollectionNames(ConfigCollectionNamesEvent $event) { + $collections = array(); + foreach (\Drupal::languageManager()->getLanguages() as $language) { + $collections[] = $this->createConfigCollectionName($language->getId()); + } + $event->addCollectionNames($collections); + } + + /** + * {@inheritdoc} + */ + static function getSubscribedEvents() { + $events[ConfigEvents::COLLECTION_NAMES][] = array('addCollectionNames'); + return $events; + } + } only in patch2: unchanged: --- a/core/modules/language/language.services.yml +++ b/core/modules/language/language.services.yml @@ -16,3 +16,4 @@ services: arguments: ['@config.storage', '@event_dispatcher', '@config.typed'] tags: - { name: config.factory.override, priority: -254 } + - { name: event_subscriber }