diff --git a/core/core.services.yml b/core/core.services.yml index 9f5ab7f2c5f899b58cd2506c65bcf024e56b274e..1f6880bbe2c5ce69a35481bc0632afec89c10a23 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -264,8 +264,6 @@ services: config.storage.schema: class: Drupal\Core\Config\ExtensionInstallStorage arguments: ['@config.storage', 'config/schema'] - config.storage.installer: - class: Drupal\Core\Config\InstallStorage config.typed: class: Drupal\Core\Config\TypedConfigManager arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler'] diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 3d5adad0e3ce52b38839c27157d5d1ec32025e9b..c180847e29825f5c5dcb110f9cb0548c4219873e 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -233,27 +233,16 @@ public function getLanguageSwitchLinks($type, Url $url) { } /** - * Some common languages with their English and native names. - * - * Language codes are defined by the W3C language tags document for - * interoperability. Language codes typically have a language and, optionally, - * a script or regional variant name. See: - * http://www.w3.org/International/articles/language-tags/ for more - * information. - * - * This list is based on languages available from localize.drupal.org. See - * http://localize.drupal.org/issues for information on how to add languages - * there. - * - * The "Left-to-right marker" comments and the enclosed UTF-8 markers are to - * make otherwise strange looking PHP syntax natural (to not be displayed in - * right to left). See http://drupal.org/node/128866#comment-528929. - * - * @return array - * An array of language code to language name information. - * Language name information itself is an array of English and native names. + * @inheritdoc */ public static function getStandardLanguageList() { + // This list is based on languages available from localize.drupal.org. See + // http://localize.drupal.org/issues for information on how to add languages + // there. + // + // The "Left-to-right marker" comments and the enclosed UTF-8 markers are to + // make otherwise strange looking PHP syntax natural (to not be displayed in + // right to left). See http://drupal.org/node/128866#comment-528929. return array( 'af' => array('Afrikaans', 'Afrikaans'), 'am' => array('Amharic', 'አማርኛ'), diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php index c29dd3395b9ea6f184ddf1a1aaf4ab0f062d5bb8..b536a00c4adefe535fdc8b9b4c4ea2651ceef1a8 100644 --- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php +++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php @@ -208,4 +208,19 @@ public function setConfigOverrideLanguage(LanguageInterface $language = NULL); */ public function getConfigOverrideLanguage(); + /** + * Some common languages with their English and native names. + * + * Language codes are defined by the W3C language tags document for + * interoperability. Language codes typically have a language and, optionally, + * a script or regional variant name. See: + * http://www.w3.org/International/articles/language-tags/ for more + * information. + * + * @return array + * An array of language code to language name information. Language name + * information itself is an array of English and native names. + */ + public static function getStandardLanguageList(); + } diff --git a/core/modules/config/src/Tests/ConfigInstallTest.php b/core/modules/config/src/Tests/ConfigInstallTest.php index fe9a6b601263bd858259ba1d8f150aa7307f14de..00ec4fabf47b0a3dab3a4137d8e466af738bc2a5 100644 --- a/core/modules/config/src/Tests/ConfigInstallTest.php +++ b/core/modules/config/src/Tests/ConfigInstallTest.php @@ -7,6 +7,7 @@ namespace Drupal\config\Tests; +use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\PreExistingConfigException; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\UnmetDependenciesException; @@ -223,7 +224,8 @@ public function testDependencyChecking() { function testLanguage() { $this->installModules(['config_test_language']); // Test imported configuration with implicit language code. - $data = $this->container->get('config.storage.installer')->read('config_test.dynamic.dotted.english'); + $storage = new InstallStorage(); + $data = $storage->read('config_test.dynamic.dotted.english'); $this->assertTrue(!isset($data['langcode'])); $this->assertEqual( $this->config('config_test.dynamic.dotted.english')->get('langcode'), @@ -231,7 +233,7 @@ function testLanguage() { ); // Test imported configuration with explicit language code. - $data = $this->container->get('config.storage.installer')->read('config_test.dynamic.dotted.french'); + $data = $storage->read('config_test.dynamic.dotted.french'); $this->assertEqual($data['langcode'], 'fr'); $this->assertEqual( $this->config('config_test.dynamic.dotted.french')->get('langcode'), diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 8e4a6c28985cf635d09a5fcb3152f119cc10efc6..6bdc5aaa2b80a888d5abc94b00de020f079e85b8 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -407,23 +407,30 @@ function locale_system_update(array $components) { // Skip running the translation imports if in the installer, // because it would break out of the installer flow. We have // built-in support for translation imports in the installer. - if (!drupal_installation_attempted() && locale_translatable_language_list() && \Drupal::config('locale.settings')->get('translation.import_enabled')) { - module_load_include('compare.inc', 'locale'); - - // Update the list of translatable projects and start the import batch. - // Only when new projects are added the update batch will be triggered. Not - // each enabled module will introduce a new project. E.g. sub modules. - $projects = array_keys(locale_translation_build_projects()); - if ($list = array_intersect($list, $projects)) { - module_load_include('fetch.inc', 'locale'); - // Get translation status of the projects, download and update - // translations. - $options = _locale_translation_default_update_options(); - $batch = locale_translation_batch_update_build($list, array(), $options); - batch_set($batch); + if (!drupal_installation_attempted() && locale_translatable_language_list()) { + if (\Drupal::config('locale.settings')->get('translation.import_enabled')) { + module_load_include('compare.inc', 'locale'); + + // Update the list of translatable projects and start the import batch. + // Only when new projects are added the update batch will be triggered. + // Not each enabled module will introduce a new project. E.g. sub modules. + $projects = array_keys(locale_translation_build_projects()); + if ($list = array_intersect($list, $projects)) { + module_load_include('fetch.inc', 'locale'); + // Get translation status of the projects, download and update + // translations. + $options = _locale_translation_default_update_options(); + $batch = locale_translation_batch_update_build($list, [], $options); + batch_set($batch); + } } + + // Construct a batch to update configuration for all components. Installing + // this component may have installed configuration from any number of other + // components. Do this even if import is not enabled because parsing new + // configuration may expose new source strings. \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc'); - if ($batch = locale_config_batch_update_components(array(), array(), $components)) { + if ($batch = locale_config_batch_update_components([])) { batch_set($batch); } } diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml index ff2bfc29981a2fbfa885701c53d3d7bcfbff5a98..393866bc0748b7cd60e0f50bd00da73859e60e8a 100644 --- a/core/modules/locale/locale.services.yml +++ b/core/modules/locale/locale.services.yml @@ -1,7 +1,11 @@ services: + locale.default.config.storage: + class: Drupal\locale\LocaleDefaultConfigStorage + arguments: ['@config.storage', '@language_manager'] + public: false locale.config_manager: class: Drupal\locale\LocaleConfigManager - arguments: ['@config.storage', '@config.storage.installer', '@locale.storage', '@config.factory', '@config.typed', '@language_manager'] + arguments: ['@config.storage', '@locale.storage', '@config.factory', '@config.typed', '@language_manager', '@locale.default.config.storage'] locale.storage: class: Drupal\locale\StringDatabaseStorage arguments: ['@database'] diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php index da21bca915ad8cb202977a60609325c4dfbf3e02..d96c758ace08be3bd88ae3f6a7b45dfd2a244f45 100644 --- a/core/modules/locale/src/LocaleConfigManager.php +++ b/core/modules/locale/src/LocaleConfigManager.php @@ -9,6 +9,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\StringTranslation\TranslationWrapper; @@ -44,13 +45,6 @@ class LocaleConfigManager { */ protected $configStorage; - /** - * The storage instance for reading default configuration data. - * - * @var \Drupal\Core\Config\StorageInterface - */ - protected $installStorage; - /** * The string storage for reading and writing translations. * @@ -95,14 +89,18 @@ class LocaleConfigManager { */ protected $isUpdatingFromLocale = FALSE; + /** + * The locale default config storage instance. + * + * @var \Drupal\locale\LocaleDefaultConfigStorage + */ + protected $defaultConfigStorage; + /** * Creates a new typed configuration manager. * * @param \Drupal\Core\Config\StorageInterface $config_storage * The storage object to use for reading configuration data. - * @param \Drupal\Core\Config\StorageInterface $install_storage - * The storage object to use for reading default configuration - * data. * @param \Drupal\locale\StringStorageInterface $locale_storage * The locale storage to use for reading string translations. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory @@ -111,14 +109,16 @@ class LocaleConfigManager { * The typed configuration manager. * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager * The language manager. + * @param \Drupal\locale\LocaleDefaultConfigStorage $default_config_storage + * The locale default configuration storage. */ - public function __construct(StorageInterface $config_storage, StorageInterface $install_storage, StringStorageInterface $locale_storage, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config, ConfigurableLanguageManagerInterface $language_manager) { + public function __construct(StorageInterface $config_storage, StringStorageInterface $locale_storage, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config, ConfigurableLanguageManagerInterface $language_manager, LocaleDefaultConfigStorage $default_config_storage) { $this->configStorage = $config_storage; - $this->installStorage = $install_storage; $this->localeStorage = $locale_storage; $this->configFactory = $config_factory; $this->typedConfigManager = $typed_config; $this->languageManager = $language_manager; + $this->defaultConfigStorage = $default_config_storage; } /** @@ -133,7 +133,7 @@ public function __construct(StorageInterface $config_storage, StorageInterface $ public function getTranslatableDefaultConfig($name) { if ($this->isSupported($name)) { // Create typed configuration wrapper based on install storage data. - $data = $this->installStorageRead($name); + $data = $this->defaultConfigStorage->read($name); $type_definition = $this->typedConfigManager->getDefinition($name); $data_definition = $this->typedConfigManager->buildDataDefinition($type_definition, $data); $typed_config = $this->typedConfigManager->create($data_definition, $data); @@ -293,12 +293,12 @@ public function getComponentNames(array $components = array()) { foreach ($components as $type => $list) { // InstallStorage::getComponentNames returns a list of folders keyed by // config name. - $names = array_merge($names, $this->installStorageComponents($type, $list)); + $names = array_merge($names, $this->defaultConfigStorage->getComponentNames($type, $list)); } return $names; } else { - return $this->installStorageAll(); + return $this->defaultConfigStorage->listAll(); } } @@ -474,7 +474,7 @@ public function hasTranslation($name, $langcode) { * configuration exists. */ public function getDefaultConfigLangcode($name) { - $shipped = $this->installStorageRead($name); + $shipped = $this->defaultConfigStorage->read($name); if (!empty($shipped)) { return !empty($shipped['langcode']) ? $shipped['langcode'] : 'en'; } @@ -635,81 +635,4 @@ protected function filterOverride(array $override_data, array $translatable) { return $filtered_data; } - /** - * Read a configuration from install storage or default languages. - * - * @param string $name - * Configuration object name. - * - * @return array - * Configuration data from install storage or default language. - */ - protected function installStorageRead($name) { - if ($this->installStorage->exists($name)) { - return $this->installStorage->read($name); - } - elseif (strpos($name, 'language.entity.') === 0) { - // Simulate default languages as if they were shipped as default - // configuration. - $langcode = str_replace('language.entity.', '', $name); - $predefined_languages = $this->languageManager->getStandardLanguageList(); - if (isset($predefined_languages[$langcode])) { - $data = $this->configStorage->read($name); - $data['label'] = $predefined_languages[$langcode][0]; - return $data; - } - } - } - - /** - * Return the list of configuration in install storage and current languages. - * - * @return array - * List of configuration in install storage and current languages. - */ - protected function installStorageAll() { - $languages = $this->predefinedConfiguredLanguages(); - return array_unique(array_merge($this->installStorage->listAll(), $languages)); - } - - /** - * Get all configuration names and folders for a list of modules or themes. - * - * @param string $type - * Type of components: 'module' | 'theme' | 'profile' - * @param array $list - * Array of theme or module names. - * - * @return array - * Configuration names provided by that component. In case of language - * module this list is extended with configured languages that have - * predefined names as well. - */ - protected function installStorageComponents($type, array $list) { - $names = array_keys($this->installStorage->getComponentNames($type, $list)); - if ($type == 'module' && in_array('language', $list)) { - $languages = $this->predefinedConfiguredLanguages(); - $names = array_unique(array_merge($names, $languages)); - } - return $names; - } - - /** - * Compute the list of configuration names that match predefined languages. - * - * @return array - * The list of configuration names that match predefined languages. - */ - protected function predefinedConfiguredLanguages() { - $names = $this->configStorage->listAll('language.entity.'); - $predefined_languages = $this->languageManager->getStandardLanguageList(); - foreach ($names as $id => $name) { - $langcode = str_replace('language.entity.', '', $name); - if (!isset($predefined_languages[$langcode])) { - unset($names[$id]); - } - } - return array_values($names); - } - } diff --git a/core/modules/locale/src/LocaleDefaultConfigStorage.php b/core/modules/locale/src/LocaleDefaultConfigStorage.php new file mode 100644 index 0000000000000000000000000000000000000000..5828f61f463cb4cd747bfc0819b38cc5c0e13027 --- /dev/null +++ b/core/modules/locale/src/LocaleDefaultConfigStorage.php @@ -0,0 +1,165 @@ +configStorage = $config_storage; + $this->languageManager = $language_manager; + + $this->requiredInstallStorage = new InstallStorage(); + $this->optionalInstallStorage = new InstallStorage(InstallStorage::CONFIG_OPTIONAL_DIRECTORY); + } + + /** + * Read a configuration from install storage or default languages. + * + * @param string $name + * Configuration object name. + * + * @return array + * Configuration data from install storage or default language. + */ + public function read($name) { + if ($this->requiredInstallStorage->exists($name)) { + return $this->requiredInstallStorage->read($name); + } + elseif ($this->optionalInstallStorage->exists($name)) { + return $this->optionalInstallStorage->read($name); + } + elseif (strpos($name, 'language.entity.') === 0) { + // Simulate default languages as if they were shipped as default + // configuration. + $langcode = str_replace('language.entity.', '', $name); + $predefined_languages = $this->languageManager->getStandardLanguageList(); + if (isset($predefined_languages[$langcode])) { + $data = $this->configStorage->read($name); + $data['label'] = $predefined_languages[$langcode][0]; + return $data; + } + } + } + + /** + * Return the list of configuration in install storage and current languages. + * + * @return array + * List of configuration in install storage and current languages. + */ + public function listAll() { + $languages = $this->predefinedConfiguredLanguages(); + return array_unique( + array_merge( + $this->requiredInstallStorage->listAll(), + $this->optionalInstallStorage->listAll(), + $languages + ) + ); + } + + /** + * Get all configuration names and folders for a list of modules or themes. + * + * @param string $type + * Type of components: 'module' | 'theme' | 'profile' + * @param array $list + * Array of theme or module names. + * + * @return array + * Configuration names provided by that component. In case of language + * module this list is extended with configured languages that have + * predefined names as well. + */ + public function getComponentNames($type, array $list) { + $names = array_unique( + array_merge( + array_keys($this->requiredInstallStorage->getComponentNames($type, $list)), + array_keys($this->optionalInstallStorage->getComponentNames($type, $list)) + ) + ); + if ($type == 'module' && in_array('language', $list)) { + $languages = $this->predefinedConfiguredLanguages(); + $names = array_unique(array_merge($names, $languages)); + } + return $names; + } + + /** + * Compute the list of configuration names that match predefined languages. + * + * @return array + * The list of configuration names that match predefined languages. + */ + protected function predefinedConfiguredLanguages() { + $names = $this->configStorage->listAll('language.entity.'); + $predefined_languages = $this->languageManager->getStandardLanguageList(); + foreach ($names as $id => $name) { + $langcode = str_replace('language.entity.', '', $name); + if (!isset($predefined_languages[$langcode])) { + unset($names[$id]); + } + } + return array_values($names); + } + +} + diff --git a/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php b/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php index 24017fd7f769c079559e68c01f65274a886da50d..376ec44655c68466f5d88cea7659bb620d622647 100644 --- a/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php +++ b/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php @@ -8,6 +8,7 @@ namespace Drupal\locale\Tests; use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\locale\Locale; use Drupal\locale\StringInterface; use Drupal\locale\TranslationString; use Drupal\simpletest\KernelTestBase; @@ -22,7 +23,7 @@ class LocaleConfigSubscriberTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['language', 'locale']; + public static $modules = ['language', 'locale', 'system']; /** * The configurable language manager used in this test. @@ -61,6 +62,7 @@ protected function setUp() { $this->setUpDefaultLanguage(); $this->installSchema('locale', ['locales_source', 'locales_target', 'locales_location']); + $this->installSchema('system', ['queue']); $this->setupLanguages(); @@ -68,7 +70,12 @@ protected function setUp() { $this->installConfig(['locale_test']); // Simulate this hook invoked which would happen if in a non-kernel test // or normal environment. - locale_modules_installed(array('locale_test')); + // @see locale_modules_installed() + // @see locale_system_update() + locale_system_set_config_langcodes(); + $langcodes = array_keys(\Drupal::languageManager()->getLanguages()); + $names = \Drupal\locale\Locale::config()->getComponentNames(); + Locale::config()->updateConfigTranslations($names, $langcodes); $this->configFactory = $this->container->get('config.factory'); $this->stringStorage = $this->container->get('locale.storage'); diff --git a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php index 4535b9b3dae285eb442c07e567677042cbadcafd..64ea7973841f868b408984a8670391aa1686d071 100644 --- a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php +++ b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php @@ -18,6 +18,13 @@ */ class LocaleConfigTranslationTest extends WebTestBase { + /** + * The language code used. + * + * @var string + */ + protected $langcode; + /** * Modules to enable. * @@ -38,28 +45,28 @@ protected function setUp() { $this->config('locale.settings') ->set('translation.import_enabled', TRUE) ->save(); - } - /** - * Tests basic configuration translation. - */ - public function testConfigTranslation() { // Add custom language. - $langcode = 'xx'; + $this->langcode = 'xx'; $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface', 'administer modules', 'access site-wide contact form', 'administer contact forms', 'administer site configuration')); $this->drupalLogin($admin_user); $name = $this->randomMachineName(16); $edit = array( 'predefined_langcode' => 'custom', - 'langcode' => $langcode, + 'langcode' => $this->langcode, 'label' => $name, 'direction' => LanguageInterface::DIRECTION_LTR, ); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); // Set path prefix. - $edit = array("prefix[$langcode]" => $langcode); + $edit = ["prefix[$this->langcode]" => $this->langcode]; $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration')); + } + /** + * Tests basic configuration translation. + */ + public function testConfigTranslation() { // Check that the maintenance message exists and create translation for it. $source = '@site is currently under maintenance. We should be back shortly. Thank you for your patience.'; $string = $this->storage->findString(array('source' => $source, 'context' => '', 'type' => 'configuration')); @@ -69,7 +76,7 @@ public function testConfigTranslation() { $message = $this->randomMachineName(20); $search = array( 'string' => $string->source, - 'langcode' => $langcode, + 'langcode' => $this->langcode, 'translation' => 'all', ); $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); @@ -82,7 +89,7 @@ public function testConfigTranslation() { $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); // Get translation and check we've only got the message. - $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'system.maintenance')->get(); + $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'system.maintenance')->get(); $this->assertEqual(count($translation), 1, 'Got the right number of properties after translation.'); $this->assertEqual($translation['message'], $message); @@ -93,7 +100,7 @@ public function testConfigTranslation() { // Translate using the UI so configuration is refreshed. $search = array( 'string' => $string->source, - 'langcode' => $langcode, + 'langcode' => $this->langcode, 'translation' => 'all', ); $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); @@ -105,12 +112,12 @@ public function testConfigTranslation() { ); $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); - $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'core.date_format.medium')->get(); + $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'core.date_format.medium')->get(); $this->assertEqual($translation['pattern'], 'D', 'Got the right date format pattern after translation.'); // Formatting the date 8 / 27 / 1985 @ 13:37 EST with pattern D should // display "Tue". - $formatted_date = format_date(494015820, $type = 'medium', NULL, NULL, $langcode); + $formatted_date = format_date(494015820, $type = 'medium', NULL, NULL, $this->langcode); $this->assertEqual($formatted_date, 'Tue', 'Got the right formatted date using the date format translation pattern.'); // Assert strings from image module config are not available. @@ -127,7 +134,7 @@ public function testConfigTranslation() { $this->assertTrue(isset($locations['configuration']) && isset($locations['configuration']['image.style.medium']), 'Configuration string has been created with the right location'); // Check the string is unique and has no translation yet. - $translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium')); + $translations = $this->storage->getTranslations(['language' => $this->langcode, 'type' => 'configuration', 'name' => 'image.style.medium']); $this->assertEqual(count($translations), 1); $translation = reset($translations); $this->assertEqual($translation->source, $string->source); @@ -137,7 +144,7 @@ public function testConfigTranslation() { $image_style_label = $this->randomMachineName(20); $search = array( 'string' => $string->source, - 'langcode' => $langcode, + 'langcode' => $this->langcode, 'translation' => 'all', ); $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); @@ -149,12 +156,12 @@ public function testConfigTranslation() { $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); // Check the right single translation has been created. - $translations = $this->storage->getTranslations(array('language' => $langcode, 'type' => 'configuration', 'name' => 'image.style.medium')); + $translations = $this->storage->getTranslations(['language' => $this->langcode, 'type' => 'configuration', 'name' => 'image.style.medium']); $translation = reset($translations); $this->assertTrue(count($translations) == 1 && $translation->source == $string->source && $translation->translation == $image_style_label, 'Got only one translation for image configuration.'); // Try more complex configuration data. - $translation = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'image.style.medium')->get(); + $translation = \Drupal::languageManager()->getLanguageConfigOverride($this->langcode, 'image.style.medium')->get(); $this->assertEqual($translation['label'], $image_style_label, 'Got the right translation for image style name after translation'); // Uninstall the module. @@ -169,7 +176,7 @@ public function testConfigTranslation() { $category_label = $this->randomMachineName(20); $search = array( 'string' => 'Website feedback', - 'langcode' => $langcode, + 'langcode' => $this->langcode, 'translation' => 'all', ); $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); @@ -183,7 +190,7 @@ public function testConfigTranslation() { // Check if this category displayed in this language will use the // translation. This test ensures the entity loaded from the request // upcasting will already work. - $this->drupalGet($langcode . '/contact/feedback'); + $this->drupalGet($this->langcode . '/contact/feedback'); $this->assertText($category_label); // Check if the UI does not show the translated String. @@ -191,4 +198,54 @@ public function testConfigTranslation() { $this->assertFieldById('edit-label', 'Website feedback', 'Translation is not loaded for Edit Form.'); } + /** + * Test translatability of optional configuration in locale. + */ + public function testOptionalConfiguration() { + $this->assertNodeConfig(FALSE, FALSE); + // Enable the node module. + $this->drupalPostForm('admin/modules', ['modules[Core][node][enable]' => "1"], t('Save configuration')); + $this->drupalPostForm(NULL, [], t('Continue')); + $this->rebuildContainer(); + $this->assertNodeConfig(TRUE, FALSE); + // Enable the views module (which node provides some optional config for). + $this->drupalPostForm('admin/modules', ['modules[Core][views][enable]' => "1"], t('Save configuration')); + $this->rebuildContainer(); + $this->assertNodeConfig(TRUE, TRUE); + } + + /** + * Check that node configuration source strings are made available in locale. + * + * @param bool $required + * Whether to assume a sample of the required default configuration is + * present. + * @param bool $optional + * Whether to assume a sample of the optional default configuration is + * present. + */ + protected function assertNodeConfig($required, $optional) { + // Check the required default configuration in node module. + $string = $this->storage->findString(['source' => 'Make content sticky', 'context' => '', 'type' => 'configuration']); + if ($required) { + $this->assertFalse($this->config('system.action.node_make_sticky_action')->isNew()); + $this->assertTrue($string, 'Node action text can be found with node module.'); + } + else { + $this->assertTrue($this->config('system.action.node_make_sticky_action')->isNew()); + $this->assertFalse($string, 'Node action text can not be found without node module.'); + } + + // Check the optional default configuration in node module. + $string = $this->storage->findString(['source' => 'No front page content has been created yet.', 'context' => '', 'type' => 'configuration']); + if ($optional) { + $this->assertFalse($this->config('views.view.frontpage')->isNew()); + $this->assertTrue($string, 'Node view text can be found with node and views modules.'); + } + else { + $this->assertTrue($this->config('views.view.frontpage')->isNew()); + $this->assertFalse($string, 'Node view text can not be found without node and/or views modules.'); + } + } + }