Total Complexity | 124 |
Total Lines | 688 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Complex classes like TPriorityList 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.
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 TPriorityList, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
52 | class TPriorityList extends TList |
||
53 | { |
||
54 | /** |
||
55 | * @var bool indicates if the _d is currently ordered. |
||
56 | */ |
||
57 | protected bool $_o = false; |
||
58 | /** |
||
59 | * @var null|array cached flattened internal data storage |
||
60 | */ |
||
61 | protected ?array $_fd = null; |
||
62 | /** |
||
63 | * @var numeric the default priority of items without specified priorities |
||
|
|||
64 | */ |
||
65 | private $_dp = 10; |
||
66 | /** |
||
67 | * @var int the precision of the numeric priorities within this priority list. |
||
68 | */ |
||
69 | private int $_p = 8; |
||
70 | |||
71 | /** |
||
72 | * Constructor. |
||
73 | * Initializes the list with an array or an iterable object. |
||
74 | * @param null|array|\Iterator $data the initial data. Default is null, meaning no initial data. |
||
75 | * @param bool $readOnly whether the list is read-only |
||
76 | * @param numeric $defaultPriority the default priority of items without specified priorities. |
||
77 | * @param int $precision the precision of the numeric priorities |
||
78 | * @throws TInvalidDataTypeException If data is not null and is neither an array nor an iterator. |
||
79 | */ |
||
80 | public function __construct($data = null, $readOnly = false, $defaultPriority = 10, $precision = 8) |
||
81 | { |
||
82 | $this->setPrecision($precision); |
||
83 | $this->setDefaultPriority($defaultPriority); |
||
84 | parent::__construct($data, $readOnly); |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @return numeric gets the default priority of inserted items without a specified priority |
||
89 | */ |
||
90 | public function getDefaultPriority() |
||
91 | { |
||
92 | return $this->_dp; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * This must be called internally or when instantiated. |
||
97 | * @param numeric $value sets the default priority of inserted items without a specified priority |
||
98 | */ |
||
99 | protected function setDefaultPriority($value) |
||
100 | { |
||
101 | $this->_dp = (string) round(TPropertyValue::ensureFloat($value), $this->_p); |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * @return int The precision of numeric priorities, defaults to 8 |
||
106 | */ |
||
107 | public function getPrecision(): int |
||
108 | { |
||
109 | return $this->_p; |
||
110 | } |
||
111 | |||
112 | /** |
||
113 | * This must be called internally or when instantiated. |
||
114 | * @param int $value The precision of numeric priorities. |
||
115 | */ |
||
116 | protected function setPrecision($value): void |
||
117 | { |
||
118 | $this->_p = TPropertyValue::ensureInteger($value); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Taken an input Priority and ensures its value. |
||
123 | * Sets the default $priority when none is set, |
||
124 | * then rounds to the proper precision and makes |
||
125 | * into a string. |
||
126 | * @param mixed $priority |
||
127 | * @return string the priority in string format |
||
128 | */ |
||
129 | protected function ensurePriority($priority): string |
||
130 | { |
||
131 | if ($priority === null || !is_numeric($priority)) { |
||
132 | $priority = $this->getDefaultPriority(); |
||
133 | } |
||
134 | return (string) round((float) $priority, $this->_p); |
||
135 | } |
||
136 | |||
137 | |||
138 | /** |
||
139 | * This orders the priority list internally. |
||
140 | */ |
||
141 | protected function sortPriorities(): void |
||
142 | { |
||
143 | if (!$this->_o) { |
||
144 | ksort($this->_d, SORT_NUMERIC); |
||
145 | $this->_o = true; |
||
146 | } |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * This flattens the priority list into a flat array [0,...,n-1] |
||
151 | * @return array array of items in the list in priority and index order |
||
152 | */ |
||
153 | protected function flattenPriorities(): array |
||
154 | { |
||
155 | if (is_array($this->_fd)) { |
||
156 | return $this->_fd; |
||
157 | } |
||
158 | |||
159 | $this->sortPriorities(); |
||
160 | $this->_fd = []; |
||
161 | foreach ($this->_d as $priority => $itemsatpriority) { |
||
162 | $this->_fd = array_merge($this->_fd, $itemsatpriority); |
||
163 | } |
||
164 | return $this->_fd; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * This returns a list of the priorities within this list, ordered lowest to highest. |
||
169 | * @return array the array of priority numerics in decreasing priority order |
||
170 | */ |
||
171 | public function getPriorities(): array |
||
172 | { |
||
173 | $this->sortPriorities(); |
||
174 | return array_keys($this->_d); |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Gets the number of items at a priority within the list |
||
179 | * @param null|numeric $priority optional priority at which to count items. if no parameter, it will be set to the default {@link getDefaultPriority} |
||
180 | * @return false|int the number of items in the list at the specified priority |
||
181 | */ |
||
182 | public function getPriorityCount($priority = null) |
||
183 | { |
||
184 | $priority = $this->ensurePriority($priority); |
||
185 | if (!isset($this->_d[$priority]) || !is_array($this->_d[$priority])) { |
||
186 | return false; |
||
187 | } |
||
188 | return count($this->_d[$priority]); |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Returns an iterator for traversing the items in the list. |
||
193 | * This method is required by the interface \IteratorAggregate. |
||
194 | * @return \Iterator an iterator for traversing the items in the list. |
||
195 | */ |
||
196 | public function getIterator(): \Iterator |
||
197 | { |
||
198 | return new \ArrayIterator($this->flattenPriorities()); |
||
199 | } |
||
200 | |||
201 | |||
202 | /** |
||
203 | * Returns the item at the index of a flattened priority list. |
||
204 | * {@link offsetGet} calls this method. |
||
205 | * @param int $index the index of the item to get |
||
206 | * @throws TInvalidDataValueException Issued when the index is invalid |
||
207 | * @return mixed the element at the offset |
||
208 | */ |
||
209 | public function itemAt($index) |
||
210 | { |
||
211 | if ($index >= 0 && $index < $this->getCount()) { |
||
212 | $arr = $this->flattenPriorities(); |
||
213 | return $arr[$index]; |
||
214 | } else { |
||
215 | throw new TInvalidDataValueException('list_index_invalid', $index); |
||
216 | } |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Gets all the items at a specific priority. |
||
221 | * @param null|numeric $priority priority of the items to get. Defaults to null, filled in with the default priority, if left blank. |
||
222 | * @return ?array all items at priority in index order, null if there are no items at that priority |
||
223 | */ |
||
224 | public function itemsAtPriority($priority = null): ?array |
||
225 | { |
||
226 | $priority = $this->ensurePriority($priority); |
||
227 | return $this->_d[$priority] ?? null; |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * Returns the item at an index within a priority |
||
232 | * @param int $index the index into the list of items at priority |
||
233 | * @param numeric $priority the priority which to index. no parameter or null will result in the default priority |
||
234 | * @return mixed the element at the offset, false if no element is found at the offset |
||
235 | */ |
||
236 | public function itemAtIndexInPriority($index, $priority = null) |
||
237 | { |
||
238 | $priority = $this->ensurePriority($priority); |
||
239 | return !isset($this->_d[$priority]) ? false : ( |
||
240 | $this->_d[$priority][$index] ?? false |
||
241 | ); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Appends an item into the list at the end of the specified priority. The position of the added item may |
||
246 | * not be at the end of the list. |
||
247 | * @param mixed $item item to add into the list at priority |
||
248 | * @param null|numeric $priority priority blank or null for the default priority |
||
249 | * @throws TInvalidOperationException if the map is read-only |
||
250 | * @return int the index within the flattened array |
||
251 | */ |
||
252 | public function add($item, $priority = null) |
||
253 | { |
||
254 | if ($this->getReadOnly()) { |
||
255 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
256 | } |
||
257 | |||
258 | return $this->insertAtIndexInPriority($item, false, $priority, true); |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * Inserts an item at an index. It reads the priority of the item at index within the flattened list |
||
263 | * and then inserts the item at that priority-index. |
||
264 | * @param int $index the specified position in the flattened list. |
||
265 | * @param mixed $item new item to add |
||
266 | * @throws TInvalidDataValueException If the index specified exceeds the bound |
||
267 | * @throws TInvalidOperationException if the list is read-only |
||
268 | */ |
||
269 | public function insertAt($index, $item) |
||
270 | { |
||
271 | if ($this->getReadOnly()) { |
||
272 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
273 | } |
||
274 | |||
275 | if (($priority = $this->priorityAt($index, true)) !== false) { |
||
276 | $this->insertAtIndexInPriority($item, $priority[1], $priority[0]); |
||
277 | } else { |
||
278 | throw new TInvalidDataValueException('list_index_invalid', $index); |
||
279 | } |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Inserts an item at the specified index within a priority. Override and call this method to |
||
284 | * insert your own functionality. |
||
285 | * @param mixed $item item to add within the list. |
||
286 | * @param false|int $index index within the priority to add the item, defaults to false which appends the item at the priority |
||
287 | * @param null|numeric $priority priority of the item. defaults to null, which sets it to the default priority |
||
288 | * @param bool $preserveCache preserveCache specifies if this is a special quick function or not. This defaults to false. |
||
289 | * @throws TInvalidDataValueException If the index specified exceeds the bound |
||
290 | * @throws TInvalidOperationException if the list is read-only |
||
291 | */ |
||
292 | public function insertAtIndexInPriority($item, $index = false, $priority = null, $preserveCache = false) |
||
293 | { |
||
294 | if ($this->getReadOnly()) { |
||
295 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
296 | } |
||
297 | |||
298 | $itemPriority = null; |
||
299 | if (($isPriorityItem = ($item instanceof IPriorityItem)) && ($priority === null || !is_numeric($priority))) { |
||
300 | $itemPriority = $priority = $item->getPriority(); |
||
301 | } |
||
302 | $priority = $this->ensurePriority($priority); |
||
303 | if (($item instanceof IPriorityCapture) && (!$isPriorityItem || $itemPriority !== $priority)) { |
||
304 | $item->setPriority($priority); |
||
305 | } |
||
306 | |||
307 | if ($index === false && isset($this->_d[$priority])) { |
||
308 | $c = count($this->_d[$priority]); |
||
309 | $this->_d[$priority][] = $item; |
||
310 | } elseif (isset($this->_d[$priority])) { |
||
311 | $c = $index; |
||
312 | array_splice($this->_d[$priority], $index, 0, [$item]); |
||
313 | } else { |
||
314 | $c = 0; |
||
315 | $this->_o = false; |
||
316 | $this->_d[$priority] = [$item]; |
||
317 | } |
||
318 | |||
319 | if ($preserveCache) { |
||
320 | if ($this->_fd !== null) { |
||
321 | $this->sortPriorities(); |
||
322 | foreach ($this->_d as $prioritykey => $items) { |
||
323 | if ($prioritykey >= $priority) { |
||
324 | break; |
||
325 | } else { |
||
326 | $c += count($items); |
||
327 | } |
||
328 | } |
||
329 | array_splice($this->_fd, $c, 0, [$item]); |
||
330 | } |
||
331 | } elseif (!$preserveCache) { |
||
332 | if ($this->_fd !== null && count($this->_d) == 1) { |
||
333 | array_splice($this->_fd, $c, 0, [$item]); |
||
334 | } else { |
||
335 | $this->_fd = null; |
||
336 | $c = null; |
||
337 | } |
||
338 | } |
||
339 | |||
340 | $this->_c++; |
||
341 | |||
342 | return $c; |
||
343 | } |
||
344 | |||
345 | |||
346 | /** |
||
347 | * Removes an item from the priority list. |
||
348 | * The list will search for the item. The first matching item found will be removed from the list. |
||
349 | * @param mixed $item item the item to be removed. |
||
350 | * @param null|bool|float $priority priority of item to remove. without this parameter it defaults to false. |
||
351 | * A value of false means any priority. null will be filled in with the default priority. |
||
352 | * @throws TInvalidDataValueException If the item does not exist |
||
353 | * @return int index within the flattened list at which the item is being removed |
||
354 | */ |
||
355 | public function remove($item, $priority = false) |
||
356 | { |
||
357 | if ($this->getReadOnly()) { |
||
358 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
359 | } |
||
360 | |||
361 | if (($p = $this->priorityOf($item, true)) !== false) { |
||
362 | if ($priority !== false) { |
||
363 | $priority = $this->ensurePriority($priority); |
||
364 | if ($p[0] != $priority) { |
||
365 | throw new TInvalidDataValueException('list_item_inexistent'); |
||
366 | } |
||
367 | } |
||
368 | $this->removeAtIndexInPriority($p[1], $p[0]); |
||
369 | return $p[2]; |
||
370 | } else { |
||
371 | throw new TInvalidDataValueException('list_item_inexistent'); |
||
372 | } |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Removes an item at the specified index in the flattened list. |
||
377 | * @param int $index index of the item to be removed. |
||
378 | * @throws TInvalidDataValueException If the index specified exceeds the bound |
||
379 | * @throws TInvalidOperationException if the list is read-only |
||
380 | * @return mixed the removed item. |
||
381 | */ |
||
382 | public function removeAt($index) |
||
383 | { |
||
384 | if ($this->getReadOnly()) { |
||
385 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
386 | } |
||
387 | |||
388 | if (($priority = $this->priorityAt($index, true)) !== false) { |
||
389 | return $this->removeAtIndexInPriority($priority[1], $priority[0]); |
||
390 | } |
||
391 | throw new TInvalidDataValueException('list_index_invalid', $index); |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Removes the item at a specific index within a priority. Override |
||
396 | * and call this method to insert your own functionality. |
||
397 | * @param int $index index of item to remove within the priority. |
||
398 | * @param null|numeric $priority priority of the item to remove, defaults to null, or left blank, it is then set to the default priority |
||
399 | * @throws TInvalidDataValueException If the item does not exist |
||
400 | * @return mixed the removed item. |
||
401 | */ |
||
402 | public function removeAtIndexInPriority($index, $priority = null) |
||
403 | { |
||
404 | if ($this->getReadOnly()) { |
||
405 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
406 | } |
||
407 | |||
408 | $priority = $this->ensurePriority($priority); |
||
409 | if (!isset($this->_d[$priority]) || $index < 0 || $index >= ($c = count($this->_d[$priority]))) { |
||
410 | throw new TInvalidDataValueException('list_item_inexistent'); |
||
411 | } |
||
412 | |||
413 | // $value is an array of elements removed, only one |
||
414 | if ($index === $c - 1) { |
||
415 | $value = array_pop($this->_d[$priority]); |
||
416 | } else { |
||
417 | $value = array_splice($this->_d[$priority], $index, 1); |
||
418 | $value = $value[0]; |
||
419 | } |
||
420 | if (!count($this->_d[$priority])) { |
||
421 | unset($this->_d[$priority]); |
||
422 | } |
||
423 | |||
424 | $this->_c--; |
||
425 | $this->_fd = null; |
||
426 | return $value; |
||
427 | } |
||
428 | |||
429 | /** |
||
430 | * Removes all items in the priority list by calling removeAtIndexInPriority from the last item to the first. |
||
431 | */ |
||
432 | public function clear(): void |
||
433 | { |
||
434 | if ($this->getReadOnly()) { |
||
435 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
436 | } |
||
437 | |||
438 | foreach ($this->_d as $priority => $items) { |
||
439 | for ($index = count($items) - 1; $index >= 0; $index--) { |
||
440 | $this->removeAtIndexInPriority($index, $priority); |
||
441 | } |
||
442 | } |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * @param mixed $item item |
||
447 | * @return int the index of the item in the flattened list (0 based), -1 if not found. |
||
448 | */ |
||
449 | public function indexOf($item) |
||
450 | { |
||
451 | if (($index = array_search($item, $this->flattenPriorities(), true)) === false) { |
||
452 | return -1; |
||
453 | } else { |
||
454 | return $index; |
||
455 | } |
||
456 | } |
||
457 | |||
458 | /** |
||
459 | * Returns the priority of a particular item |
||
460 | * @param mixed $item the item to look for within the list |
||
461 | * @param bool $withindex this specifies if the full positional data of the item within the list is returned. |
||
462 | * This defaults to false, if no parameter is provided, so only provides the priority number of the item by default. |
||
463 | * @return array|false|numeric the priority of the item in the list, false if not found. |
||
464 | * if withindex is true, an array is returned of [0 => $priority, 1 => $priorityIndex, 2 => flattenedIndex, |
||
465 | * 'priority' => $priority, 'index' => $priorityIndex, 'absindex' => flattenedIndex] |
||
466 | */ |
||
467 | public function priorityOf($item, $withindex = false) |
||
468 | { |
||
469 | $this->sortPriorities(); |
||
470 | |||
471 | $absindex = 0; |
||
472 | foreach ($this->_d as $priority => $items) { |
||
473 | if (($index = array_search($item, $items, true)) !== false) { |
||
474 | $absindex += $index; |
||
475 | return $withindex ? [$priority, $index, $absindex, |
||
476 | 'priority' => $priority, 'index' => $index, 'absindex' => $absindex, ] : $priority; |
||
477 | } else { |
||
478 | $absindex += count($items); |
||
479 | } |
||
480 | } |
||
481 | |||
482 | return false; |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Retutrns the priority of an item at a particular flattened index. |
||
487 | * @param int $index index of the item within the list |
||
488 | * @param bool $withindex this specifies if the full positional data of the item within the list is returned. |
||
489 | * This defaults to false, if no parameter is provided, so only provides the priority number of the item by default. |
||
490 | * @return array|false|numeric the priority of the item in the list, false if not found. |
||
491 | * if withindex is true, an array is returned of [0 => $priority, 1 => $priorityIndex, 2 => flattenedIndex, |
||
492 | * 'priority' => $priority, 'index' => $priorityIndex, 'absindex' => flattenedIndex] |
||
493 | */ |
||
494 | public function priorityAt($index, $withindex = false) |
||
495 | { |
||
496 | if ($index < 0 || $index >= $this->getCount()) { |
||
497 | throw new TInvalidDataValueException('list_index_invalid', $index); |
||
498 | } |
||
499 | |||
500 | $absindex = $index; |
||
501 | $this->sortPriorities(); |
||
502 | foreach ($this->_d as $priority => $items) { |
||
503 | if ($index >= ($c = count($items))) { |
||
504 | $index -= $c; |
||
505 | } else { |
||
506 | return $withindex ? [$priority, $index, $absindex, |
||
507 | 'priority' => $priority, 'index' => $index, 'absindex' => $absindex, ] : $priority; |
||
508 | } |
||
509 | } |
||
510 | return false; |
||
511 | } |
||
512 | |||
513 | /** |
||
514 | * This inserts an item before another item within the list. It uses the same priority as the |
||
515 | * found index item and places the new item before it. |
||
516 | * @param mixed $indexitem the item to index |
||
517 | * @param mixed $item the item to add before indexitem |
||
518 | * @throws TInvalidDataValueException If the item does not exist |
||
519 | * @return int where the item has been inserted in the flattened list |
||
520 | */ |
||
521 | public function insertBefore($indexitem, $item) |
||
522 | { |
||
523 | if ($this->getReadOnly()) { |
||
524 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
525 | } |
||
526 | |||
527 | if (($priority = $this->priorityOf($indexitem, true)) === false) { |
||
528 | throw new TInvalidDataValueException('list_item_inexistent'); |
||
529 | } |
||
530 | |||
531 | $this->insertAtIndexInPriority($item, $priority[1], $priority[0]); |
||
532 | |||
533 | return $priority[2]; |
||
534 | } |
||
535 | |||
536 | /** |
||
537 | * This inserts an item after another item within the list. It uses the same priority as the |
||
538 | * found index item and places the new item after it. |
||
539 | * @param mixed $indexitem the item to index |
||
540 | * @param mixed $item the item to add after indexitem |
||
541 | * @throws TInvalidDataValueException If the item does not exist |
||
542 | * @return int where the item has been inserted in the flattened list |
||
543 | */ |
||
544 | public function insertAfter($indexitem, $item) |
||
545 | { |
||
546 | if ($this->getReadOnly()) { |
||
547 | throw new TInvalidOperationException('list_readonly', get_class($this)); |
||
548 | } |
||
549 | |||
550 | if (($priority = $this->priorityOf($indexitem, true)) === false) { |
||
551 | throw new TInvalidDataValueException('list_item_inexistent'); |
||
552 | } |
||
553 | |||
554 | $this->insertAtIndexInPriority($item, $priority[1] + 1, $priority[0]); |
||
555 | |||
556 | return $priority[2] + 1; |
||
557 | } |
||
558 | |||
559 | /** |
||
560 | * @return array the priority list of items in array |
||
561 | */ |
||
562 | public function toArray(): array |
||
563 | { |
||
564 | return $this->flattenPriorities(); |
||
565 | } |
||
566 | |||
567 | /** |
||
568 | * @return array the array of priorities keys with values of arrays of items. The priorities are sorted so important priorities, lower numerics, are first. |
||
569 | */ |
||
570 | public function toPriorityArray(): array |
||
571 | { |
||
572 | $this->sortPriorities(); |
||
573 | return $this->_d; |
||
574 | } |
||
575 | |||
576 | /** |
||
577 | * Combines the map elements which have a priority below the parameter value |
||
578 | * @param numeric $priority the cut-off priority. All items of priority less than this are returned. |
||
579 | * @param bool $inclusive whether or not the input cut-off priority is inclusive. Default: false, not inclusive. |
||
580 | * @return array the array of priorities keys with values of arrays of items that are below a specified priority. |
||
581 | * The priorities are sorted so important priorities, lower numerics, are first. |
||
582 | */ |
||
583 | public function toArrayBelowPriority($priority, $inclusive = false): array |
||
584 | { |
||
585 | $this->sortPriorities(); |
||
586 | $items = []; |
||
587 | foreach ($this->_d as $itemspriority => $itemsatpriority) { |
||
588 | if ((!$inclusive && $itemspriority >= $priority) || $itemspriority > $priority) { |
||
589 | break; |
||
590 | } |
||
591 | $items = array_merge($items, $itemsatpriority); |
||
592 | } |
||
593 | return $items; |
||
594 | } |
||
595 | |||
596 | /** |
||
597 | * Combines the map elements which have a priority above the parameter value |
||
598 | * @param numeric $priority the cut-off priority. All items of priority greater than this are returned. |
||
599 | * @param bool $inclusive whether or not the input cut-off priority is inclusive. Default: true, inclusive. |
||
600 | * @return array the array of priorities keys with values of arrays of items that are above a specified priority. |
||
601 | * The priorities are sorted so important priorities, lower numerics, are first. |
||
602 | */ |
||
603 | public function toArrayAbovePriority($priority, $inclusive = true): array |
||
604 | { |
||
605 | $this->sortPriorities(); |
||
606 | $items = []; |
||
607 | foreach ($this->_d as $itemspriority => $itemsatpriority) { |
||
608 | if ((!$inclusive && $itemspriority <= $priority) || $itemspriority < $priority) { |
||
609 | continue; |
||
610 | } |
||
611 | $items = array_merge($items, $itemsatpriority); |
||
612 | } |
||
613 | return $items; |
||
614 | } |
||
615 | |||
616 | |||
617 | /** |
||
618 | * Copies iterable data into the priority list. |
||
619 | * Note, existing data in the map will be cleared first. |
||
620 | * @param mixed $data the data to be copied from, must be an array or object implementing Traversable |
||
621 | * @throws TInvalidDataTypeException If data is neither an array nor an iterator. |
||
622 | */ |
||
623 | public function copyFrom($data): void |
||
624 | { |
||
625 | if ($data instanceof TPriorityList) { |
||
626 | if ($this->getCount() > 0) { |
||
627 | $this->clear(); |
||
628 | } |
||
629 | foreach ($data->getPriorities() as $priority) { |
||
630 | foreach ($data->itemsAtPriority($priority) as $index => $item) { |
||
631 | $this->insertAtIndexInPriority($item, $index, $priority); |
||
632 | } |
||
633 | } |
||
634 | } elseif (is_array($data) || $data instanceof \Traversable) { |
||
635 | if ($this->getCount() > 0) { |
||
636 | $this->clear(); |
||
637 | } |
||
638 | foreach ($data as $key => $item) { |
||
639 | $this->add($item); |
||
640 | } |
||
641 | } elseif ($data !== null) { |
||
642 | throw new TInvalidDataTypeException('map_data_not_iterable'); |
||
643 | } |
||
644 | } |
||
645 | |||
646 | /** |
||
647 | * Merges iterable data into the priority list. |
||
648 | * New data will be appended to the end of the existing data. If another TPriorityList is merged, |
||
649 | * the incoming parameter items will be appended at the priorities they are present. These items will be added |
||
650 | * to the end of the existing items with equal priorities, if there are any. |
||
651 | * @param mixed $data the data to be merged with, must be an array or object implementing Traversable |
||
652 | * @throws TInvalidDataTypeException If data is neither an array nor an iterator. |
||
653 | */ |
||
654 | public function mergeWith($data): void |
||
655 | { |
||
656 | if ($data instanceof TPriorityList) { |
||
657 | foreach ($data->getPriorities() as $priority) { |
||
658 | foreach ($data->itemsAtPriority($priority) as $index => $item) { |
||
659 | $this->insertAtIndexInPriority($item, false, $priority); |
||
660 | } |
||
661 | } |
||
662 | } elseif (is_array($data) || $data instanceof \Traversable) { |
||
663 | foreach ($data as $priority => $item) { |
||
664 | $this->add($item); |
||
665 | } |
||
666 | } elseif ($data !== null) { |
||
667 | throw new TInvalidDataTypeException('map_data_not_iterable'); |
||
668 | } |
||
669 | } |
||
670 | |||
671 | /** |
||
672 | * Returns whether there is an element at the specified offset. |
||
673 | * This method is required by the interface \ArrayAccess. |
||
674 | * @param mixed $offset the offset to check on |
||
675 | * @return bool |
||
676 | */ |
||
677 | public function offsetExists($offset): bool |
||
678 | { |
||
679 | return ($offset >= 0 && $offset < $this->getCount()); |
||
680 | } |
||
681 | |||
682 | /** |
||
683 | * Sets the element at the specified offset. This method is required by the interface \ArrayAccess. |
||
684 | * Setting elements in a priority list is not straight forword when appending and setting at the |
||
685 | * end boundary. When appending without an offset (a null offset), the item will be added at |
||
686 | * the default priority. The item may not be the last item in the list. When appending with an |
||
687 | * offset equal to the count of the list, the item will get be appended with the last items priority. |
||
688 | * |
||
689 | * All together, when setting the location of an item, the item stays in that location, but appending |
||
690 | * an item into a priority list doesn't mean the item is at the end of the list. |
||
691 | * @param int $offset the offset to set element |
||
692 | * @param mixed $item the element value |
||
693 | */ |
||
694 | public function offsetSet($offset, $item): void |
||
695 | { |
||
696 | if ($offset === null) { |
||
697 | $this->add($item); |
||
698 | return; |
||
699 | } |
||
700 | if ($offset === $this->getCount()) { |
||
701 | $priority = $this->priorityAt($offset - 1, true); |
||
702 | $priority[1]++; |
||
703 | } else { |
||
704 | $priority = $this->priorityAt($offset, true); |
||
705 | $this->removeAtIndexInPriority($priority[1], $priority[0]); |
||
706 | } |
||
707 | $this->insertAtIndexInPriority($item, $priority[1], $priority[0]); |
||
708 | } |
||
709 | |||
710 | /** |
||
711 | * Unsets the element at the specified offset. |
||
712 | * This method is required by the interface \ArrayAccess. |
||
713 | * @param mixed $offset the offset to unset element |
||
714 | */ |
||
715 | public function offsetUnset($offset): void |
||
716 | { |
||
717 | $this->removeAt($offset); |
||
718 | } |
||
719 | |||
720 | /** |
||
721 | * Returns an array with the names of all variables of this object that should NOT be serialized |
||
722 | * because their value is the default one or useless to be cached for the next page loads. |
||
723 | * Reimplement in derived classes to add new variables, but remember to also to call the parent |
||
724 | * implementation first. |
||
725 | * @param array $exprops by reference |
||
726 | * @since 4.2.3 |
||
727 | */ |
||
728 | protected function _getZappableSleepProps(&$exprops) |
||
740 | } |
||
741 | } |
||
742 | } |
||
743 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths