Completed
Push — master ( 6af305...285eba )
by Andrii
02:22
created

ArrayHelper   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 206
Duplicated Lines 5.83 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 22.12%

Importance

Changes 0
Metric Value
wmc 47
lcom 0
cbo 0
dl 12
loc 206
ccs 25
cts 113
cp 0.2212
rs 8.439
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A insertLast() 0 11 3
A insertFirst() 0 9 2
D merge() 0 25 9
B getItems() 0 15 5
C insertInside() 12 33 13
A prepareWhere() 0 13 4
B unique() 0 13 5
A uniqueFlat() 0 15 3
A toArray() 0 11 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ArrayHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ArrayHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Collection library for PHP
4
 *
5
 * @link      https://github.com/hiqdev/php-collection
6
 * @package   php-collection
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\collection;
12
13
/**
14
 * Array Helper.
15
 *
16
 * @author Andrii Vasyliev <[email protected]>
17
 */
18
class ArrayHelper
19
{
20
    /**
21
     * Recursive safe merge.
22
     * Based on Yii2 yii\helpers\BaseArrayHelper::merge.
23
     *
24
     * Merges two or more arrays into one recursively.
25
     * If each array has an element with the same string key value, the latter
26
     * will overwrite the former (different from array_merge_recursive).
27
     * Recursive merging will be conducted if both arrays have an element of array
28
     * type and are having the same key.
29
     * For integer-keyed elements, the elements from the latter array will
30
     * be appended to the former array.
31
     *
32
     * @param array $a array to be merged to
33
     * @param array $b array to be merged from
34
     * @return array the merged array
35
     */
36
    public static function merge($a, $b)
37
    {
38
        $args = func_get_args();
39
        $res = array_shift($args);
40
        foreach ($args as $items) {
41
            if (!is_array($items)) {
42
                continue;
43
            }
44
            foreach ($items as $k => $v) {
45
                if (is_int($k)) {
46
                    if (isset($res[$k])) {
47
                        $res[] = $v;
48
                    } else {
49
                        $res[$k] = $v;
50
                    }
51
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
52
                    $res[$k] = self::merge($res[$k], $v);
53
                } else {
54
                    $res[$k] = $v;
55
                }
56
            }
57
        }
58
59
        return $res;
60
    }
61
62
    /**
63
     * Get specified items as array.
64
     * @param mixed $keys specification
65
     * @return array
66
     */
67 2
    public static function getItems($array, $keys = null)
68
    {
69 2
        if (is_null($keys)) {
70 2
            return $array;
71
        } elseif (is_scalar($keys)) {
72
            $keys = [$keys => $array[$keys]];
73
        }
74
        $res = [];
75
        foreach ($keys as $k) {
76
            if (array_key_exists($k, $array)) {
77
                $res[$k] = $array[$k];
78
            }
79
        }
80
        return $res;
81
    }
82
83
    /**
84
     * Inserts items in front of array.
85
     * rough method: unset and then set, think of better.
86
     */
87 2
    public static function insertLast(array $array, array $items)
88
    {
89 2
        foreach ($items as $k => $v) {
90 2
            unset($array[$k]);
91 2
        }
92 2
        foreach ($items as $k => $v) {
93 2
            $array[$k] = $v;
94 2
        }
95
96 2
        return $array;
97
    }
98
99
    /**
100
     * Inserts items in front of array.
101
     * rough method: unset and then set, think of better.
102
     */
103 2
    public static function insertFirst(array $array, array $items)
104
    {
105 2
        foreach (array_keys($items) as $k) {
106 2
            unset($array[$k]);
107 2
        }
108 2
        $array = array_merge($items, $array);
109
110 2
        return $array;
111
    }
112
113
    /**
114
     * Inserts items inside of array.
115
     * rough method: unset and then set, think of better.
116
     * @param array        $array source array
117
     * @param array        $items array of items
118
     * @param string|array $where where to insert
119
     * @return array new items list
120
     * @see add()
121
     */
122
    public static function insertInside(array $array, $items, $where)
123
    {
124
        foreach ($items as $k => $v) {
125
            unset($array[$k]);
126
        }
127
        $before = self::prepareWhere($array, isset($where['before']) ? $where['before'] : null);
128
        $after  = self::prepareWhere($array, isset($where['after']) ? $where['after'] : null);
129
        $new    = [];
130
        $found  = false;
131
        /// TODO think of realizing it better
132
        foreach ($array as $k => $v) {
133 View Code Duplication
            if (!$found && $k === $before) {
134
                foreach ($items as $i => $c) {
135
                    $new[$i] = $c;
136
                }
137
                $found = true;
138
            }
139
            $new[$k] = $v;
140 View Code Duplication
            if (!$found && $k === $after) {
141
                foreach ($items as $i => $c) {
142
                    $new[$i] = $c;
143
                }
144
                $found = true;
145
            }
146
        }
147
        if (!$found) {
148
            foreach ($items as $i => $c) {
149
                $new[$i] = $c;
150
            }
151
        }
152
153
        return $new;
154
    }
155
156
    /**
157
     * Internal function to prepare where list for insertInside.
158
     * @param array        $array source array
159
     * @param array|string $list  array to convert
160
     * @return array
161
     */
162
    protected static function prepareWhere(array $array, $list)
163
    {
164
        if (!is_array($list)) {
165
            $list = [$list];
166
        }
167
        foreach ($list as $v) {
168
            if (array_key_exists($v, $array)) {
169
                return $v;
170
            }
171
        }
172
173
        return null;
174
    }
175
176
    /**
177
     * Recursively removes duplicate values from non-associative arrays.
178
     */
179
    public static function unique($array)
180
    {
181
        $suitable = true;
182
        foreach ($array as $k => &$v) {
183
            if (is_array($v)) {
184
                $v = self::unique($v);
185
            } elseif (!is_int($k)) {
186
                $suitable = false;
187
            }
188
        }
189
190
        return $suitable ? self::uniqueFlat($array) : $array;
191
    }
192
193
    /**
194
     * Non-recursively removes duplicate values from non-associative arrays.
195
     */
196
    public static function uniqueFlat($array)
197
    {
198
        $uniqs = [];
199
        $res = [];
200
        foreach ($array as $k => $v) {
201
            $uv = var_export($v, true);
202
            if (array_key_exists($uv, $uniqs)) {
203
                continue;
204
            }
205
            $uniqs[$uv] = 1;
206
            $res[$k] = $v;
207
        }
208
209
        return $res;
210
    }
211
212 1
    public static function toArray($object)
213
    {
214 1
        $res = (array) $object;
215 1
        foreach ($res as &$v) {
216 1
            if (is_object($v)) {
217 1
                $v = self::toArray($v);
218 1
            }
219 1
        }
220
221 1
        return $res;
222
    }
223
}
224