Commit f2769f4d authored by catch's avatar catch

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

parent 318d178b
......@@ -512,10 +512,6 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@module_handler']
config_global_override_subscriber:
class: Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber
tags:
- { name: event_subscriber }
config_import_subscriber:
class: Drupal\Core\EventSubscriber\ConfigImportSubscriber
tags:
......
......@@ -2562,7 +2562,8 @@ function menu_router_rebuild() {
function menu_router_build($save = FALSE) {
// Ensure that all configuration used to build the menu items are loaded
// 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
// a given item came from.
$callbacks = array();
......@@ -2577,8 +2578,7 @@ function menu_router_build($save = FALSE) {
}
// Alter the menu as defined in modules, keys are like user/%user.
drupal_alter('menu', $callbacks);
// Re-enable configuration overrides.
\Drupal::configFactory()->enableOverrides();
\Drupal::configFactory()->setOverrideState($old_state);
foreach ($callbacks as $path => $router_item) {
// If the menu item is a default local task and incorrectly references a
// route, remove it.
......
......@@ -91,25 +91,27 @@ public function __construct(StorageInterface $storage, EventDispatcher $event_di
}
/**
* 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
* The config factory object.
*/
public function disableOverrides() {
$this->useOverrides = FALSE;
public function setOverrideState($state) {
$this->useOverrides = $state;
return $this;
}
/**
* Enable overrides when loading configuration objects.
* Get the override state.
*
* @return \Drupal\Core\Config\ConfigFactory
* The config factory object.
* @return bool
* TRUE if overrides are applied, FALSE otherwise.
*/
public function enableOverrides() {
$this->useOverrides = TRUE;
return $this;
public function getOverrideState() {
return $this->useOverrides;
}
/**
......
......@@ -101,7 +101,8 @@ public function installDefaultConfig($type, $name) {
}
if (!empty($config_to_install)) {
$this->configFactory->disableOverrides();
$old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
foreach ($config_to_install as $name) {
// Only import new config.
if ($this->activeStorage->exists($name)) {
......@@ -123,7 +124,7 @@ public function installDefaultConfig($type, $name) {
$new_config->save();
}
}
$this->configFactory->enableOverrides();
$this->configFactory->setOverrideState($old_state);
}
}
......
<?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;
}
}
......@@ -74,9 +74,10 @@ public function submitForm(array &$form, array &$form_state) {
* configuration.
*/
protected function config($name) {
$this->configFactory->disableOverrides();
$old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$config = $this->configFactory->get($name);
$this->configFactory->enableOverrides();
$this->configFactory->setOverrideState($old_state);
return $config;
}
}
......@@ -82,10 +82,11 @@ function testConfigLanguageOverride() {
$config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$this->assertIdentical($config->get('language'), 'override');
\Drupal::configFactory()->disableOverrides();
$old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
$config = \Drupal::config('config_test.new');
$this->assertIdentical($config->get('language'), NULL);
\Drupal::configFactory()->enableOverrides();
\Drupal::configFactory()->setOverrideState($old_state);
// Ensure that language configuration overrides can not be overridden.
global $conf;
......
......@@ -38,25 +38,31 @@ public function testSimpleModuleOverrides() {
->set('slogan', $non_overridden_slogan)
->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_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_slogan, $config_factory->get('system.site')->get('slogan'));
// 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.
$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->assertIdentical($config->get('module'), 'override');
\Drupal::configFactory()->disableOverrides();
$config_factory->setOverrideState(FALSE);
$config = \Drupal::config('config_override.new');
$this->assertIdentical($config->get('module'), NULL);
\Drupal::configFactory()->enableOverrides();
$config_factory->setOverrideState($old_state);
unset($GLOBALS['config_test_run_module_overrides']);
}
}
......@@ -122,14 +122,15 @@ function testConfOverride() {
$config = \Drupal::config('config_test.new');
$this->assertTrue($config->isNew(), 'The configuration object config_test.new is new');
$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');
$this->assertIdentical($config_raw->get('key'), NULL);
$config_raw
->set('key', 'raw')
->set('new_key', 'new_value')
->save();
\Drupal::configFactory()->enableOverrides();
\Drupal::configFactory()->setOverrideState($old_state);
// Ensure override is preserved but all other data has been updated
// accordingly.
$this->assertIdentical($config->get('key'), 'override');
......
......@@ -92,11 +92,13 @@ public function testOverridePriorities() {
$this->assertEqual($language_overridden_mail, $config_factory->get('system.site')->get('mail'));
$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_slogan, $config_factory->get('system.site')->get('slogan'));
$this->assertEqual($non_overridden_mail, $config_factory->get('system.site')->get('mail'));
$this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max'));
$config_factory->setOverrideState($old_state);
unset($GLOBALS['config_test_run_module_overrides']);
}
......
......@@ -163,12 +163,13 @@ public function buildForm(array $form, array &$form_state, Request $request = NU
$this->language = $language;
$this->sourceLanguage = $this->mapper->getLanguageWithFallback();
// Get base language configuration to display in the form before entering
// into the language context for the form. This avoids repetitively going
// in and out of the language context to get original values later.
$this->configFactory->disableOverrides();
// Get base language configuration to display in the form before setting the
// language to use for the form. This avoids repetitively setting and
// resetting the language to get original values later.
$old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$this->baseConfigData = $this->mapper->getConfigData();
$this->configFactory->enableOverrides();
$this->configFactory->setOverrideState($old_state);
// Set the translation target language on the configuration factory.
$original_language = $this->configFactory->getLanguage();
......@@ -210,7 +211,9 @@ public function submitForm(array &$form, array &$form_state) {
$form_values = $form_state['values']['config_names'];
// 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) {
// Set configuration values based on form submission and source values.
$base_config = $this->config($name);
......@@ -229,7 +232,7 @@ public function submitForm(array &$form, array &$form_state) {
$translation_config->save();
}
}
$this->configFactory->enableOverrides();
$this->configFactory->setOverrideState($old_state);
$form_state['redirect_route'] = array(
'route_name' => $this->mapper->getOverviewRoute(),
......
......@@ -55,9 +55,10 @@ public function convert($value, $definition, $name, array $defaults, Request $re
$entity_type = substr($definition['type'], strlen('entity:'));
if ($storage = $this->entityManager->getStorageController($entity_type)) {
// Make sure no overrides are loaded.
$this->configFactory->disableOverrides();
$old_state = $this->configFactory->getOverrideState();
$this->configFactory->setOverrideState(FALSE);
$entity = $storage->load($value);
$this->configFactory->enableOverrides();
$this->configFactory->setOverrideState($old_state);
return $entity;
}
}
......
......@@ -181,11 +181,12 @@ public function testSystemFile() {
$this->prepare($migration, $dumps);
$executable = new MigrateExecutable($migration, new MigrateMessage());
$executable->import();
\Drupal::configFactory()->disableOverrides();
$old_state = \Drupal::configFactory()->getOverrideState();
\Drupal::configFactory()->setOverrideState(FALSE);
$config = \Drupal::config('system.file');
$this->assertIdentical($config->get('path.private'), 'files/test');
$this->assertIdentical($config->get('path.temporary'), 'files/temp');
\Drupal::configFactory()->enableOverrides();
\Drupal::configFactory()->setOverrideState($old_state);
}
}
......@@ -138,8 +138,9 @@ public function buildRow(EntityInterface $entity) {
*/
public function buildForm(array $form, array &$form_state) {
$form = parent::buildForm($form, $form_state);
$search_settings = $this->configFactory->disableOverrides()->get('search.settings');
$this->configFactory->enableOverrides();
$old_state = $this->configFactory->getOverrideState();
$search_settings = $this->configFactory->setOverrideState(FALSE)->get('search.settings');
$this->configFactory->setOverrideState($old_state);
// Collect some stats.
$remaining = 0;
$total = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment