Code

< 40 %
40-60 %
> 60 %
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
use ArrayIterator;
14
15
/**
16
 * Base Trait.
17
 * Provides methods for iterfaces:
18
 * - ArrayAccess: offsetExists, offsetGet, offsetSet, offsetUnset
19
 * - IteratorAggregate: getIterator
20
 * - yii\base\Arrayable: fields, extraFields, toArray
21
 *
22
 * @author Andrii Vasyliev <[email protected]>
23
 */
24
trait BaseTrait
25
{
26
    /**
27
     * @var array default items
28
     */
29
    protected static $_defaults = [];
30
31
    /**
32
     * @var array items
33
     */
34
    protected $_items = [];
35
36
    /**
37
     * Straight put an item.
38
     * @param string $name  item name
39
     * @param array  $value item value
40
     */
41 4
    public function putItem($name, $value = null)
42
    {
43 4
        if (is_null($name) || is_int($name)) {
44
            $this->_items[] = $value;
45
        } else {
46 4
            $this->_items[$name] = $value;
47
        }
48 4
    }
49
50
    /**
51
     * Get raw item.
52
     * @param string $name item name
53
     * @return mixed item value
54
     */
55
    public function rawItem($name, $default = null)
56
    {
57
        return isset($this->_items[$name]) ? $this->_items[$name] : $default;
58
    }
59
60
    /**
61
     * Adds an item. Doesn't touch if already exists.
62
     * @param string       $name  item name
63
     * @param array        $value item value
64
     * @param string|array $where where to put, @see setItem
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
     * @param string       $name  item name
79
     * @param array        $value item value
80
     * @param string|array $where where to put, can be empty, first, last and array of before and after
81
     */
82 8
    public function setItem($name, $value = null, $where = '')
83
    {
84 8
        if ($name === null || $where === '') {
85 4
            $this->putItem($name, $value);
86
        } else {
87 4
            $this->setItems([$name => $value], $where);
88
        }
89 8
    }
90
91
    /**
92
     * Returns item by name.
93
     * @param string $name item name
94
     * @param mixed $default default value
95
     * @return mixed item value or default
96
     */
97 5
    public function getItem($name, $default = null)
98
    {
99 5
        return isset($this->_items[$name]) ? $this->_items[$name] : $default;
100
    }
101
102
    /**
103
     * Check collection has the item.
104
     * @param string $name item name
105
     * @return bool whether item exist
106
     */
107 10
    public function hasItem($name)
108
    {
109 10
        return array_key_exists($name, $this->_items);
110
    }
111
112
    public function mergeItem($name, array $value)
113
    {
114
        if (!is_null($name)) {
115
            $this->_items[$name] = ArrayHelper::merge($this->_items[$name], $value);
116
        }
117
    }
118
119
    /**
120
     * Check is item set.
121
     * @param string $name item name
122
     * @return bool whether item is set
123
     */
124 1
    public function issetItem($name)
125
    {
126 1
        return isset($this->_items[$name]);
127
    }
128
129
    /**
130
     * Delete an item.
131
     * @param $name
132
     */
133 2
    public function unsetItem($name)
134
    {
135 2
        unset($this->_items[$name]);
136 2
    }
137
138
    /**
139
     * Get specified items as array.
140
     * @param mixed $keys specification
141
     * @return array list of items
142
     */
143 2
    public function getItems($keys = null)
144
    {
145 2
        return ArrayHelper::getItems($this->_items, $keys);
146
    }
147
148
    /**
149
     * Straight put items.
150
     * @param array $items list of items
151
     * @see setItem
152
     */
153
    public function putItems(array $items)
154
    {
155
        foreach ($items as $k => $v) {
156
            $this->putItem($k, $v);
157
        }
158
    }
159
160
    /**
161
     * Adds items to specified place.
162
     * @param array $items list of items
163
     * @param mixed $where
164
     * @see setItem()
165
     */
166 4
    public function setItems($items, $where = '')
167
    {
168 4
        if (empty($items)) {
169
            return;
170
        }
171 4
        if (empty($where)) {
172
            $this->putItems($items);
173 4
        } elseif ($where === 'last') {
174 2
            $this->_items = ArrayHelper::insertLast($this->_items, $items);
175 2
        } elseif ($where === 'first') {
176 2
            $this->_items = ArrayHelper::insertFirst($this->_items, $items);
177
        } else {
178
            $this->_items = ArrayHelper::insertInside($this->_items, $items, $where);
179
        }
180 4
    }
181
182
    /**
183
     * Adds items to specified place.
184
     * Does not touch those items that already exists.
185
     * @param array        $items array of items
186
     * @param string|array $where where to add. See [[setItem()]]
187
     * @return $this for chaining
188
     * @see setItem()
189
     */
190
    public function addItems(array $items, $where = '')
191
    {
192
        foreach (array_keys($items) as $k) {
193
            if (!is_int($k) && $this->hasItem($k)) {
194
                unset($items[$k]);
195
            }
196
        }
197
        if (!empty($items)) {
198
            $this->setItems($items, $where);
199
        }
200
201
        return $this;
202
    }
203
204
    public function mergeItems(array $items)
205
    {
206
        $this->_items = ArrayHelper::merge($this->_items, $items);
207
    }
208
209
    /**
210
     * Unset specified items.
211
     * @param mixed $keys specification
212
     * @return array list of items
213
     */
214 2
    public function unsetItems($keys = null)
215
    {
216 2
        if (is_null($keys)) {
217 1
            $this->_items = [];
218 1
        } elseif (is_scalar($keys)) {
219 1
            unset($this->_items[$keys]);
220
        } else {
221 1
            foreach ($keys as $k) {
222 1
                unset($this->_items[$k]);
223
            }
224
        }
225 2
    }
226
227 1
    public function resetItems(array $items)
228
    {
229 1
        $this->_items = $items;
230 1
    }
231
232
    /**
233
     * Get keys.
234
     * @return array for chaining
235
     */
236 9
    public function keys()
237
    {
238 9
        return array_keys($this->_items);
239
    }
240
241
    /**
242
     * The default implementation of this method returns [[attributes()]] indexed by the same attribute names.
243
     * @return array the list of field names or field definitions
244
     * @see toArray()
245
     */
246
    public function fields()
247
    {
248
        $fields = $this->keys();
249
250
        return array_combine($fields, $fields);
251
    }
252
253
    /**
254
     * Returns number of items in the collection.
255
     * @return int
256
     */
257
    public function count()
258
    {
259
        return count($this->_items);
260
    }
261
262
    /**
263
     * Returns the element at the specified offset.
264
     * This method is required by the SPL interface `ArrayAccess`.
265
     * It is implicitly called when you use something like `$value = $collection[$offset];`.
266
     * @param mixed $offset the offset to retrieve element
267
     * @return mixed the element at the offset, null if no element is found at the offset
268
     */
269
    #[\ReturnTypeWillChange]
270
    public function offsetGet($offset)
271
    {
272
        return $this->getItem($offset);
273
    }
274
275
    /**
276
     * Sets the element at the specified offset.
277
     * This method is required by the SPL interface `ArrayAccess`.
278
     * It is implicitly called when you use something like `$collection[$offset] = $value;`.
279
     * @param int   $offset the offset to set element
280
     * @param mixed $value  the element value
281
     */
282
    #[\ReturnTypeWillChange]
283
    public function offsetSet($offset, $value)
284
    {
285
        $this->setItem($offset, $value);
286
    }
287
288
    /**
289
     * Returns whether there is an element at the specified offset.
290
     * This method is required by the SPL interface `ArrayAccess`.
291
     * It is implicitly called when you use something like `isset($collection[$offset])`.
292
     * @param mixed $offset the offset to check on
293
     * @return bool
294
     */
295
    #[\ReturnTypeWillChange]
296
    public function offsetExists($offset)
297
    {
298
        return $this->hasItem($offset);
299
    }
300
301
    /**
302
     * Sets the element value at the specified offset to null.
303
     * This method is required by the SPL interface ArrayAccess.
304
     * It is implicitly called when you use something like `unset($collection[$offset])`.
305
     * @param mixed $offset the offset to unset element
306
     */
307
    #[\ReturnTypeWillChange]
308
    public function offsetUnset($offset)
309
    {
310
        $this->unsetItem($offset);
311
    }
312
313
    /**
314 1
     * Method for IteratorAggregate interface.
315
     * Enables foreach'ing the object.
316 1
     * @return ArrayIterator
317
     */
318
    #[\ReturnTypeWillChange]
319
    public function getIterator()
320
    {
321
        return new ArrayIterator($this->_items);
322
    }
323
}
324