public static function ConfigMerger::mergeConfigItemStates in Config Merge 8
Merges changes to a configuration item into the active storage.
Parameters
array $previous: The configuration item as previously provided (from snapshot).
array $current: The configuration item as currently provided by an extension.
array $active: The configuration item as present in the active storage.
array $parent_keys: The keys of the property being merged in case of nested structure.
int $level: The level of recursion.
Return value
array
File
- src/
ConfigMerger.php, line 68
Class
- ConfigMerger
- Provides helper functions for merging configuration items.
Namespace
Drupal\config_mergeCode
public static function mergeConfigItemStates(array $previous, array $current, array $active, $parent_keys = [], $level = 0) {
if ($level === 0) {
self::$logs = [];
}
// We are merging into the active configuration state.
$result = $active;
$states = [
$previous,
$current,
$active,
];
$is_associative = FALSE;
foreach ($states as $array) {
// Analyze the array to determine if we should preserve integer keys.
if (Inline::isHash($array)) {
// If any of the states is associative, treat the item as associative.
$is_associative = TRUE;
break;
}
}
// Process associative arrays.
// Find any differences between previous and current states.
if ($is_associative) {
// Detect and process removals.
$removed = array_diff_key($previous, $current);
foreach ($removed as $key => $value) {
// Remove only if unchanged in the active state.
if (isset($active[$key]) && $active[$key] === $previous[$key]) {
unset($result[$key]);
}
}
// Detect and handle additions.
// Additions are keys added since the previous state and not overridden
// in the active state.
$added = array_diff_key($current, $previous, $active);
// Merge in all current keys while retaining the key order.
$merged = array_replace($current, $result);
// Filter to keep array items from the merged set that ...
$result = array_intersect_key($merged, array_flip(array_merge(array_keys($result), array_keys($added))));
// Detect and process changes.
foreach ($current as $key => $value) {
if (isset($previous[$key]) && $previous[$key] !== $value) {
// If we have an array, recurse.
if (is_array($value) && is_array($previous[$key]) && isset($active[$key]) && is_array($active[$key])) {
$recursion_keys = $parent_keys;
$recursion_keys[] = $key;
$level++;
$result[$key] = self::mergeConfigItemStates($previous[$key], $value, $active[$key], $recursion_keys, $level);
}
else {
$operation = static::OPERATION_IGNORE;
// Accept the new value only if the item hasn't been customized.
if (isset($active[$key]) && $active[$key] === $previous[$key]) {
$result[$key] = $value;
$operation = static::OPERATION_UPDATE;
}
self::$logs[$operation][] = [
'name' => $key,
'state' => [
'active' => $active[$key],
'previous' => $previous[$key],
'new' => $value,
],
'parents' => $parent_keys,
];
}
}
}
}
else {
$operation = static::OPERATION_IGNORE;
// If the data is unchanged, use the current value. Otherwise, retain any
// customization by keeping with the active value set above.
if ($previous === $active) {
$result = $current;
$operation = static::OPERATION_SUBSTITUTE;
}
self::$logs[$operation][] = [
'name' => end($parent_keys),
'state' => [
'active' => $active,
'previous' => $previous,
'new' => $current,
],
'parents' => $parent_keys,
];
}
return $result;
}