PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.94
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.94
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Support / EnumeratesValues.php

EnumeratesValues.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.94, at vendor/wpfluent/framework/src/WPFluent/Support/EnumeratesValues.php

1,091 lines 27.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Framework\Support;
4
5 use Closure;
6 use Exception;
7 use Traversable;
8 use CachingIterator;
9 use JsonSerializable;
10 use UnexpectedValueException;
11
12 use FluentCommunity\Framework\Support\Arr;
13 use FluentCommunity\Framework\Support\Helper;
14 use FluentCommunity\Framework\Support\Collection;
15 use FluentCommunity\Framework\Support\Enumerable;
16 use FluentCommunity\Framework\Support\JsonableInterface;
17 use FluentCommunity\Framework\Support\ArrayableInterface;
18 use FluentCommunity\Framework\Support\HigherOrderWhenProxy;
19 use FluentCommunity\Framework\Support\HigherOrderCollectionProxy;
20
21 /**
22 * @property-read HigherOrderCollectionProxy $average
23 * @property-read HigherOrderCollectionProxy $avg
24 * @property-read HigherOrderCollectionProxy $contains
25 * @property-read HigherOrderCollectionProxy $doesntContain
26 * @property-read HigherOrderCollectionProxy $each
27 * @property-read HigherOrderCollectionProxy $every
28 * @property-read HigherOrderCollectionProxy $filter
29 * @property-read HigherOrderCollectionProxy $first
30 * @property-read HigherOrderCollectionProxy $flatMap
31 * @property-read HigherOrderCollectionProxy $groupBy
32 * @property-read HigherOrderCollectionProxy $keyBy
33 * @property-read HigherOrderCollectionProxy $map
34 * @property-read HigherOrderCollectionProxy $max
35 * @property-read HigherOrderCollectionProxy $min
36 * @property-read HigherOrderCollectionProxy $partition
37 * @property-read HigherOrderCollectionProxy $reject
38 * @property-read HigherOrderCollectionProxy $some
39 * @property-read HigherOrderCollectionProxy $sortBy
40 * @property-read HigherOrderCollectionProxy $sortByDesc
41 * @property-read HigherOrderCollectionProxy $skipUntil
42 * @property-read HigherOrderCollectionProxy $skipWhile
43 * @property-read HigherOrderCollectionProxy $sum
44 * @property-read HigherOrderCollectionProxy $takeUntil
45 * @property-read HigherOrderCollectionProxy $takeWhile
46 * @property-read HigherOrderCollectionProxy $unique
47 * @property-read HigherOrderCollectionProxy $until
48 */
49 trait EnumeratesValues
50 {
51 /**
52 * Indicates that the object's string representation should be escaped when __toString is invoked.
53 *
54 * @var bool
55 */
56 protected $escapeWhenCastingToString = false;
57
58 /**
59 * The methods that can be proxied.
60 *
61 * @var string[]
62 */
63 protected static $proxies = [
64 'average',
65 'avg',
66 'contains',
67 'doesntContain',
68 'each',
69 'every',
70 'filter',
71 'first',
72 'flatMap',
73 'groupBy',
74 'keyBy',
75 'map',
76 'max',
77 'min',
78 'partition',
79 'reject',
80 'skipUntil',
81 'skipWhile',
82 'some',
83 'sortBy',
84 'sortByDesc',
85 'sum',
86 'takeUntil',
87 'takeWhile',
88 'unique',
89 'until',
90 ];
91
92 /**
93 * Create a new collection instance if the value isn't one already.
94 *
95 * @param mixed $items
96 * @return static
97 */
98 public static function make($items = [])
99 {
100 return new static($items);
101 }
102
103 /**
104 * Wrap the given value in a collection if applicable.
105 *
106 * @param mixed $value
107 * @return static
108 */
109 public static function wrap($value)
110 {
111 return $value instanceof Enumerable
112 ? new static($value)
113 : new static(Arr::wrap($value));
114 }
115
116 /**
117 * Get the underlying items from the given collection if applicable.
118 *
119 * @param array|static $value
120 * @return array
121 */
122 public static function unwrap($value)
123 {
124 return $value instanceof Enumerable ? $value->all() : $value;
125 }
126
127 /**
128 * Create a new instance with no items.
129 *
130 * @return static
131 */
132 public static function empty()
133 {
134 return new static([]);
135 }
136
137 /**
138 * Create a new collection by invoking the callback a given amount of times.
139 *
140 * @param int $number
141 * @param callable|null $callback
142 * @return static
143 */
144 public static function times($number, callable $callback = null)
145 {
146 if ($number < 1) {
147 return new static;
148 }
149
150 return static::range(1, $number)
151 ->when($callback)
152 ->map($callback);
153 }
154
155 /**
156 * Alias for the "avg" method.
157 *
158 * @param callable|string|null $callback
159 * @return mixed
160 */
161 public function average($callback = null)
162 {
163 return $this->avg($callback);
164 }
165
166 /**
167 * Alias for the "contains" method.
168 *
169 * @param mixed $key
170 * @param mixed $operator
171 * @param mixed $value
172 * @return bool
173 */
174 public function some($key, $operator = null, $value = null)
175 {
176 return $this->contains(...func_get_args());
177 }
178
179 /**
180 * Determine if an item exists, using strict comparison.
181 *
182 * @param mixed $key
183 * @param mixed $value
184 * @return bool
185 */
186 public function containsStrict($key, $value = null)
187 {
188 if (func_num_args() === 2) {
189 return $this->contains(function ($item) use ($key, $value) {
190 return Helper::dataGet($item, $key) === $value;
191 });
192 }
193
194 if ($this->useAsCallable($key)) {
195 return ! is_null($this->first($key));
196 }
197
198 foreach ($this as $item) {
199 if ($item === $key) {
200 return true;
201 }
202 }
203
204 return false;
205 }
206
207
208 /**
209 * Execute a callback over each item.
210 *
211 * @param callable $callback
212 * @return $this
213 */
214 public function each(callable $callback)
215 {
216 foreach ($this as $key => $item) {
217 if ($callback($item, $key) === false) {
218 break;
219 }
220 }
221
222 return $this;
223 }
224
225 /**
226 * Execute a callback over each nested chunk of items.
227 *
228 * @param callable $callback
229 * @return static
230 */
231 public function eachSpread(callable $callback)
232 {
233 return $this->each(function ($chunk, $key) use ($callback) {
234 $chunk[] = $key;
235
236 return $callback(...$chunk);
237 });
238 }
239
240 /**
241 * Determine if all items pass the given truth test.
242 *
243 * @param string|callable $key
244 * @param mixed $operator
245 * @param mixed $value
246 * @return bool
247 */
248 public function every($key, $operator = null, $value = null)
249 {
250 if (func_num_args() === 1) {
251 $callback = $this->valueRetriever($key);
252
253 foreach ($this as $k => $v) {
254 if (! $callback($v, $k)) {
255 return false;
256 }
257 }
258
259 return true;
260 }
261
262 return $this->every($this->operatorForWhere(...func_get_args()));
263 }
264
265 /**
266 * Get the first item by the given key value pair.
267 *
268 * @param string $key
269 * @param mixed $operator
270 * @param mixed $value
271 * @return mixed
272 */
273 public function firstWhere($key, $operator = null, $value = null)
274 {
275 return $this->first($this->operatorForWhere(...func_get_args()));
276 }
277
278 /**
279 * Determine if the collection is not empty.
280 *
281 * @return bool
282 */
283 public function isNotEmpty()
284 {
285 return ! $this->isEmpty();
286 }
287
288 /**
289 * Run a map over each nested chunk of items.
290 *
291 * @param callable $callback
292 * @return static
293 */
294 public function mapSpread(callable $callback)
295 {
296 return $this->map(function ($chunk, $key) use ($callback) {
297 $chunk[] = $key;
298
299 return $callback(...$chunk);
300 });
301 }
302
303 /**
304 * Run a grouping map over the items.
305 *
306 * The callback should return an associative array with a single key/value pair.
307 *
308 * @param callable $callback
309 * @return static
310 */
311 public function mapToGroups(callable $callback)
312 {
313 $groups = $this->mapToDictionary($callback);
314
315 return $groups->map([$this, 'make']);
316 }
317
318 /**
319 * Map a collection and flatten the result by a single level.
320 *
321 * @param callable $callback
322 * @return static
323 */
324 public function flatMap(callable $callback)
325 {
326 return $this->map($callback)->collapse();
327 }
328
329 /**
330 * Map the values into a new class.
331 *
332 * @param string $class
333 * @return static
334 */
335 public function mapInto($class)
336 {
337 return $this->map(function ($value, $key) use ($class) {
338 return new $class($value, $key);
339 });
340 }
341
342 /**
343 * Get the min value of a given key.
344 *
345 * @param callable|string|null $callback
346 * @return mixed
347 */
348 public function min($callback = null)
349 {
350 $callback = $this->valueRetriever($callback);
351
352 return $this->map(function ($value) use ($callback) {
353 return $callback($value);
354 })->filter(function ($value) {
355 return ! is_null($value);
356 })->reduce(function ($result, $value) {
357 return is_null($result) || $value < $result ? $value : $result;
358 });
359 }
360
361 /**
362 * Get the max value of a given key.
363 *
364 * @param callable|string|null $callback
365 * @return mixed
366 */
367 public function max($callback = null)
368 {
369 $callback = $this->valueRetriever($callback);
370
371 return $this->filter(function ($value) {
372 return ! is_null($value);
373 })->reduce(function ($result, $item) use ($callback) {
374 $value = $callback($item);
375
376 return is_null($result) || $value > $result ? $value : $result;
377 });
378 }
379
380 /**
381 * "Paginate" the collection by slicing it into a smaller collection.
382 *
383 * @param int $page
384 * @param int $perPage
385 * @return static
386 */
387 public function forPage($page, $perPage)
388 {
389 $offset = max(0, ($page - 1) * $perPage);
390
391 return $this->slice($offset, $perPage);
392 }
393
394 /**
395 * Partition the collection into two arrays using the given callback or key.
396 *
397 * @param callable|string $key
398 * @param mixed $operator
399 * @param mixed $value
400 * @return static
401 */
402 public function partition($key, $operator = null, $value = null)
403 {
404 $passed = [];
405 $failed = [];
406
407 $callback = func_num_args() === 1
408 ? $this->valueRetriever($key)
409 : $this->operatorForWhere(...func_get_args());
410
411 foreach ($this as $key => $item) {
412 if ($callback($item, $key)) {
413 $passed[$key] = $item;
414 } else {
415 $failed[$key] = $item;
416 }
417 }
418
419 return new static([new static($passed), new static($failed)]);
420 }
421
422 /**
423 * Get the sum of the given values.
424 *
425 * @param callable|string|null $callback
426 * @return mixed
427 */
428 public function sum($callback = null)
429 {
430 $callback = is_null($callback)
431 ? $this->identity()
432 : $this->valueRetriever($callback);
433
434 return $this->reduce(function ($result, $item) use ($callback) {
435 return $result + $callback($item);
436 }, 0);
437 }
438
439 /**
440 * Apply the callback if the value is truthy.
441 *
442 * @param bool|mixed $value
443 * @param callable|null $callback
444 * @param callable|null $default
445 * @return static|mixed
446 */
447 public function when($value, callable $callback = null, callable $default = null)
448 {
449 if (! $callback) {
450 return new HigherOrderWhenProxy($this, $value);
451 }
452
453 if ($value) {
454 return $callback($this, $value);
455 } elseif ($default) {
456 return $default($this, $value);
457 }
458
459 return $this;
460 }
461
462 /**
463 * Apply the callback if the collection is empty.
464 *
465 * @param callable $callback
466 * @param callable|null $default
467 * @return static|mixed
468 */
469 public function whenEmpty(callable $callback, callable $default = null)
470 {
471 return $this->when($this->isEmpty(), $callback, $default);
472 }
473
474 /**
475 * Apply the callback if the collection is not empty.
476 *
477 * @param callable $callback
478 * @param callable|null $default
479 * @return static|mixed
480 */
481 public function whenNotEmpty(callable $callback, callable $default = null)
482 {
483 return $this->when($this->isNotEmpty(), $callback, $default);
484 }
485
486 /**
487 * Apply the callback if the value is falsy.
488 *
489 * @param bool $value
490 * @param callable $callback
491 * @param callable|null $default
492 * @return static|mixed
493 */
494 public function unless($value, callable $callback, callable $default = null)
495 {
496 return $this->when(! $value, $callback, $default);
497 }
498
499 /**
500 * Apply the callback unless the collection is empty.
501 *
502 * @param callable $callback
503 * @param callable|null $default
504 * @return static|mixed
505 */
506 public function unlessEmpty(callable $callback, callable $default = null)
507 {
508 return $this->whenNotEmpty($callback, $default);
509 }
510
511 /**
512 * Apply the callback unless the collection is not empty.
513 *
514 * @param callable $callback
515 * @param callable|null $default
516 * @return static|mixed
517 */
518 public function unlessNotEmpty(callable $callback, callable $default = null)
519 {
520 return $this->whenEmpty($callback, $default);
521 }
522
523 /**
524 * Filter items by the given key value pair.
525 *
526 * @param string $key
527 * @param mixed $operator
528 * @param mixed $value
529 * @return static
530 */
531 public function where($key, $operator = null, $value = null)
532 {
533 return $this->filter($this->operatorForWhere(...func_get_args()));
534 }
535
536 /**
537 * Filter items where the value for the given key is null.
538 *
539 * @param string|null $key
540 * @return static
541 */
542 public function whereNull($key = null)
543 {
544 return $this->whereStrict($key, null);
545 }
546
547 /**
548 * Filter items where the value for the given key is not null.
549 *
550 * @param string|null $key
551 * @return static
552 */
553 public function whereNotNull($key = null)
554 {
555 return $this->where($key, '!==', null);
556 }
557
558 /**
559 * Filter items by the given key value pair using strict comparison.
560 *
561 * @param string $key
562 * @param mixed $value
563 * @return static
564 */
565 public function whereStrict($key, $value)
566 {
567 return $this->where($key, '===', $value);
568 }
569
570 /**
571 * Filter items by the given key value pair.
572 *
573 * @param string $key
574 * @param mixed $values
575 * @param bool $strict
576 * @return static
577 */
578 public function whereIn($key, $values, $strict = false)
579 {
580 $values = $this->getArrayableItems($values);
581
582 return $this->filter(function ($item) use ($key, $values, $strict) {
583 return in_array(Helper::dataGet($item, $key), $values, $strict);
584 });
585 }
586
587 /**
588 * Filter items by the given key value pair using strict comparison.
589 *
590 * @param string $key
591 * @param mixed $values
592 * @return static
593 */
594 public function whereInStrict($key, $values)
595 {
596 return $this->whereIn($key, $values, true);
597 }
598
599 /**
600 * Filter items such that the value of the given key is between the given values.
601 *
602 * @param string $key
603 * @param array $values
604 * @return static
605 */
606 public function whereBetween($key, $values)
607 {
608 return $this->where($key, '>=', reset($values))->where($key, '<=', end($values));
609 }
610
611 /**
612 * Filter items such that the value of the given key is not between the given values.
613 *
614 * @param string $key
615 * @param array $values
616 * @return static
617 */
618 public function whereNotBetween($key, $values)
619 {
620 return $this->filter(function ($item) use ($key, $values) {
621 return Helper::dataGet($item, $key) < reset($values) || Helper::dataGet($item, $key) > end($values);
622 });
623 }
624
625 /**
626 * Filter items by the given key value pair.
627 *
628 * @param string $key
629 * @param mixed $values
630 * @param bool $strict
631 * @return static
632 */
633 public function whereNotIn($key, $values, $strict = false)
634 {
635 $values = $this->getArrayableItems($values);
636
637 return $this->reject(function ($item) use ($key, $values, $strict) {
638 return in_array(Helper::dataGet($item, $key), $values, $strict);
639 });
640 }
641
642 /**
643 * Filter items by the given key value pair using strict comparison.
644 *
645 * @param string $key
646 * @param mixed $values
647 * @return static
648 */
649 public function whereNotInStrict($key, $values)
650 {
651 return $this->whereNotIn($key, $values, true);
652 }
653
654 /**
655 * Filter the items, removing any items that don't match the given type(s).
656 *
657 * @param string|string[] $type
658 * @return static
659 */
660 public function whereInstanceOf($type)
661 {
662 return $this->filter(function ($value) use ($type) {
663 if (is_array($type)) {
664 foreach ($type as $classType) {
665 if ($value instanceof $classType) {
666 return true;
667 }
668 }
669
670 return false;
671 }
672
673 return $value instanceof $type;
674 });
675 }
676
677 /**
678 * Pass the collection to the given callback and return the result.
679 *
680 * @param callable $callback
681 * @return mixed
682 */
683 public function pipe(callable $callback)
684 {
685 return $callback($this);
686 }
687
688 /**
689 * Pass the collection into a new class.
690 *
691 * @param string $class
692 * @return mixed
693 */
694 public function pipeInto($class)
695 {
696 return new $class($this);
697 }
698
699 /**
700 * Pass the collection through a series of callable pipes and return the result.
701 *
702 * @param array<callable> $pipes
703 * @return mixed
704 */
705 public function pipeThrough($pipes)
706 {
707 return static::make($pipes)->reduce(
708 function ($carry, $pipe) {
709 return $pipe($carry);
710 },
711 $this,
712 );
713 }
714
715 /**
716 * Pass the collection to the given callback and then return it.
717 *
718 * @param callable $callback
719 * @return $this
720 */
721 public function tap(callable $callback)
722 {
723 $callback(clone $this);
724
725 return $this;
726 }
727
728 /**
729 * Reduce the collection to a single value.
730 *
731 * @param callable $callback
732 * @param mixed $initial
733 * @return mixed
734 */
735 public function reduce(callable $callback, $initial = null)
736 {
737 $result = $initial;
738
739 foreach ($this as $key => $value) {
740 $result = $callback($result, $value, $key);
741 }
742
743 return $result;
744 }
745
746 /**
747 * Reduce the collection to multiple aggregate values.
748 *
749 * @param callable $callback
750 * @param mixed ...$initial
751 * @return array
752 *
753 * @deprecated Use "reduceSpread" instead
754 *
755 * @throws \UnexpectedValueException
756 */
757 public function reduceMany(callable $callback, ...$initial)
758 {
759 return $this->reduceSpread($callback, ...$initial);
760 }
761
762 /**
763 * Reduce the collection to multiple aggregate values.
764 *
765 * @param callable $callback
766 * @param mixed ...$initial
767 * @return array
768 *
769 * @throws \UnexpectedValueException
770 */
771 public function reduceSpread(callable $callback, ...$initial)
772 {
773 $result = $initial;
774
775 foreach ($this as $key => $value) {
776 $result = call_user_func_array($callback, array_merge($result, [$value, $key]));
777
778 if (! is_array($result)) {
779 throw new UnexpectedValueException(sprintf(
780 "%s::reduceMany expects reducer to return an array, but got a '%s' instead.",
781 static::classBasename(static::class), gettype($result)
782 ));
783 }
784 }
785
786 return $result;
787 }
788
789 /**
790 * Reduce an associative collection to a single value.
791 *
792 * @param callable $callback
793 * @param mixed $initial
794 * @return mixed
795 */
796 public function reduceWithKeys(callable $callback, $initial = null)
797 {
798 return $this->reduce($callback, $initial);
799 }
800
801 /**
802 * Create a collection of all elements that do not pass a given truth test.
803 *
804 * @param callable|mixed $callback
805 * @return static
806 */
807 public function reject($callback = true)
808 {
809 $useAsCallable = $this->useAsCallable($callback);
810
811 return $this->filter(function ($value, $key) use ($callback, $useAsCallable) {
812 return $useAsCallable
813 ? ! $callback($value, $key)
814 : $value != $callback;
815 });
816 }
817
818 /**
819 * Return only unique items from the collection array using strict comparison.
820 *
821 * @param string|callable|null $key
822 * @return static
823 */
824 public function uniqueStrict($key = null)
825 {
826 return $this->unique($key, true);
827 }
828
829 /**
830 * Collect the values into a collection.
831 *
832 * @return \FluentCommunity\Framework\Support\Collection
833 */
834 public function collect()
835 {
836 return new Collection($this->all());
837 }
838
839 /**
840 * Get the collection of items as a plain array.
841 *
842 * @return array
843 */
844 public function toArray()
845 {
846 return $this->map(function ($value) {
847 return $value instanceof ArrayableInterface ? $value->toArray() : $value;
848 })->all();
849 }
850
851 /**
852 * Convert the object into something JSON serializable.
853 *
854 * @return array
855 */
856 #[\ReturnTypeWillChange]
857 public function jsonSerialize()
858 {
859 return array_map(function ($value) {
860 if ($value instanceof JsonSerializable) {
861 return $value->jsonSerialize();
862 } elseif ($value instanceof JsonableInterface) {
863 return json_decode($value->toJson(), true);
864 } elseif ($value instanceof ArrayableInterface) {
865 return $value->toArray();
866 }
867
868 return $value;
869 }, $this->all());
870 }
871
872 /**
873 * Get the collection of items as JSON.
874 *
875 * @param int $options
876 * @return string
877 */
878 public function toJson($options = 0)
879 {
880 return json_encode($this->jsonSerialize(), $options);
881 }
882
883 /**
884 * Get a CachingIterator instance.
885 *
886 * @param int $flags
887 * @return \CachingIterator
888 */
889 public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
890 {
891 return new CachingIterator($this->getIterator(), $flags);
892 }
893
894 /**
895 * Convert the collection to its string representation.
896 *
897 * @return string
898 */
899 public function __toString()
900 {
901 return $this->escapeWhenCastingToString
902 ? esc_html($this->toJson())
903 : $this->toJson();
904 }
905
906 /**
907 * Indicate that the model's string representation should be escaped when __toString is invoked.
908 *
909 * @param bool $escape
910 * @return $this
911 */
912 public function escapeWhenCastingToString($escape = true)
913 {
914 $this->escapeWhenCastingToString = $escape;
915
916 return $this;
917 }
918
919 /**
920 * Add a method to the list of proxied methods.
921 *
922 * @param string $method
923 * @return void
924 */
925 public static function proxy($method)
926 {
927 static::$proxies[] = $method;
928 }
929
930 /**
931 * Dynamically access collection proxies.
932 *
933 * @param string $key
934 * @return mixed
935 *
936 * @throws \Exception
937 */
938 public function __get($key)
939 {
940 if (! in_array($key, static::$proxies)) {
941 throw new Exception("Property [{$key}] does not exist on this collection instance.");
942 }
943
944 return new HigherOrderCollectionProxy($this, $key);
945 }
946
947 /**
948 * Results array of items from Collection or ArrayableInterface.
949 *
950 * @param mixed $items
951 * @return array
952 */
953 protected function getArrayableItems($items)
954 {
955 if (is_array($items)) {
956 return $items;
957 } elseif ($items instanceof Enumerable) {
958 return $items->all();
959 } elseif ($items instanceof ArrayableInterface) {
960 return $items->toArray();
961 } elseif ($items instanceof JsonableInterface) {
962 return json_decode($items->toJson(), true);
963 } elseif ($items instanceof JsonSerializable) {
964 return (array) $items->jsonSerialize();
965 } elseif ($items instanceof Traversable) {
966 return iterator_to_array($items);
967 } elseif (function_exists('enum_exists')) {
968 if ($items instanceof \UnitEnum) {
969 return [$items];
970 }
971 }
972
973 return (array) $items;
974 }
975
976 /**
977 * Get an operator checker callback.
978 *
979 * @param string $key
980 * @param string|null $operator
981 * @param mixed $value
982 * @return \Closure
983 */
984 protected function operatorForWhere($key, $operator = null, $value = null)
985 {
986 if (func_num_args() === 1) {
987 $value = true;
988
989 $operator = '=';
990 }
991
992 if (func_num_args() === 2) {
993 $value = $operator;
994
995 $operator = '=';
996 }
997
998 return function ($item) use ($key, $operator, $value) {
999 $retrieved = Helper::dataGet($item, $key);
1000
1001 $strings = array_filter([$retrieved, $value], function ($value) {
1002 return is_string($value) || (is_object($value) && method_exists($value, '__toString'));
1003 });
1004
1005 if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) {
1006 return in_array($operator, ['!=', '<>', '!==']);
1007 }
1008
1009 switch ($operator) {
1010 default:
1011 case '=':
1012 case '==': return $retrieved == $value;
1013 case '!=':
1014 case '<>': return $retrieved != $value;
1015 case '<': return $retrieved < $value;
1016 case '>': return $retrieved > $value;
1017 case '<=': return $retrieved <= $value;
1018 case '>=': return $retrieved >= $value;
1019 case '===': return $retrieved === $value;
1020 case '!==': return $retrieved !== $value;
1021 }
1022 };
1023 }
1024
1025 /**
1026 * Determine if the given value is callable, but not a string.
1027 *
1028 * @param mixed $value
1029 * @return bool
1030 */
1031 protected function useAsCallable($value)
1032 {
1033 return ! is_string($value) && is_callable($value);
1034 }
1035
1036 /**
1037 * Get a value retrieving callback.
1038 *
1039 * @param callable|string|null $value
1040 * @return callable
1041 */
1042 protected function valueRetriever($value)
1043 {
1044 if ($this->useAsCallable($value)) {
1045 return $value;
1046 }
1047
1048 return function ($item) use ($value) {
1049 return Helper::dataGet($item, $value);
1050 };
1051 }
1052
1053 /**
1054 * Make a function to check an item's equality.
1055 *
1056 * @param mixed $value
1057 * @return \Closure
1058 */
1059 protected function equality($value)
1060 {
1061 return function ($item) use ($value) {
1062 return $item === $value;
1063 };
1064 }
1065
1066 /**
1067 * Make a function using another function, by negating its result.
1068 *
1069 * @param \Closure $callback
1070 * @return \Closure
1071 */
1072 protected function negate(Closure $callback)
1073 {
1074 return function (...$params) use ($callback) {
1075 return ! $callback(...$params);
1076 };
1077 }
1078
1079 /**
1080 * Make a function that returns what's passed to it.
1081 *
1082 * @return \Closure
1083 */
1084 protected function identity()
1085 {
1086 return function ($value) {
1087 return $value;
1088 };
1089 }
1090 }
1091