diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php index 2e5cd18..16bb970 100644 --- a/core/modules/locale/src/LocaleConfigManager.php +++ b/core/modules/locale/src/LocaleConfigManager.php @@ -538,7 +538,8 @@ public function isUpdatingTranslationsFromLocale() { * configurable languages. * * @return int - * Number of configuration objects updated (saved). + * Total number of configuration override and active configuration objects + * updated (saved or removed). */ public function updateConfigTranslations(array $names, array $langcodes = array()) { $langcodes = $langcodes ? $langcodes : array_keys($this->languageManager->getLanguages()); @@ -564,13 +565,25 @@ public function updateConfigTranslations(array $names, array $langcodes = array( $this->saveTranslationOverride($name, $langcode, $processed); $count++; } - elseif (!$this->languageManager->getLanguageConfigOverride($langcode, $name)->isNew()) { - // @todo need to revisit this before it gets committed. Locale does - // not control the whole file, so even if there were no locale - // translatable things anymore, this translation may still be valid. - - // Delete language override if override exists. - $this->deleteTranslationOverride($name, $langcode); + else { + $override = $this->languageManager->getLanguageConfigOverride($langcode, $name); + if (!$override->isNew()) { + $data = $this->filterOverride($override->get(), $translatable); + if (empty($data)) { + // Delete language override if there is no data left at all. + // This means all prior translations in the override were locale + // managed. + $this->deleteTranslationOverride($name, $langcode); + $count++; + } + else { + // If there were translatable elements besides locale managed + // items, save with only those, and remove the ones managed + // by locale only. + $this->saveTranslationOverride($name, $langcode, $data); + $count++; + } + } } } elseif (locale_is_translatable($langcode)) { @@ -579,6 +592,7 @@ public function updateConfigTranslations(array $names, array $langcodes = array( // translatable. $active = NestedArray::mergeDeepArray(array($active, $processed), TRUE); $this->saveTranslationActive($name, $active); + $count++; } } } @@ -586,6 +600,40 @@ public function updateConfigTranslations(array $names, array $langcodes = array( } /** + * Filters override data based on default translatable items. + * + * @param array $override_data + * Configuration override data. + * @param array $translatable + * Translatable data array. @see self::getTranslatableData() + * @return array + * Nested array of any items of $override_data which did not have keys in + * $translatable. May be empty if $override_data only had items which were + * also in $translatable. + */ + protected function filterOverride(array $override_data, array $translatable) { + $filtered_data = array(); + foreach ($override_data as $key => $value) { + if (isset($translatable[$key])) { + // If the translatable default configuration has this key, look further + // for subkeys or ignore this element for scalar values. + if (is_array($value)) { + $value = $this->filterOverride($value, $translatable[$key]); + if (!empty($value)) { + $filtered_data[$key] = $value; + } + } + } + else { + // If this key was not in the translatable default configuration, + // keep it. + $filtered_data[$key] = $value; + } + } + return $filtered_data; + } + + /** * Read a configuration from install storage or default languages. * * @param string $name