Completed
Push — master ( c9a609...7bcfa7 )
by Andrii
03:47
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 99.12%

Importance

Changes 0
Metric Value
wmc 47
lcom 0
cbo 0
dl 12
loc 206
ccs 112
cts 113
cp 0.9912
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
A toArray() 0 11 3
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

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-2017, 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 1
    public static function merge($a, $b)
37
    {
38 1
        $args = func_get_args();
39 1
        $res = array_shift($args);
40 1
        foreach ($args as $items) {
41 1
            if (!is_array($items)) {
42
                continue;
43
            }
44 1
            foreach ($items as $k => $v) {
45 1
                if (is_int($k)) {
46 1
                    if (isset($res[$k])) {
47 1
                        $res[] = $v;
48 1
                    } else {
49 1
                        $res[$k] = $v;
50
                    }
51 1
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
52 1
                    $res[$k] = self::merge($res[$k], $v);
53 1
                } else {
54 1
                    $res[$k] = $v;
55
                }
56 1
            }
57 1
        }
58
59 1
        return $res;
60
    }
61
62
    /**
63
     * Get specified items as array.
64
     * @param mixed $keys specification
65
     * @return array
66
     */
67 3
    public static function getItems($array, $keys = null)
68
    {
69 3
        if (is_null($keys)) {
70 2
            return $array;
71 1
        } elseif (is_scalar($keys)) {
72 1
            $keys = [$keys => $array[$keys]];
73 1
        }
74 1
        $res = [];
75 1
        foreach ($keys as $k) {
76 1
            if (array_key_exists($k, $array)) {
77 1
                $res[$k] = $array[$k];
78 1
            }
79 1
        }
80 1
        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 1
    public static function insertInside(array $array, $items, $where)
123
    {
124 1
        foreach ($items as $k => $v) {
125 1
            unset($array[$k]);
126 1
        }
127 1
        $before = self::prepareWhere($array, isset($where['before']) ? $where['before'] : null);
128 1
        $after  = self::prepareWhere($array, isset($where['after']) ? $where['after'] : null);
129 1
        $new    = [];
130 1
        $found  = false;
131
        /// TODO think of realizing it better
132 1
        foreach ($array as $k => $v) {
133 1 View Code Duplication
            if (!$found && $k === $before) {
134 1
                foreach ($items as $i => $c) {
135 1
                    $new[$i] = $c;
136 1
                }
137 1
                $found = true;
138 1
            }
139 1
            $new[$k] = $v;
140 1 View Code Duplication
            if (!$found && $k === $after) {
141 1
                foreach ($items as $i => $c) {
142 1
                    $new[$i] = $c;
143 1
                }
144 1
                $found = true;
145 1
            }
146 1
        }
147 1
        if (!$found) {
148 1
            foreach ($items as $i => $c) {
149 1
                $new[$i] = $c;
150 1
            }
151 1
        }
152
153 1
        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 1
    protected static function prepareWhere(array $array, $list)
163
    {
164 1
        if (!is_array($list)) {
165 1
            $list = [$list];
166 1
        }
167 1
        foreach ($list as $v) {
168 1
            if (array_key_exists($v, $array)) {
169 1
                return $v;
170
            }
171 1
        }
172
173 1
        return null;
174
    }
175
176
    /**
177
     * Recursively removes duplicate values from non-associative arrays.
178
     */
179 1
    public static function unique($array)
180
    {
181 1
        $suitable = true;
182 1
        foreach ($array as $k => &$v) {
183 1
            if (is_array($v)) {
184 1
                $v = self::unique($v);
185 1
            } elseif (!is_int($k)) {
186 1
                $suitable = false;
187 1
            }
188 1
        }
189
190 1
        return $suitable ? self::uniqueFlat($array) : $array;
191
    }
192
193
    /**
194
     * Non-recursively removes duplicate values from non-associative arrays.
195
     */
196 2
    public static function uniqueFlat($array)
197
    {
198 2
        $uniqs = [];
199 2
        $res = [];
200 2
        foreach ($array as $k => $v) {
201 2
            $uv = var_export($v, true);
202 2
            if (array_key_exists($uv, $uniqs)) {
203 2
                continue;
204
            }
205 2
            $uniqs[$uv] = 1;
206 2
            $res[$k] = $v;
207 2
        }
208
209 2
        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