Completed
Pull Request — master (#114)
by Fabian
25:22 queued 23:00
created

NestedArray::mergeDeep()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 24
ccs 0
cts 14
cp 0
rs 6.7272
cc 7
eloc 12
nc 5
nop 0
crap 56
1
<?php
2
/**
3
 * This file is part of the Composer Merge plugin.
4
 *
5
 * Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
6
 *
7
 * This software may be modified and distributed under the terms of the MIT
8
 * license. See the LICENSE file for details.
9
 */
10
11
namespace Wikimedia\Composer;
12
13
/**
14
 * Helper class to merge arrays in a deep fashion.
15
 *
16
 * @author Bryan Davis <[email protected]>
17
 */
18
class NestedArray
19
{
20
    /**
21
     * Merges multiple arrays, recursively, and returns the merged array.
22
     *
23
     * This function is similar to PHP's array_merge_recursive() function, but it
24
     * handles non-array values differently. When merging values that are not both
25
     * arrays, the latter value replaces the former rather than merging with it.
26
     *
27
     * Example:
28
     * @code
29
     * $link_options_1 = array('fragment' => 'x', 'attributes' => array('title' => t('X'), 'class' => array('a', 'b')));
30
     * $link_options_2 = array('fragment' => 'y', 'attributes' => array('title' => t('Y'), 'class' => array('c', 'd')));
31
     *
32
     * // This results in array(
33
     * //     'fragment' => array('x', 'y'),
34
     * //     'attributes' => array('title' => array(t('X'), t('Y')), 'class' => array('a', 'b', 'c', 'd'))
35
     * // ).
36
     * $incorrect = array_merge_recursive($link_options_1, $link_options_2);
37
     *
38
     * // This results in array(
39
     * //     'fragment' => 'y',
40
     * //     'attributes' => array('title' => t('Y'), 'class' => array('a', 'b', 'c', 'd'))
41
     * // ).
42
     * $correct = NestedArray::mergeDeep($link_options_1, $link_options_2);
43
     * @endcode
44
     *
45
     * Note: This function was derived from Drupal's drupal_array_merge_deep().
46
     *
47
     * @param array ...
48
     *   Arrays to merge.
49
     *
50
     * @return array
51
     *   The merged array.
52
     */
53
    public static function mergeDeep()
54
    {
55
        $arrays = func_get_args();
56
        $result = array();
57
58
        foreach ($arrays as $array) {
59
            foreach ($array as $key => $value) {
60
                // Renumber integer keys as array_merge_recursive() does. Note that PHP
61
                // automatically converts array keys that are integer strings (e.g., '1')
62
                // to integers.
63
                if (is_integer($key)) {
64
                    $result[] = $value;
65
                } elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) {
66
                    // Recurse when both values are arrays.
67
                    $result[$key] = self::mergeDeep($result[$key], $value);
68
                } else {
69
                    // Otherwise, use the latter value, overriding any previous value.
70
                    $result[$key] = $value;
71
                }
72
            }
73
        }
74
75
        return $result;
76
    }
77
}
78