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