diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 5d3756e..f4e44d1 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -312,4 +312,11 @@ public function addOverride(ConfigFactoryOverrideInterface $config_factory_overr $this->configFactoryOverrides[] = $config_factory_override; } + /** + * {@inheritdoc} + */ + public function getOverrides() { + return $this->configFactoryOverrides; + } + } diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php index 55eb6f6..cafd3fd 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php @@ -134,4 +134,11 @@ public function listAll($prefix = ''); */ public function addOverride(ConfigFactoryOverrideInterface $config_factory_override); + /** + * Get all added configuration factory override instances. + * + * @return ConfigFactoryOverrideInterface[] + * The configuration factory override instances. + */ + public function getOverrides(); } diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php index 06e1f3f..96c8d48 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php @@ -32,4 +32,24 @@ public function loadOverrides($names); */ 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 + * The type of extension being uninstalled. Either 'module' or 'theme'. + * @param string $name + * The name of the extension. + */ + public function uninstall($type, $name); + } diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index a22907b..b9e72e0 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -138,12 +138,12 @@ public function installDefaultConfig($type, $name) { // 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 @@ -159,8 +159,8 @@ public function installDefaultConfig($type, $name) { ->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); @@ -179,6 +179,12 @@ public function installDefaultConfig($type, $name) { } $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(); } diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index 139aaf0..e6e9d85 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -160,6 +160,11 @@ public function uninstall($type, $name) { 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 diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php index df1b335..e90a058 100644 --- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php @@ -51,9 +51,9 @@ public function testDefaultConfig() { $default_config_storage = new TestInstallStorage(); foreach ($default_config_storage->listAll() as $config_name) { - // @todo: remove once migration (https://drupal.org/node/2183957) and - // translation (https://drupal.org/node/2168609) schemas are in. - if (strpos($config_name, 'migrate.migration') === 0 || strpos($config_name, 'language.config') === 0) { + // @todo: remove once migration (https://drupal.org/node/2183957) schemas + // are in. + if (strpos($config_name, 'migrate.migration') === 0) { continue; } diff --git 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 index 106df3d..355869f 100644 --- 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 @@ -40,5 +40,17 @@ public function getCacheSuffix() { return 'ConfigOverrider'; } + /** + * {@inheritdoc} + */ + public function install($type, $name) { + } + + /** + * {@inheritdoc} + */ + public function uninstall($type, $name) { + } + } diff --git 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 index a9a435e..19ea21e 100644 --- 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,17 @@ public function getCacheSuffix() { return 'ConfigOverriderLowPriority'; } + /** + * {@inheritdoc} + */ + public function install($type, $name) { + } + + /** + * {@inheritdoc} + */ + public function uninstall($type, $name) { + } + } diff --git a/core/modules/config/tests/config_test/config/install/language.config.de.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/de/config_test.system.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/language.config.de.config_test.system.yml rename to core/modules/config/tests/config_test/config/install/language/de/config_test.system.yml diff --git a/core/modules/config/tests/config_test/config/install/language.config.en.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/en/config_test.system.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/language.config.en.config_test.system.yml rename to core/modules/config/tests/config_test/config/install/language/en/config_test.system.yml diff --git a/core/modules/config/tests/config_test/config/install/language.config.fr.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/fr/config_test.system.yml similarity index 100% rename from core/modules/config/tests/config_test/config/install/language.config.fr.config_test.system.yml rename to core/modules/config/tests/config_test/config/install/language/fr/config_test.system.yml diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php index fb3ba88..13311d9 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php @@ -15,6 +15,7 @@ use Drupal\Core\Form\BaseFormIdInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Language\Language; +use Drupal\language\Config\LanguageConfigOverride; use Drupal\language\ConfigurableLanguageManagerInterface; use Drupal\locale\StringStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -352,7 +353,7 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d * Set the configuration in this language. * @param \Drupal\Core\Config\Config $base_config * Base configuration values, in the source language. - * @param \Drupal\Core\Config\Config $config_translation + * @param \Drupal\language\Config\LanguageConfigOverride $config_translation * Translation configuration override data. * @param array $config_values * A simple one dimensional or recursive array: @@ -372,7 +373,7 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d * @return array * Translation configuration override data. */ - protected function setConfig(Language $language, Config $base_config, Config $config_translation, array $config_values, $shipped_config = FALSE) { + protected function setConfig(Language $language, Config $base_config, LanguageConfigOverride $config_translation, array $config_values, $shipped_config = FALSE) { foreach ($config_values as $key => $value) { if (is_array($value) && !isset($value['translation'])) { // Traverse into this level in the configuration. diff --git a/core/modules/language/language.install b/core/modules/language/language.install new file mode 100644 index 0000000..8825db3 --- /dev/null +++ b/core/modules/language/language.install @@ -0,0 +1,26 @@ +getModuleList()) as $module) { + $language_config_override->install('module', $module); + } + /** @var \Drupal\Core\Extension\ThemeHandler $theme_handler */ + $theme_handler = \Drupal::service('theme_handler'); + foreach ($theme_handler->listInfo() as $theme) { + if ($theme->status) { + $language_config_override->install('theme', $theme->name); + } + } + \Drupal::configFactory()->reset(); +} diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php index bfadec0..02606a7 100644 --- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php @@ -7,7 +7,7 @@ namespace Drupal\language\Config; -use Drupal\Core\Config\Config; +use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Language\Language; @@ -22,9 +22,19 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte /** * The configuration storage. * + * Do not access this directly. Should be accessed through self::getStorage() + * so that the cache of storages per langcode is used. + * * @var \Drupal\Core\Config\StorageInterface */ - protected $storage; + protected $baseStorage; + + /** + * An array of configuration storages keyed by langcode. + * + * @var \Drupal\Core\Config\StorageInterface[] + */ + protected $storages; /** * The typed config manager. @@ -58,7 +68,7 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte * The typed configuration manager. */ public function __construct(StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) { - $this->storage = $storage; + $this->baseStorage = $storage; $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; } @@ -67,72 +77,34 @@ public function __construct(StorageInterface $storage, EventDispatcherInterface * {@inheritdoc} */ public function loadOverrides($names) { - $data = array(); - $language_names = $this->getLanguageConfigNames($names); - if ($language_names) { - $data = $this->storage->readMultiple(array_values($language_names)); - // Re-key the data array to use configuration names rather than override - // names. - $prefix_length = strlen(static::LANGUAGE_CONFIG_PREFIX . '.' . $this->language->id) + 1; - foreach ($data as $key => $value) { - unset($data[$key]); - $key = substr($key, $prefix_length); - $data[$key] = $value; - } + if ($this->language) { + $storage = $this->getStorage($this->language->getId()); + return $storage->readMultiple($names); } - return $data; + return array(); } /** * {@inheritdoc} */ public function getOverride($langcode, $name) { - $override_name = $this->getLanguageConfigName($langcode, $name); - $overrides = $this->storage->read($override_name); - $config = new Config($override_name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); - if (!empty($overrides)) { - $config->initWithData($overrides); - } - return $config; - } - - /** - * Generate a list of configuration names based on base names. - * - * @param array $names - * List of configuration names. - * - * @return array - * List of configuration names for language override files if applicable. - */ - protected function getLanguageConfigNames(array $names) { - $language_names = array(); - if (isset($this->language)) { - foreach ($names as $name) { - if ($language_name = $this->getLanguageConfigName($this->language->id, $name)) { - $language_names[$name] = $language_name; - } - } + $storage = $this->getStorage($langcode); + $data = $storage->read($name); + $override = new LanguageConfigOverride($name, $storage, $this->typedConfigManager); + if (!empty($data)) { + $override->initWithData($data); } - return $language_names; + return $override; } /** - * Get language override name for given language and configuration name. - * - * @param string $langcode - * Language code. - * @param string $name - * Configuration name. - * - * @return bool|string - * Configuration name or FALSE if not applicable. + * {@inheritdoc} */ - protected function getLanguageConfigName($langcode, $name) { - if (strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0) { - return FALSE; + public function getStorage($langcode) { + if (!isset($this->storages[$langcode])) { + $this->storages[$langcode] = $this->baseStorage->createCollection('language.' . $langcode); } - return static::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.' . $name; + return $this->storages[$langcode]; } /** @@ -165,4 +137,38 @@ public function setLanguageFromDefault(LanguageDefault $language_default = NULL) return $this; } + /** + * {@inheritdoc} + */ + public function install($type, $name) { + // Work out if this extension provides default language overrides. + $config_dir = drupal_get_path($type, $name) . '/config/install/language'; + if (is_dir($config_dir)) { + // List all the directories. + // \DirectoryIterator on Windows requires an absolute path. + $it = new \DirectoryIterator(realpath($config_dir)); + foreach ($it as $dir) { + if (!$dir->isDot() && $dir->isDir() ) { + $default_language_config = new FileStorage($dir->getPathname()); + $storage = $this->getStorage($dir->getFilename()); + foreach ($default_language_config->listAll() as $config_name) { + $data = $default_language_config->read($config_name); + $config = new LanguageConfigOverride($config_name, $storage, $this->typedConfigManager); + $config->setData($data)->save(); + } + } + } + } + } + + /** + * {@inheritdoc} + */ + public function uninstall($type, $name) { + foreach (\Drupal::languageManager()->getLanguages() as $language) { + $storage = $this->getStorage($language->getId()); + $storage->deleteAll($name . '.'); + } + } + } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php index 1c3de55..61d5b5b 100644 --- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php @@ -17,11 +17,6 @@ interface LanguageConfigFactoryOverrideInterface extends ConfigFactoryOverrideInterface { /** - * Prefix for all language configuration files. - */ - const LANGUAGE_CONFIG_PREFIX = 'language.config'; - - /** * Gets the language object used to override configuration data. * * @return \Drupal\Core\Language\Language @@ -62,4 +57,15 @@ public function setLanguageFromDefault(LanguageDefault $language_default = NULL) */ public function getOverride($langcode, $name); + /** + * Returns the storage instance for a particular langcode. + * + * @param string $langcode + * Language code. + * + * @return \Drupal\language\Config\LanguageOverrideStorageInterface + * The language override storage object. + */ + public function getStorage($langcode); + } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php new file mode 100644 index 0000000..6ed2b11 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php @@ -0,0 +1,71 @@ +name = $name; + $this->storage = $storage; + $this->typedConfigManager = $typed_config; + } + + /** + * {@inheritdoc} + */ + public function save() { + // Validate the configuration object name before saving. + static::validateName($this->name); + + // If there is a schema for this configuration object, cast all values to + // conform to the schema. + if ($this->typedConfigManager->hasConfigSchema($this->name)) { + // Ensure that the schema wrapper has the latest data. + $this->schemaWrapper = NULL; + foreach ($this->data as $key => $value) { + $this->data[$key] = $this->castValue($key, $value); + } + } + + $this->storage->write($this->name, $this->data); + $this->isNew = FALSE; + $this->originalData = $this->data; + return $this; + } + + /** + * {@inheritdoc} + */ + public function delete() { + // @todo Consider to remove the pruning of data for Config::delete(). + $this->data = array(); + $this->storage->delete($this->name); + $this->isNew = TRUE; + $this->originalData = $this->data; + return $this; + } + +} diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php index 101449c..b28e02b 100644 --- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php @@ -410,6 +410,13 @@ public function getLanguageConfigOverride($langcode, $name) { /** * {@inheritdoc} */ + public function getLanguageConfigOverrideStorage($langcode) { + return $this->configFactoryOverride->getStorage($langcode); + } + + /** + * {@inheritdoc} + */ public function getStandardLanguageListWithoutConfigured() { $languages = $this->getLanguages(); $predefined = $this->getStandardLanguageList(); diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php index 9bbf2ce..0007524 100644 --- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php @@ -91,12 +91,24 @@ public function updateLockedLanguageWeights(); * @param string $name * The language configuration object name. * - * @return \Drupal\Core\Config\Config + * @return \Drupal\language\Config\LanguageConfigOverride * The language config override object. */ public function getLanguageConfigOverride($langcode, $name); /** + * Gets a language config override storage object. + * + * @param string $langcode + * The language code for the override. + * + * @param \Drupal\Core\Config\StorageInterface $storage + * A storage object to use for reading and writing the + * configuration override. + */ + public function getLanguageConfigOverrideStorage($langcode); + + /** * Returns the standard language list excluding already configured languages. * * @return array diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php new file mode 100644 index 0000000..9df51e3 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php @@ -0,0 +1,67 @@ + 'Language config override synchronize', + 'description' => 'Ensures the language config overrides can be synchronized.', + 'group' => 'Language', + ); + } + + /** + * + */ + public function testConfigOverrideImport() { + language_save(new Language(array( + 'name' => 'French', + 'id' => 'fr', + ))); + /* @var \Drupal\Core\Config\StorageInterface $staging */ + $staging = \Drupal::service('config.storage.staging'); + $this->copyConfig(\Drupal::service('config.storage'), $staging); + + \Drupal::moduleHandler()->uninstall(array('language')); + // Ensure that the current site has no overrides registered to the + // ConfigFactory. + $this->rebuildContainer(); + + /* @var \Drupal\Core\Config\StorageInterface $override_staging */ + $override_staging = new FileStorage(config_get_config_directory(CONFIG_STAGING_DIRECTORY) . '/language/fr'); + // Create some overrides in staging. + $override_staging->write('system.site', array('name' => 'FR default site name')); + $override_staging->write('system.maintenance', array('message' => 'FR message: @site is currently under maintenance. We should be back shortly. Thank you for your patience')); + + $this->configImporter()->import(); + $this->rebuildContainer(); + \Drupal::service('router.builder')->rebuild(); + + $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site'); + $this->assertEqual('FR default site name', $override->get('name')); + $this->drupalGet('fr'); + $this->assertText('FR default site name'); + + $this->drupalLogin($this->root_user); + $this->drupalGet('admin/config/development/maintenance/translate/fr/edit'); + $this->assertText('FR message: @site is currently under maintenance. We should be back shortly. Thank you for your patience'); + } +} diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php index 3c0dc57..f731b13 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php @@ -230,9 +230,9 @@ public function getStringNames(array $lids) { * Language code to delete. */ public function deleteLanguageTranslations($langcode) { - $locale_name = LanguageConfigFactoryOverrideInterface::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.'; - foreach ($this->configStorage->listAll($locale_name) as $name) { - $this->configStorage->delete($name); + $storage = $this->languageManager->getLanguageConfigOverrideStorage($langcode); + foreach ($storage->listAll() as $name) { + $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete(); } } diff --git a/core/modules/locale/tests/modules/locale_test/config/install/language.config.de.locale_test.translation.yml b/core/modules/locale/tests/modules/locale_test/config/install/language/de/locale_test.translation.yml similarity index 100% rename from core/modules/locale/tests/modules/locale_test/config/install/language.config.de.locale_test.translation.yml rename to core/modules/locale/tests/modules/locale_test/config/install/language/de/locale_test.translation.yml diff --git a/core/modules/system/tests/modules/menu_test/config/install/language.config.nl.menu_test.menu_item.yml b/core/modules/system/tests/modules/menu_test/config/install/language/nl/menu_test.menu_item.yml similarity index 100% rename from core/modules/system/tests/modules/menu_test/config/install/language.config.nl.menu_test.menu_item.yml rename to core/modules/system/tests/modules/menu_test/config/install/language/nl/menu_test.menu_item.yml diff --git a/core/modules/tour/tests/tour_test/config/install/language.config.it.tour.tour.tour-test.yml b/core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml similarity index 100% rename from core/modules/tour/tests/tour_test/config/install/language.config.it.tour.tour.tour-test.yml rename to core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml