Completed
Push — v0.10 ( f42b97...309689 )
by Simonas
8s
created

MappingTool::recursiveDiff()   C

Complexity

Conditions 8
Paths 18

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 30
rs 5.3846
cc 8
eloc 17
nc 18
nop 2
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchBundle\Mapping;
13
14
/**
15
 * Mapping tool for comparing.
16
 */
17
class MappingTool
18
{
19
    /**
20
     * @var array
21
     */
22
    private $removedTypes = [];
23
24
    /**
25
     * @var array
26
     */
27
    private $updatedTypes = [];
28
29
    /**
30
     * Compares two mappings and returns true if changes detected.
31
     *
32
     * @param array $oldMapping
33
     * @param array $newMapping
34
     *
35
     * @return bool
36
     */
37
    public function checkMapping($oldMapping, $newMapping)
38
    {
39
        $updated = false;
40
41
        // Find out which types don't exist anymore.
42
        $typeDiff = array_diff_key($oldMapping, $newMapping);
43
        foreach ($typeDiff as $oldTypeName => $oldType) {
44
            $this->removedTypes[] = $oldTypeName;
45
            $updated = true;
46
        }
47
48
        // Search for differences in types.
49
        foreach ($newMapping as $type => $properties) {
50
            $diff = null;
51
            if (array_key_exists($type, $oldMapping)) {
52
                $diff = $this->symDifference($properties, $oldMapping[$type]);
53
            }
54
55
            // Empty array type properties hasn't changed, NULL - new type.
56
            if ($diff !== [] || $diff === null) {
57
                $this->updatedTypes[$type] = $properties;
58
                $updated = true;
59
            }
60
        }
61
62
        return $updated;
63
    }
64
65
    /**
66
     * Returns symmetric difference.
67
     *
68
     * @param array $oldMapping
69
     * @param array $newMapping
70
     *
71
     * @return array
72
     */
73
    public function symDifference($oldMapping, $newMapping)
74
    {
75
        return array_replace_recursive(
76
            $this->recursiveDiff($oldMapping, $newMapping),
77
            $this->recursiveDiff($newMapping, $oldMapping)
78
        );
79
    }
80
81
    /**
82
     * Returns type name which has been removed.
83
     *
84
     * @return array
85
     */
86
    public function getRemovedTypes()
87
    {
88
        return $this->removedTypes;
89
    }
90
91
    /**
92
     * Returns type names with new properties which has been updated.
93
     *
94
     * @return array
95
     */
96
    public function getUpdatedTypes()
97
    {
98
        return $this->updatedTypes;
99
    }
100
101
    /**
102
     * Recursively computes the difference of arrays.
103
     *
104
     * @param array $compareFrom
105
     * @param array $compareAgainst
106
     *
107
     * @return array
108
     */
109
    private function recursiveDiff($compareFrom, $compareAgainst)
110
    {
111
        $out = [];
112
113
        foreach ($compareFrom as $mKey => $mValue) {
114
            if (array_key_exists($mKey, $compareAgainst)) {
115
                if (is_array($mValue)) {
116
                    $aRecursiveDiff = $this->recursiveDiff($mValue, $compareAgainst[$mKey]);
117
                    if (count($aRecursiveDiff)) {
118
                        $out[$mKey] = $aRecursiveDiff;
119
                    }
120
                } else {
121
                    if ($mValue != $compareAgainst[$mKey]) {
122
                        $out[$mKey] = $mValue;
123
                    }
124
                }
125
            } else {
126
                $out[$mKey] = $mValue;
127
            }
128
        }
129
130
        // Check for empty arrays.
131
        foreach ($out as $key => $element) {
132
            if ($this->countRecursiveScalars($element) == 0) {
133
                unset($out[$key]);
134
            }
135
        }
136
137
        return $out;
138
    }
139
140
    /**
141
     * Counts scalar values recursively in array.
142
     *
143
     * @param mixed $array
144
     *
145
     * @return int
146
     */
147
    private function countRecursiveScalars($array)
148
    {
149
        $count = 0;
150
151
        if (!is_array($array)) {
152
            return 1;
153
        }
154
155
        foreach ($array as $element) {
156
            if (is_array($element)) {
157
                $count += $this->countRecursiveScalars($element);
158
            } else {
159
                $count++;
160
            }
161
        }
162
163
        return $count;
164
    }
165
}
166