Passed
Push — master ( cf27e8...f24788 )
by Harry
02:00
created

ArrayMerger::merge()   B

Complexity

Conditions 9
Paths 7

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 7
nop 2
dl 0
loc 31
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
namespace Graze\ArrayMerger;
4
5
use Graze\ArrayMerger\ValueMerger\LastValue;
6
7
/**
8
 * Class ArrayMerger
9
 *
10
 * This does a simple, `array_merge`, but you can choose how to merge the values yourself
11
 */
12
class ArrayMerger implements ArrayMergerInterface
13
{
14
    use StaticMethodsTrait;
15
    use SequentialTrait;
16
17
    /** @var callable */
18
    protected $valueMerger;
19
    /** @var int */
20
    private $flags;
21
22
    /**
23
     * @param callable $valueMerger
24
     * @param int      $flags
25
     */
26
    public function __construct(callable $valueMerger = null, $flags = 0)
27
    {
28
        $this->valueMerger = $valueMerger ?: new LastValue();
29
        $this->flags = $flags;
30
    }
31
32
    /**
33
     * Merge using the supplied Value Merge
34
     *
35
     * @param callable $valueMerger
36
     * @param array    $array1
37
     * @param array    $arrays
38
     *
39
     * @return array
40
     */
41
    public static function mergeUsing(callable $valueMerger, array $array1, array $arrays)
42
    {
43
        $merger = new static($valueMerger);
44
        return call_user_func_array([$merger, 'merge'], array_merge([$array1], array_slice(func_get_args(), 2)));
45
    }
46
47
    /**
48
     * Merge the values from all the array supplied, the first array is treated as the base array to merge into
49
     *
50
     * @param array      $array1
51
     * @param array|null $arrays
52
     *
53
     * @return array
54
     */
55
    public function merge(array $array1, array $arrays = null)
56
    {
57
        $arrays = array_slice(func_get_args(), 1);
58
        if (count($arrays) === 0) {
59
            return $array1;
60
        }
61
62
        // if all arrays are sequential and flag is set, append them all
63
        if ($this->flags & static::FLAG_APPEND_VALUE_ARRAY == static::FLAG_APPEND_VALUE_ARRAY
64
            && $this->areSequential(array_merge([$array1], $arrays))) {
65
            return call_user_func_array('array_merge', array_merge([$array1], $arrays));
66
        }
67
68
        $merged = $array1;
69
70
        foreach ($arrays as $toMerge) {
71
            foreach ($toMerge as $key => &$value) {
72
                if (array_key_exists($key, $merged)) {
73
                    if ($this->flags & static::FLAG_APPEND_VALUE_ARRAY == static::FLAG_APPEND_VALUE_ARRAY
74
                        && $this->areSequential([$value, $merged[$key]])) {
75
                        $merged[$key] = array_merge($merged[$key], $value);
76
                    } else {
77
                        $merged[$key] = call_user_func($this->valueMerger, $merged[$key], $value);
78
                    }
79
                } else {
80
                    $merged[$key] = $value;
81
                }
82
            }
83
        }
84
85
        return $merged;
86
    }
87
}
88