Issue #2268939 by Gábor Hojtsy, vijaycs85: Fixed Config overrides not updated when config changes.
parent
074bc73e5d
commit
179c0920f5
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Config\ConfigFactoryOverrideBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Config;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Defines a base event listener implementation configuration overrides.
|
||||
*/
|
||||
abstract class ConfigFactoryOverrideBase implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* Reacts to the ConfigEvents::COLLECTION_INFO event.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigCollectionInfo $collection_info
|
||||
* The configuration collection names event.
|
||||
*/
|
||||
abstract public function addCollections(ConfigCollectionInfo $collection_info);
|
||||
|
||||
/**
|
||||
* Actions to be performed to configuration override on configuration save.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigCrudEvent $event
|
||||
* The config CRUD event.
|
||||
*/
|
||||
abstract public function onConfigSave(ConfigCrudEvent $event);
|
||||
|
||||
/**
|
||||
* Actions to be performed to configuration override on configuration delete.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigCrudEvent $event
|
||||
* The config CRUD event.
|
||||
*/
|
||||
abstract public function onConfigDelete(ConfigCrudEvent $event);
|
||||
|
||||
/**
|
||||
* Actions to be performed to configuration override on configuration rename.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigRenameEvent $event
|
||||
* The config rename event.
|
||||
*/
|
||||
abstract public function onConfigRename(ConfigRenameEvent $event);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[ConfigEvents::COLLECTION_INFO][] = array('addCollections');
|
||||
$events[ConfigEvents::SAVE][] = array('onConfigSave', 20);
|
||||
$events[ConfigEvents::DELETE][] = array('onConfigDelete', 20);
|
||||
$events[ConfigEvents::RENAME][] = array('onConfigRename', 20);
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters data in the override based on what is currently in configuration.
|
||||
*
|
||||
* @param \Drupal\Core\Config\Config $config
|
||||
* Current configuration object.
|
||||
* @param \Drupal\Core\Config\StorableConfigBase $override
|
||||
* Override object corresponding to the configuration to filter data in.
|
||||
*/
|
||||
protected function filterOverride(Config $config, StorableConfigBase $override) {
|
||||
$override_data = $override->get();
|
||||
$this->filterNestedArray($config->get(), $override_data);
|
||||
if (empty($override_data)) {
|
||||
// If no override values are left that would apply, remove the override.
|
||||
$override->delete();
|
||||
}
|
||||
else {
|
||||
// Otherwise set the filtered override values back.
|
||||
$override->setData($override_data)->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters data in nested arrays.
|
||||
*
|
||||
* @param array $original_data
|
||||
* Original data array to filter against.
|
||||
* @param array $override_data
|
||||
* Override data to filter.
|
||||
*/
|
||||
protected function filterNestedArray(array $original_data, array &$override_data) {
|
||||
foreach ($override_data as $key => $value) {
|
||||
if (!isset($original_data[$key])) {
|
||||
// The original data is not there anymore, remove the override.
|
||||
unset($override_data[$key]);
|
||||
}
|
||||
elseif (is_array($override_data[$key])) {
|
||||
if (is_array($original_data[$key])) {
|
||||
// Do the filtering one level deeper.
|
||||
$this->filterNestedArray($original_data[$key], $override_data[$key]);
|
||||
// If no overrides are left under this level, remove the level.
|
||||
if (empty($override_data[$key])) {
|
||||
unset($override_data[$key]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The override is an array but the value is not, this will not go
|
||||
// well, remove the override.
|
||||
unset($override_data[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -76,6 +76,56 @@ class ConfigLanguageOverrideTest extends DrupalUnitTestBase {
|
|||
$config = \Drupal::config('config_test.new');
|
||||
$this->assertIdentical($config->get('language'), NULL);
|
||||
\Drupal::configFactory()->setOverrideState($old_state);
|
||||
|
||||
// Test how overrides react to base configuration changes. Set up some base
|
||||
// values.
|
||||
\Drupal::config('config_test.foo')
|
||||
->set('value', array('key' => 'original'))
|
||||
->set('label', 'Original')
|
||||
->save();
|
||||
\Drupal::languageManager()
|
||||
->getLanguageConfigOverride('de', 'config_test.foo')
|
||||
->set('value', array('key' => 'override'))
|
||||
->set('label', 'Override')
|
||||
->save();
|
||||
\Drupal::languageManager()
|
||||
->getLanguageConfigOverride('fr', 'config_test.foo')
|
||||
->set('value', array('key' => 'override'))
|
||||
->save();
|
||||
\Drupal::configFactory()->clearStaticCache();
|
||||
$config = \Drupal::config('config_test.foo');
|
||||
$this->assertIdentical($config->get('value'), array('key' => 'override'));
|
||||
|
||||
// Ensure renaming the config will rename the override.
|
||||
\Drupal::configFactory()->rename('config_test.foo', 'config_test.bar');
|
||||
$config = \Drupal::config('config_test.bar');
|
||||
$this->assertEqual($config->get('value'), array('key' => 'original'));
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.foo');
|
||||
$this->assertTrue($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), array('key' => 'override'));
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), array('key' => 'override'));
|
||||
|
||||
// Ensure changing data in the config will update the overrides.
|
||||
$config = \Drupal::config('config_test.bar')->clear('value.key')->save();
|
||||
$this->assertEqual($config->get('value'), array());
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
|
||||
$this->assertFalse($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
// The French override will become empty and therefore removed.
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar');
|
||||
$this->assertTrue($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
|
||||
// Ensure deleting the config will delete the override.
|
||||
\Drupal::configFactory()->get('config_test.bar')->delete();
|
||||
$override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar');
|
||||
$this->assertTrue($override->isNew());
|
||||
$this->assertEqual($override->get('value'), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ namespace Drupal\language\Config;
|
|||
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Config\ConfigCollectionInfo;
|
||||
use Drupal\Core\Config\ConfigEvents;
|
||||
use Drupal\Core\Config\ConfigCrudEvent;
|
||||
use Drupal\Core\Config\ConfigFactoryOverrideBase;
|
||||
use Drupal\Core\Config\ConfigRenameEvent;
|
||||
use Drupal\Core\Config\StorageInterface;
|
||||
use Drupal\Core\Config\TypedConfigManagerInterface;
|
||||
use Drupal\Core\Language\LanguageDefault;
|
||||
|
|
@ -20,7 +22,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|||
/**
|
||||
* Provides language overrides for the configuration factory.
|
||||
*/
|
||||
class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInterface, EventSubscriberInterface {
|
||||
class LanguageConfigFactoryOverride extends ConfigFactoryOverrideBase implements LanguageConfigFactoryOverrideInterface, EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* The configuration storage.
|
||||
|
|
@ -194,10 +196,7 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte
|
|||
}
|
||||
|
||||
/**
|
||||
* Reacts to the ConfigEvents::COLLECTION_INFO event.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigCollectionInfo $collection_info
|
||||
* The configuration collection names event.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCollections(ConfigCollectionInfo $collection_info) {
|
||||
foreach (\Drupal::languageManager()->getLanguages() as $language) {
|
||||
|
|
@ -208,9 +207,47 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[ConfigEvents::COLLECTION_INFO][] = array('addCollections');
|
||||
return $events;
|
||||
public function onConfigSave(ConfigCrudEvent $event) {
|
||||
$config = $event->getConfig();
|
||||
$name = $config->getName();
|
||||
foreach (\Drupal::languageManager()->getLanguages() as $language) {
|
||||
$config_translation = $this->getOverride($language->getId(), $name);
|
||||
if (!$config_translation->isNew()) {
|
||||
$this->filterOverride($config, $config_translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onConfigRename(ConfigRenameEvent $event) {
|
||||
$config = $event->getConfig();
|
||||
$name = $config->getName();
|
||||
$old_name = $event->getOldName();
|
||||
foreach (\Drupal::languageManager()->getLanguages() as $language) {
|
||||
$config_translation = $this->getOverride($language->getId(), $old_name);
|
||||
if (!$config_translation->isNew()) {
|
||||
$saved_config = $config_translation->get();
|
||||
$storage = $this->getStorage($language->getId());
|
||||
$storage->write($name, $saved_config);
|
||||
$config_translation->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onConfigDelete(ConfigCrudEvent $event) {
|
||||
$config = $event->getConfig();
|
||||
$name = $config->getName();
|
||||
foreach (\Drupal::languageManager()->getLanguages() as $language) {
|
||||
$config_translation = $this->getOverride($language->getId(), $name);
|
||||
if (!$config_translation->isNew()) {
|
||||
$config_translation->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue