diff --git a/core/lib/Drupal/Core/Config/CachedStorage.php b/core/lib/Drupal/Core/Config/CachedStorage.php index 1ff4046..cfb06ce 100644 --- a/core/lib/Drupal/Core/Config/CachedStorage.php +++ b/core/lib/Drupal/Core/Config/CachedStorage.php @@ -41,6 +41,13 @@ class CachedStorage implements StorageInterface, StorageCacheInterface { protected $findByPrefixCache = array(); /** + * The cache prefix to use for all cache entries. + * + * @var string + */ + protected $cachePrefix = NULL; + + /** * Constructs a new CachedStorage controller. * * @param \Drupal\Core\Config\StorageInterface $storage @@ -67,7 +74,7 @@ public function exists($name) { * Implements Drupal\Core\Config\StorageInterface::read(). */ public function read($name) { - if ($cache = $this->cache->get($name)) { + if ($cache = $this->cache->get($this->getCacheKey($name))) { // The cache contains either the cached configuration data or FALSE // if the configuration file does not exist. return $cache->data; @@ -75,7 +82,7 @@ public function read($name) { // Read from the storage on a cache miss and cache the data. Also cache // information about missing configuration objects. $data = $this->storage->read($name); - $this->cache->set($name, $data); + $this->cache->set($this->getCacheKey($name), $data); return $data; } @@ -87,14 +94,15 @@ public function readMultiple(array $names) { // The names array is passed by reference and will only contain the names of // config object not found after the method call. // @see \Drupal\Core\Cache\CacheBackendInterface::getMultiple() - $cached_list = $this->cache->getMultiple($names); + $cids = $this->getCacheKeys($names); + $cached_list = $this->cache->getMultiple($cids); if (!empty($names)) { $list = $this->storage->readMultiple($names); // Cache configuration objects that were loaded from the storage, cache // missing configuration objects as an explicit FALSE. foreach ($names as $name) { - $this->cache->set($name, isset($list[$name]) ? $list[$name] : FALSE); + $this->cache->set($this->getCacheKey($name), isset($list[$name]) ? $list[$name] : FALSE); } } @@ -115,7 +123,8 @@ public function write($name, array $data) { if ($this->storage->write($name, $data)) { // While not all written data is read back, setting the cache instead of // just deleting it avoids cache rebuild stampedes. - $this->cache->set($name, $data); + $this->cache->set($this->getCacheKey($name), $data); + // @todo: How to deal with the prefix for the tag? Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); $this->findByPrefixCache = array(); return TRUE; @@ -130,7 +139,7 @@ public function delete($name) { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is gone. if ($this->storage->delete($name)) { - $this->cache->delete($name); + $this->cache->delete($this->getCacheKey($name)); Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); $this->findByPrefixCache = array(); return TRUE; @@ -145,8 +154,8 @@ public function rename($name, $new_name) { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is renamed. if ($this->storage->rename($name, $new_name)) { - $this->cache->delete($name); - $this->cache->delete($new_name); + $this->cache->delete($this->getCacheKey($name)); + $this->cache->delete($this->getCacheKey($new_name)); Cache::deleteTags(array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE)); $this->findByPrefixCache = array(); return TRUE; @@ -199,13 +208,13 @@ protected function findByPrefix($prefix) { if (!isset($this->findByPrefixCache[$prefix])) { // The : character is not allowed in config file names, so this can not // conflict. - if ($cache = $this->cache->get('find:' . $prefix)) { + if ($cache = $this->cache->get($this->getCacheKey('find:' . $prefix))) { $this->findByPrefixCache[$prefix] = $cache->data; } else { $this->findByPrefixCache[$prefix] = $this->storage->listAll($prefix); $this->cache->set( - 'find:' . $prefix, + $this->getCacheKey('find:' . $prefix), $this->findByPrefixCache[$prefix], Cache::PERMANENT, array($this::FIND_BY_PREFIX_CACHE_TAG => TRUE) @@ -221,9 +230,9 @@ protected function findByPrefix($prefix) { public function deleteAll($prefix = '') { // If the cache was the first to be deleted, another process might start // rebuilding the cache before the storage is renamed. - $cids = $this->storage->listAll($prefix); + $names = $this->storage->listAll($prefix); if ($this->storage->deleteAll($prefix)) { - $this->cache->deleteMultiple($cids); + $this->cache->deleteMultiple($this->getCacheKeys($names)); return TRUE; } return FALSE; @@ -235,4 +244,35 @@ public function deleteAll($prefix = '') { public function resetListCache() { $this->findByPrefixCache = array(); } + + /** + * Builds the cache key for a config name. + * + * @param string $name + * Name of the config file. + * + * @return string + * The cache key. + */ + protected function getCacheKey($name) { + return $this->cachePrefix ? $this->cachePrefix . ':' . $name : $name; + } + + /** + * Builds the cache key for a list of config names. + * + * @param array $names + * List of config file names. + * + * @return array + * List of cache keys, keyed by config name. + */ + protected function getCacheKeys(array $names) { + $cids = array(); + foreach ($names as $name) { + $cids[$name] = $this->getCacheKey($name); + } + return $cids; + } + } diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php index 0e7826e..dcfa4f4 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactory.php +++ b/core/lib/Drupal/Core/Config/ConfigFactory.php @@ -312,4 +312,11 @@ public function addOverride(ConfigFactoryOverrideInterface $config_factory_overr $this->configFactoryOverrides[] = $config_factory_override; } + /** + * {@inheritdoc} + */ + public function getOverrides() { + return $this->configFactoryOverrides; + } + } diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php index 639b483..04bfe81 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php @@ -134,4 +134,11 @@ public function listAll($prefix = ''); */ public function addOverride(ConfigFactoryOverrideInterface $config_factory_override); + /** + * Get all added configuration factory override instances. + * + * @return ConfigFactoryOverrideInterface[] + * The configuration factory override instances. + */ + public function getOverrides(); } diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php index 06e1f3f..96c8d48 100644 --- a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php @@ -32,4 +32,24 @@ public function loadOverrides($names); */ public function getCacheSuffix(); + /** + * Reacts to default configuration installation during extension install. + * + * @param string $type + * The type of extension being installed. Either 'module' or 'theme'. + * @param string $name + * The name of the extension. + */ + public function install($type, $name); + + /** + * Reacts to configuration removal during extension uninstallation. + * + * @param string $type + * The type of extension being uninstalled. Either 'module' or 'theme'. + * @param string $name + * The name of the extension. + */ + public function uninstall($type, $name); + } diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index 038dbd6..4a84033 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -155,6 +155,12 @@ public function installDefaultConfig($type, $name) { } $this->configFactory->setOverrideState($old_state); } + + // Allow configuration factory overrides to respond to installation. + foreach ($this->configFactory->getOverrides() as $config_override) { + $config_override->install($type, $name); + } + // Reset all the static caches and list caches. $this->configFactory->reset(); } diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index d1048ea..535b14c 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -149,6 +149,11 @@ public function uninstall($type, $name) { foreach ($config_names as $config_name) { $this->configFactory->get($config_name)->delete(); } + // Allow configuration factory overrides to respond to uninstallation. + foreach ($this->configFactory->getOverrides() as $config_override) { + $config_override->uninstall($type, $name); + } + $schema_dir = drupal_get_path($type, $name) . '/config/schema'; if (is_dir($schema_dir)) { // Refresh the schema cache if uninstalling an extension that provides diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php index 14268e9..3f47027 100644 --- a/core/lib/Drupal/Core/Config/FileStorage.php +++ b/core/lib/Drupal/Core/Config/FileStorage.php @@ -241,4 +241,14 @@ public function deleteAll($prefix = '') { return $success; } + + /** + * Sets the filesystem path for configuration objects. + * + * @param string $directory + * The filesystem path for configuration objects. + */ + public function setDirectory($directory) { + $this->directory = $directory; + } } diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php index b7424f3..4f3174d 100644 --- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php @@ -79,9 +79,9 @@ public function testDefaultConfig() { $default_config_storage = new TestInstallStorage(); foreach ($default_config_storage->listAll() as $config_name) { - // @todo: remove once migration (https://drupal.org/node/2183957) and - // translation (https://drupal.org/node/2168609) schemas are in. - if (strpos($config_name, 'migrate.migration') === 0 || strpos($config_name, 'language.config') === 0) { + // @todo: remove once migration (https://drupal.org/node/2183957) schemas + // are in. + if (strpos($config_name, 'migrate.migration') === 0) { continue; } 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 106df3d..355869f 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 @@ -40,5 +40,17 @@ public function getCacheSuffix() { return 'ConfigOverrider'; } + /** + * {@inheritdoc} + */ + public function install($type, $name) { + } + + /** + * {@inheritdoc} + */ + public function uninstall($type, $name) { + } + } 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 a9a435e..19ea21e 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 @@ -41,5 +41,17 @@ public function getCacheSuffix() { return 'ConfigOverriderLowPriority'; } + /** + * {@inheritdoc} + */ + public function install($type, $name) { + } + + /** + * {@inheritdoc} + */ + public function uninstall($type, $name) { + } + } 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 4d2bd68..851a9b2 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\Config\LanguageConfigOverride; use Drupal\language\ConfigurableLanguageManagerInterface; use Drupal\locale\StringStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -355,7 +356,7 @@ 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 $config_translation + * @param \Drupal\language\Config\LanguageConfigOverride $config_translation * Translation configuration override data. * @param array $config_values * A simple one dimensional or recursive array: @@ -375,7 +376,7 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d * @return array * Translation configuration override data. */ - protected function setConfig(Language $language, Config $base_config, Config $config_translation, array $config_values, $shipped_config = FALSE) { + protected function setConfig(Language $language, Config $base_config, LanguageConfigOverride $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. diff --git a/core/modules/language/language.install b/core/modules/language/language.install new file mode 100644 index 0000000..8825db3 --- /dev/null +++ b/core/modules/language/language.install @@ -0,0 +1,26 @@ +getModuleList()) as $module) { + $language_config_override->install('module', $module); + } + /** @var \Drupal\Core\Extension\ThemeHandler $theme_handler */ + $theme_handler = \Drupal::service('theme_handler'); + foreach ($theme_handler->listInfo() as $theme) { + if ($theme->status) { + $language_config_override->install('theme', $theme->name); + } + } + \Drupal::configFactory()->reset(); +} diff --git a/core/modules/language/language.services.yml b/core/modules/language/language.services.yml index acfb3fa..bfeee31 100644 --- a/core/modules/language/language.services.yml +++ b/core/modules/language/language.services.yml @@ -11,8 +11,20 @@ services: class: Drupal\language\EventSubscriber\ConfigSubscriber tags: - { name: event_subscriber } + language.cache_config: + class: Drupal\Core\Cache\CacheBackendInterface + tags: + - { name: cache.bin } + factory_method: get + factory_service: cache_factory + arguments: [language_config] + language.config_storage.file: + class: Drupal\language\Config\LanguageOverrideFileStorage + language.config_storage: + class: Drupal\language\Config\LanguageOverrideCachedStorage + arguments: ['@language.config_storage.file', '@language.cache_config'] language.config_factory_override: class: Drupal\language\Config\LanguageConfigFactoryOverride - arguments: ['@config.storage', '@event_dispatcher', '@config.typed'] + arguments: ['@language.config_storage', '@event_dispatcher', '@config.typed'] tags: - { name: config.factory.override, priority: -254 } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php index bfadec0..bc3c034 100644 --- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php @@ -8,6 +8,7 @@ namespace Drupal\language\Config; use Drupal\Core\Config\Config; +use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\Language\Language; @@ -22,7 +23,7 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte /** * The configuration storage. * - * @var \Drupal\Core\Config\StorageInterface + * @var \Drupal\language\Config\LanguageOverrideStorageInterface */ protected $storage; @@ -50,14 +51,14 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte /** * Constructs the LanguageConfigFactoryOverride object. * - * @param \Drupal\Core\Config\StorageInterface $storage + * @param \Drupal\language\Config\LanguageOverrideStorageInterface $storage * The configuration storage engine. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher * An event dispatcher instance to use for configuration events. * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config * The typed configuration manager. */ - public function __construct(StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) { + public function __construct(LanguageOverrideStorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) { $this->storage = $storage; $this->eventDispatcher = $event_dispatcher; $this->typedConfigManager = $typed_config; @@ -67,72 +68,30 @@ public function __construct(StorageInterface $storage, EventDispatcherInterface * {@inheritdoc} */ public function loadOverrides($names) { - $data = array(); - $language_names = $this->getLanguageConfigNames($names); - if ($language_names) { - $data = $this->storage->readMultiple(array_values($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; - } + if ($this->language) { + return $this->storage->readMultiple($names); } - return $data; + return array(); } /** * {@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; - } - } + $storage = clone $this->storage; + $data = $storage->setLangcode($langcode)->read($name); + $override = new LanguageConfigOverride($name, $this->storage, $this->typedConfigManager); + if (!empty($data)) { + $override->initWithData($data); } - return $language_names; + return $override; } /** - * 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. + * {@inheritdoc} */ - protected function getLanguageConfigName($langcode, $name) { - if (strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0) { - return FALSE; - } - return static::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.' . $name; + public function getStorage() { + return $this->storage; } /** @@ -154,6 +113,7 @@ public function getLanguage() { */ public function setLanguage(Language $language = NULL) { $this->language = $language; + $this->storage->setLangcode($this->language ? $this->language->id : NULL); return $this; } @@ -162,7 +122,58 @@ public function setLanguage(Language $language = NULL) { */ public function setLanguageFromDefault(LanguageDefault $language_default = NULL) { $this->language = $language_default ? $language_default->get() : NULL; + $this->storage->setLangcode($this->language->id); return $this; } + /** + * {@inheritdoc} + * + * @todo maybe this should be done somewhere else? + */ + public function install($type, $name) { + // Work out if this extension provides default language overrides. + $config_dir = drupal_get_path($type, $name) . '/config/language'; + if (is_dir($config_dir)) { + // List all the directories. + // \DirectoryIterator on Windows requires an absolute path. + $it = new \DirectoryIterator(realpath($config_dir)); + foreach ($it as $dir) { + if (!$dir->isDot() && $dir->isDir() ) { + $default_language_config = new FileStorage($dir->getPathname()); + $this->storage->setLangcode($dir->getFilename()); + foreach ($default_language_config->listAll() as $config_name) { + $data = $default_language_config->read($config_name); + $config = new LanguageConfigOverride($config_name, $this->storage, $this->typedConfigManager); + $config->setData($data)->save(); + } + } + } + } + } + + /** + * {@inheritdoc} + * + * @todo maybe this should be done somewhere else? + */ + public function uninstall($type, $name) { + // Can not use ConfigurableLanguageManager::getLanguages() since that would + // create a circular dependency. + $language_directory = config_get_config_directory() .'/language'; + if (is_dir(($language_directory))) { + $it = new \DirectoryIterator(realpath($language_directory)); + foreach ($it as $dir) { + if (!$dir->isDot() && $dir->isDir() ) { + $this->storage->setLangcode($dir->getFilename()); + $config_names = $this->storage->listAll($name . '.'); + foreach ($config_names as $config_name) { + $config = new LanguageConfigOverride($config_name, $this->storage, $this->typedConfig); + $config->delete(); + } + } + } + } + } + } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php index 1c3de55..43fcd41 100644 --- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php @@ -62,4 +62,9 @@ public function setLanguageFromDefault(LanguageDefault $language_default = NULL) */ public function getOverride($langcode, $name); + /** + * Returns the storage instance. + */ + public function getStorage(); + } diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php new file mode 100644 index 0000000..6ed2b11 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php @@ -0,0 +1,71 @@ +name = $name; + $this->storage = $storage; + $this->typedConfigManager = $typed_config; + } + + /** + * {@inheritdoc} + */ + public function save() { + // Validate the configuration object name before saving. + static::validateName($this->name); + + // If there is a schema for this configuration object, cast all values to + // conform to the schema. + if ($this->typedConfigManager->hasConfigSchema($this->name)) { + // Ensure that the schema wrapper has the latest data. + $this->schemaWrapper = NULL; + foreach ($this->data as $key => $value) { + $this->data[$key] = $this->castValue($key, $value); + } + } + + $this->storage->write($this->name, $this->data); + $this->isNew = FALSE; + $this->originalData = $this->data; + return $this; + } + + /** + * {@inheritdoc} + */ + public function delete() { + // @todo Consider to remove the pruning of data for Config::delete(). + $this->data = array(); + $this->storage->delete($this->name); + $this->isNew = TRUE; + $this->originalData = $this->data; + return $this; + } + +} diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageOverrideCachedStorage.php b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideCachedStorage.php new file mode 100644 index 0000000..40983d6 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideCachedStorage.php @@ -0,0 +1,46 @@ +cachePrefix = $langcode; + $this->storage->setLangcode($langcode); + return $this; + } + +} diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageOverrideFileStorage.php b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideFileStorage.php new file mode 100644 index 0000000..fa31003 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideFileStorage.php @@ -0,0 +1,128 @@ +ensureDirectory(); + return parent::write($name, $data); + } + + /** + * {@inheritdoc} + */ + public function delete($name) { + if ($this->hasDirectory()) { + return parent::delete($name); + } + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function listAll($prefix = '') { + if ($this->hasDirectory()) { + return parent::listAll($prefix); + } + return array(); + } + + /** + * Creates a directory if necessary. + */ + protected function ensureDirectory() { + if (!$this->hasDirectory()) { + drupal_mkdir($this->directory, NULL, TRUE); + $this->directoryExists = TRUE; + } + } + + /** + * {@inheritdoc} + */ + public function setLangcode($langcode) { + // Reset directory check. + $this->directoryExists = NULL; + $this->langcode = $langcode; + $this->directory = $this->getDirectory($langcode); + if (empty($this->storage)) { + $this->storage = new FileStorage($this->directory); + } + else { + $this->storage->setDirectory($this->directory); + } + return $this; + } + + /** + * Discovers is the directory for the language exists. + * + * @return bool + * TRUE if the directory exists, FALSE if not. + */ + protected function hasDirectory() { + if (!isset($this->directoryExists)) { + $this->directoryExists = is_dir($this->directory); + } + return $this->directoryExists; + } + +} diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageOverrideStorageInterface.php b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideStorageInterface.php new file mode 100644 index 0000000..ba62497 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Config/LanguageOverrideStorageInterface.php @@ -0,0 +1,26 @@ +configFactoryOverride->getOverride($langcode, $name); } + /** + * {@inheritdoc} + */ + public function getLanguageOverrideStorage($langcode) { + // Clone the language override storage so a process could compare language + // overrides if it wanted to. + $storage = clone $this->configFactoryOverride->getStorage(); + return $storage->setLancgode($langcode); + } } diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php index d2f4f36..4f7fd24 100644 --- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php +++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php @@ -86,7 +86,7 @@ public function updateLockedLanguageWeights(); * @param string $name * The language configuration object name. * - * @return \Drupal\Core\Config\Config + * @return \Drupal\language\Config\LanguageConfigOverride * The language config override object. */ public function getLanguageConfigOverride($langcode, $name); diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php index 3c0dc57..50e2f40 100644 --- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php +++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php @@ -230,9 +230,9 @@ public function getStringNames(array $lids) { * Language code to delete. */ public function deleteLanguageTranslations($langcode) { - $locale_name = LanguageConfigFactoryOverrideInterface::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(); } }