Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * This file is part of the Composer Merge plugin.
|
Chris@0
|
4 *
|
Chris@0
|
5 * Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
|
Chris@0
|
6 *
|
Chris@0
|
7 * This software may be modified and distributed under the terms of the MIT
|
Chris@0
|
8 * license. See the LICENSE file for details.
|
Chris@0
|
9 */
|
Chris@0
|
10
|
Chris@0
|
11 namespace Wikimedia\Composer\Merge;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * Adapted from
|
Chris@0
|
15 * http://cgit.drupalcode.org/drupal/tree/core/lib/Drupal/Component/Utility/NestedArray.php
|
Chris@0
|
16 * @ f86a4d650d5af0b82a3981e09977055fa63f6f2e
|
Chris@0
|
17 */
|
Chris@0
|
18 class NestedArray
|
Chris@0
|
19 {
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Merges multiple arrays, recursively, and returns the merged array.
|
Chris@0
|
23 *
|
Chris@0
|
24 * This function is similar to PHP's array_merge_recursive() function, but
|
Chris@0
|
25 * it handles non-array values differently. When merging values that are
|
Chris@0
|
26 * not both arrays, the latter value replaces the former rather than
|
Chris@0
|
27 * merging with it.
|
Chris@0
|
28 *
|
Chris@0
|
29 * Example:
|
Chris@0
|
30 *
|
Chris@0
|
31 * @code
|
Chris@0
|
32 * $link_options_1 = array('fragment' => 'x', 'attributes' => array('title' => t('X'), 'class' => array('a', 'b')));
|
Chris@0
|
33 * $link_options_2 = array('fragment' => 'y', 'attributes' => array('title' => t('Y'), 'class' => array('c', 'd')));
|
Chris@0
|
34 *
|
Chris@0
|
35 * // This results in array('fragment' => array('x', 'y'), 'attributes' =>
|
Chris@0
|
36 * // array('title' => array(t('X'), t('Y')), 'class' => array('a', 'b',
|
Chris@0
|
37 * // 'c', 'd'))).
|
Chris@0
|
38 * $incorrect = array_merge_recursive($link_options_1, $link_options_2);
|
Chris@0
|
39 *
|
Chris@0
|
40 * // This results in array('fragment' => 'y', 'attributes' =>
|
Chris@0
|
41 * // array('title' => t('Y'), 'class' => array('a', 'b', 'c', 'd'))).
|
Chris@0
|
42 * $correct = NestedArray::mergeDeep($link_options_1, $link_options_2);
|
Chris@0
|
43 * @endcode
|
Chris@0
|
44 *
|
Chris@0
|
45 * @param array ...
|
Chris@0
|
46 * Arrays to merge.
|
Chris@0
|
47 *
|
Chris@0
|
48 * @return array
|
Chris@0
|
49 * The merged array.
|
Chris@0
|
50 *
|
Chris@0
|
51 * @see NestedArray::mergeDeepArray()
|
Chris@0
|
52 */
|
Chris@0
|
53 public static function mergeDeep()
|
Chris@0
|
54 {
|
Chris@0
|
55 return self::mergeDeepArray(func_get_args());
|
Chris@0
|
56 }
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * Merges multiple arrays, recursively, and returns the merged array.
|
Chris@0
|
60 *
|
Chris@0
|
61 * This function is equivalent to NestedArray::mergeDeep(), except the
|
Chris@0
|
62 * input arrays are passed as a single array parameter rather than
|
Chris@0
|
63 * a variable parameter list.
|
Chris@0
|
64 *
|
Chris@0
|
65 * The following are equivalent:
|
Chris@0
|
66 * - NestedArray::mergeDeep($a, $b);
|
Chris@0
|
67 * - NestedArray::mergeDeepArray(array($a, $b));
|
Chris@0
|
68 *
|
Chris@0
|
69 * The following are also equivalent:
|
Chris@0
|
70 * - call_user_func_array('NestedArray::mergeDeep', $arrays_to_merge);
|
Chris@0
|
71 * - NestedArray::mergeDeepArray($arrays_to_merge);
|
Chris@0
|
72 *
|
Chris@0
|
73 * @param array $arrays
|
Chris@0
|
74 * An arrays of arrays to merge.
|
Chris@0
|
75 * @param bool $preserveIntegerKeys
|
Chris@0
|
76 * (optional) If given, integer keys will be preserved and merged
|
Chris@0
|
77 * instead of appended. Defaults to false.
|
Chris@0
|
78 *
|
Chris@0
|
79 * @return array
|
Chris@0
|
80 * The merged array.
|
Chris@0
|
81 *
|
Chris@0
|
82 * @see NestedArray::mergeDeep()
|
Chris@0
|
83 */
|
Chris@0
|
84 public static function mergeDeepArray(
|
Chris@0
|
85 array $arrays,
|
Chris@0
|
86 $preserveIntegerKeys = false
|
Chris@0
|
87 ) {
|
Chris@0
|
88 $result = array();
|
Chris@0
|
89 foreach ($arrays as $array) {
|
Chris@0
|
90 foreach ($array as $key => $value) {
|
Chris@0
|
91 // Renumber integer keys as array_merge_recursive() does
|
Chris@0
|
92 // unless $preserveIntegerKeys is set to TRUE. Note that PHP
|
Chris@0
|
93 // automatically converts array keys that are integer strings
|
Chris@0
|
94 // (e.g., '1') to integers.
|
Chris@0
|
95 if (is_integer($key) && !$preserveIntegerKeys) {
|
Chris@0
|
96 $result[] = $value;
|
Chris@0
|
97 } elseif (isset($result[$key]) &&
|
Chris@0
|
98 is_array($result[$key]) &&
|
Chris@0
|
99 is_array($value)
|
Chris@0
|
100 ) {
|
Chris@0
|
101 // Recurse when both values are arrays.
|
Chris@0
|
102 $result[$key] = self::mergeDeepArray(
|
Chris@0
|
103 array($result[$key], $value),
|
Chris@0
|
104 $preserveIntegerKeys
|
Chris@0
|
105 );
|
Chris@0
|
106 } else {
|
Chris@0
|
107 // Otherwise, use the latter value, overriding any
|
Chris@0
|
108 // previous value.
|
Chris@0
|
109 $result[$key] = $value;
|
Chris@0
|
110 }
|
Chris@0
|
111 }
|
Chris@0
|
112 }
|
Chris@0
|
113 return $result;
|
Chris@0
|
114 }
|
Chris@0
|
115 }
|
Chris@0
|
116 // vim:sw=4:ts=4:sts=4:et:
|