diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 584feb7c53..b55d46b161 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -85,19 +85,7 @@ public function get($key = '') { if (!isset($this->overriddenData)) { $this->setOverriddenData(); } - if (empty($key)) { - return $this->overriddenData; - } - else { - $parts = explode('.', $key); - if (count($parts) == 1) { - return isset($this->overriddenData[$key]) ? $this->overriddenData[$key] : NULL; - } - else { - $value = NestedArray::getValue($this->overriddenData, $parts, $key_exists); - return $key_exists ? $value : NULL; - } - } + return self::extractKeyedData($this->overriddenData, $key); } /** @@ -141,6 +129,27 @@ public function setModuleOverride(array $data) { return $this; } + /** + * Returns overrides that apply to this configuration. + * + * Simply comparing the the data from getOriginal() with and without overrides + * does not help to detect overrides if the override happens to have the same + * value as the original data. + * + * @param string $key + * A string that maps to a key within the configuration data. + * + * @return mixed + * The value of the override or NULL if not overwritten. + */ + public function getOverrides($key = '') { + $overrides = $this->mergeOverridesWithData([]); + if (empty($overrides)) { + return NULL; + } + return self::extractKeyedData($overrides, $key); + } + /** * Sets the current data for this configuration object. * @@ -153,13 +162,7 @@ public function setModuleOverride(array $data) { * The configuration object. */ protected function setOverriddenData() { - $this->overriddenData = $this->data; - if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { - $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->moduleOverrides], TRUE); - } - if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) { - $this->overriddenData = NestedArray::mergeDeepArray([$this->overriddenData, $this->settingsOverrides], TRUE); - } + $this->overriddenData = $this->mergeOverridesWithData($this->data); return $this; } @@ -280,27 +283,44 @@ public function getOriginal($key = '', $apply_overrides = TRUE) { $original_data = $this->originalData; if ($apply_overrides) { // Apply overrides. - if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { - $original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE); - } - if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) { - $original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE); - } + $original_data = $this->mergeOverridesWithData($original_data); } - if (empty($key)) { - return $original_data; + return self::extractKeyedData($original_data, $key); + } + + /** + * Merge module and settings overrides with the provided data. + * + * @param array $data + * The data to merge the overrides with. + * + * @return array + * The overwritten data, unchanged if no overrides apply. + */ + protected function mergeOverridesWithData(array $data) { + if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { + $data = NestedArray::mergeDeepArray([$data, $this->moduleOverrides], TRUE); } - else { - $parts = explode('.', $key); - if (count($parts) == 1) { - return isset($original_data[$key]) ? $original_data[$key] : NULL; - } - else { - $value = NestedArray::getValue($original_data, $parts, $key_exists); - return $key_exists ? $value : NULL; - } + if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) { + $data = NestedArray::mergeDeepArray([$data, $this->settingsOverrides], TRUE); } + return $data; + } + + /** + * Extract the value of a sub key in the data. + * + * @param array $data + * The configuration data. + * @param string $key + * A string that maps to a key within the configuration data. + * + * @return mixed + * The data at the key or NULL if it is not set. + */ + protected static function extractKeyedData(array $data, $key) { + return NestedArray::getValue($data, $key ? explode('.', $key) : []); } } diff --git a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php index 41c3e93c99..4a583bbdd3 100644 --- a/core/tests/Drupal/Tests/Core/Config/ConfigTest.php +++ b/core/tests/Drupal/Tests/Core/Config/ConfigTest.php @@ -173,6 +173,7 @@ public function testSaveExisting($data) { * @covers ::setModuleOverride * @covers ::setSettingsOverride * @covers ::getOriginal + * @covers ::getOverrides * @dataProvider overrideDataProvider */ public function testOverrideData($data, $module_data, $setting_data) { @@ -184,26 +185,38 @@ public function testOverrideData($data, $module_data, $setting_data) { // Save so that the original data is stored. $this->config->save(); + $this->assertNull($this->config->getOverrides()); // Set module override data and check value before and after save. $this->config->setModuleOverride($module_data); $this->assertConfigDataEquals($module_data); + $this->assertEquals($module_data, $this->config->getOverrides()); $this->config->save(); $this->assertConfigDataEquals($module_data); + $this->assertEquals($module_data, $this->config->getOverrides()); + + // Reset the module overrides. + $this->config->setModuleOverride([]); + $this->assertNull($this->config->getOverrides()); // Set setting override data and check value before and after save. $this->config->setSettingsOverride($setting_data); $this->assertConfigDataEquals($setting_data); + $this->assertEquals($setting_data, $this->config->getOverrides()); $this->config->save(); $this->assertConfigDataEquals($setting_data); + $this->assertEquals($setting_data, $this->config->getOverrides()); // Set module overrides again to ensure override order is correct. $this->config->setModuleOverride($module_data); + $merged_overrides = array_merge($module_data, $setting_data); // Setting data should be overriding module data. $this->assertConfigDataEquals($setting_data); + $this->assertEquals($merged_overrides, $this->config->getOverrides()); $this->config->save(); $this->assertConfigDataEquals($setting_data); + $this->assertEquals($merged_overrides, $this->config->getOverrides()); // Check original data has not changed. $this->assertOriginalConfigDataEquals($data, FALSE); @@ -215,7 +228,29 @@ public function testOverrideData($data, $module_data, $setting_data) { foreach ($setting_data as $key => $value) { $config_value = $this->config->getOriginal($key); $this->assertEquals($value, $config_value); + $this->assertEquals($value, $this->config->getOverrides($key)); + } + + // Check that getOverrides only returns overrides. + foreach ($data as $key => $value) { + $config_value = $this->config->get($key); + if (isset($merged_overrides[$key])) { + $this->assertEquals($config_value, $this->config->getOverrides($key)); + } + else { + $this->assertNull($this->config->getOverrides($key)); + $this->assertEquals($value, $config_value); + } } + + // Check that the overrides can be completely reset. + $this->config->setModuleOverride([]); + $this->config->setSettingsOverride([]); + $this->assertConfigDataEquals($data); + $this->assertNull($this->config->getOverrides()); + $this->config->save(); + $this->assertConfigDataEquals($data); + $this->assertNull($this->config->getOverrides()); } /** @@ -449,6 +484,23 @@ public function overrideDataProvider() { 'a' => 'settingValue', ], ], + [ + // Original data. + [ + 'a' => 'originalValue', + 'b' => 'originalValue', + 'c' => 'originalValue', + ], + // Module overrides. + [ + 'a' => 'moduleValue', + 'b' => 'moduleValue', + ], + // Setting overrides. + [ + 'a' => 'settingValue', + ], + ], ]; }