Completed
Push — master ( 02a8d3...7dfb00 )
by Andrii
02:55
created

BaseTrait   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 326
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 6
Bugs 2 Features 1
Metric Value
wmc 43
c 6
b 2
f 1
lcom 1
cbo 1
dl 0
loc 326
rs 8.3157

24 Methods

Rating   Name   Duplication   Size   Complexity  
A rawItem() 0 4 2
A getItem() 0 4 1
A hasItem() 0 4 1
A issetItem() 0 4 1
A unsetItem() 0 4 1
A getItems() 0 4 1
A mergeItems() 0 4 1
A unsetItems() 0 12 4
A resetItems() 0 4 1
A keys() 0 4 1
A count() 0 4 1
A offsetGet() 0 4 1
A offsetSet() 0 4 1
A offsetExists() 0 4 1
A offsetUnset() 0 4 1
A getIterator() 0 4 1
A putItem() 0 8 3
A addItem() 0 8 2
A setItem() 0 8 3
A mergeItem() 0 6 2
A putItems() 0 6 2
B setItems() 0 14 5
B addItems() 0 13 5
A fields() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like BaseTrait 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 BaseTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * Collection library for PHP
5
 *
6
 * @link      https://github.com/hiqdev/php-collection
7
 * @package   php-collection
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\php\collection;
13
14
use ArrayIterator;
15
16
/**
17
 * Base Trait.
18
 */
19
trait BaseTrait
20
{
21
    /**
22
     * @var array default items
23
     */
24
    protected static $_defaults = [];
25
26
    /**
27
     * @var array items
28
     */
29
    protected $_items = [];
30
31
    /**
32
     * Straight put an item.
33
     *
34
     * @param string $name  item name.
35
     * @param array  $value item value.
36
     */
37
    public function putItem($name, $value = null)
38
    {
39
        if (is_null($name) || is_int($name)) {
40
            $this->_items[] = $value;
41
        } else {
42
            $this->_items[$name] = $value;
43
        }
44
    }
45
46
    /**
47
     * Get raw item.
48
     *
49
     * @param string $name item name.
50
     *
51
     * @return mixed item value.
52
     */
53
    public function rawItem($name, $default = null)
54
    {
55
        return isset($this->_items[$name]) ? $this->_items[$name] : $default;
56
    }
57
58
    /**
59
     * Adds an item. Doesn't touch if already exists.
60
     *
61
     * @param string       $name  item name.
62
     * @param array        $value item value.
63
     * @param string|array $where where to put, @see setItem
64
     *
65
     * @return $this for chaining
66
     */
67
    public function addItem($name, $value = null, $where = '')
68
    {
69
        if (!$this->hasItem($name)) {
70
            $this->setItem($name, $value, $where);
71
        }
72
73
        return $this;
74
    }
75
76
    /**
77
     * Sets an item. Silently resets if already exists and mov.
78
     *
79
     * @param string       $name  item name.
80
     * @param array        $value item value.
81
     * @param string|array $where where to put, can be empty, first, last and array of before and after
82
     */
83
    public function setItem($name, $value = null, $where = '')
84
    {
85
        if ($name === null || $where === '') {
86
            $this->putItem($name, $value);
87
        } else {
88
            $this->setItems([$name => $value], $where);
89
        }
90
    }
91
92
    /**
93
     * Returns item by name.
94
     *
95
     * @param string $name item name.
96
     *
97
     * @return mixed item value.
98
     */
99
    public function getItem($name)
100
    {
101
        return $this->_items[$name];
102
    }
103
104
    /**
105
     * Check collection has the item.
106
     *
107
     * @param string $name item name.
108
     *
109
     * @return bool whether item exist.
110
     */
111
    public function hasItem($name)
112
    {
113
        return array_key_exists($name, $this->_items);
114
    }
115
116
    public function mergeItem($name, array $value)
117
    {
118
        if (!is_null($name)) {
119
            $this->_items[$name] = ArrayHelper::merge($this->_items[$name], $value);
120
        }
121
    }
122
123
    /**
124
     * Check is item set.
125
     *
126
     * @param string $name item name.
127
     *
128
     * @return bool whether item is set.
129
     */
130
    public function issetItem($name)
131
    {
132
        return isset($this->_items[$name]);
133
    }
134
135
    /**
136
     * Delete an item.
137
     *
138
     * @param $name
139
     */
140
    public function unsetItem($name)
141
    {
142
        unset($this->_items[$name]);
143
    }
144
145
    /**
146
     * Get specified items as array.
147
     *
148
     * @param mixed $keys specification
149
     *
150
     * @return array list of items
151
     */
152
    public function getItems($keys = null)
153
    {
154
        return ArrayHelper::getItems($this->_items, $keys);
155
    }
156
157
    /**
158
     * Straight put items.
159
     *
160
     * @param array $items list of items
161
     *
162
     * @see setItem
163
     */
164
    public function putItems(array $items)
165
    {
166
        foreach ($items as $k => $v) {
167
            $this->putItem($k, $v);
168
        }
169
    }
170
171
    /**
172
     * Adds items to specified place.
173
     *
174
     * @param array $items list of items
175
     * @param mixed $where
176
     *
177
     * @see setItem()
178
     */
179
    public function setItems($items, $where = '')
180
    {
181
        if (!$items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
182
            return;
183
        } elseif ($where === '') {
184
            $this->putItems($items);
185
        } elseif ($where === 'last') {
186
            $this->_items = ArrayHelper::insertLast($this->_items, $items);
187
        } elseif ($where === 'first') {
188
            $this->_items = ArrayHelper::insertFirst($this->_items, $items);
189
        } else {
190
            $this->_items = ArrayHelper::insertInside($this->_items, $items, $where);
191
        }
192
    }
193
194
    /**
195
     * Adds items to specified place.
196
     * Does not touch those items that already exists.
197
     *
198
     * @param array        $items array of items.
199
     * @param string|array $where where to add. See [[setItem()]]
200
     *
201
     * @return $this for chaining
202
     *
203
     * @see setItem()
204
     */
205
    public function addItems(array $items, $where = '')
206
    {
207
        foreach ($items as $k => $v) {
208
            if (!is_int($k) && $this->hasItem($k)) {
209
                unset($items[$k]);
210
            }
211
        }
212
        if ($items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
213
            $this->setItems($items, $where);
214
        }
215
216
        return $this;
217
    }
218
219
    public function mergeItems(array $items)
220
    {
221
        $this->_items = ArrayHelper::merge($this->_items, $items);
222
    }
223
224
    /**
225
     * Unset specified items.
226
     *
227
     * @param mixed $keys specification
228
     *
229
     * @return array list of items
230
     */
231
    public function unsetItems($keys = null)
232
    {
233
        if (is_null($keys)) {
234
            $this->_items = [];
235
        } elseif (is_scalar($keys)) {
236
            unset($this->_items[$keys]);
237
        } else {
238
            foreach ($keys as $k) {
239
                unset($this->_items[$k]);
240
            }
241
        }
242
    }
243
244
    public function resetItems(array $items)
245
    {
246
        $this->_items = $items;
247
    }
248
    /**
249
     * Get keys.
250
     *
251
     * @return array for chaining
252
     */
253
    public function keys()
254
    {
255
        return array_keys($this->_items);
256
    }
257
258
    /**
259
     * The default implementation of this method returns [[attributes()]] indexed by the same attribute names.
260
     *
261
     * @return array the list of field names or field definitions.
262
     *
263
     * @see toArray()
264
     */
265
    public function fields()
266
    {
267
        $fields = $this->keys();
268
269
        return array_combine($fields, $fields);
270
    }
271
272
    /**
273
     * Returns number of items in the collection.
274
     *
275
     * @return int
276
     */
277
    public function count()
278
    {
279
        return count($this->_items);
280
    }
281
    /**
282
     * Returns the element at the specified offset.
283
     * This method is required by the SPL interface `ArrayAccess`.
284
     * It is implicitly called when you use something like `$value = $collection[$offset];`.
285
     *
286
     * @param mixed $offset the offset to retrieve element.
287
     *
288
     * @return mixed the element at the offset, null if no element is found at the offset
289
     */
290
    public function offsetGet($offset)
291
    {
292
        return $this->getItem($offset);
293
    }
294
295
    /**
296
     * Sets the element at the specified offset.
297
     * This method is required by the SPL interface `ArrayAccess`.
298
     * It is implicitly called when you use something like `$collection[$offset] = $value;`.
299
     *
300
     * @param int   $offset the offset to set element
301
     * @param mixed $value  the element value
302
     */
303
    public function offsetSet($offset, $value)
304
    {
305
        $this->setItem($offset, $value);
306
    }
307
308
    /**
309
     * Returns whether there is an element at the specified offset.
310
     * This method is required by the SPL interface `ArrayAccess`.
311
     * It is implicitly called when you use something like `isset($collection[$offset])`.
312
     *
313
     * @param mixed $offset the offset to check on
314
     *
315
     * @return bool
316
     */
317
    public function offsetExists($offset)
318
    {
319
        return $this->hasItem($offset);
320
    }
321
322
    /**
323
     * Sets the element value at the specified offset to null.
324
     * This method is required by the SPL interface ArrayAccess.
325
     * It is implicitly called when you use something like `unset($collection[$offset])`.
326
     *
327
     * @param mixed $offset the offset to unset element
328
     */
329
    public function offsetUnset($offset)
330
    {
331
        $this->unsetItem($offset);
332
    }
333
334
    /**
335
     * Method for IteratorAggregate interface.
336
     * Enables foreach'ing the object.
337
     *
338
     * @return ArrayIterator
339
     */
340
    public function getIterator()
341
    {
342
        return new ArrayIterator($this->_items);
343
    }
344
}
345