PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
← All changes | includes/sdk/google/ramsey/collection/src/AbstractCollection.php +135 -104 1.2.71.4.1 View file →
@@ -9,33 +9,33 @@
9 9 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
10 10 * @license http://opensource.org/licenses/MIT MIT
11 11 */
12 12 declare (strict_types=1);
13 -namespace Dudlewebs\WPMCS\Ramsey\Collection;
13 +namespace Dudlewebs\WPMCS\GCP\Ramsey\Collection;
14 14
15 15 use Closure;
16 -use Dudlewebs\WPMCS\Ramsey\Collection\Exception\CollectionMismatchException;
17 -use Dudlewebs\WPMCS\Ramsey\Collection\Exception\InvalidArgumentException;
18 -use Dudlewebs\WPMCS\Ramsey\Collection\Exception\InvalidSortOrderException;
19 -use Dudlewebs\WPMCS\Ramsey\Collection\Exception\OutOfBoundsException;
20 -use Dudlewebs\WPMCS\Ramsey\Collection\Tool\TypeTrait;
21 -use Dudlewebs\WPMCS\Ramsey\Collection\Tool\ValueExtractorTrait;
22 -use Dudlewebs\WPMCS\Ramsey\Collection\Tool\ValueToStringTrait;
16 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Exception\CollectionMismatchException;
17 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Exception\InvalidArgumentException;
18 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Exception\InvalidPropertyOrMethod;
19 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Exception\NoSuchElementException;
20 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Exception\UnsupportedOperationException;
21 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Tool\TypeTrait;
22 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Tool\ValueExtractorTrait;
23 +use Dudlewebs\WPMCS\GCP\Ramsey\Collection\Tool\ValueToStringTrait;
23 24 use function array_filter;
25 +use function array_key_first;
26 +use function array_key_last;
24 27 use function array_map;
25 28 use function array_merge;
29 +use function array_reduce;
26 30 use function array_search;
27 31 use function array_udiff;
28 32 use function array_uintersect;
29 -use function current;
30 -use function end;
31 33 use function in_array;
32 34 use function is_int;
33 35 use function is_object;
34 -use function reset;
35 36 use function spl_object_id;
36 37 use function sprintf;
37 -use function unserialize;
38 38 use function usort;
39 39 /**
40 40 * This class provides a basic implementation of `CollectionInterface`, to
41 41 * minimize the effort required to implement this interface
@@ -49,26 +49,23 @@
49 49 use TypeTrait;
50 50 use ValueToStringTrait;
51 51 use ValueExtractorTrait;
52 52 /**
53 - * @inheritDoc
53 + * @throws InvalidArgumentException if $element is of the wrong type.
54 54 */
55 - public function add($element): bool
55 + public function add(mixed $element) : bool
56 56 {
57 57 $this[] = $element;
58 58 return \true;
59 59 }
60 - /**
61 - * @inheritDoc
62 - */
63 - public function contains($element, bool $strict = \true): bool
60 + public function contains(mixed $element, bool $strict = \true) : bool
64 61 {
65 62 return in_array($element, $this->data, $strict);
66 63 }
67 64 /**
68 - * @inheritDoc
65 + * @throws InvalidArgumentException if $element is of the wrong type.
69 66 */
70 - public function offsetSet($offset, $value): void
67 + public function offsetSet(mixed $offset, mixed $value) : void
71 68 {
72 69 if ($this->checkType($this->getType(), $value) === \false) {
73 70 throw new InvalidArgumentException('Value must be of type ' . $this->getType() . '; value is ' . $this->toolValueToString($value));
74 71 }
@@ -77,12 +74,9 @@
77 74 } else {
78 75 $this->data[$offset] = $value;
79 76 }
80 77 }
81 - /**
82 - * @inheritDoc
83 - */
84 - public function remove($element): bool
78 + public function remove(mixed $element) : bool
85 79 {
86 80 if (($position = array_search($element, $this->data, \true)) !== \false) {
87 81 unset($this[$position]);
88 82 return \true;
@@ -89,70 +83,73 @@
89 83 }
90 84 return \false;
91 85 }
92 86 /**
87 + * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
88 + * on the elements in this collection.
89 + * @throws UnsupportedOperationException if unable to call column() on this
90 + * collection.
91 + *
93 92 * @inheritDoc
94 93 */
95 - public function column(string $propertyOrMethod): array
94 + public function column(string $propertyOrMethod) : array
96 95 {
97 96 $temp = [];
98 97 foreach ($this->data as $item) {
99 - /** @var mixed $value */
100 - $value = $this->extractValue($item, $propertyOrMethod);
101 - /** @psalm-suppress MixedAssignment */
102 - $temp[] = $value;
98 + $temp[] = $this->extractValue($item, $propertyOrMethod);
103 99 }
104 100 return $temp;
105 101 }
106 102 /**
107 - * @inheritDoc
103 + * @return T
104 + *
105 + * @throws NoSuchElementException if this collection is empty.
108 106 */
109 - public function first()
107 + public function first() : mixed
110 108 {
111 - if ($this->isEmpty()) {
112 - throw new OutOfBoundsException('Can\'t determine first item. Collection is empty');
109 + $firstIndex = array_key_first($this->data);
110 + if ($firstIndex === null) {
111 + throw new NoSuchElementException('Can\'t determine first item. Collection is empty');
113 112 }
114 - reset($this->data);
115 - /** @var T $first */
116 - $first = current($this->data);
117 - return $first;
113 + return $this->data[$firstIndex];
118 114 }
119 115 /**
120 - * @inheritDoc
116 + * @return T
117 + *
118 + * @throws NoSuchElementException if this collection is empty.
121 119 */
122 - public function last()
120 + public function last() : mixed
123 121 {
124 - if ($this->isEmpty()) {
125 - throw new OutOfBoundsException('Can\'t determine last item. Collection is empty');
122 + $lastIndex = array_key_last($this->data);
123 + if ($lastIndex === null) {
124 + throw new NoSuchElementException('Can\'t determine last item. Collection is empty');
126 125 }
127 - /** @var T $item */
128 - $item = end($this->data);
129 - reset($this->data);
130 - return $item;
126 + return $this->data[$lastIndex];
131 127 }
132 - public function sort(string $propertyOrMethod, string $order = self::SORT_ASC): CollectionInterface
128 + /**
129 + * @return CollectionInterface<T>
130 + *
131 + * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
132 + * on the elements in this collection.
133 + * @throws UnsupportedOperationException if unable to call sort() on this
134 + * collection.
135 + */
136 + public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending) : CollectionInterface
133 137 {
134 - if (!in_array($order, [self::SORT_ASC, self::SORT_DESC], \true)) {
135 - throw new InvalidSortOrderException('Invalid sort order given: ' . $order);
136 - }
137 138 $collection = clone $this;
138 - usort(
139 - $collection->data,
140 - /**
141 - * @param T $a
142 - * @param T $b
143 - */
144 - function ($a, $b) use ($propertyOrMethod, $order): int {
145 - /** @var mixed $aValue */
146 - $aValue = $this->extractValue($a, $propertyOrMethod);
147 - /** @var mixed $bValue */
148 - $bValue = $this->extractValue($b, $propertyOrMethod);
149 - return ($aValue <=> $bValue) * ($order === self::SORT_DESC ? -1 : 1);
150 - }
151 - );
139 + usort($collection->data, function (mixed $a, mixed $b) use($propertyOrMethod, $order) : int {
140 + $aValue = $this->extractValue($a, $propertyOrMethod);
141 + $bValue = $this->extractValue($b, $propertyOrMethod);
142 + return ($aValue <=> $bValue) * ($order === Sort::Descending ? -1 : 1);
143 + });
152 144 return $collection;
153 145 }
154 - public function filter(callable $callback): CollectionInterface
146 + /**
147 + * @param callable(T): bool $callback A callable to use for filtering elements.
148 + *
149 + * @return CollectionInterface<T>
150 + */
151 + public function filter(callable $callback) : CollectionInterface
155 152 {
156 153 $collection = clone $this;
157 154 $collection->data = array_merge([], array_filter($collection->data, $callback));
158 155 return $collection;
@@ -157,43 +154,88 @@
157 154 $collection->data = array_merge([], array_filter($collection->data, $callback));
158 155 return $collection;
159 156 }
160 157 /**
161 - * {@inheritdoc}
158 + * @return CollectionInterface<T>
159 + *
160 + * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist
161 + * on the elements in this collection.
162 + * @throws UnsupportedOperationException if unable to call where() on this
163 + * collection.
162 164 */
163 - public function where(string $propertyOrMethod, $value): CollectionInterface
165 + public function where(?string $propertyOrMethod, mixed $value) : CollectionInterface
164 166 {
165 - return $this->filter(function ($item) use ($propertyOrMethod, $value) {
166 - /** @var mixed $accessorValue */
167 - $accessorValue = $this->extractValue($item, $propertyOrMethod);
168 - return $accessorValue === $value;
169 - });
167 + return $this->filter(fn(mixed $item): bool => $this->extractValue($item, $propertyOrMethod) === $value);
170 168 }
171 - public function map(callable $callback): CollectionInterface
169 + /**
170 + * @param callable(T): TCallbackReturn $callback A callable to apply to each
171 + * item of the collection.
172 + *
173 + * @return CollectionInterface<TCallbackReturn>
174 + *
175 + * @template TCallbackReturn
176 + */
177 + public function map(callable $callback) : CollectionInterface
172 178 {
173 179 return new Collection('mixed', array_map($callback, $this->data));
174 180 }
175 - public function diff(CollectionInterface $other): CollectionInterface
181 + /**
182 + * @param callable(TCarry, T): TCarry $callback A callable to apply to each
183 + * item of the collection to reduce it to a single value.
184 + * @param TCarry $initial This is the initial value provided to the callback.
185 + *
186 + * @return TCarry
187 + *
188 + * @template TCarry
189 + */
190 + public function reduce(callable $callback, mixed $initial) : mixed
176 191 {
192 + return array_reduce($this->data, $callback, $initial);
193 + }
194 + /**
195 + * @param CollectionInterface<T> $other The collection to check for divergent
196 + * items.
197 + *
198 + * @return CollectionInterface<T>
199 + *
200 + * @throws CollectionMismatchException if the compared collections are of
201 + * differing types.
202 + */
203 + public function diff(CollectionInterface $other) : CollectionInterface
204 + {
177 205 $this->compareCollectionTypes($other);
178 206 $diffAtoB = array_udiff($this->data, $other->toArray(), $this->getComparator());
179 207 $diffBtoA = array_udiff($other->toArray(), $this->data, $this->getComparator());
180 - /** @var array<array-key, T> $diff */
181 - $diff = array_merge($diffAtoB, $diffBtoA);
182 208 $collection = clone $this;
183 - $collection->data = $diff;
209 + $collection->data = array_merge($diffAtoB, $diffBtoA);
184 210 return $collection;
185 211 }
186 - public function intersect(CollectionInterface $other): CollectionInterface
212 + /**
213 + * @param CollectionInterface<T> $other The collection to check for
214 + * intersecting items.
215 + *
216 + * @return CollectionInterface<T>
217 + *
218 + * @throws CollectionMismatchException if the compared collections are of
219 + * differing types.
220 + */
221 + public function intersect(CollectionInterface $other) : CollectionInterface
187 222 {
188 223 $this->compareCollectionTypes($other);
189 - /** @var array<array-key, T> $intersect */
190 - $intersect = array_uintersect($this->data, $other->toArray(), $this->getComparator());
191 224 $collection = clone $this;
192 - $collection->data = $intersect;
225 + $collection->data = array_uintersect($this->data, $other->toArray(), $this->getComparator());
193 226 return $collection;
194 227 }
195 - public function merge(CollectionInterface ...$collections): CollectionInterface
228 + /**
229 + * @param CollectionInterface<T> ...$collections The collections to merge.
230 + *
231 + * @return CollectionInterface<T>
232 + *
233 + * @throws CollectionMismatchException if unable to merge any of the given
234 + * collections or items within the given collections due to type
235 + * mismatch errors.
236 + */
237 + public function merge(CollectionInterface ...$collections) : CollectionInterface
196 238 {
197 239 $mergedCollection = clone $this;
198 240 foreach ($collections as $index => $collection) {
199 241 if (!$collection instanceof static) {
@@ -214,20 +256,13 @@
214 256 }
215 257 return $mergedCollection;
216 258 }
217 259 /**
218 - * @inheritDoc
219 - */
220 - public function unserialize($serialized): void
221 - {
222 - /** @var array<array-key, T> $data */
223 - $data = unserialize($serialized, ['allowed_classes' => [$this->getType()]]);
224 - $this->data = $data;
225 - }
226 - /**
227 260 * @param CollectionInterface<T> $other
261 + *
262 + * @throws CollectionMismatchException
228 263 */
229 - private function compareCollectionTypes(CollectionInterface $other): void
264 + private function compareCollectionTypes(CollectionInterface $other) : void
230 265 {
231 266 if (!$other instanceof static) {
232 267 throw new CollectionMismatchException('Collection must be of type ' . static::class);
233 268 }
@@ -236,11 +271,11 @@
236 271 if ($this->getUniformType($other) !== $this->getUniformType($this)) {
237 272 throw new CollectionMismatchException('Collection items must be of type ' . $this->getType());
238 273 }
239 274 }
240 - private function getComparator(): Closure
275 + private function getComparator() : Closure
241 276 {
242 - return function ($a, $b): int {
277 + return function (mixed $a, mixed $b) : int {
243 278 // If the two values are object, we convert them to unique scalars.
244 279 // If the collection contains mixed values (unlikely) where some are objects
245 280 // and some are not, we leave them as they are.
246 281 // The comparator should still work and the result of $a < $b should
@@ -254,18 +289,14 @@
254 289 }
255 290 /**
256 291 * @param CollectionInterface<mixed> $collection
257 292 */
258 - private function getUniformType(CollectionInterface $collection): string
293 + private function getUniformType(CollectionInterface $collection) : string
259 294 {
260 - switch ($collection->getType()) {
261 - case 'integer':
262 - return 'int';
263 - case 'boolean':
264 - return 'bool';
265 - case 'double':
266 - return 'float';
267 - default:
268 - return $collection->getType();
269 - }
295 + return match ($collection->getType()) {
296 + 'integer' => 'int',
297 + 'boolean' => 'bool',
298 + 'double' => 'float',
299 + default => $collection->getType(),
300 + };
270 301 }
271 302 }