Passed
Push — master ( 246025...18c029 )
by Fabio
05:31
created

TArraySubscription::getKey()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 12
nc 8
nop 0
dl 0
loc 18
rs 8.4444
c 1
b 0
f 0
1
<?php
2
/**
3
 * TArraySubscription classes
4
 *
5
 * @author Brad Anderson <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 */
9
10
namespace Prado\Collections;
11
12
use Prado\Exceptions\TInvalidOperationException;
13
use Prado\Exceptions\TInvalidDataValueException;
14
use Prado\TPropertyValue;
15
use Prado\Util\Helpers\TArrayHelper;
16
17
use ArrayAccess;
18
use WeakReference;
19
20
/**
21
 * TArraySubscription class.
22
 *
23
 * Given an array reference or ArrayAccess object, this class adds an item to an
24
 * array on {@see self::subscribe()} and removes the element of the array when the
25
 * instance is dereferenced or {@see self::unsubscribe()} is called.
26
 *
27
 * These are specific types that can be subscribed: PHP Array, Object implementing
28
 * ArrayAccess, TList and subclasses, and TMap and subclasses.  A priority can be
29
 * specified for {@see IPriorityCollection} instances.
30
 *
31
 * When an array is associative, the original element is saved and restored (with
32
 * its original priority).  IWeakCollections retain their elements in their weakened
33
 * "storage" state.
34
 *
35
 * ```php
36
 *		$map = new TPriorityMap(['key' => 'original value']);
37
 *
38
 *		$subscription = new TArraySubscription($map, 'key', 'new value', priority: 5);
39
 *
40
 *		$subscription->getIsSubscribed() === true;
41
 *		$map['key'] === 'new value';	// @ priority = 5
42
 *
43
 *		$subscription->unsubscribe();
44
 *
45
 *		$subscription->getIsSubscribed() === false;
46
 *		$map['key'] === 'original value';	// @ priority = default (10)
47
 * ```
48
 *
49
 * When the TArraySubscription is dereferenced, the item is also automatically unsubscribed.
50
 * ```php
51
 *	{
52
 *		$list = [];
53
 *		{
54
 *			$subscription = new TArraySubscription($list, null, 'subscribed item', isAssociative: false);
55
 *			$list[0] === 'subscribed item';
56
 *			array_splice($list, 0, 0, ['first item']);
57
 *			$list[] = 'last item'; // ['first item', 'subscribed item', 'last item']
58
 *			...
59
 *		}	// $subscription unsubscribes here, out of scope
60
 *		$list[0] === 'first item';
61
 *		$list[1] === 'last item'; // count = 2
62
 *	}
63
 * ```
64
 *
65
 * @author Brad Anderson <[email protected]>
66
 * @since 4.2.3
67
 * @todo TComponent is too complex, TBaseObject for getters/setters.
68
 */
69
class TArraySubscription
70
{
71
	use TPriorityPropertyTrait;
72
73
	/**
74
	 * @var null|array|ArrayAccess The array reference or ArrayAccess being subscribed to.
75
	 */
76
	private mixed $_array = null;
77
78
	/**
79
	 * @var null|int|string The key that the item is added to the array.
80
	 */
81
	private null|int|string $_key = null;
82
83
	/**
84
	 * @var mixed The item subscribing to the array.
85
	 */
86
	protected mixed $_item = null;
87
88
	/**
89
	 * @var ?string The class filtering the item for storage.  This is populated when
90
	 * the {@see self::getArray()} is an instanceOf {@see ICollectionFilter}.
91
	 */
92
	protected ?string $_filterClass = null;
93
94
	/**
95
	 * @var null|bool|int Is the array an associative array.  False for a "list" style array.
96
	 *   null for discovery of the style of array on subscribe.  default true.
97
	 */
98
	protected null|bool|int $_isAssoc = true;
99
100
	/**
101
	 * @var bool Is the item inserted into the collection.
102
	 */
103
	private bool $_isSubscribed = false;
104
105
	/**
106
	 * @var ?bool Is the subscription replacing an item.
107
	 */
108
	private ?bool $_isReplacing = null;
109
110
	/**
111
	 * @var mixed The original item.
112
	 */
113
	private mixed $_originalItem = null;
114
115
	/**
116
	 * @var ?float The priority of the original item.
117
	 */
118
	private ?float $_originalPriority = null;
119
120
	/**
121
	 * Constructs the TArraySubscription.  If there is an key or item then the item is
122
	 * automatically subscribed to the array when $autoSubscribe is the default null.
123
	 * When $autoSubscribe = true, the item is added regardless of a key and/or item
124
	 * has a value.
125
	 * @param mixed &$array The array to subscribe to, passed by reference.
126
	 *   Default null.
127
	 * @param mixed $key The key of the subscribed item, default null for append the
128
	 *   item. Default null.
129
	 * @param mixed $item The item to insert into the array at $key with $priority.
130
	 *   Default null.
131
	 * @param null|float|int $priority The priority of the item for IPriorityCollection.
132
	 *   Default null.
133
	 * @param null|bool|int $isAssociative Is the array an associative array.  false is
134
	 *   the list from (0...n-1).  When false, this will use `array_splice` to insert
135
	 *   the item.  Default 1 for true except for TList.
136
	 * @param bool $autoSubscribe Should the
137
	 */
138
	public function __construct(mixed &$array = null, mixed $key = null, mixed $item = null, null|int|float $priority = null, null|bool|int $isAssociative = 1, ?bool $autoSubscribe = null)
139
	{
140
		$this->setArray($array);
141
		$this->setKey($key);
142
		$this->setItem($item);
143
		$this->setPriority($priority);
0 ignored issues
show
Bug introduced by
It seems like $priority can also be of type double and integer; however, parameter $value of Prado\Collections\TArray...cription::setPriority() does only seem to accept Prado\Collections\numeric|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

143
		$this->setPriority(/** @scrutinizer ignore-type */ $priority);
Loading history...
144
		$this->setIsAssociative($isAssociative);
145
146
		//parent::__construct();
147
148
		if (($autoSubscribe === null && ($key !== null || $item !== null) || $autoSubscribe === true) && $this->getArray() !== null) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ($autoSubscribe === null...is->getArray() !== null, Probably Intended Meaning: $autoSubscribe === null ...s->getArray() !== null)
Loading history...
149
			$this->subscribe();
150
		}
151
	}
152
153
	/**
154
	 * Cleans up the instance on destruction.
155
	 * If the item is subscribed to the array, the item is removed.
156
	 */
157
	public function __destruct()
158
	{
159
		$this->unsubscribe();
160
		//parent::__destruct();
161
	}
162
163
	/**
164
	 * Returns the collection to which the item is subscribed.
165
	 * Be very careful with the returnad array as it is passed by reference and could change
166
	 * the original variable to something other than an array.
167
	 * ```php
168
	 *		$array = & $subscription->getArray();
169
	 *		... //use $array
170
	 *		// $array = null;  // This will destroy the array being used originally.  Avoid this.
171
	 *		unset($array);  // This dereferences.
172
	 *
173
	 *		// or, use a non pass-by-reference
174
	 *		$array = $subscription->getArray();
175
	 *		$array = null;  // ok.
176
	 * ```
177
	 * @param bool $weak
178
	 * @return array|ArrayAccess The subscribed array-collection, passed by reference.
179
	 */
180
	public function &getArray(bool $weak = false): array|ArrayAccess|WeakReference|null
181
	{
182
		if ($this->_array instanceof WeakReference) {
183
			if ($weak) {
184
				$collection = $this->_array;
185
			} else {
186
				$collection = $this->_array->get();
187
			}
188
		} elseif (is_array($this->_array)) {
189
			$collection = &$this->_array;
190
		} elseif ($this->_array instanceof ArrayAccess) {
191
			$collection = $this->_array;
192
		} else {
193
			$collection = null;
194
		}
195
		return $collection;
196
	}
197
198
	/**
199
	 * Sets the array or ArrayAccess object.
200
	 * @param null|array|ArrayAccess $value The array, passed by reference.
201
	 * @throws TInvalidOperationException When setting during a subscription.
202
	 * @throws TInvalidOperationException If the item is already subscribed.
203
	 * @return static The current object.
204
	 */
205
	public function setArray(null|array|ArrayAccess &$value): static
206
	{
207
		if ($this->_isSubscribed) {
208
			throw new TInvalidOperationException('arraysubscription_no_change', 'Array');
209
		}
210
211
		unset($this->_array);
212
		if (is_object($value)) {
0 ignored issues
show
introduced by
The condition is_object($value) is always false.
Loading history...
213
			$this->_array = WeakReference::create($value);
214
		} else {
215
			$this->_array = &$value;
216
		}
217
218
		return $this;
219
	}
220
221
	/**
222
	 * If the item is subscribed and the key is null, the item key will be discovered
223
	 * with the TList (by {@see TList::indexOf()}) or array (by array_search).
224
	 * @return null|int|string The key for the item subscription to the array.
225
	 */
226
	public function getKey(): null|int|string
227
	{
228
		$collection = &$this->getArray();
229
		if ($this->_isSubscribed && $this->_key === null) {
230
			if ($collection instanceof TList) {
231
				$args = [$this->getItem()];
232
				if ($collection instanceof IPriorityCollection) {
233
					$args[] = $this->getPriority();
234
				}
235
				return ($index = $collection->indexOf(...$args)) === -1 ? null : $index;
0 ignored issues
show
Bug introduced by
The method indexOf() does not exist on ArrayAccess. It seems like you code against a sub-type of ArrayAccess such as Prado\Collections\TList or Prado\Collections\TMap or Prado\Web\THttpSession or Prado\Web\THttpRequest or Prado\Caching\TCache. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

235
				return ($index = $collection->/** @scrutinizer ignore-call */ indexOf(...$args)) === -1 ? null : $index;
Loading history...
Bug introduced by
The method indexOf() does not exist on WeakReference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

235
				return ($index = $collection->/** @scrutinizer ignore-call */ indexOf(...$args)) === -1 ? null : $index;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
236
			} elseif (is_array($collection)) {
237
				if (($key = array_search($this->getItem(), $collection, true)) === false) {
238
					return null;
239
				}
240
				return $key;
241
			}
242
		}
243
		return $this->_key;
244
	}
245
246
	/**
247
	 * @param mixed $value The key for the item subscription to the array.
248
	 * @throws TInvalidOperationException If the item is already subscribed.
249
	 */
250
	public function setKey(mixed $value): static
251
	{
252
		if ($this->_isSubscribed) {
253
			throw new TInvalidOperationException('arraysubscription_no_change', 'Key');
254
		}
255
256
		if (is_bool($value) || is_float($value)) {
257
			$value = (int) $value;
258
		}
259
		$this->_key = $value;
260
261
		return $this;
262
	}
263
264
	/**
265
	 * @param bool $unfiltered Should the item be unfiltered back from the stored format.
266
	 *   default false.
267
	 * @return mixed The item subscribing to the array.
268
	 */
269
	public function getItem(bool $unfiltered = false): mixed
270
	{
271
		$item = $this->_item;
272
273
		if (!$unfiltered && $this->_filterClass !== null) {
274
			$this->_filterClass::filterItemForOutput($item);
275
		}
276
277
		return $item;
278
	}
279
280
	/**
281
	 * @param mixed $value The item subscribing to the array.
282
	 * @throws TInvalidOperationException If the item is already subscribed.
283
	 * @return static The current object.
284
	 */
285
	public function setItem(mixed $value): static
286
	{
287
		if ($this->_isSubscribed) {
288
			throw new TInvalidOperationException('arraysubscription_no_change', 'Item');
289
		}
290
291
		$this->_item = $value;
292
293
		return $this;
294
	}
295
296
	/**
297
	 * This is on applicable to {@see IPriorityCollection}.
298
	 * @param ?numeric $value The priority of the item.
0 ignored issues
show
Bug introduced by
The type Prado\Collections\numeric was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
299
	 * @throws TInvalidOperationException If the item is already subscribed.
300
	 * @return static The current object.
301
	 */
302
	public function setPriority($value): static
303
	{
304
		if ($this->_isSubscribed) {
305
			throw new TInvalidOperationException('arraysubscription_no_change', 'Priority');
306
		}
307
308
		if ($value === '') {
0 ignored issues
show
introduced by
The condition $value === '' is always false.
Loading history...
309
			$value = null;
310
		}
311
		if ($value !== null) {
312
			$value = TPropertyValue::ensureFloat($value);
313
		}
314
		$this->_priority = $value;
315
316
		return $this;
317
	}
318
319
	/**
320
	 * Whether to add to the array by association or by splicing (for an ordered list).
321
	 * @return null|null|bool Is the array associative; default true.  false will treat the array
322
	 *   as a list from (0, ..., count() - 1).  if null, where needed, the "list"ness
323
	 *   of the array will be determined by {@see TArrayHelper::array_is_list()}.
324
	 */
325
	public function getIsAssociative(): null|bool|int
326
	{
327
		return $this->_isAssoc;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_isAssoc also could return the type integer which is incompatible with the documented return type boolean|null.
Loading history...
328
	}
329
330
	/**
331
	 * @param null|bool|int $value Is the array associative; default null.  false will treat the array
332
	 *   as a list from (0, ..., count() - 1).  if null, where needed, the "list"ness
333
	 *   of the array will be determined by {@see TArrayHelper::array_is_list()}.
334
	 * @throws TInvalidOperationException If the item is already subscribed.
335
	 * @return static The current object.
336
	 */
337
	public function setIsAssociative(null|bool|int $value = null): static
338
	{
339
		if ($this->_isSubscribed) {
340
			throw new TInvalidOperationException('arraysubscription_no_change', 'Key');
341
		}
342
343
		$this->_isAssoc = $value;
344
345
		return $this;
346
	}
347
348
	/**
349
	 * @return bool Is the item subscribed to the array.
350
	 */
351
	public function getIsSubscribed(): bool
352
	{
353
		return $this->_isSubscribed;
354
	}
355
356
	/**
357
	 * Places the item in the array at the key (and priority, where possible).
358
	 * List based ArrayAccess must also implement \Countable as well.
359
	 * @throws TInvalidDataValueException When the Array is an ArrayAccess (but not
360
	 *   TMap nor TList), the Array isAssociative, and key is null.
361
	 * @return ?bool Was the subscription successful.  If the item is already subscribed
362
	 *   this will return false.  If the array is not an array, this returns null;
363
	 */
364
	public function subscribe(): ?bool
365
	{
366
		if ($this->_isSubscribed) {
367
			return false;
368
		}
369
370
		$collection = &$this->getArray();
371
		if (!is_array($collection) && !($collection instanceof ArrayAccess)) {
372
			return null;
373
		}
374
375
		if (is_int($this->_isAssoc)) {
376
			$this->_isAssoc = !($collection instanceof TList);
377
		}
378
379
		$this->_isReplacing = false;
380
		$key = $this->_key;
381
382
		// @todo, PHPStan bug https://github.com/phpstan/phpstan/issues/9519
383
		if ($collection instanceof TList || ($collection instanceof TMap)) {
384
			$this->_isAssoc = $collection instanceof TMap;
385
			if ($collection instanceof TList && $key !== null) {
386
				$priority = $collection->insertAt($key, $this->getItem());
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type string; however, parameter $index of Prado\Collections\TList::insertAt() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

386
				$priority = $collection->insertAt(/** @scrutinizer ignore-type */ $key, $this->getItem());
Loading history...
Bug introduced by
Are you sure the assignment to $priority is correct as $collection->insertAt($key, $this->getItem()) targeting Prado\Collections\TList::insertAt() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
387
				if ($collection instanceof IPriorityCollection) {
388
					$this->setPriority($priority);
389
				}
390
				$this->setKey(null);
391
			} else {
392
				$args = [];
393
				$item = $this->getItem();
394
				if ($collection instanceof TMap) {
395
					if ($collection->contains($key)) {
396
						$this->_isReplacing = true;
397
						$this->_originalItem = $collection[$key];
398
399
						if ($collection instanceof IPriorityCollection) {
400
							$this->_originalPriority = $collection->priorityAt($key);
0 ignored issues
show
Bug introduced by
The method priorityAt() does not exist on Prado\Collections\TMap. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

400
							/** @scrutinizer ignore-call */ 
401
       $this->_originalPriority = $collection->priorityAt($key);
Loading history...
401
							if ($item === null) {
402
								$this->setItem($item = $this->_originalItem);
403
							}
404
						}
405
					}
406
					array_push($args, $key);
407
				}
408
				array_push($args, $item);
409
				if ($collection instanceof IPriorityCollection) {
410
					if (($priority = $this->getPriority()) === null) {
411
						$this->setPriority($collection->getDefaultPriority());
0 ignored issues
show
Bug introduced by
The method getDefaultPriority() does not exist on Prado\Collections\TList. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

411
						$this->setPriority($collection->/** @scrutinizer ignore-call */ getDefaultPriority());
Loading history...
Bug introduced by
The method getDefaultPriority() does not exist on Prado\Collections\TMap. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

411
						$this->setPriority($collection->/** @scrutinizer ignore-call */ getDefaultPriority());
Loading history...
412
					}
413
					array_push($args, $priority);
414
				}
415
416
				$key = $collection->add(...$args);
0 ignored issues
show
Bug introduced by
The call to Prado\Collections\TMap::add() has too few arguments starting with value. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

416
				/** @scrutinizer ignore-call */ 
417
    $key = $collection->add(...$args);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
$args is expanded, but the parameter $item of Prado\Collections\TList::add() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

416
				$key = $collection->add(/** @scrutinizer ignore-type */ ...$args);
Loading history...
417
418
				if ($collection instanceof TMap) {
419
					$this->setKey($key);
420
				}
421
			}
422
		} else {
423
			if ($collection instanceof ArrayAccess) {
424
				$this->_isAssoc = true;
425
			} elseif ($this->_isAssoc === null) {
426
				$this->_isAssoc = !TArrayHelper::array_is_list($collection);
427
			}
428
			if ($key === null && $this->_isAssoc) {
429
				if ($collection instanceof ArrayAccess) {
430
					throw new TInvalidDataValueException('arraysubscription_no_null_key');
431
				}
432
				$collection[] = $this->getItem();
433
				$this->setKey(array_key_last($collection));
434
			} else {
435
				if ($key === null) {
436
					$key = count($collection);
0 ignored issues
show
Bug introduced by
It seems like $collection can also be of type ArrayAccess; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

436
					$key = count(/** @scrutinizer ignore-type */ $collection);
Loading history...
437
				}
438
				$offsetSet = $this->_isAssoc || !is_array($collection);
439
				if ($offsetSet || $key === count($collection)) {
440
					if ($offsetSet && (isset($collection[$key]) || is_array($collection) && array_key_exists($key, $collection))) {
441
						$this->_isReplacing = true;
442
						$this->_originalItem = $collection[$key];
443
					}
444
					$collection[$key] = $this->getItem();
445
				} else {
446
					if ($key < 0 && $key > count($collection)) {
447
						throw new TInvalidDataValueException('arraysubscription_index_invalid', $key, count($collection));
448
					}
449
					array_splice($collection, $key, 0, [$this->getItem()]);
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type string; however, parameter $offset of array_splice() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

449
					array_splice($collection, /** @scrutinizer ignore-type */ $key, 0, [$this->getItem()]);
Loading history...
450
				}
451
				if (!$this->_isAssoc && is_array($collection)) {
452
					$this->setKey(null);
453
				}
454
			}
455
		}
456
457
		if ($collection instanceof ICollectionFilter) {
458
			$this->_filterClass = $collection::class;
459
			$collection::filterItemForInput($this->_item);
460
			if ($this->_isReplacing) {
461
				$collection::filterItemForInput($this->_originalItem);
462
			}
463
		}
464
465
		$this->_isSubscribed = true;
466
467
		return true;
468
	}
469
470
	/**
471
	 * Removes the item from the array at the key (and priority, where possible).
472
	 * @return ?bool Was the unsubscribe successful.  null when the array is not the proper
473
	 *   type, and false if already unsubscribe.
474
	 */
475
	public function unsubscribe(): ?bool
476
	{
477
		if (!$this->_isSubscribed) {
478
			return false;
479
		}
480
481
		$this->_isSubscribed = false;
482
483
		if ($this->_filterClass !== null) {
484
			$this->_filterClass::filterItemForOutput($this->_item);
485
486
			if ($this->_isReplacing) {
487
				$this->_filterClass::filterItemForOutput($this->_originalItem);
488
			}
489
			$this->_filterClass = null;
490
		}
491
492
		$collection = &$this->getArray();
493
494
		if (!is_array($collection) && !($collection instanceof ArrayAccess)) {
495
			return null;
496
		}
497
498
		if ($collection instanceof TList) {
499
			$args = [$this->getItem()];
500
			if ($collection instanceof IPriorityCollection) {
501
				array_push($args, $this->getPriority());
502
			}
503
			try {
504
				$collection->remove(...$args);
0 ignored issues
show
Bug introduced by
The method remove() does not exist on ArrayAccess. It seems like you code against a sub-type of ArrayAccess such as Prado\Collections\TList or Prado\Collections\TMap or Prado\Web\THttpSession or Cassandra\Map or Prado\Web\THttpRequest or Prado\Caching\TCache. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

504
				$collection->/** @scrutinizer ignore-call */ 
505
                 remove(...$args);
Loading history...
505
			} catch (TInvalidDataValueException $e) {
506
				// if not found, continue.
507
			}
508
		} else {
509
			if ($this->_isAssoc || !is_array($collection)) {
510
				$key = $this->_key;
511
				if (isset($collection[$key]) || is_array($collection) && array_key_exists($key, $collection)) {
512
					$item = $collection[$key];
513
					if ($item === $this->getItem()) {
514
						unset($collection[$key]);
515
						if ($this->_isReplacing && (!($collection instanceof IWeakCollection) || $this->_originalItem !== null)) {
516
							if ($collection instanceof TPriorityMap) {
517
								$collection->add($key, $this->_originalItem, $this->_originalPriority);
0 ignored issues
show
Bug introduced by
It seems like $this->_originalPriority can also be of type double; however, parameter $priority of Prado\Collections\TPriorityMap::add() does only seem to accept Prado\Collections\numeric|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

517
								$collection->add($key, $this->_originalItem, /** @scrutinizer ignore-type */ $this->_originalPriority);
Loading history...
518
							} else {
519
								$collection[$key] = $this->_originalItem;
520
							}
521
						}
522
					}
523
				}
524
				unset($this->_originalItem);
525
				unset($this->_originalPriority);
526
				$this->_isReplacing = null;
527
			} else {
528
				$key = array_search($this->getItem(), $collection, true);
529
				if ($key !== false) {
530
					array_splice($collection, $key, 1);
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type string; however, parameter $offset of array_splice() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

530
					array_splice($collection, /** @scrutinizer ignore-type */ $key, 1);
Loading history...
531
				}
532
			}
533
		}
534
535
		return true;
536
	}
537
538
}
539