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

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

nedjo created an issue. See original summary.

nedjo’s picture

Issue summary: View changes

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.

nedjo’s picture

Draft patch, tests need updating.

  • nedjo committed 79029f0 on 8.x-1.x
    Issue #2998326 by nedjo: Retain sort order when merging in associative...
nedjo’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.