diff -u b/core/core.services.yml b/core/core.services.yml --- b/core/core.services.yml +++ b/core/core.services.yml @@ -80,7 +80,7 @@ tags: - { name: persist } - { name: event_subscriber } - arguments: ['@config.storage', '@event_dispatcher', '@config.typed', '@language.default'] + arguments: ['@config.storage', '@event_dispatcher', '@config.typed'] config.installer: class: Drupal\Core\Config\ConfigInstaller arguments: ['@config.factory', '@config.storage', '@config.typed', '@entity.manager', '@event_dispatcher'] diff -u b/core/includes/install.core.inc b/core/includes/install.core.inc --- b/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -390,8 +390,7 @@ $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') ->addArgument(new Reference('config.storage')) ->addArgument(new Reference('event_dispatcher')) - ->addArgument(new Reference('config.typed')) - ->addArgument(new Reference('language.default')); + ->addArgument(new Reference('config.typed')); // Register the 'language_manager' service. $container->register('language_manager', 'Drupal\Core\Language\LanguageManager') diff -u b/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php --- b/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -83,16 +83,11 @@ * An event dispatcher instance to use for configuration events. * @param \Drupal\Core\Config\TypedConfigManager $typed_config * The typed configuration manager. - * @param \Drupal\Core\Language\LanguageDefault - * The default language service. This sets the initial language on the - * config factory to the site's default. The language can be used to - * override configuration data if language overrides are available. */ - public function __construct(StorageInterface $storage, EventDispatcher $event_dispatcher, TypedConfigManager $typed_config, LanguageDefault $default_language) { + public function __construct(StorageInterface $storage, EventDispatcher $event_dispatcher, TypedConfigManager $typed_config) { $this->storage = $storage; $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; - $this->language = $default_language->get(); } /** @@ -146,7 +141,12 @@ if ($this->canOverride($name)) { // Get and apply any language overrides. - $language_overrides = $this->storage->read($this->getLanguageConfigName($this->language->id, $name)); + if ($this->language) { + $language_overrides = $this->storage->read($this->getLanguageConfigName($this->language->id, $name)); + } + else { + $language_overrides = FALSE; + } if (is_array($language_overrides)) { $this->cache[$cache_key]->setLanguageOverride($language_overrides); } @@ -322,7 +322,7 @@ $can_override = $this->canOverride($name); $cache_key = $name . ':' . ($can_override ? 'overrides' : 'raw'); - if ($can_override) { + if ($can_override && isset($this->language)) { $cache_key = $cache_key . ':' . $this->language->id; } return $cache_key; @@ -356,7 +356,7 @@ } /** - * Set the language to be used in configuration overrides. + * Sets the language to be used in configuration overrides. * * @param \Drupal\Core\Language\Language $language * The language object to be set on the config factory. Used to override @@ -365,12 +365,28 @@ * @return \Drupal\Core\Config\ConfigFactory * The config factory object. */ - public function setLanguage(Language $language) { + public function setLanguage(Language $language = NULL) { $this->language = $language; return $this; } /** + * Sets the language for configuration overrides using the default language. + * + * @param \Drupal\Core\Language\LanguageDefault $language_default + * The default language service. This sets the initial language on the + * config factory to the site's default. The language can be used to + * override configuration data if language overrides are available. + * + * @return \Drupal\Core\Config\ConfigFactory + * The config factory object. + */ + public function setLanguageFromDefault(LanguageDefault $language_default) { + $this->language = $language_default->get(); + return $this; + } + + /** * Gets the language Used to override configuration. * * @return \Drupal\Core\Language\Language @@ -393,9 +409,11 @@ */ public function getLanguageConfigNames(array $names) { $language_names = array(); - foreach ($names as $name) { - if ($language_name = $this->getLanguageConfigName($this->language->id, $name)) { - $language_names[$name] = $language_name; + if (isset($this->language)) { + foreach ($names as $name) { + if ($language_name = $this->getLanguageConfigName($this->language->id, $name)) { + $language_names[$name] = $language_name; + } } } return $language_names; diff -u b/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php --- b/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -518,8 +518,10 @@ $container->setParameter('container.namespaces', $namespaces); // Store the default language values on the container. This is so that the - // default language can be configured and the configuration factory can - // depend on it. + // default language can be configured using the configuration factory. This + // avoids the circular dependencies that would created by + // \Drupal\language\LanguageServiceProvider::alter() and allows the default + // language to not be english in the installer. $system = BootstrapConfigStorageFactory::get()->read('system.site'); $default_language_values = Language::$defaultValues; if ($default_language_values['id'] != $system['langcode']) { diff -u b/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php --- b/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -93,6 +93,7 @@ * {@inheritdoc} */ public function reset($type = NULL) { + return $this; } /** diff -u b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php --- b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php @@ -39,8 +39,16 @@ * Tests locale override based on language. */ function testConfigLanguageOverride() { - // The configuration factory always has the default language injected by the - // container. + // The default configuration factory does not have the default language + // injected unless the Language module is enabled. + $config = \Drupal::config('config_test.system'); + $this->assertIdentical($config->get('foo'), 'bar'); + + // \Drupal\language\LanguageServiceProvider::alter() calls + // \Drupal\Core\Config\ConfigFactory::setLanguageFromDefault() to set the + // language when the Language module is enabled. This test ensures that + // english overrides work. + \Drupal::configFactory()->setLanguageFromDefault(\Drupal::service('language.default')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'en bar'); diff -u b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php --- b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php @@ -108,13 +108,6 @@ /** * {@inheritdoc} */ - public function initConfigOverrides() { - $this->configFactory->setLanguage($this->getCurrentLanguage()); - } - - /** - * {@inheritdoc} - */ public function init() { if (!$this->initialized) { foreach ($this->getDefinedLanguageTypes() as $type) { @@ -226,6 +219,7 @@ elseif (isset($this->negotiatedLanguages[$type])) { unset($this->negotiatedLanguages[$type]); } + return $this; } /** diff -u b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php --- b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php +++ b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php @@ -31,7 +31,8 @@ ->addArgument(new Reference('language_manager')) ->addArgument(new Reference('language_negotiator')) ->addArgument(new Reference('string_translation')) - ->addArgument(new Reference('current_user')); + ->addArgument(new Reference('current_user')) + ->addArgument(new Reference('config.factory')); $container->register('path_processor_language', 'Drupal\language\HttpKernel\PathProcessorLanguage') ->addTag('path_processor_inbound', array('priority' => 300)) @@ -54,6 +55,11 @@ ->addArgument(new Reference('module_handler')); if ($default_language_values = $this->getDefaultLanguageValues()) { $container->setParameter('language.default_values', $default_language_values); + // Ensure that configuration is can be localised if site is monolingual + // but the Language module is enabled. This will the case for monolingual + // sites not in english. + $definition = $container->getDefinition('config.factory'); + $definition->addMethodCall('setLanguageFromDefault', array(new Reference('language.default'))); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php +++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php @@ -62,6 +62,9 @@ public function getCurrentLanguage($type = Language::TYPE_INTERFACE); * (optional) The language type to reset as a string, e.g., * Language::TYPE_INTERFACE, or NULL to reset all language types. Defaults * to NULL. + * + * @return \Drupal\Core\Language\LanguageManagerInterface + * The language manager that has been reset. */ public function reset($type = NULL); only in patch2: unchanged: --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php @@ -65,6 +65,21 @@ function testSiteNameTranslation() { // @see \Drupal\Core\PathProcessor::processInbound() $this->drupalGet('xx'); $this->assertText('XX site name'); + + // Set the xx language to be the default language and delete the english + // language so the site is no longer multi-lingual and confirm configuration + // overrides still work. + $language_manager = \Drupal::languageManager()->reset(); + $this->assertTrue($language_manager->isMultilingual(), 'The test site is multilingual.'); + $language = \Drupal::languageManager()->getLanguage('xx'); + $language->default = TRUE; + language_save($language); + language_delete('en'); + $this->assertFalse($language_manager->isMultilingual(), 'The test site is monolingual.'); + + $this->drupalGet('xx'); + $this->assertText('XX site name'); + } } only in patch2: unchanged: --- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php @@ -78,9 +78,4 @@ public function saveLanguageTypesConfiguration(array $config); */ public function updateLockedLanguageWeights(); - /** - * Initializes per-language overrides for configuration. - */ - public function initConfigOverrides(); - } only in patch2: unchanged: --- a/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php +++ b/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php @@ -7,6 +7,7 @@ namespace Drupal\language\EventSubscriber; +use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\Translator\TranslatorInterface; @@ -51,6 +52,13 @@ class LanguageRequestSubscriber implements EventSubscriberInterface { protected $currentUser; /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactory + */ + protected $configFactory; + + /** * Constructs a LanguageRequestSubscriber object. * * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager @@ -61,12 +69,15 @@ class LanguageRequestSubscriber implements EventSubscriberInterface { * The translation service. * @param \Drupal\Core\Session\AccountInterface $current_user * The current active user. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The configuration factory. */ - public function __construct(ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, TranslatorInterface $translation, AccountInterface $current_user) { + public function __construct(ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, TranslatorInterface $translation, AccountInterface $current_user, ConfigFactory $config_factory) { $this->languageManager = $language_manager; $this->negotiator = $negotiator; $this->translation = $translation; $this->currentUser = $current_user; + $this->configFactory = $config_factory; } /** @@ -83,7 +94,7 @@ public function onKernelRequestLanguage(GetResponseEvent $event) { if ($this->languageManager instanceof ConfigurableLanguageManagerInterface) { $this->languageManager->setNegotiator($this->negotiator); $this->languageManager->setRequest($request); - $this->languageManager->initConfigOverrides(); + $this->configFactory->setLanguage($this->languageManager->getCurrentLanguage()); } // After the language manager has initialized, set the default langcode // for the string translations.