diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php index 82c3c8f..999dd82 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php @@ -228,7 +228,9 @@ public function updateConfigTranslation($name, $langcodes = array()) { $wrapper = $this->getLocaleWrapper($name); $count = 0; foreach ($langcodes as $langcode) { - $translation = $wrapper ? $wrapper->getTranslation($langcode) : NULL; + $existing = $this->getTranslationData($name, $langcode); + $existing = $existing ?: array(); + $translation = $wrapper ? $wrapper->getTranslation($langcode, $existing) : NULL; if ($translation) { $this->configStorage->writeTranslation($name, $langcode, $translation); $count++; diff --git a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php index a4d1692..141de9f 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleTypedConfig.php @@ -35,10 +35,6 @@ class LocaleTypedConfig extends Element { /** * Constructs a configuration wrapper object. * - * @param array $definition - * The data definition. - * @param string $name - * The configuration object name. * @param Drupal\Core\Config\Schema\Element $element * Typed configuration element. * @param Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator; @@ -65,11 +61,15 @@ public function getTypedConfig() { * * @param string $langcode * Language code to translate to. + * @param array $defaults + * Optional existing translations to be used when translatability is not + * defined. These may be provided by other modules and we just keep them + * in case we cannot determine how to translate an element. * @return array * Translated configuration data. */ - public function getTranslation($langcode) { - return $this->getElementTranslation($this->getTypedConfig(), $langcode); + public function getTranslation($langcode, $defaults = array()) { + return $this->getElementTranslation($this->getTypedConfig(), $langcode, $defaults); } /** @@ -85,12 +85,12 @@ public function getTranslation($langcode) { * Configuration data translated to the requested language if available, * an empty array otherwise. */ - protected function getElementTranslation($element, $langcode) { + protected function getElementTranslation($element, $langcode, $defaults) { $translation = array(); if ($element instanceof ArrayElement) { - $translation = $this->getArrayTranslation($element, $langcode); + $translation = $this->getArrayTranslation($element, $langcode, $defaults); } - elseif ($this->translateElement($element, $langcode)) { + elseif ($this->translateElement($element, $langcode, $defaults)) { $translation = $element->getValue(); } return $translation; @@ -103,14 +103,17 @@ protected function getElementTranslation($element, $langcode) { * Typed configuration array element. * @param string $langcode * Language code to translate to. + * @param array|NULL $defaults + * Existing translations. * * @return array * Configuration data translated to the requested language. */ - protected function getArrayTranslation(ArrayElement $element, $langcode) { + protected function getArrayTranslation(ArrayElement $element, $langcode, $defaults) { $translation = array(); foreach ($element as $key => $property) { - $value = $this->getElementTranslation($property, $langcode); + $default = $defaults && isset($defaults[$key]) ? $defaults[$key] : NULL; + $value = $this->getElementTranslation($property, $langcode, $default); if (!empty($value)) { $translation[$key] = $value; } @@ -132,17 +135,27 @@ protected function getArrayTranslation(ArrayElement $element, $langcode) { * Configuration element. * @param string $langcode * Language code to translate to. + * @param $default + * Current translation for this element that will be kept when the element + * cannot be translated through localization. * * @return bool * Whether the element fits the translation criteria. */ - protected function translateElement(\Drupal\Core\TypedData\TypedDataInterface $element, $langcode) { + protected function translateElement(\Drupal\Core\TypedData\TypedDataInterface $element, $langcode, $default) { $definition = $element->getDefinition(); $value = $element->getValue(); - if ($value && !empty($definition['translatable'])) { - $context = isset($definition['locale context']) ? $definition['locale context'] : ''; - if ($translation = $this->translator->getStringTranslation($langcode, $value, $context)) { - $element->setValue($translation); + if (isset($value)) { + if ($value && !empty($definition['translatable'])) { + $context = isset($definition['locale context']) ? $definition['locale context'] : ''; + if ($translation = $this->translator->getStringTranslation($langcode, $value, $context)) { + $element->setValue($translation); + return TRUE; + } + } + elseif (!isset($definition['translatable']) && isset($default)) { + // Translatability is undefined but we have a default translation. + $element->setValue($default); return TRUE; } } diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php index 18f3d97..966dd8b 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php @@ -194,9 +194,15 @@ function testConfigUpdate() { $this->drupalGet($langcode); $this->assertText($site_name, 'The translated site name is displayed after configuration is changed back to default.'); - // Check translated configuration is deleted after language is deleted. - $config_name = 'locale.config.' . $langcode . '.system.site'; + // Check whether translations provided by other modules are kept. $config_factory = $this->container->get('config.factory'); + $config_name = 'locale.config.' . $langcode . '.system.site'; + $config_factory->get($config_name)->set('page.front', 'admin')->save(); + $edit = array(); + $this->drupalPost('admin/config/system/site-information', $edit, t('Save configuration')); + $this->assertEqual($config_factory->get($config_name)->get('page.front'), 'admin', 'Other translated elements are kept after refreshing translation.'); + + // Check translated configuration is deleted after language is deleted. $this->assertEqual($config_factory->get($config_name)->get('name'), $site_name, 'Translated site name is stored into configuration.'); $edit = array( 'confirm' => 1,