Passed
Pull Request — master (#62)
by Sergei
12:22
created

ArrayCollectionHelper::mergeBase()   B

Complexity

Conditions 10
Paths 3

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 20
c 1
b 0
f 0
dl 0
loc 33
rs 7.6666
cc 10
nc 3
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\ModifierInterface\AfterMergeModifierInterface;
9
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\BeforeMergeModifierInterface;
10
11
final class ArrayCollectionHelper
12
{
13
    /**
14
     * @param array|ArrayCollection ...$args
15
     * @return ArrayCollection
16
     */
17
    public static function merge(...$args): ArrayCollection
18
    {
19
        $arrays = [];
20
        foreach ($args as $arg) {
21
            $arrays[] = $arg instanceof ArrayCollection ? $arg->getData() : $arg;
22
        }
23
24
        $collections = [];
25
        foreach ($args as $index => $arg) {
26
            $collection = $arg instanceof ArrayCollection ? $arg : new ArrayCollection($arg);
27
            foreach ($collection->getModifiers() as $modifier) {
28
                if ($modifier instanceof BeforeMergeModifierInterface) {
29
                    $collection->setData(
30
                        $modifier->beforeMerge($arrays, $index)
31
                    );
32
                }
33
            }
34
            $collections[$index] = $collection;
35
        }
36
37
        $collection = static::mergeBase(...$collections);
38
39
        foreach ($collection->getModifiers() as $modifier) {
40
            if ($modifier instanceof AfterMergeModifierInterface) {
41
                $collection->setData($modifier->afterMerge($collection->getData()));
42
            }
43
        }
44
45
        return $collection;
46
    }
47
48
    /**
49
     * @param array|ArrayCollection ...$args
50
     * @return ArrayCollection
51
     */
52
    private static function mergeBase(...$args): ArrayCollection
53
    {
54
        $collection = new ArrayCollection();
55
56
        while (!empty($args)) {
57
            $array = array_shift($args);
58
59
            if ($array instanceof ArrayCollection) {
60
                $collection->pullCollectionArgs($array);
61
                $collection->setData(
62
                    static::mergeBase($collection->getData(), $array->getData())->getData()
63
                );
64
                continue;
65
            }
66
67
            foreach ($array as $k => $v) {
68
                if (is_int($k)) {
69
                    if ($collection->keyExists($k)) {
70
                        if ($collection[$k] !== $v) {
71
                            $collection[] = $v;
72
                        }
73
                    } else {
74
                        $collection[$k] = $v;
75
                    }
76
                } elseif (static::isMergable($v) && isset($collection[$k]) && static::isMergable($collection[$k])) {
77
                    $collection[$k] = static::mergeBase($collection[$k], $v)->getData();
78
                } else {
79
                    $collection[$k] = $v;
80
                }
81
            }
82
        }
83
84
        return $collection;
85
    }
86
87
    /**
88
     * @param mixed $value
89
     * @return bool
90
     */
91
    private static function isMergable($value): bool
92
    {
93
        return is_array($value) || $value instanceof ArrayCollection;
94
    }
95
}
96