Completed
Push — master ( c3d67b...f97578 )
by Shcherbak
79:27 queued 64:23
created

BaseCollection::addAfter()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 8.7624
c 0
b 0
f 0
cc 5
eloc 13
nc 6
nop 2
1
<?php
2
3
  namespace Funivan\PhpTokenizer\Collection;
4
5
  use Funivan\PhpTokenizer\Token;
6
7
  /**
8
   *
9
   * @package Fiv\Spl
10
   */
11
  class BaseCollection implements \Iterator, \ArrayAccess, \Countable {
12
13
    /**
14
     * @var int
15
     */
16
    protected $position = 0;
17
18
    /**
19
     * Array of objects
20
     *
21
     * @var array
22
     */
23
    protected $items = [];
24
25
26
    /**
27
     * @param array $items
28
     */
29
    public function __construct(array $items = []) {
30
31
      if (!empty($items)) {
32
        $this->setItems($items);
33
      }
34
35
    }
36
37
38
    /**
39
     *
40
     */
41
    public function __clone() {
42
      $items = [];
43
      foreach ($this->items as $item) {
44
        $items[] = $item;
45
      }
46
      $this->setItems($items);
47
    }
48
49
50
    /**
51
     * Return number of items in this collection
52
     *
53
     * @return int
54
     */
55
    public function count() {
56
      return count($this->items);
57
    }
58
59
60
    /**
61
     * Add one item to begin of collection
62
     * This item is accessible via `$collection->getFirst();`
63
     *
64
     * @param $item
65
     * @return $this
66
     */
67
    public function prepend(Token $item) {
68
      array_unshift($this->items, $item);
69
      return $this;
70
    }
71
72
73
    /**
74
     * Add one item to the end of collection
75
     * This item is accessible via `$collection->getLast();`
76
     *
77
     * @param $item
78
     * @return $this
79
     */
80
    public function append(Token $item) {
81
      $this->items[] = $item;
82
      return $this;
83
    }
84
85
86
    /**
87
     * @param int $index
88
     * @param array $items
89
     * @return $this
90
     * @throws \InvalidArgumentException
91
     */
92
    public function addAfter($index, $items) {
93
      if (!is_array($items)) {
94
        throw new \InvalidArgumentException('You can add after only array of items');
95
      }
96
97
      foreach ($items as $item) {
98
        if (!($item instanceof Token)) {
99
          throw new \InvalidArgumentException('Expect array of tokens. Token[]');
100
        }
101
      }
102
103
      if (!is_int($index)) {
104
        throw new \InvalidArgumentException('Invalid type of index. Must be integer');
105
      }
106
107
      $offset = $index + 1;
108
      $firstPart = array_slice($this->items, 0, $offset);
109
      $secondPart = array_slice($this->items, $offset);
110
      $this->items = array_merge($firstPart, $items, $secondPart);
111
      return $this;
112
    }
113
114
115
    /**
116
     * Truncate current list of items and add new
117
     *
118
     * @param array $items
119
     * @return $this
120
     */
121
    public function setItems($items) {
122
      if (!is_array($items)) {
123
        throw new \InvalidArgumentException("You can set only array of items");
124
      }
125
126
      foreach ($items as $item) {
127
        if (!($item instanceof Token)) {
128
          throw new \InvalidArgumentException('Expect array of tokens. Token[]');
129
        }
130
      }
131
132
      $this->items = $items;
133
      $this->rewind();
134
      return $this;
135
    }
136
137
138
    /**
139
     * Remove part of items from collection
140
     * Works as array_slice
141
     *
142
     *
143
     * @param $offset
144
     * @param null $length
145
     * @return $this
146
     */
147
    public function slice($offset, $length = null) {
148
      $this->items = array_slice($this->items, $offset, $length);
149
      return $this;
150
    }
151
152
153
    /**
154
     * Take part of items and return new collection
155
     * Works as array_slice
156
     * At this point items in 2 collection is same
157
     *
158
     * @param int $offset
159
     * @param null $length
160
     * @return self
161
     */
162
    public function extractItems($offset, $length = null) {
163
      $items = array_slice($this->items, $offset, $length);
164
      $className = get_called_class();
165
      $collection = new $className();
166
      /** @var BaseCollection $collection */
167
      $collection->setItems($items);
168
      return $collection;
169
    }
170
171
172
    /**
173
     * Rewind current collection
174
     */
175
    public function rewind() {
176
      $this->position = 0;
177
      $this->items = array_values($this->items);
178
    }
179
180
181
    /**
182
     * Return last item from collection
183
     *
184
     * @return mixed
185
     */
186
    public function getLast() {
187
      return end($this->items);
188
    }
189
190
191
    /**
192
     * Return first item from collection
193
     * @return mixed
194
     */
195
    public function getFirst() {
196
      return reset($this->items);
197
    }
198
199
200
    /**
201
     * Return next item from current
202
     * Also can return item with position from current + $step
203
     *
204
     * @param int $step
205
     * @return mixed
206
     */
207
    public function getNext($step = 1) {
208
      $position = ($this->position + $step);
209
      return isset($this->items[$position]) ? $this->items[$position] : null;
210
    }
211
212
213
    /**
214
     * Return previous item
215
     * Also can return previous from current position + $step
216
     *
217
     * @param int $step
218
     * @return mixed
219
     */
220
    public function getPrevious($step = 1) {
221
      $position = ($this->position - $step);
222
      return isset($this->items[$position]) ? $this->items[$position] : null;
223
    }
224
225
226
    /**
227
     * Return current item in collection
228
     *
229
     * @return object
230
     */
231
    public function current() {
232
      return $this->items[$this->position];
233
    }
234
235
236
    /**
237
     * Return current position
238
     *
239
     * @return int
240
     */
241
    public function key() {
242
      return $this->position;
243
    }
244
245
246
    /**
247
     * Switch to next position
248
     */
249
    public function next() {
250
      ++$this->position;
251
    }
252
253
254
    /**
255
     * Check if item exist in current position
256
     *
257
     * @return bool
258
     */
259
    public function valid() {
260
      return isset($this->items[$this->position]);
261
    }
262
263
264
    /**
265
     * Add item to the end or modify item with given key
266
     *
267
     * @param int|null $offset
268
     * @param object $item
269
     * @return $this
270
     */
271
    public function offsetSet($offset, $item) {
272
      if (!($item instanceof Token)) {
273
        throw new \InvalidArgumentException('Expect Token object');
274
      }
275
276
      if (is_null($offset)) {
277
        $this->append($item);
278
        return $this;
279
      }
280
      
281
      if (!is_int($offset)) {
282
        throw new \InvalidArgumentException('Invalid type of index. Must be integer');
283
      }
284
      $this->items[$offset] = $item;
285
286
      return $this;
287
    }
288
289
290
    /**
291
     * Check if item with given offset exists
292
     *
293
     * @param mixed $offset
294
     * @return bool
295
     */
296
    public function offsetExists($offset) {
297
      return isset($this->items[$offset]);
298
    }
299
300
301
    /**
302
     * Remove item from collection
303
     *
304
     * @param int $offset
305
     */
306
    public function offsetUnset($offset) {
307
      unset($this->items[$offset]);
308
    }
309
310
311
    /**
312
     * Get item from collection
313
     *
314
     * @param int $offset
315
     * @return object
316
     */
317
    public function offsetGet($offset) {
318
      return isset($this->items[$offset]) ? $this->items[$offset] : null;
319
    }
320
321
322
    /**
323
     * Return array of items connected to this collection
324
     *
325
     * Rewrite this method in you class
326
     *
327
     * <code>
328
     * foreach($collection->getTokens() as $item){
329
     *  echo get_class($item)."\n;
330
     * }
331
     * </code>
332
     * @return Token[]
333
     */
334
    public function getTokens() : array {
335
      return $this->items;
336
    }
337
338
339
    public function getItems() {
340
      trigger_error('Deprecated. See getTokens', E_USER_DEPRECATED);
341
      return $this->items;
342
    }
343
344
345
    /**
346
     * Iterate over objects in collection
347
     *
348
     * <code>
349
     * $collection->each(function($item, $index, $collection){
350
     *    if ( $index > 0 ) {
351
     *      $item->remove();
352
     *    }
353
     * })
354
     * </code>
355
     *
356
     * @param callable $callback
357
     * @return $this
358
     * @throws \InvalidArgumentException
359
     */
360
    public function each(callable $callback) : self {
361
362
      if (!is_callable($callback)) {
363
        throw new \InvalidArgumentException('Invalid callback function');
364
      }
365
366
      foreach ($this->getTokens() as $index => $item) {
367
        call_user_func_array($callback, [$item, $index, $this]);
368
      }
369
370
      $this->rewind();
371
372
      return $this;
373
    }
374
375
376
    public function map(callable $callback) {
377
      trigger_error('Deprecated. See each', E_USER_DEPRECATED);
378
      return $this->each($callback);
379
    }
380
381
382
    /**
383
     * @param int $index
384
     */
385
    protected function validateIndex($index) {
0 ignored issues
show
Unused Code introduced by
The parameter $index is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
386
387
    }
388
389
390
  }