commit d9d374820269261496fa016bf5b155e890e8fb58 Author: Sally Young Date: Thu Nov 1 10:01:18 2012 -0700 Config merge diff --git a/core/includes/update.inc b/core/includes/update.inc index ec21aca..512c0b7 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -12,6 +12,7 @@ use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\ConfigException; use Drupal\Component\Uuid\Uuid; +use Drupal\Component\Utility\NestedArray; /** * Minimum schema version of Drupal 7 required for upgrade to Drupal 8. @@ -1217,18 +1218,15 @@ function update_variables_to_config($config_name, array $variable_map) { } $default_data = $file->read($config_name); + // Apply the default values. + $config->setData($default_data); + // Merge any possibly existing original data into default values. // Only relevant when being called repetitively on the same config object. if (!empty($original_data)) { - $data = drupal_array_merge_deep($default_data, $original_data); - } - else { - $data = $default_data; + $config->merge($original_data); } - // Apply the default values. - $config->setData($data); - // Fetch existing variables. $variables = db_query('SELECT name, value FROM {variable} WHERE name IN (:variables)', array(':variables' => array_keys($variable_map)))->fetchAllKeyed(); diff --git a/core/lib/Drupal/Component/Utility/NestedArray.php b/core/lib/Drupal/Component/Utility/NestedArray.php index 6617c68..acfdc2f 100644 --- a/core/lib/Drupal/Component/Utility/NestedArray.php +++ b/core/lib/Drupal/Component/Utility/NestedArray.php @@ -289,6 +289,10 @@ public static function keyExists(array $array, array $parents) { * @param array ... * Arrays to merge. * + * @param bool $preserve_integer_keys + * (optional) If given, integer keys will be preserved and merged instead of + * appended. + * * @return array * The merged array. * @@ -315,19 +319,19 @@ public static function mergeDeep() { * * @see NestedArray::mergeDeep() */ - public static function mergeDeepArray(array $arrays) { + public static function mergeDeepArray(array $arrays, $preserve_integer_keys = FALSE) { $result = array(); foreach ($arrays as $array) { foreach ($array as $key => $value) { - // Renumber integer keys as array_merge_recursive() does. Note that PHP - // automatically converts array keys that are integer strings (e.g., '1') - // to integers. - if (is_integer($key)) { + // Renumber integer keys as array_merge_recursive() does unless + // $preserve_integer_keys is set to TRUE. Note that PHP automatically + // converts array keys that are integer strings (e.g., '1') to integers. + if (is_integer($key) && !$preserve_integer_keys) { $result[] = $value; } // Recurse when both values are arrays. elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { - $result[$key] = self::mergeDeepArray(array($result[$key], $value)); + $result[$key] = self::mergeDeepArray(array($result[$key], $value), $preserve_integer_keys); } // Otherwise, use the latter value, overriding any previous value. else { diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 3fe9563..c63b2a0 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -401,4 +401,19 @@ public function getStorage() { protected function notify($config_event_name) { $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this)); } + + /* + * Merges data into a configuration object. + * + * @param array $data_to_merge + * An array containing data to merge. + * + * @return Drupal\Core\Config\Config + * The configuration object. + */ + public function merge(array $data_to_merge) { + // Preserve integer keys so that config keys are not changed. + $this->data = NestedArray::mergeDeepArray(array($this->data, $data_to_merge), TRUE); + return $this; + } } diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php index 6fe07de..f55921e 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigUpgradeTest.php @@ -98,5 +98,26 @@ function testConfigurationUpdate() { catch (ConfigException $e) { $this->pass('Exception was thrown on missing default module configuration file.'); } + + // For this test it is essential that update_variables_to_config has already + // run on the config object. + config('config_upgrade.test') + ->set('numeric_keys.403', '') + ->set('numeric_keys.404', '') + ->save(); + + db_insert('variable') + ->fields(array('name', 'value')) + ->values(array('config_upgrade_403', serialize('custom403'))) + ->values(array('config_upgrade_404', serialize('custom404'))) + ->execute(); + + // Perform migration. + update_variables_to_config('config_upgrade.test', array( + 'config_upgrade_403' => 'numeric_keys.403', + 'config_upgrade_404' => 'numeric_keys.404', + )); + + $this->assertIdentical(config('config_upgrade.test')->get('numeric_keys'), array(403 => 'custom403', 404 => 'custom404')); } } diff --git a/core/modules/system/tests/modules/config_upgrade/config/config_upgrade.test.yml b/core/modules/system/tests/modules/config_upgrade/config/config_upgrade.test.yml index c921534..fc448c1 100644 --- a/core/modules/system/tests/modules/config_upgrade/config/config_upgrade.test.yml +++ b/core/modules/system/tests/modules/config_upgrade/config/config_upgrade.test.yml @@ -2,3 +2,6 @@ parent: bar: Bar baz: Baz foo: Foo +numeric_keys: + 403: '' + 404: ''