YamlUtils::recursiveMerge()   B
last analyzed

Complexity

Conditions 8
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 11
nc 6
nop 2
dl 0
loc 20
rs 7.7777
c 0
b 0
f 0
1
<?php
2
3
4
namespace TheCodingMachine\CMS\StaticRegistry\Loaders;
5
6
7
class YamlUtils
8
{
9
    public const OVERRIDE = 'override';
10
    public const MERGE_ARRAY = 'mergeArray';
11
12
    /**
13
     * @param mixed[] $baseYaml
14
     * @param mixed[] $yaml
15
     * @param string[] $instructions
16
     * @return mixed[]
17
     */
18
    public function mergeArrays(array $baseYaml, array $yaml, array $instructions): array
19
    {
20
        foreach ($instructions as $key => $value) {
21
            switch ($value) {
22
                case self::OVERRIDE:
23
                    if (!isset($yaml[$key]) && isset($baseYaml[$key])) {
24
                        $yaml[$key] = $baseYaml[$key];
25
                    }
26
                    break;
27
                case self::MERGE_ARRAY:
28
                    if (isset($baseYaml[$key])) {
29
                        if (isset($yaml[$key])) {
30
                            $yaml[$key] = $this->recursiveMerge($baseYaml[$key], $yaml[$key]);
31
                        } else {
32
                            $yaml[$key] = $baseYaml[$key];
33
                        }
34
                    }
35
                    break;
36
                default:
37
                    throw new \InvalidArgumentException('Unexpected instruction "'.$value.'" passed. Expecting either "override" or "mergeArray".');
38
            }
39
        }
40
41
        return $yaml;
42
    }
43
44
    /**
45
     * @param mixed[] $base
46
     * @param mixed[] $target
47
     * @return mixed[]
48
     */
49
    private function recursiveMerge(array $base, array $target): array
50
    {
51
        if (!$this->isAssoc($base) && !$this->isAssoc($target)) {
52
            foreach ($target as $value) {
53
                $base[] = $value;
54
            }
55
            return $base;
56
        }
57
58
        foreach ($base as $key => $value) {
59
            if (!isset($target[$key])) {
60
                $target[$key] = $value;
61
                continue;
62
            }
63
            if (is_array($target[$key]) && is_array($value)) {
64
                $target[$key] = $this->recursiveMerge($value, $target[$key]);
65
            }
66
            // Otherwise, target wins, nothing to do
67
        }
68
        return $target;
69
    }
70
71
    /**
72
     * @param mixed[] $arr
73
     * @return bool
74
     */
75
    private function isAssoc(array $arr): bool
76
    {
77
        if (array() === $arr) return false;
78
        return array_keys($arr) !== range(0, count($arr) - 1);
79
    }
80
}
81