Issue #2172561 by Gábor Hojtsy: Config overrides may spill over to undesired places.

8.0.x
Nathaniel Catchpole 2014-01-27 11:50:29 +00:00
parent 318d178b6e
commit f2769f4db3
14 changed files with 59 additions and 85 deletions

View File

@ -512,10 +512,6 @@ services:
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
arguments: ['@module_handler'] arguments: ['@module_handler']
config_global_override_subscriber:
class: Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber
tags:
- { name: event_subscriber }
config_import_subscriber: config_import_subscriber:
class: Drupal\Core\EventSubscriber\ConfigImportSubscriber class: Drupal\Core\EventSubscriber\ConfigImportSubscriber
tags: tags:

View File

@ -2562,7 +2562,8 @@ function menu_router_rebuild() {
function menu_router_build($save = FALSE) { function menu_router_build($save = FALSE) {
// Ensure that all configuration used to build the menu items are loaded // Ensure that all configuration used to build the menu items are loaded
// without overrides. // without overrides.
\Drupal::configFactory()->disableOverrides(); $old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
// We need to manually call each module so that we can know which module // We need to manually call each module so that we can know which module
// a given item came from. // a given item came from.
$callbacks = array(); $callbacks = array();
@ -2577,8 +2578,7 @@ function menu_router_build($save = FALSE) {
} }
// Alter the menu as defined in modules, keys are like user/%user. // Alter the menu as defined in modules, keys are like user/%user.
drupal_alter('menu', $callbacks); drupal_alter('menu', $callbacks);
// Re-enable configuration overrides. \Drupal::configFactory()->setOverrideState($old_state);
\Drupal::configFactory()->enableOverrides();
foreach ($callbacks as $path => $router_item) { foreach ($callbacks as $path => $router_item) {
// If the menu item is a default local task and incorrectly references a // If the menu item is a default local task and incorrectly references a
// route, remove it. // route, remove it.

View File

@ -91,25 +91,27 @@ class ConfigFactory implements EventSubscriberInterface {
} }
/** /**
* Disable overrides when loading configuration objects. * Set the override state.
*
* @param bool $state
* TRUE if overrides should be applied, FALSE otherwise.
* *
* @return \Drupal\Core\Config\ConfigFactory * @return \Drupal\Core\Config\ConfigFactory
* The config factory object. * The config factory object.
*/ */
public function disableOverrides() { public function setOverrideState($state) {
$this->useOverrides = FALSE; $this->useOverrides = $state;
return $this; return $this;
} }
/** /**
* Enable overrides when loading configuration objects. * Get the override state.
* *
* @return \Drupal\Core\Config\ConfigFactory * @return bool
* The config factory object. * TRUE if overrides are applied, FALSE otherwise.
*/ */
public function enableOverrides() { public function getOverrideState() {
$this->useOverrides = TRUE; return $this->useOverrides;
return $this;
} }
/** /**

View File

@ -101,7 +101,8 @@ class ConfigInstaller implements ConfigInstallerInterface {
} }
if (!empty($config_to_install)) { if (!empty($config_to_install)) {
$this->configFactory->disableOverrides(); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
foreach ($config_to_install as $name) { foreach ($config_to_install as $name) {
// Only import new config. // Only import new config.
if ($this->activeStorage->exists($name)) { if ($this->activeStorage->exists($name)) {
@ -123,7 +124,7 @@ class ConfigInstaller implements ConfigInstallerInterface {
$new_config->save(); $new_config->save();
} }
} }
$this->configFactory->enableOverrides(); $this->configFactory->setOverrideState($old_state);
} }
} }

View File

@ -1,42 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Defines a configuration global override for contexts.
*/
class ConfigGlobalOverrideSubscriber implements EventSubscriberInterface {
/**
* Overrides configuration values with values in global $conf variable.
*
* @param \Drupal\Core\Config\ConfigEvent $event
* The Event to process.
*/
public function configInit(ConfigEvent $event) {
global $conf;
$config = $event->getConfig();
if (isset($conf[$config->getName()])) {
$config->setOverride($conf[$config->getName()]);
}
}
/**
* Implements EventSubscriberInterface::getSubscribedEvents().
*/
static function getSubscribedEvents() {
$events['config.init'][] = array('configInit', 30);
return $events;
}
}

View File

@ -74,9 +74,10 @@ abstract class ConfigFormBase extends FormBase {
* configuration. * configuration.
*/ */
protected function config($name) { protected function config($name) {
$this->configFactory->disableOverrides(); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$config = $this->configFactory->get($name); $config = $this->configFactory->get($name);
$this->configFactory->enableOverrides(); $this->configFactory->setOverrideState($old_state);
return $config; return $config;
} }
} }

View File

@ -82,10 +82,11 @@ class ConfigLanguageOverride extends DrupalUnitTestBase {
$config = \Drupal::config('config_test.new'); $config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new'); $this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$this->assertIdentical($config->get('language'), 'override'); $this->assertIdentical($config->get('language'), 'override');
\Drupal::configFactory()->disableOverrides(); $old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
$config = \Drupal::config('config_test.new'); $config = \Drupal::config('config_test.new');
$this->assertIdentical($config->get('language'), NULL); $this->assertIdentical($config->get('language'), NULL);
\Drupal::configFactory()->enableOverrides(); \Drupal::configFactory()->setOverrideState($old_state);
// Ensure that language configuration overrides can not be overridden. // Ensure that language configuration overrides can not be overridden.
global $conf; global $conf;

View File

@ -38,25 +38,31 @@ class ConfigModuleOverridesTest extends DrupalUnitTestBase {
->set('slogan', $non_overridden_slogan) ->set('slogan', $non_overridden_slogan)
->save(); ->save();
$config_factory->disableOverrides(); $this->assertTrue($config_factory->getOverrideState(), 'By default ConfigFactory has overrides enabled.');
$old_state = $config_factory->getOverrideState();
$config_factory->setOverrideState(FALSE);
$this->assertFalse($config_factory->getOverrideState(), 'ConfigFactory can disable overrides.');
$this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name')); $this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan')); $this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$config_factory->enableOverrides(); $config_factory->setOverrideState(TRUE);
$this->assertTrue($config_factory->getOverrideState(), 'ConfigFactory can enable overrides.');
$this->assertEqual($overridden_name, $config_factory->get('system.site')->get('name')); $this->assertEqual($overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($overridden_slogan, $config_factory->get('system.site')->get('slogan')); $this->assertEqual($overridden_slogan, $config_factory->get('system.site')->get('slogan'));
// Test overrides of completely new configuration objects. In normal runtime // Test overrides of completely new configuration objects. In normal runtime
// this should only happen for configuration entities as we should not be // this should only happen for configuration entities as we should not be
// creating simple configuration objects on the fly. // creating simple configuration objects on the fly.
$config = \Drupal::config('config_override.new'); $config = $config_factory->get('config_override.new');
$this->assertTrue($config->isNew(), 'The configuration object config_override.new is new'); $this->assertTrue($config->isNew(), 'The configuration object config_override.new is new');
$this->assertIdentical($config->get('module'), 'override'); $this->assertIdentical($config->get('module'), 'override');
\Drupal::configFactory()->disableOverrides(); $config_factory->setOverrideState(FALSE);
$config = \Drupal::config('config_override.new'); $config = \Drupal::config('config_override.new');
$this->assertIdentical($config->get('module'), NULL); $this->assertIdentical($config->get('module'), NULL);
\Drupal::configFactory()->enableOverrides();
$config_factory->setOverrideState($old_state);
unset($GLOBALS['config_test_run_module_overrides']); unset($GLOBALS['config_test_run_module_overrides']);
} }
} }

View File

@ -122,14 +122,15 @@ class ConfigOverrideTest extends DrupalUnitTestBase {
$config = \Drupal::config('config_test.new'); $config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new'); $this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$this->assertIdentical($config->get('key'), 'override'); $this->assertIdentical($config->get('key'), 'override');
\Drupal::configFactory()->disableOverrides(); $old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
$config_raw = \Drupal::config('config_test.new'); $config_raw = \Drupal::config('config_test.new');
$this->assertIdentical($config_raw->get('key'), NULL); $this->assertIdentical($config_raw->get('key'), NULL);
$config_raw $config_raw
->set('key', 'raw') ->set('key', 'raw')
->set('new_key', 'new_value') ->set('new_key', 'new_value')
->save(); ->save();
\Drupal::configFactory()->enableOverrides(); \Drupal::configFactory()->setOverrideState($old_state);
// Ensure override is preserved but all other data has been updated // Ensure override is preserved but all other data has been updated
// accordingly. // accordingly.
$this->assertIdentical($config->get('key'), 'override'); $this->assertIdentical($config->get('key'), 'override');

View File

@ -92,11 +92,13 @@ class ConfigOverridesPriorityTest extends DrupalUnitTestBase {
$this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail')); $this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max')); $this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
$config_factory->disableOverrides(); $old_state = $config_factory->getOverrideState();
$config_factory->setOverrideState(FALSE);
$this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name')); $this->assertEqual($non_overridden_name, $config_factory->get('system.site')->get('name'));
$this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan')); $this->assertEqual($non_overridden_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($non_overridden_mail, $config_factory->get('system.site')->get('mail')); $this->assertEqual($non_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max')); $this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
$config_factory->setOverrideState($old_state);
unset($GLOBALS['config_test_run_module_overrides']); unset($GLOBALS['config_test_run_module_overrides']);
} }

View File

@ -163,12 +163,13 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
$this->language = $language; $this->language = $language;
$this->sourceLanguage = $this->mapper->getLanguageWithFallback(); $this->sourceLanguage = $this->mapper->getLanguageWithFallback();
// Get base language configuration to display in the form before entering // Get base language configuration to display in the form before setting the
// into the language context for the form. This avoids repetitively going // language to use for the form. This avoids repetitively setting and
// in and out of the language context to get original values later. // resetting the language to get original values later.
$this->configFactory->disableOverrides(); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$this->baseConfigData = $this->mapper->getConfigData(); $this->baseConfigData = $this->mapper->getConfigData();
$this->configFactory->enableOverrides(); $this->configFactory->setOverrideState($old_state);
// Set the translation target language on the configuration factory. // Set the translation target language on the configuration factory.
$original_language = $this->configFactory->getLanguage(); $original_language = $this->configFactory->getLanguage();
@ -210,7 +211,9 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
$form_values = $form_state['values']['config_names']; $form_values = $form_state['values']['config_names'];
// For the form submission handling, use the raw data. // For the form submission handling, use the raw data.
$this->configFactory->disableOverrides(); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
foreach ($this->mapper->getConfigNames() as $name) { foreach ($this->mapper->getConfigNames() as $name) {
// Set configuration values based on form submission and source values. // Set configuration values based on form submission and source values.
$base_config = $this->config($name); $base_config = $this->config($name);
@ -229,7 +232,7 @@ abstract class ConfigTranslationFormBase extends FormBase implements BaseFormIdI
$translation_config->save(); $translation_config->save();
} }
} }
$this->configFactory->enableOverrides(); $this->configFactory->setOverrideState($old_state);
$form_state['redirect_route'] = array( $form_state['redirect_route'] = array(
'route_name' => $this->mapper->getOverviewRoute(), 'route_name' => $this->mapper->getOverviewRoute(),

View File

@ -55,9 +55,10 @@ class LocaleAdminPathConfigEntityConverter extends EntityConverter {
$entity_type = substr($definition['type'], strlen('entity:')); $entity_type = substr($definition['type'], strlen('entity:'));
if ($storage = $this->entityManager->getStorageController($entity_type)) { if ($storage = $this->entityManager->getStorageController($entity_type)) {
// Make sure no overrides are loaded. // Make sure no overrides are loaded.
$this->configFactory->disableOverrides(); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$entity = $storage->load($value); $entity = $storage->load($value);
$this->configFactory->enableOverrides(); $this->configFactory->setOverrideState($old_state);
return $entity; return $entity;
} }
} }

View File

@ -181,11 +181,12 @@ class MigrateSystemConfigsTest extends MigrateDrupalTestBase {
$this->prepare($migration, $dumps); $this->prepare($migration, $dumps);
$executable = new MigrateExecutable($migration, new MigrateMessage()); $executable = new MigrateExecutable($migration, new MigrateMessage());
$executable->import(); $executable->import();
\Drupal::configFactory()->disableOverrides(); $old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
$config = \Drupal::config('system.file'); $config = \Drupal::config('system.file');
$this->assertIdentical($config->get('path.private'), 'files/test'); $this->assertIdentical($config->get('path.private'), 'files/test');
$this->assertIdentical($config->get('path.temporary'), 'files/temp'); $this->assertIdentical($config->get('path.temporary'), 'files/temp');
\Drupal::configFactory()->enableOverrides(); \Drupal::configFactory()->setOverrideState($old_state);
} }
} }

View File

@ -138,8 +138,9 @@ class SearchPageListController extends DraggableListController implements FormIn
*/ */
public function buildForm(array $form, array &$form_state) { public function buildForm(array $form, array &$form_state) {
$form = parent::buildForm($form, $form_state); $form = parent::buildForm($form, $form_state);
$search_settings = $this->configFactory->disableOverrides()->get('search.settings'); $old_state = $this->configFactory->getOverrideState();
$this->configFactory->enableOverrides(); $search_settings = $this->configFactory->setOverrideState(FALSE)->get('search.settings');
$this->configFactory->setOverrideState($old_state);
// Collect some stats. // Collect some stats.
$remaining = 0; $remaining = 0;
$total = 0; $total = 0;