Problem/Motivation
Currently we add new keys to the end of the target associative array.
How to reproduce:
1. Create a following config item, for example as mymodule.settings.yml file:
key1: value1
key2: value2
key3: value3
2. Import configuration into active configuration (e.g. by using drush cd-update).
3. Check the configuration item from the config storage:
$ drush cget mymodule.settings
key1: value1
key2: value2
key3: value3
4. Edit the configuration item by adding "key2a: value2a" between key2 and key3, so the mymodule.settings.yml file looks like:
key1: value1
key2: value2
key2a: value2a
key3: value3
5. Import the configuration: drush cc plugin && drush cd-update
6. Check the configuration item from the config storage again:
$ drush cget mymodule.settings
key1: value1
key2: value2
key3: value3
key2a: value2a
However, expected would be the following output:
$ drush cget mymodule.settings
key1: value1
key2: value2
key2a: value2a
key3: value3
The module does not preserve the order of entered config items on import; instead it always adds the new items as the last items to the storage. However, this can cause fatal issues in some cases (e.g. migration plugins in migrate_plus.migration.* config items), where order of the config items or array keys is very important.
Proposed resolution
Use array_replace()
followed by array_intersect_key()
to retain original order while bringing in additions.
A similar pattern in config_normalizer:
// Merge in uuid and _core while retaining the key order.
$merged = array_replace($active_data, $data);
$data = array_intersect_key($merged, array_flip(array_merge(array_keys($data), ['uuid', '_core'])));
Meantime a workaround would be to avoid merging in this case. If using Configuration Synchronizer, you could try setting the update mode to partial reset (or, more drastically, full reset) rather than the default, merge. Neither partial reset nor full reset invokes the merging from Config Merge.
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#3 | config_merge-addition-order-2998326-3.patch | 1.21 KB | nedjo |
Comments
Comment #2
nedjoA workaround would be to avoid merging in this case. If using Configuration Synchronizer, you could try setting the update mode to partial reset (or, more drastically, full reset) rather than the default, merge. Neither partial reset nor full reset invokes the merging from Config Merge.
Comment #3
nedjoDraft patch, tests need updating.
Comment #5
nedjo