Skip to content
Snippets Groups Projects
Verified Commit f2bb7483 authored by catch's avatar catch Committed by Lee Rowlands
Browse files

Issue #2806009 by alexpott, JvE, Berdir, Dmitriy.trt, jhodgdon, lokapujya,...

Issue #2806009 by alexpott, JvE, Berdir, Dmitriy.trt, jhodgdon, lokapujya, VladimirAus, Gábor Hojtsy, Jose Reyero, Anybody, kristiaanvandeneynde, Sutharsan, casey, smustgrave, nod_: Installing a module causes translations to be overwritten

(cherry picked from commit e029e6cd)
parent 7fe89741
No related branches found
No related tags found
5 merge requests!8506Draft: Issue #3456536 by ibrahim tameme,!5646Issue #3350972 by nod_: [random test failure]...,!5600Issue #3350972 by nod_: [random test failure]...,!5343Issue #3305066 by quietone, Rename RedirectLeadingSlashesSubscriber,!3603#ISSUE 3346218 Add a different message on edit comment
......@@ -1839,7 +1839,7 @@ function install_finish_translations(&$install_state) {
}
// Creates configuration translations.
$batches[] = locale_config_batch_update_components([], array_keys($languages));
$batches[] = locale_config_batch_update_components([], array_keys($languages), [], TRUE);
return $batches;
}
......
......@@ -538,14 +538,19 @@ function locale_translate_delete_translation_files(array $projects = [], array $
* @param array $components
* (optional) Array of component lists indexed by type. If not present or it
* is an empty array, it will update all components.
* @param bool $update_default_config_langcodes
* Determines whether default configuration langcodes should be updated. This
* Should only happen during site and extension install.
*
* @return array
* The batch definition.
*/
function locale_config_batch_update_components(array $options, array $langcodes = [], array $components = []) {
function locale_config_batch_update_components(array $options, array $langcodes = [], array $components = [], bool $update_default_config_langcodes = FALSE) {
$langcodes = $langcodes ? $langcodes : array_keys(\Drupal::languageManager()->getLanguages());
if ($langcodes && $names = Locale::config()->getComponentNames($components)) {
return locale_config_batch_build($names, $langcodes, $options);
// If the component list is empty we need to ensure that all configuration
// in the default collection is using the site's default langcode.
return locale_config_batch_build($names, $langcodes, $options, $update_default_config_langcodes);
}
}
......@@ -560,19 +565,27 @@ function locale_config_batch_update_components(array $options, array $langcodes
* (optional) An array with options that can have the following elements:
* - 'finish_feedback': Whether or not to give feedback to the user when the
* batch is finished. Defaults to TRUE.
* @param bool $update_default_config_langcodes
* Determines whether default configuration langcodes should be updated. This
* Should only happen during site and extension install.
*
* @return array
* The batch definition.
*
* @see locale_config_batch_refresh_name()
*/
function locale_config_batch_build(array $names, array $langcodes, array $options = []) {
function locale_config_batch_build(array $names, array $langcodes, array $options = [], bool $update_default_config_langcodes = FALSE) {
$options += ['finish_feedback' => TRUE];
$batch_builder = (new BatchBuilder())
->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.bulk.inc')
->setTitle(t('Updating configuration translations'))
->setInitMessage(t('Starting configuration update'))
->setErrorMessage(t('Error updating configuration translations'));
if ($update_default_config_langcodes && \Drupal::languageManager()->getDefaultLanguage()->getId() !== 'en') {
$batch_builder->addOperation('locale_config_batch_set_config_langcodes');
}
$i = 0;
$batch_names = [];
foreach ($names as $name) {
......@@ -596,6 +609,20 @@ function locale_config_batch_build(array $names, array $langcodes, array $option
return $batch_builder->toArray();
}
/**
* Implements callback_batch_operation().
*
* Updates default configuration when new modules or themes are installed.
*
* @param array|\ArrayAccess $context
* The batch context.
*/
function locale_config_batch_set_config_langcodes(&$context) {
Locale::config()->updateDefaultConfigLangcodes();
$context['finished'] = 1;
$context['message'] = t('Updated default configuration to %langcode', ['%langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId()]);
}
/**
* Implements callback_batch_operation().
*
......
......@@ -319,8 +319,6 @@ function locale_get_plural($count, $langcode = NULL) {
* Implements hook_modules_installed().
*/
function locale_modules_installed($modules) {
locale_system_set_config_langcodes();
$components['module'] = $modules;
locale_system_update($components);
}
......@@ -337,8 +335,6 @@ function locale_module_preuninstall($module) {
* Implements hook_themes_installed().
*/
function locale_themes_installed($themes) {
locale_system_set_config_langcodes();
$components['theme'] = $themes;
locale_system_update($components);
}
......@@ -370,28 +366,7 @@ function locale_cron() {
* Updates default configuration when new modules or themes are installed.
*/
function locale_system_set_config_langcodes() {
// Need to rewrite some default configuration language codes if the default
// site language is not English.
$default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
if ($default_langcode != 'en') {
// Update active configuration copies of all prior shipped configuration if
// they are still English. It is not enough to change configuration shipped
// with the components just installed, because installing a component such
// as views or tour module may bring in default configuration from prior
// components.
$names = Locale::config()->getComponentNames();
foreach ($names as $name) {
$config = \Drupal::configFactory()->reset($name)->getEditable($name);
// Should only update if still exists in active configuration. If locale
// module is enabled later, then some configuration may not exist anymore.
if (!$config->isNew()) {
$langcode = $config->get('langcode');
if (empty($langcode) || $langcode == 'en') {
$config->set('langcode', $default_langcode)->save();
}
}
}
}
Locale::config()->updateDefaultConfigLangcodes();
}
/**
......@@ -435,7 +410,7 @@ function locale_system_update(array $components) {
// components. Do this even if import is not enabled because parsing new
// configuration may expose new source strings.
$module_handler->loadInclude('locale', 'inc', 'locale.bulk');
if ($batch = locale_config_batch_update_components([])) {
if ($batch = locale_config_batch_update_components([], [], [], TRUE)) {
batch_set($batch);
}
}
......
......@@ -649,4 +649,34 @@ protected function filterOverride(array $override_data, array $translatable) {
return $filtered_data;
}
/**
* Updates default configuration when new modules or themes are installed.
*/
public function updateDefaultConfigLangcodes() {
$this->isUpdatingFromLocale = TRUE;
// Need to rewrite some default configuration language codes if the default
// site language is not English.
$default_langcode = $this->languageManager->getDefaultLanguage()->getId();
if ($default_langcode != 'en') {
// Update active configuration copies of all prior shipped configuration if
// they are still English. It is not enough to change configuration shipped
// with the components just installed, because installing a component such
// as views or tour module may bring in default configuration from prior
// components.
$names = $this->getComponentNames();
foreach ($names as $name) {
$config = $this->configFactory->reset($name)->getEditable($name);
// Should only update if still exists in active configuration. If locale
// module is enabled later, then some configuration may not exist anymore.
if (!$config->isNew()) {
$langcode = $config->get('langcode');
if (empty($langcode) || $langcode == 'en') {
$config->set('langcode', $default_langcode)->save();
}
}
}
}
$this->isUpdatingFromLocale = FALSE;
}
}
......@@ -8,3 +8,5 @@ locale_test_translate.settings:
type: label
translatable_default_with_no_translation:
type: label
key_set_during_install:
type: boolean
......@@ -20,3 +20,15 @@ function locale_test_translate_system_info_alter(&$info, Extension $file, $type)
$info['hidden'] = FALSE;
}
}
/**
* Implements hook_modules_installed().
*
* @see \Drupal\Tests\locale\Functional\LocaleConfigTranslationImportTest::testConfigTranslationWithForeignLanguageDefault
*/
function locale_test_translate_modules_installed($modules, $is_syncing) {
// Ensure that writing to configuration during install does not cause
// \Drupal\locale\LocaleConfigSubscriber to create incorrect translations due
// the configuration langcode and data being out-of-sync.
\Drupal::configFactory()->getEditable('locale_test_translate.settings')->set('key_set_during_install', TRUE)->save();
}
......@@ -305,4 +305,66 @@ public function testLocaleRemovalAndConfigOverridePreserve() {
$this->assertEquals($expected, $override->get());
}
/**
* Tests setting a non-English language as default and importing configuration.
*/
public function testConfigTranslationWithNonEnglishLanguageDefault() {
/** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
$module_installer = $this->container->get('module_installer');
ConfigurableLanguage::createFromLangcode('af')->save();
$module_installer->install(['locale']);
$this->resetAll();
/** @var \Drupal\locale\StringStorageInterface $local_storage */
$local_storage = $this->container->get('locale.storage');
$source_string = 'Locale can translate';
$translation_string = 'Locale can translate Afrikaans';
// Create a translation for the "Locale can translate" string, this string
// can be found in the "locale_test_translate" module's install config.
$source = $local_storage->createString([
'source' => $source_string,
])->save();
$local_storage->createTranslation([
'lid' => $source->getId(),
'language' => 'af',
'translation' => $translation_string,
])->save();
// Verify that we can find the newly added string translation, it is not a
// customized translation.
$translation = $local_storage->findTranslation([
'source' => $source_string,
'language' => 'af',
]);
$this->assertEquals($translation_string, $translation->getString());
$this->assertFalse((bool) $translation->customized);
// Uninstall the "locale_test_translate" module, verify that we can still
// find the string translation.
$module_installer->uninstall(['locale_test_translate']);
$this->resetAll();
$translation = $local_storage->findTranslation([
'source' => $source_string,
'language' => 'af',
]);
$this->assertEquals($translation_string, $translation->getString());
// Set the default language to "Afrikaans" and re-enable the
// "locale_test_translate" module.
$this->config('system.site')->set('default_langcode', 'af')->save();
$module_installer->install(['locale_test_translate']);
$this->resetAll();
// Verify that enabling the "locale_test_translate" module didn't cause
// the string translation to be overwritten.
$translation = $local_storage->findTranslation([
'source' => $source_string,
'language' => 'af',
]);
$this->assertEquals($translation_string, $translation->getString());
$this->assertFalse((bool) $translation->customized);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment