Passed
Pull Request — master (#62)
by Sergei
13:28
created

ArrayCollectionHelper::mergeBase()   B

Complexity

Conditions 11
Paths 4

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 22
c 1
b 0
f 0
dl 0
loc 35
rs 7.3166
cc 11
nc 4
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Arrays\Collection;
6
7
use InvalidArgumentException;
8
use Yiisoft\Arrays\Collection\Modifier\MergeWithKeysAsReverseMerge;
9
10
final class ArrayCollectionHelper
11
{
12
    public static function merge(...$args): ArrayCollection
13
    {
14
        $lastArray = end($args);
15
        if (
16
            $lastArray instanceof ArrayCollection &&
17
            static::hasMergeWithKeysAsReverseMergeModifier($lastArray)
18
        ) {
19
            return static::mergeWithKeysAsReverseMerge(...$args);
20
        }
21
22
        return static::mergeBase(...$args);
23
    }
24
25
    private static function hasMergeWithKeysAsReverseMergeModifier(ArrayCollection $collection): bool
26
    {
27
        foreach ($collection->getModifiers() as $modifier) {
28
            if ($modifier instanceof MergeWithKeysAsReverseMerge) {
29
                return true;
30
            }
31
        }
32
        return false;
33
    }
34
35
    private static function mergeBase(...$args): ArrayCollection
36
    {
37
        $collection = new ArrayCollection();
38
39
        while (!empty($args)) {
40
            $array = array_shift($args);
41
42
            if ($array instanceof ArrayCollection) {
43
                $collection->pullCollectionArgs($array);
44
                $collection->setData(
45
                    static::mergeBase($collection->getData(), $array->getData())->getData()
46
                );
47
                continue;
48
            } elseif (!is_array($array)) {
49
                throw new InvalidArgumentException();
50
            }
51
52
            foreach ($array as $k => $v) {
53
                if (is_int($k)) {
54
                    if ($collection->keyExists($k)) {
55
                        if ($collection[$k] !== $v) {
56
                            $collection[] = $v;
57
                        }
58
                    } else {
59
                        $collection[$k] = $v;
60
                    }
61
                } elseif (static::isMergable($v) && isset($collection[$k]) && static::isMergable($collection[$k])) {
62
                    $collection[$k] = static::mergeBase($collection[$k], $v)->getData();
63
                } else {
64
                    $collection[$k] = $v;
65
                }
66
            }
67
        }
68
69
        return $collection;
70
    }
71
72
    private static function mergeWithKeysAsReverseMerge(...$args): ArrayCollection
73
    {
74
        $collection = new ArrayCollection();
75
76
        while (!empty($args)) {
77
            $array = array_pop($args);
78
79
            if ($array instanceof ArrayCollection) {
80
                $collection->pullCollectionArgs($array);
81
                $collection->setData(
82
                    static::mergeWithKeysAsReverseMerge($collection->getData(), $array->getData())->getData()
83
                );
84
                continue;
85
            } elseif (!is_array($array)) {
86
                throw new InvalidArgumentException();
87
            }
88
89
            foreach ($array as $k => $v) {
90
                if (is_int($k)) {
91
                    if ($collection->keyExists($k)) {
92
                        if ($collection[$k] !== $v) {
93
                            $collection[] = $v;
94
                        }
95
                    } else {
96
                        $collection[$k] = $v;
97
                    }
98
                } elseif (static::isMergable($v) && isset($collection[$k]) && static::isMergable($collection[$k])) {
99
                    $collection[$k] = static::mergeWithKeysAsReverseMerge($v, $collection[$k]);
100
                } elseif (!$collection->keyExists($k)) {
101
                    $collection[$k] = $v;
102
                }
103
            }
104
        }
105
106
        return $collection;
107
    }
108
109
    private static function isMergable($value): bool
110
    {
111
        return is_array($value) || $value instanceof ArrayCollection;
112
    }
113
}
114