diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 7ad1aee..19899a5 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -8,12 +8,6 @@ namespace Drupal\Core\Config; use Drupal\Component\Utility\NestedArray; -use Drupal\Component\Utility\String; -use Drupal\Core\Config\Schema\SchemaIncompleteException; -use Drupal\Core\TypedData\PrimitiveInterface; -use Drupal\Core\TypedData\Type\FloatInterface; -use Drupal\Core\TypedData\Type\IntegerInterface; -use Drupal\Core\Language\Language; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -34,30 +28,16 @@ class Config extends StorableConfigBase { protected $eventDispatcher; /** - * The language object used to override configuration data. - * - * @var \Drupal\Core\Language\Language - */ - protected $language; - - /** * The current runtime data. * - * The configuration data from storage merged with language, module and - * settings overrides. + * The configuration data from storage merged with module and settings + * overrides. * * @var array */ protected $overriddenData; /** - * The current language overrides. - * - * @var array - */ - protected $languageOverrides; - - /** * The current module overrides. * * @var array @@ -83,15 +63,12 @@ class Config extends StorableConfigBase { * An event dispatcher instance to use for configuration events. * @param \Drupal\Core\Config\TypedConfigManager $typed_config * The typed configuration manager service. - * @param \Drupal\Core\Language\Language $language - * The language object used to override configuration data. */ - public function __construct($name, StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManager $typed_config, Language $language = NULL) { + public function __construct($name, StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManager $typed_config) { $this->name = $name; $this->storage = $storage; $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; - $this->language = $language; } /** @@ -100,7 +77,6 @@ public function __construct($name, StorageInterface $storage, EventDispatcherInt public function initWithData(array $data) { parent::initWithData($data); $this->settingsOverrides = array(); - $this->languageOverrides = array(); $this->moduleOverrides = array(); $this->setData($data); return $this; @@ -170,36 +146,18 @@ public function setModuleOverride(array $data) { } /** - * Sets language overrides for this configuration object. - * - * @param array $data - * The overridden values of the configuration data. - * - * @return \Drupal\Core\Config\Config - * The configuration object. - */ - public function setLanguageOverride(array $data) { - $this->languageOverrides = $data; - $this->resetOverriddenData(); - return $this; - } - - /** * Sets the current data for this configuration object. * - * Configuration overrides operate at three distinct layers: language, modules - * and settings.php, with the last of these taking precedence. Overrides in - * settings.php take precedence over values provided by modules. Overrides - * provided by modules take precedence over language. + * Configuration overrides operate at two distinct layers: modules and + * settings.php. Overrides in settings.php take precedence over values + * provided by modules. Precedence or different module overrides is + * determined by the priority of the config.factory.override tagged services. * * @return \Drupal\Core\Config\Config * The configuration object. */ protected function setOverriddenData() { $this->overriddenData = $this->data; - if (isset($this->languageOverrides) && is_array($this->languageOverrides)) { - $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $this->languageOverrides), TRUE); - } if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { $this->overriddenData = NestedArray::mergeDeepArray(array($this->overriddenData, $this->moduleOverrides), TRUE); } @@ -283,15 +241,6 @@ public function delete() { } /** - * Returns the language object for this Config object. - * - * @return \Drupal\Core\Language\Language - */ - public function getLanguage() { - return $this->language; - } - - /** * Gets the raw data without overrides. * * @return array @@ -322,9 +271,6 @@ public function getOriginal($key = '', $apply_overrides = TRUE) { $original_data = $this->originalData; if ($apply_overrides) { // Apply overrides. - if (isset($this->languageOverrides) && is_array($this->languageOverrides)) { - $original_data = NestedArray::mergeDeepArray(array($original_data, $this->languageOverrides), TRUE); - } if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { $original_data = NestedArray::mergeDeepArray(array($original_data, $this->moduleOverrides), TRUE); } diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 2703646..0e7826e 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -7,9 +7,6 @@ namespace Drupal\Core\Config; -use Drupal\Core\Language\Language; -use Drupal\Core\Language\LanguageDefault; -use Symfony\Component\EventDispatcher\EventDispatcher; use Drupal\Component\Utility\NestedArray; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -51,13 +48,6 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface protected $useOverrides = TRUE; /** - * The language object used to override configuration data. - * - * @var \Drupal\Core\Language\Language - */ - protected $language; - - /** * Cached configuration objects. * * @var \Drupal\Core\Config\Config[] @@ -126,23 +116,13 @@ public function get($name) { // If the configuration object does not exist in the configuration // storage or static cache create a new object and add it to the static // cache. - $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); + $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); - if ($this->canOverride($name)) { - // Get and apply any language overrides. - 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); - } - // Get and apply any module overrides. - $module_overrides = $this->loadModuleOverrides(array($name)); - if (isset($module_overrides[$name])) { - $this->cache[$cache_key]->setModuleOverride($module_overrides[$name]); + if ($this->useOverrides) { + // Get and apply any overrides. + $overrides = $this->loadOverrides(array($name)); + if (isset($overrides[$name])) { + $this->cache[$cache_key]->setModuleOverride($overrides[$name]); } // Apply any settings.php overrides. if (isset($GLOBALS['config'][$name])) { @@ -174,38 +154,19 @@ public function loadMultiple(array $names) { if (!empty($names)) { // Initialise override information. $module_overrides = array(); - $language_names = array(); - - if ($this->useOverrides) { - // In order to make just one call to storage, add in language names. - // Keep track of them separately, so we can get language override data - // returned from storage and set it on new Config objects. - $language_names = $this->getLanguageConfigNames($names); - } - - $storage_data = $this->storage->readMultiple(array_merge($names, array_values($language_names))); + $storage_data = $this->storage->readMultiple($names); if ($this->useOverrides && !empty($storage_data)) { - // Only fire module override event if we have configuration to override. - $module_overrides = $this->loadModuleOverrides($names); + // Only get module overrides if we have configuration to override. + $module_overrides = $this->loadOverrides($names); } foreach ($storage_data as $name => $data) { - if (in_array($name, $language_names)) { - // Language override configuration is used to override other - // configuration. Therefore, when it has been added to the - // $storage_data it is not statically cached in the config factory or - // overridden in any way. - continue; - } $cache_key = $this->getCacheKey($name); - $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); + $this->cache[$cache_key] = new Config($name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); $this->cache[$cache_key]->initWithData($data); - if ($this->canOverride($name)) { - if (isset($language_names[$name]) && isset($storage_data[$language_names[$name]])) { - $this->cache[$cache_key]->setLanguageOverride($storage_data[$language_names[$name]]); - } + if ($this->useOverrides) { if (isset($module_overrides[$name])) { $this->cache[$cache_key]->setModuleOverride($module_overrides[$name]); } @@ -229,7 +190,7 @@ public function loadMultiple(array $names) { * @return array * An array of overrides keyed by the configuration object name. */ - protected function loadModuleOverrides(array $names) { + protected function loadOverrides(array $names) { $overrides = array(); foreach ($this->configFactoryOverrides as $override) { // Existing overrides take precedence since these will have been added @@ -280,11 +241,14 @@ public function rename($old_name, $new_name) { * {@inheritdoc} */ public function getCacheKey($name) { - $can_override = $this->canOverride($name); - $cache_key = $name . ':' . ($can_override ? 'overrides' : 'raw'); - - if ($can_override && isset($this->language)) { - $cache_key = $cache_key . ':' . $this->language->id; + if ($this->useOverrides) { + $cache_key = $name . ':overrides'; + foreach($this->configFactoryOverrides as $override) { + $cache_key = $cache_key . ':' . $override->getCacheSuffix(); + } + } + else { + $cache_key = $name . ':raw'; } return $cache_key; } @@ -310,74 +274,11 @@ public function clearStaticCache() { /** * {@inheritdoc} */ - public function setLanguage(Language $language = NULL) { - $this->language = $language; - return $this; - } - - /** - * {@inheritdoc} - */ - public function setLanguageFromDefault(LanguageDefault $language_default) { - $this->language = $language_default->get(); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getLanguage() { - return $this->language; - } - - /** - * {@inheritdoc} - */ - public function getLanguageConfigNames(array $names) { - $language_names = array(); - 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; - } - - /** - * {@inheritdoc} - */ - public function getLanguageConfigName($langcode, $name) { - if (strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0) { - return FALSE; - } - return static::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.' . $name; - } - - /** - * {@inheritdoc} - */ public function listAll($prefix = '') { return $this->storage->listAll($prefix); } /** - * Determines if a particular configuration object can be overridden. - * - * Language override configuration should not be overridden. - * - * @param string $name - * The name of the configuration object. - * - * @return bool - * TRUE if the configuration object can be overridden. - */ - protected function canOverride($name) { - return $this->useOverrides && !(strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0); - } - - /** * Removes stale static cache entries when configuration is saved. * * @param ConfigCrudEvent $event diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php index be656ea..639b483 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php @@ -16,11 +16,6 @@ interface ConfigFactoryInterface { /** - * Prefix for all language configuration files. - */ - const LANGUAGE_CONFIG_PREFIX = 'language.config'; - - /** * Sets the override state. * * @param bool $state @@ -117,67 +112,6 @@ public function getCacheKeys($name); public function clearStaticCache(); /** - * Sets the language to be used in configuration overrides. - * - * @param \Drupal\Core\Language\Language|null $language - * The language object to be set on the config factory. Used to override - * configuration by language. - * - * @return $this - */ - public function setLanguage(Language $language = NULL); - - /** - * 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 $this - */ - public function setLanguageFromDefault(LanguageDefault $language_default); - - /** - * Gets the language Used to override configuration. - * - * @return \Drupal\Core\Language\Language - */ - public function getLanguage(); - - /** - * Gets configuration names for this language. - * - * It will be the same name with a prefix depending on language code: - * language.config.LANGCODE.NAME - * - * @param array $names - * A list of configuration object names. - * - * @return array - * The localized config names, keyed by configuration object name. - */ - public function getLanguageConfigNames(array $names); - - /** - * Gets configuration name for the provided language. - * - * The name will be the same name with a prefix depending on language code: - * language.config.LANGCODE.NAME - * - * @param string $langcode - * The language code. - * @param string $name - * The name of the configuration object. - * - * @return bool|string - * The configuration name for configuration object providing overrides. - * Returns false if the name already starts with the language config prefix. - */ - public function getLanguageConfigName($langcode, $name); - - /** * Gets configuration object names starting with a given prefix. * * @see \Drupal\Core\Config\StorageInterface::listAll() diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php index cd66d75..06e1f3f 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php @@ -24,4 +24,12 @@ */ public function loadOverrides($names); + /** + * The string to append to the configuration static cache name. + * + * @return string + * A string to append to the configuration static cache name. + */ + public function getCacheSuffix(); + } diff --git a/core/lib/Drupal/Core/Datetime/Date.php b/core/lib/Drupal/Core/Datetime/Date.php index 5c2b92b..c908ca8 100644 --- a/core/lib/Drupal/Core/Datetime/Date.php +++ b/core/lib/Drupal/Core/Datetime/Date.php @@ -215,11 +215,10 @@ protected function t($string, array $args = array(), array $options = array()) { */ protected function dateFormat($format, $langcode) { if (!isset($this->dateFormats[$format][$langcode])) { - // Enter a language specific context so the right date format is loaded. - $original_language = $this->configFactory->getLanguage(); - $this->configFactory->setLanguage(new Language(array('id' => $langcode))); + $original_language = $this->languageManager->getConfigOverrideLanguage(); + $this->languageManager->setConfigOverrideLanguage(new Language(array('id' => $langcode))); $this->dateFormats[$format][$langcode] = $this->dateFormatStorage->load($format); - $this->configFactory->setLanguage($original_language); + $this->languageManager->setConfigOverrideLanguage($original_language); } return $this->dateFormats[$format][$langcode]; } diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 6ddf673..d7b88d0 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -329,4 +329,24 @@ public static function getStandardLanguageList() { ); } + /** + * {@inheritdoc} + * + * This function is a noop since the configuration can not be overridden by + * language unless the Language module is enabled. That replaces the default + * language manger with a configurable language manager. + * + * @see \Drupal\language\ConfigurableLanguageManager::setConfigOverrideLanguage() + */ + public function setConfigOverrideLanguage(Language $language) { + return $this; + } + + /** + * {@inheritdoc} + */ + public function getConfigOverrideLanguage() { + return $this->getCurrentLanguage(); + } + } diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php index 16c7c01..764cf0b 100644 --- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php +++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php @@ -168,4 +168,23 @@ public function getFallbackCandidates($langcode = NULL, array $context = array() */ function getLanguageSwitchLinks($type, $path); + /** + * Sets the configuration override language. + * + * @param \Drupal\Core\Language\Language $language + * The language to override configuration with. + * + * @return $this + * The language manager. + */ + public function setConfigOverrideLanguage(Language $language); + + /** + * Gets the current configuration override language. + * + * @return \Drupal\Core\Language\Language $language + * The current configuration override language. + */ + public function getConfigOverrideLanguage(); + } diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php index 7a6f3cc..81853af 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php @@ -345,7 +345,7 @@ function testLanguages() { * Tests that CKEditor plugins participate in JS translation. */ function testJSTranslation() { - $this->enableModules(array('locale')); + $this->enableModules(array('language', 'locale')); $this->installSchema('locale', 'locales_source'); $this->installSchema('locale', 'locales_location'); $editor = entity_load('editor', 'filtered_html'); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php index 12ff3cd..e0d5b6b 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\config\Tests\ConfigLanguageOverride. + * Contains \Drupal\config\Tests\ConfigLanguageOverrideTest. */ namespace Drupal\config\Tests; @@ -13,14 +13,14 @@ /** * Tests language config override. */ -class ConfigLanguageOverride extends DrupalUnitTestBase { +class ConfigLanguageOverrideTest extends DrupalUnitTestBase { /** * Modules to enable. * * @var array */ - public static $modules = array('config_test', 'user', 'language', 'system', 'field'); + public static $modules = array('user', 'language', 'config_test', 'system', 'field'); public static function getInfo() { return array( @@ -39,16 +39,10 @@ public function setUp() { * Tests locale override based on language. */ function testConfigLanguageOverride() { - // 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 + // The language module implements a config factory override object that + // overrides configuration when the Language module is enabled. This test ensures that // English overrides work. - \Drupal::configFactory()->setLanguageFromDefault(\Drupal::service('language.default')); + \Drupal::languageManager()->setConfigOverrideLanguage(language_load('en')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'en bar'); @@ -65,20 +59,21 @@ function testConfigLanguageOverride() { 'id' => 'de', ))); - \Drupal::configFactory()->setLanguage(language_load('fr')); + \Drupal::languageManager()->setConfigOverrideLanguage(language_load('fr')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'fr bar'); - \Drupal::configFactory()->setLanguage(language_load('de')); + \Drupal::languageManager()->setConfigOverrideLanguage(language_load('de')); $config = \Drupal::config('config_test.system'); $this->assertIdentical($config->get('foo'), 'de bar'); // Test overrides of completely new configuration objects. In normal runtime // this should only happen for configuration entities as we should not be // creating simple configuration objects on the fly. - $language_config_name = \Drupal::configFactory()->getLanguageConfigName('de', 'config_test.new'); - \Drupal::config($language_config_name)->set('language', 'override')->save(); - \Drupal::config('config_test.new'); + \Drupal::languageManager() + ->getLanguageConfigOverride('de', 'config_test.new') + ->set('language', 'override') + ->save(); $config = \Drupal::config('config_test.new'); $this->assertTrue($config->isNew(), 'The configuration object config_test.new is new'); $this->assertIdentical($config->get('language'), 'override'); @@ -87,11 +82,6 @@ function testConfigLanguageOverride() { $config = \Drupal::config('config_test.new'); $this->assertIdentical($config->get('language'), NULL); \Drupal::configFactory()->setOverrideState($old_state); - - // Ensure that language configuration overrides can not be overridden. - global $conf; - $conf[$language_config_name]['language'] = 'conf cannot override'; - $this->assertIdentical(\Drupal::config($language_config_name)->get('language'), 'override'); } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php index 3ffb54f..34f5172 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverrideWebTest.php @@ -45,10 +45,10 @@ function testSiteNameTranslation() { 'direction' => '0', ); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); - - // Save an override for the XX language. - $config_name = \Drupal::configFactory()->getLanguageConfigName('xx', 'system.site'); - \Drupal::config($config_name)->set('name', 'XX site name')->save(); + \Drupal::languageManager() + ->getLanguageConfigOverride($langcode, 'system.site') + ->set('name', 'XX site name') + ->save(); $this->drupalLogout(); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigOverridesPriorityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigOverridesPriorityTest.php index 49482f9..6deab96 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigOverridesPriorityTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigOverridesPriorityTest.php @@ -15,7 +15,7 @@ */ class ConfigOverridesPriorityTest extends DrupalUnitTestBase { - public static $modules = array('system', 'config', 'config_override'); + public static $modules = array('system', 'config', 'config_override', 'language'); public static function getInfo() { return array( @@ -59,10 +59,9 @@ public function testOverridePriorities() { 'name' => 'French', 'id' => 'fr', )); - $config_factory->setLanguage($language); - $language_config_name = $config_factory->getLanguageConfigName($language->id, 'system.site'); - $config_factory - ->get($language_config_name) + \Drupal::languageManager()->setConfigOverrideLanguage($language); + \Drupal::languageManager() + ->getLanguageConfigOverride($language->id, 'system.site') ->set('name', $language_overridden_name) ->set('mail', $language_overridden_mail) ->save(); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php index e9d7562..79c8fc5 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php @@ -21,7 +21,7 @@ class ConfigSchemaTest extends DrupalUnitTestBase { * * @var array */ - public static $modules = array('system', 'locale', 'field', 'image', 'config_test'); + public static $modules = array('system', 'language', ',locale', 'field', 'image', 'config_test'); public static function getInfo() { return array( diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php index 2d60d33..106df3d 100644 --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php @@ -33,5 +33,12 @@ public function loadOverrides($names) { return $overrides; } + /** + * {@inheritdoc} + */ + public function getCacheSuffix() { + return 'ConfigOverrider'; + } + } diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php index 1903888..a9a435e 100644 --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php @@ -34,5 +34,12 @@ public function loadOverrides($names) { return $overrides; } + /** + * {@inheritdoc} + */ + public function getCacheSuffix() { + return 'ConfigOverriderLowPriority'; + } + } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php index 319e168..fe79059 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationDeleteForm.php @@ -9,10 +9,9 @@ use Drupal\config_translation\ConfigMapperManagerInterface; use Drupal\Core\Cache\Cache; -use Drupal\Core\Config\StorageInterface; -use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfirmFormBase; +use Drupal\language\ConfigurableLanguageManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -23,11 +22,11 @@ class ConfigTranslationDeleteForm extends ConfirmFormBase { /** - * The configuration storage. + * The language manager. * - * @var \Drupal\Core\Config\StorageInterface $config_storage + * @var \Drupal\language\ConfigurableLanguageManagerInterface */ - protected $configStorage; + protected $languageManager; /** * The configuration mapper manager. @@ -60,20 +59,17 @@ class ConfigTranslationDeleteForm extends ConfirmFormBase { /** * Constructs a ConfigTranslationDeleteForm. * - * @param \Drupal\Core\Config\StorageInterface $config_storage - * The configuration storage. + * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager + * The language override configuration storage. * @param \Drupal\config_translation\ConfigMapperManagerInterface $config_mapper_manager * The configuration mapper manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The configuration factory. */ - public function __construct(StorageInterface $config_storage, ConfigMapperManagerInterface $config_mapper_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory) { - $this->configStorage = $config_storage; + public function __construct(ConfigurableLanguageManagerInterface $language_manager, ConfigMapperManagerInterface $config_mapper_manager, ModuleHandlerInterface $module_handler) { + $this->languageManager = $language_manager; $this->configMapperManager = $config_mapper_manager; $this->moduleHandler = $module_handler; - $this->configFactory = $config_factory; } /** @@ -81,10 +77,9 @@ public function __construct(StorageInterface $config_storage, ConfigMapperManage */ public static function create(ContainerInterface $container) { return new static( - $container->get('config.storage'), + $container->get('language_manager'), $container->get('plugin.manager.config_translation.mapper'), - $container->get('module_handler'), - $container->get('config.factory') + $container->get('module_handler') ); } @@ -142,8 +137,7 @@ public function buildForm(array $form, array &$form_state, Request $request = NU */ public function submitForm(array &$form, array &$form_state) { foreach ($this->mapper->getConfigNames() as $name) { - $config_name = $this->configFactory->getLanguageConfigName($this->language->id, $name); - $this->configStorage->delete($config_name); + $this->languageManager->getLanguageConfigOverride($this->language->id, $name)->delete(); } // Flush all persistent caches. diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php index 3c09ba4..4d2bd68 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php @@ -16,6 +16,7 @@ use Drupal\Core\Form\BaseFormIdInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\Language\Language; +use Drupal\language\ConfigurableLanguageManagerInterface; use Drupal\locale\StringStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -62,6 +63,13 @@ protected $mapper; /** + * The language manager. + * + * @var \Drupal\language\ConfigurableLanguageManagerInterface + */ + protected $languageManager; + + /** * The language of the configuration translation. * * @var \Drupal\Core\Language\Language @@ -96,12 +104,13 @@ * @param \Drupal\Core\Config\ConfigFactoryInterface * The config factory. */ - public function __construct(TypedConfigManager $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory) { + public function __construct(TypedConfigManager $typed_config_manager, ConfigMapperManagerInterface $config_mapper_manager, StringStorageInterface $locale_storage, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, ConfigurableLanguageManagerInterface $language_manager) { $this->typedConfigManager = $typed_config_manager; $this->configMapperManager = $config_mapper_manager; $this->localeStorage = $locale_storage; $this->moduleHandler = $module_handler; $this->configFactory = $config_factory; + $this->languageManager = $language_manager; } /** @@ -113,7 +122,8 @@ public static function create(ContainerInterface $container) { $container->get('plugin.manager.config_translation.mapper'), $container->get('locale.storage'), $container->get('module_handler'), - $container->get('config.factory') + $container->get('config.factory'), + $container->get('language_manager') ); } @@ -172,8 +182,8 @@ public function buildForm(array $form, array &$form_state, Request $request = NU $this->configFactory->setOverrideState($old_state); // Set the translation target language on the configuration factory. - $original_language = $this->configFactory->getLanguage(); - $this->configFactory->setLanguage($this->language); + $original_language = $this->languageManager->getConfigOverrideLanguage(); + $this->languageManager->setConfigOverrideLanguage($this->language); // Add some information to the form state for easier form altering. $form_state['config_translation_mapper'] = $this->mapper; @@ -199,7 +209,7 @@ public function buildForm(array $form, array &$form_state, Request $request = NU ); // Set the configuration language back. - $this->configFactory->setLanguage($original_language); + $this->languageManager->setConfigOverrideLanguage($original_language); return $form; } @@ -217,19 +227,18 @@ public function submitForm(array &$form, array &$form_state) { foreach ($this->mapper->getConfigNames() as $name) { // Set configuration values based on form submission and source values. $base_config = $this->config($name); - $translation_config_name = $this->configFactory->getLanguageConfigName($this->language->id, $name); - $translation_config = $this->config($translation_config_name); + $config_translation = $this->languageManager->getLanguageConfigOverride($this->language->id, $name); $locations = $this->localeStorage->getLocations(array('type' => 'configuration', 'name' => $name)); - $this->setConfig($this->language, $base_config, $translation_config, $form_values[$name], !empty($locations)); + $this->setConfig($this->language, $base_config, $config_translation, $form_values[$name], !empty($locations)); // If no overrides, delete language specific configuration file. - $saved_config = $translation_config->get(); + $saved_config = $config_translation->get(); if (empty($saved_config)) { - $translation_config->delete(); + $config_translation->delete(); } else { - $translation_config->save(); + $config_translation->save(); } } $this->configFactory->setOverrideState($old_state); @@ -346,9 +355,8 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d * Set the configuration in this language. * @param \Drupal\Core\Config\Config $base_config * Base configuration values, in the source language. - * @param \Drupal\Core\Config\Config $translation_config - * Translation configuration instance. Values from $config_values will be - * set in this instance. + * @param \Drupal\Core\Config\Config $config_translation + * Translation configuration override data. * @param array $config_values * A simple one dimensional or recursive array: * - simple: @@ -363,12 +371,15 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d * @param bool $shipped_config * (optional) Flag to specify whether the configuration had a shipped * version and therefore should also be stored in the locale database. + * + * @return array + * Translation configuration override data. */ - protected function setConfig(Language $language, Config $base_config, Config $translation_config, array $config_values, $shipped_config = FALSE) { + protected function setConfig(Language $language, Config $base_config, Config $config_translation, array $config_values, $shipped_config = FALSE) { foreach ($config_values as $key => $value) { if (is_array($value) && !isset($value['translation'])) { // Traverse into this level in the configuration. - $this->setConfig($language, $base_config, $translation_config, $value, $shipped_config); + $this->setConfig($language, $base_config, $config_translation, $value, $shipped_config); } else { @@ -398,10 +409,10 @@ protected function setConfig(Language $language, Config $base_config, Config $tr // Save value, if different from the source value in the base // configuration. If same as original configuration, remove override. if ($base_config->get($key) !== $value['translation']) { - $translation_config->set($key, $value['translation']); + $config_translation->set($key, $value['translation']); } else { - $translation_config->clear($key); + $config_translation->clear($key); } } } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php index ed4b1e2..405aaf5 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php @@ -177,16 +177,14 @@ public function testSourceValueDuplicateSave() { $this->drupalPostForm("$translation_base_url/fr/add", $edit, t('Save translation')); // Read overridden file from active config. - $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); - $language_config_name = \Drupal::configFactory()->getLanguageConfigName('fr', 'system.site'); - $config_parsed = $file_storage->read($language_config_name); + $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site'); // Expect both name and slogan in language specific file. $expected = array( 'name' => 'FR ' . $site_name, 'slogan' => 'FR ' . $site_slogan, ); - $this->assertEqual($expected, $config_parsed); + $this->assertEqual($expected, $override->get()); // Case 2: Update new value for site slogan and default value for site name. $this->drupalGet("$translation_base_url/fr/edit"); @@ -200,11 +198,11 @@ public function testSourceValueDuplicateSave() { ); $this->drupalPostForm(NULL, $edit, t('Save translation')); $this->assertRaw(t('Successfully updated @language translation.', array('@language' => 'French'))); - $config_parsed = $file_storage->read($language_config_name); + $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site'); // Expect only slogan in language specific file. - $expected = array('slogan' => 'FR ' . $site_slogan); - $this->assertEqual($expected, $config_parsed); + $expected = 'FR ' . $site_slogan; + $this->assertEqual($expected, $override->get('slogan')); // Case 3: Keep default value for site name and slogan. $this->drupalGet("$translation_base_url/fr/edit"); @@ -214,10 +212,10 @@ public function testSourceValueDuplicateSave() { 'config_names[system.site][slogan][translation]' => $site_slogan, ); $this->drupalPostForm(NULL, $edit, t('Save translation')); - $config_parsed = $file_storage->read($language_config_name); + $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site'); // Expect no language specific file. - $this->assertFalse($config_parsed); + $this->assertTrue($override->isNew()); // Check configuration page with translator user. Should have no access. $this->drupalLogout(); @@ -240,8 +238,6 @@ public function testSourceValueDuplicateSave() { public function testContactConfigEntityTranslation() { $this->drupalLogin($this->admin_user); - $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); - $this->drupalGet('admin/structure/contact'); // Check for default contact form configuration entity from Contact module. @@ -285,13 +281,12 @@ public function testContactConfigEntityTranslation() { $this->drupalPostForm($translation_page_url, $edit, t('Save translation')); // Expect translated values in language specific file. - $language_config_name = \Drupal::configFactory()->getLanguageConfigName($langcode, 'contact.category.feedback'); - $config_parsed = $file_storage->read($language_config_name); + $override = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'contact.category.feedback'); $expected = array( 'label' => 'Website feedback - ' . $langcode, 'reply' => 'Thank you for your mail - ' . $langcode, ); - $this->assertEqual($expected, $config_parsed); + $this->assertEqual($expected, $override->get()); // Check for edit, delete links (and no 'add' link) for $langcode. $this->assertNoLinkByHref("$translation_base_url/$langcode/add"); @@ -349,9 +344,8 @@ public function testContactConfigEntityTranslation() { $this->assertNoLinkByHref("$translation_base_url/$langcode/delete"); // Expect no language specific file present anymore. - $language_config_name = \Drupal::configFactory()->getLanguageConfigName($langcode, 'contact.category.feedback'); - $config_parsed = $file_storage->read($language_config_name); - $this->assertFalse($config_parsed); + $override = \Drupal::languageManager()->getLanguageConfigOverride($langcode, 'contact.category.feedback'); + $this->assertTrue($override->isNew()); } // Check configuration page with translator user. Should have no access. @@ -417,13 +411,12 @@ public function testDateFormatTranslation() { $this->drupalPostForm($translation_page_url, $edit, t('Save translation')); // Get translation and check we've got the right value. - $language_config_name = \Drupal::configFactory()->getLanguageConfigName('fr', 'system.date_format.' . $id); - $config_parsed = $file_storage->read($language_config_name); + $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.date_format.' . $id); $expected = array( 'label' => $id . ' - FR', 'pattern' => array('php' => 'D'), ); - $this->assertEqual($expected, $config_parsed); + $this->assertEqual($expected, $override->get()); // Formatting the date 8 / 27 / 1985 @ 13:37 EST with pattern D should // display "Tue". diff --git a/core/modules/language/language.services.yml b/core/modules/language/language.services.yml index 422644a..9f1a38f 100644 --- a/core/modules/language/language.services.yml +++ b/core/modules/language/language.services.yml @@ -11,3 +11,9 @@ services: class: Drupal\language\EventSubscriber\ConfigSubscriber tags: - { name: event_subscriber } + language.config_factory_override: + class: Drupal\language\Config\LanguageConfigFactoryOverride + arguments: ['@language.default', '@config.storage', '@event_dispatcher', '@config.typed'] + tags: + - { name: config.factory.override, priority: -254 } + - { name: persist } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php new file mode 100644 index 0000000..39da8dc --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php @@ -0,0 +1,170 @@ +language = $language_default->get(); + $this->storage = $storage; + $this->eventDispatcher = $event_dispatcher; + $this->typedConfigManager = $typed_config; + } + + /** + * {@inheritdoc} + */ + public function loadOverrides($names) { + $data = array(); + $language_names = $this->getLanguageConfigNames($names); + if ($language_names) { + $data = $this->storage->readMultiple($language_names); + // Re-key the data array to use configuration names rather than override + // names. + $prefix_length = strlen(static::LANGUAGE_CONFIG_PREFIX . '.' . $this->language->id) + 1; + foreach ($data as $key => $value) { + unset($data[$key]); + $key = substr($key, $prefix_length); + $data[$key] = $value; + } + } + return $data; + } + + /** + * {@inheritdoc} + */ + public function getOverride($langcode, $name) { + $override_name = $this->getLanguageConfigName($langcode, $name); + $overrides = $this->storage->read($override_name); + $config = new Config($override_name, $this->storage, $this->eventDispatcher, $this->typedConfigManager); + if (!empty($overrides)) { + $config->initWithData($overrides); + } + return $config; + } + + /** + * Generate a list of configuration names based on base names. + * + * @param array $names + * List of configuration names. + * + * @return array + * List of configuration names for language override files if applicable. + */ + protected function getLanguageConfigNames(array $names) { + $language_names = array(); + 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; + } + + /** + * Get language override name for given language and configuration name. + * + * @param string $langcode + * Language code. + * @param string $name + * Configuration name. + * + * @return bool|string + * Configuration name or FALSE if not applicable. + */ + protected function getLanguageConfigName($langcode, $name) { + if (strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0) { + return FALSE; + } + return static::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.' . $name; + } + + /** + * {@inheritdoc} + */ + public function getCacheSuffix() { + return $this->language->id; + } + + /** + * {@inheritdoc} + */ + public function getLanguage() { + return $this->language; + } + + /** + * {@inheritdoc} + */ + public function setLanguage(Language $language = NULL) { + $this->language = $language; + return $this; + } + +} diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php new file mode 100644 index 0000000..6a0fc2f --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php @@ -0,0 +1,46 @@ +defaultLanguage = $default_language; $this->configFactory = $config_factory; $this->moduleHandler = $module_handler; + $this->configFactoryOverride = $config_override; } /** @@ -371,4 +386,40 @@ public function getLanguageSwitchLinks($type, $path) { return $links; } + /** + * {@inheritdoc} + */ + public function setConfigOverrideLanguage(Language $language) { + $this->configFactoryOverride->setLanguage($language); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getConfigOverrideLanguage() { + return $this->configFactoryOverride->getLanguage(); + } + + /** + * {@inheritdoc} + */ + public function getLanguageConfigOverride($langcode, $name) { + return $this->configFactoryOverride->getOverride($langcode, $name); + } + + /** + * Provides the overrider storage. + * + * @param string $langcode + * The language code. + * + * @return \Drupal\Core\Config\StorageInterface + * The configuration storage engine. + */ + public function getLanguageOverrideStorage($langcode = Language::LANGCODE_NOT_SPECIFIED) { + $prefix = 'language.entity.'; + return $this->configFactory->get($prefix . $langcode)->getStorage(); + } + } diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php index 02c8205..d2f4f36 100644 --- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php @@ -78,4 +78,17 @@ public function saveLanguageTypesConfiguration(array $config); */ public function updateLockedLanguageWeights(); + /** + * Gets a language config override object. + * + * @param string $langcode + * The language code for the override. + * @param string $name + * The language configuration object name. + * + * @return \Drupal\Core\Config\Config + * The language config override object. + */ + public function getLanguageConfigOverride($langcode, $name); + } diff --git a/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php b/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php index 2d81206..7700611 100644 --- a/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php +++ b/core/modules/language/lib/Drupal/language/EventSubscriber/LanguageRequestSubscriber.php @@ -7,8 +7,6 @@ namespace Drupal\language\EventSubscriber; -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\Translator\TranslatorInterface; use Drupal\language\ConfigurableLanguageManagerInterface; @@ -52,13 +50,6 @@ class LanguageRequestSubscriber implements EventSubscriberInterface { protected $currentUser; /** - * The configuration factory. - * - * @var \Drupal\Core\Config\ConfigFactoryInterface - */ - protected $configFactory; - - /** * Constructs a LanguageRequestSubscriber object. * * @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager @@ -69,15 +60,12 @@ class LanguageRequestSubscriber implements EventSubscriberInterface { * The translation service. * @param \Drupal\Core\Session\AccountInterface $current_user * The current active user. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The configuration factory. */ - public function __construct(ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, TranslatorInterface $translation, AccountInterface $current_user, ConfigFactoryInterface $config_factory) { + public function __construct(ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, TranslatorInterface $translation, AccountInterface $current_user) { $this->languageManager = $language_manager; $this->negotiator = $negotiator; $this->translation = $translation; $this->currentUser = $current_user; - $this->configFactory = $config_factory; } /** @@ -94,7 +82,7 @@ public function onKernelRequestLanguage(GetResponseEvent $event) { if ($this->languageManager instanceof ConfigurableLanguageManagerInterface) { $this->languageManager->setNegotiator($this->negotiator); $this->languageManager->setRequest($request); - $this->configFactory->setLanguage($this->languageManager->getCurrentLanguage()); + $this->languageManager->setConfigOverrideLanguage($this->languageManager->getCurrentLanguage()); } // After the language manager has initialized, set the default langcode // for the string translations. diff --git a/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php index 8c11eca..c62b2f0 100644 --- a/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php +++ b/core/modules/language/lib/Drupal/language/LanguageServiceProvider.php @@ -31,8 +31,7 @@ public function register(ContainerBuilder $container) { ->addArgument(new Reference('language_manager')) ->addArgument(new Reference('language_negotiator')) ->addArgument(new Reference('string_translation')) - ->addArgument(new Reference('current_user')) - ->addArgument(new Reference('config.factory')); + ->addArgument(new Reference('current_user')); $container->register('path_processor_language', 'Drupal\language\HttpKernel\PathProcessorLanguage') ->addTag('path_processor_inbound', array('priority' => 300)) @@ -52,14 +51,10 @@ public function alter(ContainerBuilder $container) { $definition = $container->getDefinition('language_manager'); $definition->setClass('Drupal\language\ConfigurableLanguageManager') ->addArgument(new Reference('config.factory')) - ->addArgument(new Reference('module_handler')); + ->addArgument(new Reference('module_handler')) + ->addArgument(new Reference('language.config_factory_override')); if ($default_language_values = $this->getDefaultLanguageValues()) { $container->setParameter('language.default_values', $default_language_values); - // Ensure that configuration can be localised if the site is monolingual - // but the Language module is enabled. This is the case for monolingual - // sites not in English. - $definition = $container->getDefinition('config.factory'); - $definition->addMethodCall('setLanguageFromDefault', array(new Reference('language.default'))); } } diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php index 353fcc6..94bd547 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php @@ -12,6 +12,8 @@ use Drupal\Core\Config\TypedConfigManager; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\language\Config\LanguageOverrideStorageInterface; +use Drupal\language\ConfigurableLanguageManagerInterface; /** * Manages localized configuration type plugins. @@ -45,6 +47,13 @@ class LocaleConfigManager extends TypedConfigManager { protected $configFactory; /** + * The language manager. + * + * @var \Drupal\language\ConfigurableLanguageManagerInterface + */ + protected $languageManager; + + /** * Creates a new typed configuration manager. * * @param \Drupal\Core\Config\StorageInterface $configStorage @@ -60,13 +69,16 @@ class LocaleConfigManager extends TypedConfigManager { * The cache backend to use for caching the definitions. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory + * @param \Drupal\language\ConfigurableLanguageManagerInterface + * The language manager. */ - public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage, CacheBackendInterface $cache, ConfigFactoryInterface $config_factory) { + public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, StorageInterface $installStorage, StringStorageInterface $localeStorage, CacheBackendInterface $cache, ConfigFactoryInterface $config_factory, ConfigurableLanguageManagerInterface $language_manager) { // Note we use the install storage for the parent constructor. parent::__construct($configStorage, $schemaStorage, $cache); $this->installStorage = $installStorage; $this->localeStorage = $localeStorage; $this->configFactory = $config_factory; + $this->languageManager = $language_manager; } /** @@ -133,8 +145,7 @@ protected function compareConfigData(array $default, $updated) { * Configuration data to be saved, that will be only the translated values. */ public function saveTranslationData($name, $langcode, array $data) { - $locale_name = $this->configFactory->getLanguageConfigName($langcode, $name); - $this->configStorage->write($locale_name, $data); + $this->languageManager->getLanguageConfigOverride($langcode, $name)->setData($data)->save(); } /** @@ -146,8 +157,7 @@ public function saveTranslationData($name, $langcode, array $data) { * Language code. */ public function deleteTranslationData($name, $langcode) { - $locale_name = $this->configFactory->getLanguageConfigName($langcode, $name); - $this->configStorage->delete($locale_name); + $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete(); } /** @@ -220,9 +230,9 @@ public function getStringNames(array $lids) { * Language code to delete. */ public function deleteLanguageTranslations($langcode) { - $locale_name = ConfigFactoryInterface::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.'; - foreach ($this->configStorage->listAll($locale_name) as $name) { - $this->configStorage->delete($name); + $storage = $this->languageManager->getLanguageOverrideStorage($langcode); + foreach ($storage->listAll() as $name) { + $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete(); } } @@ -305,9 +315,8 @@ public function translateString($name, $langcode, $source, $context) { * A boolean indicating if a language has configuration translations. */ public function hasTranslation($name, Language $language) { - $locale_name = $this->configFactory->getLanguageConfigName($language->id, $name); - $translation = $this->configStorage->read($locale_name); - return !empty($translation); + $translation = $this->languageManager->getLanguageConfigOverride($language->id, $name); + return !$translation->isNew(); } } diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php index 16fc30b..453743c 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php @@ -22,7 +22,7 @@ class LocaleConfigManagerTest extends DrupalUnitTestBase { * * @var array */ - public static $modules = array('locale', 'locale_test'); + public static $modules = array('language', 'locale', 'locale_test'); /** * {@inheritdoc} @@ -39,30 +39,19 @@ public static function getInfo() { * Tests hasTranslation(). */ public function testHasTranslation() { + $this->installConfig(array('locale_test')); $locale_config_manager = new LocaleConfigManager( - // In contrast to the actual configuration we use the installer storage - // as the config storage. That way, we do not actually have to install - // the module and can extend DrupalUnitTestBase. - $this->container->get('config.storage.installer'), + $this->container->get('config.storage'), $this->container->get('config.storage.schema'), $this->container->get('config.storage.installer'), $this->container->get('locale.storage'), $this->container->get('cache.config'), - $this->container->get('config.factory') + $this->container->get('config.factory'), + $this->container->get('language_manager') ); $language = new Language(array('id' => 'de')); - // The installer storage throws an expcetion when requesting a non-existing - // file. - try { - $locale_config_manager->hasTranslation('locale_test.no_translation', $language); - } - catch (StorageException $exception) { - $result = FALSE; - } - $this->assertIdentical(FALSE, $result); - - $result = $locale_config_manager->hasTranslation('locale_test.translation', $language); - $this->assertIdentical(TRUE, $result); + $this->assertFalse($locale_config_manager->hasTranslation('locale_test.no_translation', $language), 'There is no translation for locale_test.no_translation configuration.'); + $this->assertTrue($locale_config_manager->hasTranslation('locale_test.translation', $language), 'There is a translation for locale_test.translation configuration.'); } } diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php index f7c64bf..48a0132 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigTranslationTest.php @@ -171,15 +171,16 @@ function testConfigTranslation() { $this->assertEqual($property->getValue(), $image_style_label, 'Got the right translation for image style name after translation'); // Quick test to ensure translation file exists. - $language_config_name = \Drupal::configFactory()->getLanguageConfigName('xx', 'image.style.medium'); - $this->assertEqual(\Drupal::config($language_config_name)->get('label'), $image_style_label); + $override = \Drupal::languageManager()->getLanguageConfigOverride('xx', 'image.style.medium'); + $this->assertEqual($override->get('label'), $image_style_label); // Uninstall the module. $this->drupalPostForm('admin/modules/uninstall', array('uninstall[image]' => "image"), t('Uninstall')); $this->drupalPostForm(NULL, array(), t('Uninstall')); // Ensure that the translated configuration has been removed. - $this->assertFalse(\Drupal::config($language_config_name)->get('label'), 'Translated configuration for image module removed.'); + $override = \Drupal::languageManager()->getLanguageConfigOverride('xx', 'image.style.medium'); + $this->assertTrue($override->isNew(), 'Translated configuration for image module removed.'); // Translate default category using the UI so configuration is refreshed. $category_label = $this->randomName(20); diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml index b5f4cf4..7a0f0d7 100644 --- a/core/modules/locale/locale.services.yml +++ b/core/modules/locale/locale.services.yml @@ -6,7 +6,7 @@ services: arguments: ['@entity.manager', '@config.factory'] locale.config.typed: class: Drupal\locale\LocaleConfigManager - arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage', '@cache.config', '@config.factory'] + arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage', '@cache.config', '@config.factory', '@language_manager'] locale.storage: class: Drupal\locale\StringDatabaseStorage arguments: ['@database'] diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php index 93bb446..f3d43b2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterRebuildTest.php @@ -20,7 +20,7 @@ class MenuRouterRebuildTest extends WebTestBase { * * @var array */ - public static $modules = array('locale', 'menu_test'); + public static $modules = array('language', 'menu_test'); /** * {@inheritdoc} @@ -48,7 +48,7 @@ function setUp() { */ public function testMenuRouterRebuildContext() { // Enter a language context before rebuilding the menu router tables. - \Drupal::configFactory()->setLanguage(language_load('nl')); + \Drupal::languageManager()->setConfigOverrideLanguage(language_load('nl')); \Drupal::service('router.builder')->rebuild(); // Check that the language context was not used for building the menu item. diff --git a/core/modules/user/user.module b/core/modules/user/user.module index ab9a163..4e8bbe4 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1183,13 +1183,13 @@ function user_view_multiple($accounts, $view_mode = 'full', $langcode = NULL) { */ function user_mail($key, &$message, $params) { $token_service = \Drupal::token(); + $language_manager = \Drupal::languageManager(); $langcode = $message['langcode']; $variables = array('user' => $params['account']); - $original_language = \Drupal::configFactory()->getLanguage(); - $language = language_load($params['account']->getPreferredLangcode()); - \Drupal::configFactory()->setLanguage($language); + $original_language = $language_manager->getConfigOverrideLanguage(); + $language_manager->setConfigOverrideLanguage($language); $mail_config = \Drupal::config('user.mail'); // We do not sanitize the token replacement, since the output of this @@ -1198,7 +1198,8 @@ function user_mail($key, &$message, $params) { $message['subject'] .= $token_service->replace($mail_config->get($key . '.subject'), $variables, $token_options); $message['body'][] = $token_service->replace($mail_config->get($key . '.body'), $variables, $token_options); - \Drupal::configFactory()->setLanguage($original_language); + $language_manager->setConfigOverrideLanguage($original_language); + } /**