Merger   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 3
dl 0
loc 136
rs 9.6
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
D merge() 0 34 10
A mergeAgg() 0 6 2
A mergePreToAgg() 0 6 2
A mergePre() 0 13 2
C mergeArrays() 0 43 16
1
<?php
2
3
namespace Dwo\Aggregator;
4
5
use Dwo\Aggregator\Exception\AggregatorException;
6
use Dwo\Aggregator\Model\Aggregate;
7
use Dwo\Aggregator\Model\PreAggregate;
8
9
/**
10
 * Class Merger
11
 *
12
 * @author Dave Www <[email protected]>
13
 */
14
class Merger
15
{
16
    /**
17
     * merges Aggregate+Aggregate | Aggregate+PreAggregate | PreAggregate+PreAggregate | array()+array()
18
     *
19
     * @param mixed       $origin Aggregate|PreAggregate|array
20
     * @param mixed       $merge  Aggregate|PreAggregate|array
21
     * @param array       $saveKeys
22
     * @param string|null $idKey
23
     */
24
    public static function merge(&$origin, $merge, array $saveKeys = [], $idKey = null)
25
    {
26
        $checkMergeType = function ($a) {
27
            if ($a instanceof Aggregate) {
28
                return 16;
29
            } elseif ($a instanceof PreAggregate) {
30
                return 4;
31
            } else {
32
                if (is_array($a)) {
33
                    return 1;
34
                }
35
            }
36
37
            return null;
38
        };
39
40
        $typeOne = $checkMergeType($origin);
41
        $typeTwo = $checkMergeType($merge);
42
        $mergeType = $typeOne + $typeTwo;
43
44
        if (32 === $mergeType) {
45
            self::mergePre($origin, $merge, $saveKeys, $idKey);
46
            self::mergeAgg($origin, $merge);
47
        } elseif (16 === $typeOne && 4 === $typeTwo) {
48
            self::mergePre($origin, $merge, $saveKeys, $idKey);
49
            self::mergePreToAgg($origin, $merge);
50
        } elseif (4 <= $typeOne && 4 <= $typeTwo) {
51
            self::mergePre($origin, $merge, $saveKeys, $idKey);
52
        } elseif (2 === $mergeType) {
53
            self::mergeArrays($origin, $merge, $saveKeys);
54
        } else {
55
            throw new AggregatorException('cant be merged');
56
        }
57
    }
58
59
    /**
60
     * @param Aggregate $origin
61
     * @param Aggregate $merge
62
     */
63
    private static function mergeAgg(Aggregate $origin, Aggregate $merge)
64
    {
65
        foreach ($merge->getOriginIds() as $id) {
66
            $origin->addOriginId($id);
67
        }
68
    }
69
70
    /**
71
     * @param Aggregate    $origin
72
     * @param PreAggregate $merge
73
     */
74
    private static function mergePreToAgg(Aggregate $origin, PreAggregate $merge)
75
    {
76
        if (null !== $id = $merge->getId()) {
77
            $origin->addOriginId($id);
78
        }
79
    }
80
81
    /**
82
     * @param PreAggregate $origin
83
     * @param PreAggregate $merge
84
     * @param array        $saveKeys
85
     * @param string|null  $idKey
86
     */
87
    private static function mergePre(PreAggregate $origin, PreAggregate $merge, array $saveKeys = [], $idKey = null)
88
    {
89
        $originData = $origin->getData();
90
        $data = $merge->getData();
91
        if (null !== $idKey) {
92
            unset($data[$idKey]);
93
        }
94
95
        self::mergeArrays($originData, $data, $saveKeys);
96
97
        $origin->setData($originData);
98
        $origin->incrementCount($merge->getCount());
99
    }
100
101
    /**
102
     * @param array $dataOrigin
103
     * @param array $data
104
     * @param array $saveKeys
105
     */
106
    private static function mergeArrays(array &$dataOrigin, array $data, array $saveKeys = [])
107
    {
108
        foreach ($data as $key => $value) {
109
            if (!isset($dataOrigin[$key])) {
110
                $dataOrigin[$key] = null;
111
            }
112
113
            $mergeable = !in_array($key, $saveKeys);
114
            $operation = isset($saveKeys[$key]);
115
116
            switch (true) {
117
                case is_numeric($value) && $mergeable && !$operation:
118
                    $dataOrigin[$key] += $value;
119
                    break;
120
121
                case is_array($value) && $mergeable && !$operation:
122
                    if (null === $dataOrigin[$key]) {
123
                        $dataOrigin[$key] = [];
124
                    }
125
                    self::mergeArrays($dataOrigin[$key], $value);
126
                    break;
127
128
                case $mergeable && $operation:
129
                    if (null === $dataOrigin[$key]) {
130
                        $dataOrigin[$key] = [];
131
                    } elseif (!is_array($dataOrigin[$key])) {
132
                        $dataOrigin[$key] = array($dataOrigin[$key]);
133
                    }
134
                    if (is_array($value)) {
135
                        $dataOrigin[$key] = array_merge($dataOrigin[$key], $value);
136
                    } else {
137
                        $dataOrigin[$key][] = $value;
138
                    }
139
                    break;
140
141
                default:
142
                    if (null === $dataOrigin[$key]) {
143
                        $dataOrigin[$key] = $value;
144
                    }
145
                    break;
146
            }
147
        }
148
    }
149
}