diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php index 3712fc3..e6412d0 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php @@ -150,6 +150,75 @@ function testConfigLocaleUserOverride() { } /** + * Tests locale override based on language. + */ + function testConfigLocaleLanguageOverride() { + $this->installSchema('system', 'variable'); + $this->installSchema('language', 'language'); + language_save(new Language(array( + 'name' => 'French', + 'langcode' => 'fr', + ))); + language_save(new Language(array( + 'name' => 'English', + 'langcode' => 'en', + ))); + language_save(new Language(array( + 'name' => 'German', + 'langcode' => 'de', + ))); + + $language = language_load('fr'); + $language_config_context = config_context_enter('Drupal\language\LanguageConfigContext'); + $language_config_context->setLanguage($language); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'fr bar'); + // Ensure the non-overridden value is still the same. + $this->assertIdentical($config->get('404'), 'herp'); + + // Ensure that we get the expected value when we leave the user context. The + // locale overrides contain an English override too, so although we are not + // in a user based language override context, the English language override + // applies due to the negotiated language for the page. + config_context_leave(); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'en bar'); + + $config_factory = \Drupal::service('config.factory'); + $language = language_load('de'); + $config_factory->enterContext($language_config_context->setLanguage($language)); + // Should not have to re-initialize the configuration object to get new + // overrides as the new context will have a different uuid. + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'de bar'); + + // Enter an english context on top of the german context. + $language = language_load('en'); + // Create a new language config context to stack on top of the existing one. + $en_language_config_context = config_context_enter('Drupal\language\LanguageConfigContext'); + $en_language_config_context->setLanguage($language); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'en bar'); + + // Ensure that we get the expected value when we leave the english user + // context. + config_context_leave(); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'de bar'); + + // Ensure that we get the expected value when we leave the german user + // context. + config_context_leave(); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'en bar'); + + // Ensure that we cannot leave the default context. + config_context_leave(); + $config = config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'en bar'); + } + + /** * Tests locale override in combination with global overrides. */ function testConfigLocaleUserAndGlobalOverride() { diff --git a/core/modules/language/lib/Drupal/language/LanguageConfigContext.php b/core/modules/language/lib/Drupal/language/LanguageConfigContext.php new file mode 100644 index 0000000..58b83a6 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/LanguageConfigContext.php @@ -0,0 +1,44 @@ +set(self::LANGUAGE_KEY, $language); + // Re-initialize since the language change changes the context fundamentally. + $this->init(); + return $this; + } + +} diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php index 093c787..d0eb123 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php @@ -62,10 +62,14 @@ public function __construct(LanguageManager $language_manager, ContextInterface public function configContext(ConfigEvent $event) { $context = $event->getContext(); - // If there is a user set in the current context, set the language based on - // the preferred language of the user. Otherwise set it based on the - // negotiated interface language. - if ($account = $context->get('user.account')) { + // If there is a language set explicitly in current context, use it. + // otherwise check if there is a user set in the current context, + // to set the language based on the preferred language of the user. + // Otherwise set it based on the negotiated interface language. + if ($language = $context->get('language')) { + $context->set('locale.language', $language); + } + elseif ($account = $context->get('user.account')) { $context->set('locale.language', language_load(user_preferred_langcode($account))); } elseif ($language = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)) {