diff options
author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
---|---|---|
committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/doctrine/collections/src | |
parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/doctrine/collections/src')
-rw-r--r-- | vendor/doctrine/collections/src/AbstractLazyCollection.php | 414 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/ArrayCollection.php | 490 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Collection.php | 117 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Criteria.php | 285 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php | 222 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/Comparison.php | 62 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/CompositeExpression.php | 70 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/Expression.php | 14 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/ExpressionVisitor.php | 52 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Expr/Value.php | 26 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/ExpressionBuilder.php | 123 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Order.php | 11 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/ReadableCollection.php | 242 | ||||
-rw-r--r-- | vendor/doctrine/collections/src/Selectable.php | 32 |
14 files changed, 2160 insertions, 0 deletions
diff --git a/vendor/doctrine/collections/src/AbstractLazyCollection.php b/vendor/doctrine/collections/src/AbstractLazyCollection.php new file mode 100644 index 0000000..56a340b --- /dev/null +++ b/vendor/doctrine/collections/src/AbstractLazyCollection.php | |||
@@ -0,0 +1,414 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use Closure; | ||
8 | use LogicException; | ||
9 | use ReturnTypeWillChange; | ||
10 | use Traversable; | ||
11 | |||
12 | /** | ||
13 | * Lazy collection that is backed by a concrete collection | ||
14 | * | ||
15 | * @psalm-template TKey of array-key | ||
16 | * @psalm-template T | ||
17 | * @template-implements Collection<TKey,T> | ||
18 | */ | ||
19 | abstract class AbstractLazyCollection implements Collection | ||
20 | { | ||
21 | /** | ||
22 | * The backed collection to use | ||
23 | * | ||
24 | * @psalm-var Collection<TKey,T>|null | ||
25 | * @var Collection<mixed>|null | ||
26 | */ | ||
27 | protected Collection|null $collection; | ||
28 | |||
29 | protected bool $initialized = false; | ||
30 | |||
31 | /** | ||
32 | * {@inheritDoc} | ||
33 | * | ||
34 | * @return int | ||
35 | */ | ||
36 | #[ReturnTypeWillChange] | ||
37 | public function count() | ||
38 | { | ||
39 | $this->initialize(); | ||
40 | |||
41 | return $this->collection->count(); | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * {@inheritDoc} | ||
46 | */ | ||
47 | public function add(mixed $element) | ||
48 | { | ||
49 | $this->initialize(); | ||
50 | |||
51 | $this->collection->add($element); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * {@inheritDoc} | ||
56 | */ | ||
57 | public function clear() | ||
58 | { | ||
59 | $this->initialize(); | ||
60 | $this->collection->clear(); | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * {@inheritDoc} | ||
65 | */ | ||
66 | public function contains(mixed $element) | ||
67 | { | ||
68 | $this->initialize(); | ||
69 | |||
70 | return $this->collection->contains($element); | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * {@inheritDoc} | ||
75 | */ | ||
76 | public function isEmpty() | ||
77 | { | ||
78 | $this->initialize(); | ||
79 | |||
80 | return $this->collection->isEmpty(); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * {@inheritDoc} | ||
85 | */ | ||
86 | public function remove(string|int $key) | ||
87 | { | ||
88 | $this->initialize(); | ||
89 | |||
90 | return $this->collection->remove($key); | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * {@inheritDoc} | ||
95 | */ | ||
96 | public function removeElement(mixed $element) | ||
97 | { | ||
98 | $this->initialize(); | ||
99 | |||
100 | return $this->collection->removeElement($element); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * {@inheritDoc} | ||
105 | */ | ||
106 | public function containsKey(string|int $key) | ||
107 | { | ||
108 | $this->initialize(); | ||
109 | |||
110 | return $this->collection->containsKey($key); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * {@inheritDoc} | ||
115 | */ | ||
116 | public function get(string|int $key) | ||
117 | { | ||
118 | $this->initialize(); | ||
119 | |||
120 | return $this->collection->get($key); | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * {@inheritDoc} | ||
125 | */ | ||
126 | public function getKeys() | ||
127 | { | ||
128 | $this->initialize(); | ||
129 | |||
130 | return $this->collection->getKeys(); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * {@inheritDoc} | ||
135 | */ | ||
136 | public function getValues() | ||
137 | { | ||
138 | $this->initialize(); | ||
139 | |||
140 | return $this->collection->getValues(); | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * {@inheritDoc} | ||
145 | */ | ||
146 | public function set(string|int $key, mixed $value) | ||
147 | { | ||
148 | $this->initialize(); | ||
149 | $this->collection->set($key, $value); | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * {@inheritDoc} | ||
154 | */ | ||
155 | public function toArray() | ||
156 | { | ||
157 | $this->initialize(); | ||
158 | |||
159 | return $this->collection->toArray(); | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * {@inheritDoc} | ||
164 | */ | ||
165 | public function first() | ||
166 | { | ||
167 | $this->initialize(); | ||
168 | |||
169 | return $this->collection->first(); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * {@inheritDoc} | ||
174 | */ | ||
175 | public function last() | ||
176 | { | ||
177 | $this->initialize(); | ||
178 | |||
179 | return $this->collection->last(); | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * {@inheritDoc} | ||
184 | */ | ||
185 | public function key() | ||
186 | { | ||
187 | $this->initialize(); | ||
188 | |||
189 | return $this->collection->key(); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * {@inheritDoc} | ||
194 | */ | ||
195 | public function current() | ||
196 | { | ||
197 | $this->initialize(); | ||
198 | |||
199 | return $this->collection->current(); | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * {@inheritDoc} | ||
204 | */ | ||
205 | public function next() | ||
206 | { | ||
207 | $this->initialize(); | ||
208 | |||
209 | return $this->collection->next(); | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * {@inheritDoc} | ||
214 | */ | ||
215 | public function exists(Closure $p) | ||
216 | { | ||
217 | $this->initialize(); | ||
218 | |||
219 | return $this->collection->exists($p); | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * {@inheritDoc} | ||
224 | */ | ||
225 | public function findFirst(Closure $p) | ||
226 | { | ||
227 | $this->initialize(); | ||
228 | |||
229 | return $this->collection->findFirst($p); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * {@inheritDoc} | ||
234 | */ | ||
235 | public function filter(Closure $p) | ||
236 | { | ||
237 | $this->initialize(); | ||
238 | |||
239 | return $this->collection->filter($p); | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * {@inheritDoc} | ||
244 | */ | ||
245 | public function forAll(Closure $p) | ||
246 | { | ||
247 | $this->initialize(); | ||
248 | |||
249 | return $this->collection->forAll($p); | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * {@inheritDoc} | ||
254 | */ | ||
255 | public function map(Closure $func) | ||
256 | { | ||
257 | $this->initialize(); | ||
258 | |||
259 | return $this->collection->map($func); | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * {@inheritDoc} | ||
264 | */ | ||
265 | public function reduce(Closure $func, mixed $initial = null) | ||
266 | { | ||
267 | $this->initialize(); | ||
268 | |||
269 | return $this->collection->reduce($func, $initial); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * {@inheritDoc} | ||
274 | */ | ||
275 | public function partition(Closure $p) | ||
276 | { | ||
277 | $this->initialize(); | ||
278 | |||
279 | return $this->collection->partition($p); | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * {@inheritDoc} | ||
284 | * | ||
285 | * @template TMaybeContained | ||
286 | */ | ||
287 | public function indexOf(mixed $element) | ||
288 | { | ||
289 | $this->initialize(); | ||
290 | |||
291 | return $this->collection->indexOf($element); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * {@inheritDoc} | ||
296 | */ | ||
297 | public function slice(int $offset, int|null $length = null) | ||
298 | { | ||
299 | $this->initialize(); | ||
300 | |||
301 | return $this->collection->slice($offset, $length); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * {@inheritDoc} | ||
306 | * | ||
307 | * @return Traversable<int|string, mixed> | ||
308 | * @psalm-return Traversable<TKey,T> | ||
309 | */ | ||
310 | #[ReturnTypeWillChange] | ||
311 | public function getIterator() | ||
312 | { | ||
313 | $this->initialize(); | ||
314 | |||
315 | return $this->collection->getIterator(); | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * {@inheritDoc} | ||
320 | * | ||
321 | * @param TKey $offset | ||
322 | * | ||
323 | * @return bool | ||
324 | */ | ||
325 | #[ReturnTypeWillChange] | ||
326 | public function offsetExists(mixed $offset) | ||
327 | { | ||
328 | $this->initialize(); | ||
329 | |||
330 | return $this->collection->offsetExists($offset); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * {@inheritDoc} | ||
335 | * | ||
336 | * @param TKey $offset | ||
337 | * | ||
338 | * @return T|null | ||
339 | */ | ||
340 | #[ReturnTypeWillChange] | ||
341 | public function offsetGet(mixed $offset) | ||
342 | { | ||
343 | $this->initialize(); | ||
344 | |||
345 | return $this->collection->offsetGet($offset); | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * {@inheritDoc} | ||
350 | * | ||
351 | * @param TKey|null $offset | ||
352 | * @param T $value | ||
353 | * | ||
354 | * @return void | ||
355 | */ | ||
356 | #[ReturnTypeWillChange] | ||
357 | public function offsetSet(mixed $offset, mixed $value) | ||
358 | { | ||
359 | $this->initialize(); | ||
360 | $this->collection->offsetSet($offset, $value); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * @param TKey $offset | ||
365 | * | ||
366 | * @return void | ||
367 | */ | ||
368 | #[ReturnTypeWillChange] | ||
369 | public function offsetUnset(mixed $offset) | ||
370 | { | ||
371 | $this->initialize(); | ||
372 | $this->collection->offsetUnset($offset); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Is the lazy collection already initialized? | ||
377 | * | ||
378 | * @return bool | ||
379 | * | ||
380 | * @psalm-assert-if-true Collection<TKey,T> $this->collection | ||
381 | */ | ||
382 | public function isInitialized() | ||
383 | { | ||
384 | return $this->initialized; | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * Initialize the collection | ||
389 | * | ||
390 | * @return void | ||
391 | * | ||
392 | * @psalm-assert Collection<TKey,T> $this->collection | ||
393 | */ | ||
394 | protected function initialize() | ||
395 | { | ||
396 | if ($this->initialized) { | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | $this->doInitialize(); | ||
401 | $this->initialized = true; | ||
402 | |||
403 | if ($this->collection === null) { | ||
404 | throw new LogicException('You must initialize the collection property in the doInitialize() method.'); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * Do the initialization logic | ||
410 | * | ||
411 | * @return void | ||
412 | */ | ||
413 | abstract protected function doInitialize(); | ||
414 | } | ||
diff --git a/vendor/doctrine/collections/src/ArrayCollection.php b/vendor/doctrine/collections/src/ArrayCollection.php new file mode 100644 index 0000000..2e7d0e3 --- /dev/null +++ b/vendor/doctrine/collections/src/ArrayCollection.php | |||
@@ -0,0 +1,490 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use ArrayIterator; | ||
8 | use Closure; | ||
9 | use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; | ||
10 | use ReturnTypeWillChange; | ||
11 | use Stringable; | ||
12 | use Traversable; | ||
13 | |||
14 | use function array_filter; | ||
15 | use function array_key_exists; | ||
16 | use function array_keys; | ||
17 | use function array_map; | ||
18 | use function array_reduce; | ||
19 | use function array_reverse; | ||
20 | use function array_search; | ||
21 | use function array_slice; | ||
22 | use function array_values; | ||
23 | use function count; | ||
24 | use function current; | ||
25 | use function end; | ||
26 | use function in_array; | ||
27 | use function key; | ||
28 | use function next; | ||
29 | use function reset; | ||
30 | use function spl_object_hash; | ||
31 | use function uasort; | ||
32 | |||
33 | use const ARRAY_FILTER_USE_BOTH; | ||
34 | |||
35 | /** | ||
36 | * An ArrayCollection is a Collection implementation that wraps a regular PHP array. | ||
37 | * | ||
38 | * Warning: Using (un-)serialize() on a collection is not a supported use-case | ||
39 | * and may break when we change the internals in the future. If you need to | ||
40 | * serialize a collection use {@link toArray()} and reconstruct the collection | ||
41 | * manually. | ||
42 | * | ||
43 | * @psalm-template TKey of array-key | ||
44 | * @psalm-template T | ||
45 | * @template-implements Collection<TKey,T> | ||
46 | * @template-implements Selectable<TKey,T> | ||
47 | * @psalm-consistent-constructor | ||
48 | */ | ||
49 | class ArrayCollection implements Collection, Selectable, Stringable | ||
50 | { | ||
51 | /** | ||
52 | * An array containing the entries of this collection. | ||
53 | * | ||
54 | * @psalm-var array<TKey,T> | ||
55 | * @var mixed[] | ||
56 | */ | ||
57 | private array $elements = []; | ||
58 | |||
59 | /** | ||
60 | * Initializes a new ArrayCollection. | ||
61 | * | ||
62 | * @psalm-param array<TKey,T> $elements | ||
63 | */ | ||
64 | public function __construct(array $elements = []) | ||
65 | { | ||
66 | $this->elements = $elements; | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * {@inheritDoc} | ||
71 | */ | ||
72 | public function toArray() | ||
73 | { | ||
74 | return $this->elements; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * {@inheritDoc} | ||
79 | */ | ||
80 | public function first() | ||
81 | { | ||
82 | return reset($this->elements); | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Creates a new instance from the specified elements. | ||
87 | * | ||
88 | * This method is provided for derived classes to specify how a new | ||
89 | * instance should be created when constructor semantics have changed. | ||
90 | * | ||
91 | * @param array $elements Elements. | ||
92 | * @psalm-param array<K,V> $elements | ||
93 | * | ||
94 | * @return static | ||
95 | * @psalm-return static<K,V> | ||
96 | * | ||
97 | * @psalm-template K of array-key | ||
98 | * @psalm-template V | ||
99 | */ | ||
100 | protected function createFrom(array $elements) | ||
101 | { | ||
102 | return new static($elements); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * {@inheritDoc} | ||
107 | */ | ||
108 | public function last() | ||
109 | { | ||
110 | return end($this->elements); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * {@inheritDoc} | ||
115 | */ | ||
116 | public function key() | ||
117 | { | ||
118 | return key($this->elements); | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * {@inheritDoc} | ||
123 | */ | ||
124 | public function next() | ||
125 | { | ||
126 | return next($this->elements); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * {@inheritDoc} | ||
131 | */ | ||
132 | public function current() | ||
133 | { | ||
134 | return current($this->elements); | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * {@inheritDoc} | ||
139 | */ | ||
140 | public function remove(string|int $key) | ||
141 | { | ||
142 | if (! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) { | ||
143 | return null; | ||
144 | } | ||
145 | |||
146 | $removed = $this->elements[$key]; | ||
147 | unset($this->elements[$key]); | ||
148 | |||
149 | return $removed; | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * {@inheritDoc} | ||
154 | */ | ||
155 | public function removeElement(mixed $element) | ||
156 | { | ||
157 | $key = array_search($element, $this->elements, true); | ||
158 | |||
159 | if ($key === false) { | ||
160 | return false; | ||
161 | } | ||
162 | |||
163 | unset($this->elements[$key]); | ||
164 | |||
165 | return true; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * Required by interface ArrayAccess. | ||
170 | * | ||
171 | * @param TKey $offset | ||
172 | * | ||
173 | * @return bool | ||
174 | */ | ||
175 | #[ReturnTypeWillChange] | ||
176 | public function offsetExists(mixed $offset) | ||
177 | { | ||
178 | return $this->containsKey($offset); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * Required by interface ArrayAccess. | ||
183 | * | ||
184 | * @param TKey $offset | ||
185 | * | ||
186 | * @return T|null | ||
187 | */ | ||
188 | #[ReturnTypeWillChange] | ||
189 | public function offsetGet(mixed $offset) | ||
190 | { | ||
191 | return $this->get($offset); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * Required by interface ArrayAccess. | ||
196 | * | ||
197 | * @param TKey|null $offset | ||
198 | * @param T $value | ||
199 | * | ||
200 | * @return void | ||
201 | */ | ||
202 | #[ReturnTypeWillChange] | ||
203 | public function offsetSet(mixed $offset, mixed $value) | ||
204 | { | ||
205 | if ($offset === null) { | ||
206 | $this->add($value); | ||
207 | |||
208 | return; | ||
209 | } | ||
210 | |||
211 | $this->set($offset, $value); | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * Required by interface ArrayAccess. | ||
216 | * | ||
217 | * @param TKey $offset | ||
218 | * | ||
219 | * @return void | ||
220 | */ | ||
221 | #[ReturnTypeWillChange] | ||
222 | public function offsetUnset(mixed $offset) | ||
223 | { | ||
224 | $this->remove($offset); | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * {@inheritDoc} | ||
229 | */ | ||
230 | public function containsKey(string|int $key) | ||
231 | { | ||
232 | return isset($this->elements[$key]) || array_key_exists($key, $this->elements); | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * {@inheritDoc} | ||
237 | */ | ||
238 | public function contains(mixed $element) | ||
239 | { | ||
240 | return in_array($element, $this->elements, true); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * {@inheritDoc} | ||
245 | */ | ||
246 | public function exists(Closure $p) | ||
247 | { | ||
248 | foreach ($this->elements as $key => $element) { | ||
249 | if ($p($key, $element)) { | ||
250 | return true; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | return false; | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * {@inheritDoc} | ||
259 | * | ||
260 | * @psalm-param TMaybeContained $element | ||
261 | * | ||
262 | * @return int|string|false | ||
263 | * @psalm-return (TMaybeContained is T ? TKey|false : false) | ||
264 | * | ||
265 | * @template TMaybeContained | ||
266 | */ | ||
267 | public function indexOf($element) | ||
268 | { | ||
269 | return array_search($element, $this->elements, true); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * {@inheritDoc} | ||
274 | */ | ||
275 | public function get(string|int $key) | ||
276 | { | ||
277 | return $this->elements[$key] ?? null; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * {@inheritDoc} | ||
282 | */ | ||
283 | public function getKeys() | ||
284 | { | ||
285 | return array_keys($this->elements); | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * {@inheritDoc} | ||
290 | */ | ||
291 | public function getValues() | ||
292 | { | ||
293 | return array_values($this->elements); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * {@inheritDoc} | ||
298 | * | ||
299 | * @return int<0, max> | ||
300 | */ | ||
301 | #[ReturnTypeWillChange] | ||
302 | public function count() | ||
303 | { | ||
304 | return count($this->elements); | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * {@inheritDoc} | ||
309 | */ | ||
310 | public function set(string|int $key, mixed $value) | ||
311 | { | ||
312 | $this->elements[$key] = $value; | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * {@inheritDoc} | ||
317 | * | ||
318 | * @psalm-suppress InvalidPropertyAssignmentValue | ||
319 | * | ||
320 | * This breaks assumptions about the template type, but it would | ||
321 | * be a backwards-incompatible change to remove this method | ||
322 | */ | ||
323 | public function add(mixed $element) | ||
324 | { | ||
325 | $this->elements[] = $element; | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * {@inheritDoc} | ||
330 | */ | ||
331 | public function isEmpty() | ||
332 | { | ||
333 | return empty($this->elements); | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * {@inheritDoc} | ||
338 | * | ||
339 | * @return Traversable<int|string, mixed> | ||
340 | * @psalm-return Traversable<TKey, T> | ||
341 | */ | ||
342 | #[ReturnTypeWillChange] | ||
343 | public function getIterator() | ||
344 | { | ||
345 | return new ArrayIterator($this->elements); | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * {@inheritDoc} | ||
350 | * | ||
351 | * @psalm-param Closure(T):U $func | ||
352 | * | ||
353 | * @return static | ||
354 | * @psalm-return static<TKey, U> | ||
355 | * | ||
356 | * @psalm-template U | ||
357 | */ | ||
358 | public function map(Closure $func) | ||
359 | { | ||
360 | return $this->createFrom(array_map($func, $this->elements)); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * {@inheritDoc} | ||
365 | */ | ||
366 | public function reduce(Closure $func, $initial = null) | ||
367 | { | ||
368 | return array_reduce($this->elements, $func, $initial); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * {@inheritDoc} | ||
373 | * | ||
374 | * @psalm-param Closure(T, TKey):bool $p | ||
375 | * | ||
376 | * @return static | ||
377 | * @psalm-return static<TKey,T> | ||
378 | */ | ||
379 | public function filter(Closure $p) | ||
380 | { | ||
381 | return $this->createFrom(array_filter($this->elements, $p, ARRAY_FILTER_USE_BOTH)); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * {@inheritDoc} | ||
386 | */ | ||
387 | public function findFirst(Closure $p) | ||
388 | { | ||
389 | foreach ($this->elements as $key => $element) { | ||
390 | if ($p($key, $element)) { | ||
391 | return $element; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | return null; | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * {@inheritDoc} | ||
400 | */ | ||
401 | public function forAll(Closure $p) | ||
402 | { | ||
403 | foreach ($this->elements as $key => $element) { | ||
404 | if (! $p($key, $element)) { | ||
405 | return false; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | return true; | ||
410 | } | ||
411 | |||
412 | /** | ||
413 | * {@inheritDoc} | ||
414 | */ | ||
415 | public function partition(Closure $p) | ||
416 | { | ||
417 | $matches = $noMatches = []; | ||
418 | |||
419 | foreach ($this->elements as $key => $element) { | ||
420 | if ($p($key, $element)) { | ||
421 | $matches[$key] = $element; | ||
422 | } else { | ||
423 | $noMatches[$key] = $element; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | return [$this->createFrom($matches), $this->createFrom($noMatches)]; | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * Returns a string representation of this object. | ||
432 | * {@inheritDoc} | ||
433 | * | ||
434 | * @return string | ||
435 | */ | ||
436 | #[ReturnTypeWillChange] | ||
437 | public function __toString() | ||
438 | { | ||
439 | return self::class . '@' . spl_object_hash($this); | ||
440 | } | ||
441 | |||
442 | /** | ||
443 | * {@inheritDoc} | ||
444 | */ | ||
445 | public function clear() | ||
446 | { | ||
447 | $this->elements = []; | ||
448 | } | ||
449 | |||
450 | /** | ||
451 | * {@inheritDoc} | ||
452 | */ | ||
453 | public function slice(int $offset, int|null $length = null) | ||
454 | { | ||
455 | return array_slice($this->elements, $offset, $length, true); | ||
456 | } | ||
457 | |||
458 | /** @psalm-return Collection<TKey, T>&Selectable<TKey,T> */ | ||
459 | public function matching(Criteria $criteria) | ||
460 | { | ||
461 | $expr = $criteria->getWhereExpression(); | ||
462 | $filtered = $this->elements; | ||
463 | |||
464 | if ($expr) { | ||
465 | $visitor = new ClosureExpressionVisitor(); | ||
466 | $filter = $visitor->dispatch($expr); | ||
467 | $filtered = array_filter($filtered, $filter); | ||
468 | } | ||
469 | |||
470 | $orderings = $criteria->orderings(); | ||
471 | |||
472 | if ($orderings) { | ||
473 | $next = null; | ||
474 | foreach (array_reverse($orderings) as $field => $ordering) { | ||
475 | $next = ClosureExpressionVisitor::sortByField($field, $ordering === Order::Descending ? -1 : 1, $next); | ||
476 | } | ||
477 | |||
478 | uasort($filtered, $next); | ||
479 | } | ||
480 | |||
481 | $offset = $criteria->getFirstResult(); | ||
482 | $length = $criteria->getMaxResults(); | ||
483 | |||
484 | if ($offset !== null && $offset > 0 || $length !== null && $length > 0) { | ||
485 | $filtered = array_slice($filtered, (int) $offset, $length, true); | ||
486 | } | ||
487 | |||
488 | return $this->createFrom($filtered); | ||
489 | } | ||
490 | } | ||
diff --git a/vendor/doctrine/collections/src/Collection.php b/vendor/doctrine/collections/src/Collection.php new file mode 100644 index 0000000..c3c62aa --- /dev/null +++ b/vendor/doctrine/collections/src/Collection.php | |||
@@ -0,0 +1,117 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use ArrayAccess; | ||
8 | use Closure; | ||
9 | |||
10 | /** | ||
11 | * The missing (SPL) Collection/Array/OrderedMap interface. | ||
12 | * | ||
13 | * A Collection resembles the nature of a regular PHP array. That is, | ||
14 | * it is essentially an <b>ordered map</b> that can also be used | ||
15 | * like a list. | ||
16 | * | ||
17 | * A Collection has an internal iterator just like a PHP array. In addition, | ||
18 | * a Collection can be iterated with external iterators, which is preferable. | ||
19 | * To use an external iterator simply use the foreach language construct to | ||
20 | * iterate over the collection (which calls {@link getIterator()} internally) or | ||
21 | * explicitly retrieve an iterator though {@link getIterator()} which can then be | ||
22 | * used to iterate over the collection. | ||
23 | * You can not rely on the internal iterator of the collection being at a certain | ||
24 | * position unless you explicitly positioned it before. Prefer iteration with | ||
25 | * external iterators. | ||
26 | * | ||
27 | * @psalm-template TKey of array-key | ||
28 | * @psalm-template T | ||
29 | * @template-extends ReadableCollection<TKey, T> | ||
30 | * @template-extends ArrayAccess<TKey, T> | ||
31 | */ | ||
32 | interface Collection extends ReadableCollection, ArrayAccess | ||
33 | { | ||
34 | /** | ||
35 | * Adds an element at the end of the collection. | ||
36 | * | ||
37 | * @param mixed $element The element to add. | ||
38 | * @psalm-param T $element | ||
39 | * | ||
40 | * @return void we will require a native return type declaration in 3.0 | ||
41 | */ | ||
42 | public function add(mixed $element); | ||
43 | |||
44 | /** | ||
45 | * Clears the collection, removing all elements. | ||
46 | * | ||
47 | * @return void | ||
48 | */ | ||
49 | public function clear(); | ||
50 | |||
51 | /** | ||
52 | * Removes the element at the specified index from the collection. | ||
53 | * | ||
54 | * @param string|int $key The key/index of the element to remove. | ||
55 | * @psalm-param TKey $key | ||
56 | * | ||
57 | * @return mixed The removed element or NULL, if the collection did not contain the element. | ||
58 | * @psalm-return T|null | ||
59 | */ | ||
60 | public function remove(string|int $key); | ||
61 | |||
62 | /** | ||
63 | * Removes the specified element from the collection, if it is found. | ||
64 | * | ||
65 | * @param mixed $element The element to remove. | ||
66 | * @psalm-param T $element | ||
67 | * | ||
68 | * @return bool TRUE if this collection contained the specified element, FALSE otherwise. | ||
69 | */ | ||
70 | public function removeElement(mixed $element); | ||
71 | |||
72 | /** | ||
73 | * Sets an element in the collection at the specified key/index. | ||
74 | * | ||
75 | * @param string|int $key The key/index of the element to set. | ||
76 | * @param mixed $value The element to set. | ||
77 | * @psalm-param TKey $key | ||
78 | * @psalm-param T $value | ||
79 | * | ||
80 | * @return void | ||
81 | */ | ||
82 | public function set(string|int $key, mixed $value); | ||
83 | |||
84 | /** | ||
85 | * {@inheritDoc} | ||
86 | * | ||
87 | * @psalm-param Closure(T):U $func | ||
88 | * | ||
89 | * @return Collection<mixed> | ||
90 | * @psalm-return Collection<TKey, U> | ||
91 | * | ||
92 | * @psalm-template U | ||
93 | */ | ||
94 | public function map(Closure $func); | ||
95 | |||
96 | /** | ||
97 | * {@inheritDoc} | ||
98 | * | ||
99 | * @psalm-param Closure(T, TKey):bool $p | ||
100 | * | ||
101 | * @return Collection<mixed> A collection with the results of the filter operation. | ||
102 | * @psalm-return Collection<TKey, T> | ||
103 | */ | ||
104 | public function filter(Closure $p); | ||
105 | |||
106 | /** | ||
107 | * {@inheritDoc} | ||
108 | * | ||
109 | * @psalm-param Closure(TKey, T):bool $p | ||
110 | * | ||
111 | * @return Collection<mixed>[] An array with two elements. The first element contains the collection | ||
112 | * of elements where the predicate returned TRUE, the second element | ||
113 | * contains the collection of elements where the predicate returned FALSE. | ||
114 | * @psalm-return array{0: Collection<TKey, T>, 1: Collection<TKey, T>} | ||
115 | */ | ||
116 | public function partition(Closure $p); | ||
117 | } | ||
diff --git a/vendor/doctrine/collections/src/Criteria.php b/vendor/doctrine/collections/src/Criteria.php new file mode 100644 index 0000000..4c8a0a7 --- /dev/null +++ b/vendor/doctrine/collections/src/Criteria.php | |||
@@ -0,0 +1,285 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use Doctrine\Common\Collections\Expr\CompositeExpression; | ||
8 | use Doctrine\Common\Collections\Expr\Expression; | ||
9 | use Doctrine\Deprecations\Deprecation; | ||
10 | |||
11 | use function array_map; | ||
12 | use function func_num_args; | ||
13 | use function strtoupper; | ||
14 | |||
15 | /** | ||
16 | * Criteria for filtering Selectable collections. | ||
17 | * | ||
18 | * @psalm-consistent-constructor | ||
19 | */ | ||
20 | class Criteria | ||
21 | { | ||
22 | /** @deprecated use Order::Ascending instead */ | ||
23 | final public const ASC = 'ASC'; | ||
24 | |||
25 | /** @deprecated use Order::Descending instead */ | ||
26 | final public const DESC = 'DESC'; | ||
27 | |||
28 | private static ExpressionBuilder|null $expressionBuilder = null; | ||
29 | |||
30 | /** @var array<string, Order> */ | ||
31 | private array $orderings = []; | ||
32 | |||
33 | private int|null $firstResult = null; | ||
34 | private int|null $maxResults = null; | ||
35 | |||
36 | /** | ||
37 | * Creates an instance of the class. | ||
38 | * | ||
39 | * @return static | ||
40 | */ | ||
41 | public static function create() | ||
42 | { | ||
43 | return new static(); | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * Returns the expression builder. | ||
48 | * | ||
49 | * @return ExpressionBuilder | ||
50 | */ | ||
51 | public static function expr() | ||
52 | { | ||
53 | if (self::$expressionBuilder === null) { | ||
54 | self::$expressionBuilder = new ExpressionBuilder(); | ||
55 | } | ||
56 | |||
57 | return self::$expressionBuilder; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Construct a new Criteria. | ||
62 | * | ||
63 | * @param array<string, string|Order>|null $orderings | ||
64 | */ | ||
65 | public function __construct( | ||
66 | private Expression|null $expression = null, | ||
67 | array|null $orderings = null, | ||
68 | int|null $firstResult = null, | ||
69 | int|null $maxResults = null, | ||
70 | ) { | ||
71 | $this->expression = $expression; | ||
72 | |||
73 | if ($firstResult === null && func_num_args() > 2) { | ||
74 | Deprecation::trigger( | ||
75 | 'doctrine/collections', | ||
76 | 'https://github.com/doctrine/collections/pull/311', | ||
77 | 'Passing null as $firstResult to the constructor of %s is deprecated. Pass 0 instead or omit the argument.', | ||
78 | self::class, | ||
79 | ); | ||
80 | } | ||
81 | |||
82 | $this->setFirstResult($firstResult); | ||
83 | $this->setMaxResults($maxResults); | ||
84 | |||
85 | if ($orderings === null) { | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | $this->orderBy($orderings); | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * Sets the where expression to evaluate when this Criteria is searched for. | ||
94 | * | ||
95 | * @return $this | ||
96 | */ | ||
97 | public function where(Expression $expression) | ||
98 | { | ||
99 | $this->expression = $expression; | ||
100 | |||
101 | return $this; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Appends the where expression to evaluate when this Criteria is searched for | ||
106 | * using an AND with previous expression. | ||
107 | * | ||
108 | * @return $this | ||
109 | */ | ||
110 | public function andWhere(Expression $expression) | ||
111 | { | ||
112 | if ($this->expression === null) { | ||
113 | return $this->where($expression); | ||
114 | } | ||
115 | |||
116 | $this->expression = new CompositeExpression( | ||
117 | CompositeExpression::TYPE_AND, | ||
118 | [$this->expression, $expression], | ||
119 | ); | ||
120 | |||
121 | return $this; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * Appends the where expression to evaluate when this Criteria is searched for | ||
126 | * using an OR with previous expression. | ||
127 | * | ||
128 | * @return $this | ||
129 | */ | ||
130 | public function orWhere(Expression $expression) | ||
131 | { | ||
132 | if ($this->expression === null) { | ||
133 | return $this->where($expression); | ||
134 | } | ||
135 | |||
136 | $this->expression = new CompositeExpression( | ||
137 | CompositeExpression::TYPE_OR, | ||
138 | [$this->expression, $expression], | ||
139 | ); | ||
140 | |||
141 | return $this; | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * Gets the expression attached to this Criteria. | ||
146 | * | ||
147 | * @return Expression|null | ||
148 | */ | ||
149 | public function getWhereExpression() | ||
150 | { | ||
151 | return $this->expression; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * Gets the current orderings of this Criteria. | ||
156 | * | ||
157 | * @deprecated use orderings() instead | ||
158 | * | ||
159 | * @return array<string, string> | ||
160 | */ | ||
161 | public function getOrderings() | ||
162 | { | ||
163 | Deprecation::trigger( | ||
164 | 'doctrine/collections', | ||
165 | 'https://github.com/doctrine/collections/pull/389', | ||
166 | 'Calling %s() is deprecated. Use %s::orderings() instead.', | ||
167 | __METHOD__, | ||
168 | self::class, | ||
169 | ); | ||
170 | |||
171 | return array_map( | ||
172 | static fn (Order $ordering): string => $ordering->value, | ||
173 | $this->orderings, | ||
174 | ); | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * Gets the current orderings of this Criteria. | ||
179 | * | ||
180 | * @return array<string, Order> | ||
181 | */ | ||
182 | public function orderings(): array | ||
183 | { | ||
184 | return $this->orderings; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Sets the ordering of the result of this Criteria. | ||
189 | * | ||
190 | * Keys are field and values are the order, being a valid Order enum case. | ||
191 | * | ||
192 | * @see Order::Ascending | ||
193 | * @see Order::Descending | ||
194 | * | ||
195 | * @param array<string, string|Order> $orderings | ||
196 | * | ||
197 | * @return $this | ||
198 | */ | ||
199 | public function orderBy(array $orderings) | ||
200 | { | ||
201 | $method = __METHOD__; | ||
202 | $this->orderings = array_map( | ||
203 | static function (string|Order $ordering) use ($method): Order { | ||
204 | if ($ordering instanceof Order) { | ||
205 | return $ordering; | ||
206 | } | ||
207 | |||
208 | static $triggered = false; | ||
209 | |||
210 | if (! $triggered) { | ||
211 | Deprecation::trigger( | ||
212 | 'doctrine/collections', | ||
213 | 'https://github.com/doctrine/collections/pull/389', | ||
214 | 'Passing non-Order enum values to %s() is deprecated. Pass Order enum values instead.', | ||
215 | $method, | ||
216 | ); | ||
217 | } | ||
218 | |||
219 | $triggered = true; | ||
220 | |||
221 | return strtoupper($ordering) === Order::Ascending->value ? Order::Ascending : Order::Descending; | ||
222 | }, | ||
223 | $orderings, | ||
224 | ); | ||
225 | |||
226 | return $this; | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * Gets the current first result option of this Criteria. | ||
231 | * | ||
232 | * @return int|null | ||
233 | */ | ||
234 | public function getFirstResult() | ||
235 | { | ||
236 | return $this->firstResult; | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * Set the number of first result that this Criteria should return. | ||
241 | * | ||
242 | * @param int|null $firstResult The value to set. | ||
243 | * | ||
244 | * @return $this | ||
245 | */ | ||
246 | public function setFirstResult(int|null $firstResult) | ||
247 | { | ||
248 | if ($firstResult === null) { | ||
249 | Deprecation::triggerIfCalledFromOutside( | ||
250 | 'doctrine/collections', | ||
251 | 'https://github.com/doctrine/collections/pull/311', | ||
252 | 'Passing null to %s() is deprecated, pass 0 instead.', | ||
253 | __METHOD__, | ||
254 | ); | ||
255 | } | ||
256 | |||
257 | $this->firstResult = $firstResult; | ||
258 | |||
259 | return $this; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * Gets maxResults. | ||
264 | * | ||
265 | * @return int|null | ||
266 | */ | ||
267 | public function getMaxResults() | ||
268 | { | ||
269 | return $this->maxResults; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Sets maxResults. | ||
274 | * | ||
275 | * @param int|null $maxResults The value to set. | ||
276 | * | ||
277 | * @return $this | ||
278 | */ | ||
279 | public function setMaxResults(int|null $maxResults) | ||
280 | { | ||
281 | $this->maxResults = $maxResults; | ||
282 | |||
283 | return $this; | ||
284 | } | ||
285 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php b/vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php new file mode 100644 index 0000000..4319b9b --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php | |||
@@ -0,0 +1,222 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | use ArrayAccess; | ||
8 | use Closure; | ||
9 | use RuntimeException; | ||
10 | |||
11 | use function explode; | ||
12 | use function in_array; | ||
13 | use function is_array; | ||
14 | use function is_scalar; | ||
15 | use function iterator_to_array; | ||
16 | use function method_exists; | ||
17 | use function preg_match; | ||
18 | use function preg_replace_callback; | ||
19 | use function str_contains; | ||
20 | use function str_ends_with; | ||
21 | use function str_starts_with; | ||
22 | use function strtoupper; | ||
23 | |||
24 | /** | ||
25 | * Walks an expression graph and turns it into a PHP closure. | ||
26 | * | ||
27 | * This closure can be used with {@Collection#filter()} and is used internally | ||
28 | * by {@ArrayCollection#select()}. | ||
29 | */ | ||
30 | class ClosureExpressionVisitor extends ExpressionVisitor | ||
31 | { | ||
32 | /** | ||
33 | * Accesses the field of a given object. This field has to be public | ||
34 | * directly or indirectly (through an accessor get*, is*, or a magic | ||
35 | * method, __get, __call). | ||
36 | * | ||
37 | * @param object|mixed[] $object | ||
38 | * | ||
39 | * @return mixed | ||
40 | */ | ||
41 | public static function getObjectFieldValue(object|array $object, string $field) | ||
42 | { | ||
43 | if (str_contains($field, '.')) { | ||
44 | [$field, $subField] = explode('.', $field, 2); | ||
45 | $object = self::getObjectFieldValue($object, $field); | ||
46 | |||
47 | return self::getObjectFieldValue($object, $subField); | ||
48 | } | ||
49 | |||
50 | if (is_array($object)) { | ||
51 | return $object[$field]; | ||
52 | } | ||
53 | |||
54 | $accessors = ['get', 'is', '']; | ||
55 | |||
56 | foreach ($accessors as $accessor) { | ||
57 | $accessor .= $field; | ||
58 | |||
59 | if (method_exists($object, $accessor)) { | ||
60 | return $object->$accessor(); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | if (preg_match('/^is[A-Z]+/', $field) === 1 && method_exists($object, $field)) { | ||
65 | return $object->$field(); | ||
66 | } | ||
67 | |||
68 | // __call should be triggered for get. | ||
69 | $accessor = $accessors[0] . $field; | ||
70 | |||
71 | if (method_exists($object, '__call')) { | ||
72 | return $object->$accessor(); | ||
73 | } | ||
74 | |||
75 | if ($object instanceof ArrayAccess) { | ||
76 | return $object[$field]; | ||
77 | } | ||
78 | |||
79 | if (isset($object->$field)) { | ||
80 | return $object->$field; | ||
81 | } | ||
82 | |||
83 | // camelcase field name to support different variable naming conventions | ||
84 | $ccField = preg_replace_callback('/_(.?)/', static fn ($matches) => strtoupper((string) $matches[1]), $field); | ||
85 | |||
86 | foreach ($accessors as $accessor) { | ||
87 | $accessor .= $ccField; | ||
88 | |||
89 | if (method_exists($object, $accessor)) { | ||
90 | return $object->$accessor(); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return $object->$field; | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * Helper for sorting arrays of objects based on multiple fields + orientations. | ||
99 | * | ||
100 | * @return Closure | ||
101 | */ | ||
102 | public static function sortByField(string $name, int $orientation = 1, Closure|null $next = null) | ||
103 | { | ||
104 | if (! $next) { | ||
105 | $next = static fn (): int => 0; | ||
106 | } | ||
107 | |||
108 | return static function ($a, $b) use ($name, $next, $orientation): int { | ||
109 | $aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name); | ||
110 | |||
111 | $bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name); | ||
112 | |||
113 | if ($aValue === $bValue) { | ||
114 | return $next($a, $b); | ||
115 | } | ||
116 | |||
117 | return ($aValue > $bValue ? 1 : -1) * $orientation; | ||
118 | }; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * {@inheritDoc} | ||
123 | */ | ||
124 | public function walkComparison(Comparison $comparison) | ||
125 | { | ||
126 | $field = $comparison->getField(); | ||
127 | $value = $comparison->getValue()->getValue(); | ||
128 | |||
129 | return match ($comparison->getOperator()) { | ||
130 | Comparison::EQ => static fn ($object): bool => self::getObjectFieldValue($object, $field) === $value, | ||
131 | Comparison::NEQ => static fn ($object): bool => self::getObjectFieldValue($object, $field) !== $value, | ||
132 | Comparison::LT => static fn ($object): bool => self::getObjectFieldValue($object, $field) < $value, | ||
133 | Comparison::LTE => static fn ($object): bool => self::getObjectFieldValue($object, $field) <= $value, | ||
134 | Comparison::GT => static fn ($object): bool => self::getObjectFieldValue($object, $field) > $value, | ||
135 | Comparison::GTE => static fn ($object): bool => self::getObjectFieldValue($object, $field) >= $value, | ||
136 | Comparison::IN => static function ($object) use ($field, $value): bool { | ||
137 | $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); | ||
138 | |||
139 | return in_array($fieldValue, $value, is_scalar($fieldValue)); | ||
140 | }, | ||
141 | Comparison::NIN => static function ($object) use ($field, $value): bool { | ||
142 | $fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field); | ||
143 | |||
144 | return ! in_array($fieldValue, $value, is_scalar($fieldValue)); | ||
145 | }, | ||
146 | Comparison::CONTAINS => static fn ($object): bool => str_contains((string) self::getObjectFieldValue($object, $field), (string) $value), | ||
147 | Comparison::MEMBER_OF => static function ($object) use ($field, $value): bool { | ||
148 | $fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field); | ||
149 | |||
150 | if (! is_array($fieldValues)) { | ||
151 | $fieldValues = iterator_to_array($fieldValues); | ||
152 | } | ||
153 | |||
154 | return in_array($value, $fieldValues, true); | ||
155 | }, | ||
156 | Comparison::STARTS_WITH => static fn ($object): bool => str_starts_with((string) self::getObjectFieldValue($object, $field), (string) $value), | ||
157 | Comparison::ENDS_WITH => static fn ($object): bool => str_ends_with((string) self::getObjectFieldValue($object, $field), (string) $value), | ||
158 | default => throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()), | ||
159 | }; | ||
160 | } | ||
161 | |||
162 | /** | ||
163 | * {@inheritDoc} | ||
164 | */ | ||
165 | public function walkValue(Value $value) | ||
166 | { | ||
167 | return $value->getValue(); | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * {@inheritDoc} | ||
172 | */ | ||
173 | public function walkCompositeExpression(CompositeExpression $expr) | ||
174 | { | ||
175 | $expressionList = []; | ||
176 | |||
177 | foreach ($expr->getExpressionList() as $child) { | ||
178 | $expressionList[] = $this->dispatch($child); | ||
179 | } | ||
180 | |||
181 | return match ($expr->getType()) { | ||
182 | CompositeExpression::TYPE_AND => $this->andExpressions($expressionList), | ||
183 | CompositeExpression::TYPE_OR => $this->orExpressions($expressionList), | ||
184 | CompositeExpression::TYPE_NOT => $this->notExpression($expressionList), | ||
185 | default => throw new RuntimeException('Unknown composite ' . $expr->getType()), | ||
186 | }; | ||
187 | } | ||
188 | |||
189 | /** @param callable[] $expressions */ | ||
190 | private function andExpressions(array $expressions): Closure | ||
191 | { | ||
192 | return static function ($object) use ($expressions): bool { | ||
193 | foreach ($expressions as $expression) { | ||
194 | if (! $expression($object)) { | ||
195 | return false; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return true; | ||
200 | }; | ||
201 | } | ||
202 | |||
203 | /** @param callable[] $expressions */ | ||
204 | private function orExpressions(array $expressions): Closure | ||
205 | { | ||
206 | return static function ($object) use ($expressions): bool { | ||
207 | foreach ($expressions as $expression) { | ||
208 | if ($expression($object)) { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return false; | ||
214 | }; | ||
215 | } | ||
216 | |||
217 | /** @param callable[] $expressions */ | ||
218 | private function notExpression(array $expressions): Closure | ||
219 | { | ||
220 | return static fn ($object) => ! $expressions[0]($object); | ||
221 | } | ||
222 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/Comparison.php b/vendor/doctrine/collections/src/Expr/Comparison.php new file mode 100644 index 0000000..f1ea07f --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/Comparison.php | |||
@@ -0,0 +1,62 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | /** | ||
8 | * Comparison of a field with a value by the given operator. | ||
9 | */ | ||
10 | class Comparison implements Expression | ||
11 | { | ||
12 | final public const EQ = '='; | ||
13 | final public const NEQ = '<>'; | ||
14 | final public const LT = '<'; | ||
15 | final public const LTE = '<='; | ||
16 | final public const GT = '>'; | ||
17 | final public const GTE = '>='; | ||
18 | final public const IS = '='; // no difference with EQ | ||
19 | final public const IN = 'IN'; | ||
20 | final public const NIN = 'NIN'; | ||
21 | final public const CONTAINS = 'CONTAINS'; | ||
22 | final public const MEMBER_OF = 'MEMBER_OF'; | ||
23 | final public const STARTS_WITH = 'STARTS_WITH'; | ||
24 | final public const ENDS_WITH = 'ENDS_WITH'; | ||
25 | |||
26 | private readonly Value $value; | ||
27 | |||
28 | public function __construct(private readonly string $field, private readonly string $op, mixed $value) | ||
29 | { | ||
30 | if (! ($value instanceof Value)) { | ||
31 | $value = new Value($value); | ||
32 | } | ||
33 | |||
34 | $this->value = $value; | ||
35 | } | ||
36 | |||
37 | /** @return string */ | ||
38 | public function getField() | ||
39 | { | ||
40 | return $this->field; | ||
41 | } | ||
42 | |||
43 | /** @return Value */ | ||
44 | public function getValue() | ||
45 | { | ||
46 | return $this->value; | ||
47 | } | ||
48 | |||
49 | /** @return string */ | ||
50 | public function getOperator() | ||
51 | { | ||
52 | return $this->op; | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * {@inheritDoc} | ||
57 | */ | ||
58 | public function visit(ExpressionVisitor $visitor) | ||
59 | { | ||
60 | return $visitor->walkComparison($this); | ||
61 | } | ||
62 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/CompositeExpression.php b/vendor/doctrine/collections/src/Expr/CompositeExpression.php new file mode 100644 index 0000000..b7b4544 --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/CompositeExpression.php | |||
@@ -0,0 +1,70 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | use RuntimeException; | ||
8 | |||
9 | use function count; | ||
10 | |||
11 | /** | ||
12 | * Expression of Expressions combined by AND or OR operation. | ||
13 | */ | ||
14 | class CompositeExpression implements Expression | ||
15 | { | ||
16 | final public const TYPE_AND = 'AND'; | ||
17 | final public const TYPE_OR = 'OR'; | ||
18 | final public const TYPE_NOT = 'NOT'; | ||
19 | |||
20 | /** @var list<Expression> */ | ||
21 | private array $expressions = []; | ||
22 | |||
23 | /** | ||
24 | * @param Expression[] $expressions | ||
25 | * | ||
26 | * @throws RuntimeException | ||
27 | */ | ||
28 | public function __construct(private readonly string $type, array $expressions) | ||
29 | { | ||
30 | foreach ($expressions as $expr) { | ||
31 | if ($expr instanceof Value) { | ||
32 | throw new RuntimeException('Values are not supported expressions as children of and/or expressions.'); | ||
33 | } | ||
34 | |||
35 | if (! ($expr instanceof Expression)) { | ||
36 | throw new RuntimeException('No expression given to CompositeExpression.'); | ||
37 | } | ||
38 | |||
39 | $this->expressions[] = $expr; | ||
40 | } | ||
41 | |||
42 | if ($type === self::TYPE_NOT && count($this->expressions) !== 1) { | ||
43 | throw new RuntimeException('Not expression only allows one expression as child.'); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Returns the list of expressions nested in this composite. | ||
49 | * | ||
50 | * @return list<Expression> | ||
51 | */ | ||
52 | public function getExpressionList() | ||
53 | { | ||
54 | return $this->expressions; | ||
55 | } | ||
56 | |||
57 | /** @return string */ | ||
58 | public function getType() | ||
59 | { | ||
60 | return $this->type; | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * {@inheritDoc} | ||
65 | */ | ||
66 | public function visit(ExpressionVisitor $visitor) | ||
67 | { | ||
68 | return $visitor->walkCompositeExpression($this); | ||
69 | } | ||
70 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/Expression.php b/vendor/doctrine/collections/src/Expr/Expression.php new file mode 100644 index 0000000..70ad45f --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/Expression.php | |||
@@ -0,0 +1,14 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | /** | ||
8 | * Expression for the {@link Selectable} interface. | ||
9 | */ | ||
10 | interface Expression | ||
11 | { | ||
12 | /** @return mixed */ | ||
13 | public function visit(ExpressionVisitor $visitor); | ||
14 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php b/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php new file mode 100644 index 0000000..afbd3d1 --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/ExpressionVisitor.php | |||
@@ -0,0 +1,52 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | use RuntimeException; | ||
8 | |||
9 | /** | ||
10 | * An Expression visitor walks a graph of expressions and turns them into a | ||
11 | * query for the underlying implementation. | ||
12 | */ | ||
13 | abstract class ExpressionVisitor | ||
14 | { | ||
15 | /** | ||
16 | * Converts a comparison expression into the target query language output. | ||
17 | * | ||
18 | * @return mixed | ||
19 | */ | ||
20 | abstract public function walkComparison(Comparison $comparison); | ||
21 | |||
22 | /** | ||
23 | * Converts a value expression into the target query language part. | ||
24 | * | ||
25 | * @return mixed | ||
26 | */ | ||
27 | abstract public function walkValue(Value $value); | ||
28 | |||
29 | /** | ||
30 | * Converts a composite expression into the target query language output. | ||
31 | * | ||
32 | * @return mixed | ||
33 | */ | ||
34 | abstract public function walkCompositeExpression(CompositeExpression $expr); | ||
35 | |||
36 | /** | ||
37 | * Dispatches walking an expression to the appropriate handler. | ||
38 | * | ||
39 | * @return mixed | ||
40 | * | ||
41 | * @throws RuntimeException | ||
42 | */ | ||
43 | public function dispatch(Expression $expr) | ||
44 | { | ||
45 | return match (true) { | ||
46 | $expr instanceof Comparison => $this->walkComparison($expr), | ||
47 | $expr instanceof Value => $this->walkValue($expr), | ||
48 | $expr instanceof CompositeExpression => $this->walkCompositeExpression($expr), | ||
49 | default => throw new RuntimeException('Unknown Expression ' . $expr::class), | ||
50 | }; | ||
51 | } | ||
52 | } | ||
diff --git a/vendor/doctrine/collections/src/Expr/Value.php b/vendor/doctrine/collections/src/Expr/Value.php new file mode 100644 index 0000000..776770d --- /dev/null +++ b/vendor/doctrine/collections/src/Expr/Value.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections\Expr; | ||
6 | |||
7 | class Value implements Expression | ||
8 | { | ||
9 | public function __construct(private readonly mixed $value) | ||
10 | { | ||
11 | } | ||
12 | |||
13 | /** @return mixed */ | ||
14 | public function getValue() | ||
15 | { | ||
16 | return $this->value; | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * {@inheritDoc} | ||
21 | */ | ||
22 | public function visit(ExpressionVisitor $visitor) | ||
23 | { | ||
24 | return $visitor->walkValue($this); | ||
25 | } | ||
26 | } | ||
diff --git a/vendor/doctrine/collections/src/ExpressionBuilder.php b/vendor/doctrine/collections/src/ExpressionBuilder.php new file mode 100644 index 0000000..fc25e3a --- /dev/null +++ b/vendor/doctrine/collections/src/ExpressionBuilder.php | |||
@@ -0,0 +1,123 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use Doctrine\Common\Collections\Expr\Comparison; | ||
8 | use Doctrine\Common\Collections\Expr\CompositeExpression; | ||
9 | use Doctrine\Common\Collections\Expr\Expression; | ||
10 | use Doctrine\Common\Collections\Expr\Value; | ||
11 | |||
12 | /** | ||
13 | * Builder for Expressions in the {@link Selectable} interface. | ||
14 | * | ||
15 | * Important Notice for interoperable code: You have to use scalar | ||
16 | * values only for comparisons, otherwise the behavior of the comparison | ||
17 | * may be different between implementations (Array vs ORM vs ODM). | ||
18 | */ | ||
19 | class ExpressionBuilder | ||
20 | { | ||
21 | /** @return CompositeExpression */ | ||
22 | public function andX(Expression ...$expressions) | ||
23 | { | ||
24 | return new CompositeExpression(CompositeExpression::TYPE_AND, $expressions); | ||
25 | } | ||
26 | |||
27 | /** @return CompositeExpression */ | ||
28 | public function orX(Expression ...$expressions) | ||
29 | { | ||
30 | return new CompositeExpression(CompositeExpression::TYPE_OR, $expressions); | ||
31 | } | ||
32 | |||
33 | public function not(Expression $expression): CompositeExpression | ||
34 | { | ||
35 | return new CompositeExpression(CompositeExpression::TYPE_NOT, [$expression]); | ||
36 | } | ||
37 | |||
38 | /** @return Comparison */ | ||
39 | public function eq(string $field, mixed $value) | ||
40 | { | ||
41 | return new Comparison($field, Comparison::EQ, new Value($value)); | ||
42 | } | ||
43 | |||
44 | /** @return Comparison */ | ||
45 | public function gt(string $field, mixed $value) | ||
46 | { | ||
47 | return new Comparison($field, Comparison::GT, new Value($value)); | ||
48 | } | ||
49 | |||
50 | /** @return Comparison */ | ||
51 | public function lt(string $field, mixed $value) | ||
52 | { | ||
53 | return new Comparison($field, Comparison::LT, new Value($value)); | ||
54 | } | ||
55 | |||
56 | /** @return Comparison */ | ||
57 | public function gte(string $field, mixed $value) | ||
58 | { | ||
59 | return new Comparison($field, Comparison::GTE, new Value($value)); | ||
60 | } | ||
61 | |||
62 | /** @return Comparison */ | ||
63 | public function lte(string $field, mixed $value) | ||
64 | { | ||
65 | return new Comparison($field, Comparison::LTE, new Value($value)); | ||
66 | } | ||
67 | |||
68 | /** @return Comparison */ | ||
69 | public function neq(string $field, mixed $value) | ||
70 | { | ||
71 | return new Comparison($field, Comparison::NEQ, new Value($value)); | ||
72 | } | ||
73 | |||
74 | /** @return Comparison */ | ||
75 | public function isNull(string $field) | ||
76 | { | ||
77 | return new Comparison($field, Comparison::EQ, new Value(null)); | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * @param mixed[] $values | ||
82 | * | ||
83 | * @return Comparison | ||
84 | */ | ||
85 | public function in(string $field, array $values) | ||
86 | { | ||
87 | return new Comparison($field, Comparison::IN, new Value($values)); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * @param mixed[] $values | ||
92 | * | ||
93 | * @return Comparison | ||
94 | */ | ||
95 | public function notIn(string $field, array $values) | ||
96 | { | ||
97 | return new Comparison($field, Comparison::NIN, new Value($values)); | ||
98 | } | ||
99 | |||
100 | /** @return Comparison */ | ||
101 | public function contains(string $field, mixed $value) | ||
102 | { | ||
103 | return new Comparison($field, Comparison::CONTAINS, new Value($value)); | ||
104 | } | ||
105 | |||
106 | /** @return Comparison */ | ||
107 | public function memberOf(string $field, mixed $value) | ||
108 | { | ||
109 | return new Comparison($field, Comparison::MEMBER_OF, new Value($value)); | ||
110 | } | ||
111 | |||
112 | /** @return Comparison */ | ||
113 | public function startsWith(string $field, mixed $value) | ||
114 | { | ||
115 | return new Comparison($field, Comparison::STARTS_WITH, new Value($value)); | ||
116 | } | ||
117 | |||
118 | /** @return Comparison */ | ||
119 | public function endsWith(string $field, mixed $value) | ||
120 | { | ||
121 | return new Comparison($field, Comparison::ENDS_WITH, new Value($value)); | ||
122 | } | ||
123 | } | ||
diff --git a/vendor/doctrine/collections/src/Order.php b/vendor/doctrine/collections/src/Order.php new file mode 100644 index 0000000..4741bba --- /dev/null +++ b/vendor/doctrine/collections/src/Order.php | |||
@@ -0,0 +1,11 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | enum Order: string | ||
8 | { | ||
9 | case Ascending = 'ASC'; | ||
10 | case Descending = 'DESC'; | ||
11 | } | ||
diff --git a/vendor/doctrine/collections/src/ReadableCollection.php b/vendor/doctrine/collections/src/ReadableCollection.php new file mode 100644 index 0000000..a8dbd43 --- /dev/null +++ b/vendor/doctrine/collections/src/ReadableCollection.php | |||
@@ -0,0 +1,242 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | use Closure; | ||
8 | use Countable; | ||
9 | use IteratorAggregate; | ||
10 | |||
11 | /** | ||
12 | * @psalm-template TKey of array-key | ||
13 | * @template-covariant T | ||
14 | * @template-extends IteratorAggregate<TKey, T> | ||
15 | */ | ||
16 | interface ReadableCollection extends Countable, IteratorAggregate | ||
17 | { | ||
18 | /** | ||
19 | * Checks whether an element is contained in the collection. | ||
20 | * This is an O(n) operation, where n is the size of the collection. | ||
21 | * | ||
22 | * @param mixed $element The element to search for. | ||
23 | * @psalm-param TMaybeContained $element | ||
24 | * | ||
25 | * @return bool TRUE if the collection contains the element, FALSE otherwise. | ||
26 | * @psalm-return (TMaybeContained is T ? bool : false) | ||
27 | * | ||
28 | * @template TMaybeContained | ||
29 | */ | ||
30 | public function contains(mixed $element); | ||
31 | |||
32 | /** | ||
33 | * Checks whether the collection is empty (contains no elements). | ||
34 | * | ||
35 | * @return bool TRUE if the collection is empty, FALSE otherwise. | ||
36 | */ | ||
37 | public function isEmpty(); | ||
38 | |||
39 | /** | ||
40 | * Checks whether the collection contains an element with the specified key/index. | ||
41 | * | ||
42 | * @param string|int $key The key/index to check for. | ||
43 | * @psalm-param TKey $key | ||
44 | * | ||
45 | * @return bool TRUE if the collection contains an element with the specified key/index, | ||
46 | * FALSE otherwise. | ||
47 | */ | ||
48 | public function containsKey(string|int $key); | ||
49 | |||
50 | /** | ||
51 | * Gets the element at the specified key/index. | ||
52 | * | ||
53 | * @param string|int $key The key/index of the element to retrieve. | ||
54 | * @psalm-param TKey $key | ||
55 | * | ||
56 | * @return mixed | ||
57 | * @psalm-return T|null | ||
58 | */ | ||
59 | public function get(string|int $key); | ||
60 | |||
61 | /** | ||
62 | * Gets all keys/indices of the collection. | ||
63 | * | ||
64 | * @return int[]|string[] The keys/indices of the collection, in the order of the corresponding | ||
65 | * elements in the collection. | ||
66 | * @psalm-return list<TKey> | ||
67 | */ | ||
68 | public function getKeys(); | ||
69 | |||
70 | /** | ||
71 | * Gets all values of the collection. | ||
72 | * | ||
73 | * @return mixed[] The values of all elements in the collection, in the | ||
74 | * order they appear in the collection. | ||
75 | * @psalm-return list<T> | ||
76 | */ | ||
77 | public function getValues(); | ||
78 | |||
79 | /** | ||
80 | * Gets a native PHP array representation of the collection. | ||
81 | * | ||
82 | * @return mixed[] | ||
83 | * @psalm-return array<TKey,T> | ||
84 | */ | ||
85 | public function toArray(); | ||
86 | |||
87 | /** | ||
88 | * Sets the internal iterator to the first element in the collection and returns this element. | ||
89 | * | ||
90 | * @return mixed | ||
91 | * @psalm-return T|false | ||
92 | */ | ||
93 | public function first(); | ||
94 | |||
95 | /** | ||
96 | * Sets the internal iterator to the last element in the collection and returns this element. | ||
97 | * | ||
98 | * @return mixed | ||
99 | * @psalm-return T|false | ||
100 | */ | ||
101 | public function last(); | ||
102 | |||
103 | /** | ||
104 | * Gets the key/index of the element at the current iterator position. | ||
105 | * | ||
106 | * @return int|string|null | ||
107 | * @psalm-return TKey|null | ||
108 | */ | ||
109 | public function key(); | ||
110 | |||
111 | /** | ||
112 | * Gets the element of the collection at the current iterator position. | ||
113 | * | ||
114 | * @return mixed | ||
115 | * @psalm-return T|false | ||
116 | */ | ||
117 | public function current(); | ||
118 | |||
119 | /** | ||
120 | * Moves the internal iterator position to the next element and returns this element. | ||
121 | * | ||
122 | * @return mixed | ||
123 | * @psalm-return T|false | ||
124 | */ | ||
125 | public function next(); | ||
126 | |||
127 | /** | ||
128 | * Extracts a slice of $length elements starting at position $offset from the Collection. | ||
129 | * | ||
130 | * If $length is null it returns all elements from $offset to the end of the Collection. | ||
131 | * Keys have to be preserved by this method. Calling this method will only return the | ||
132 | * selected slice and NOT change the elements contained in the collection slice is called on. | ||
133 | * | ||
134 | * @param int $offset The offset to start from. | ||
135 | * @param int|null $length The maximum number of elements to return, or null for no limit. | ||
136 | * | ||
137 | * @return mixed[] | ||
138 | * @psalm-return array<TKey,T> | ||
139 | */ | ||
140 | public function slice(int $offset, int|null $length = null); | ||
141 | |||
142 | /** | ||
143 | * Tests for the existence of an element that satisfies the given predicate. | ||
144 | * | ||
145 | * @param Closure $p The predicate. | ||
146 | * @psalm-param Closure(TKey, T):bool $p | ||
147 | * | ||
148 | * @return bool TRUE if the predicate is TRUE for at least one element, FALSE otherwise. | ||
149 | */ | ||
150 | public function exists(Closure $p); | ||
151 | |||
152 | /** | ||
153 | * Returns all the elements of this collection that satisfy the predicate p. | ||
154 | * The order of the elements is preserved. | ||
155 | * | ||
156 | * @param Closure $p The predicate used for filtering. | ||
157 | * @psalm-param Closure(T, TKey):bool $p | ||
158 | * | ||
159 | * @return ReadableCollection<mixed> A collection with the results of the filter operation. | ||
160 | * @psalm-return ReadableCollection<TKey, T> | ||
161 | */ | ||
162 | public function filter(Closure $p); | ||
163 | |||
164 | /** | ||
165 | * Applies the given function to each element in the collection and returns | ||
166 | * a new collection with the elements returned by the function. | ||
167 | * | ||
168 | * @psalm-param Closure(T):U $func | ||
169 | * | ||
170 | * @return ReadableCollection<mixed> | ||
171 | * @psalm-return ReadableCollection<TKey, U> | ||
172 | * | ||
173 | * @psalm-template U | ||
174 | */ | ||
175 | public function map(Closure $func); | ||
176 | |||
177 | /** | ||
178 | * Partitions this collection in two collections according to a predicate. | ||
179 | * Keys are preserved in the resulting collections. | ||
180 | * | ||
181 | * @param Closure $p The predicate on which to partition. | ||
182 | * @psalm-param Closure(TKey, T):bool $p | ||
183 | * | ||
184 | * @return ReadableCollection<mixed>[] An array with two elements. The first element contains the collection | ||
185 | * of elements where the predicate returned TRUE, the second element | ||
186 | * contains the collection of elements where the predicate returned FALSE. | ||
187 | * @psalm-return array{0: ReadableCollection<TKey, T>, 1: ReadableCollection<TKey, T>} | ||
188 | */ | ||
189 | public function partition(Closure $p); | ||
190 | |||
191 | /** | ||
192 | * Tests whether the given predicate p holds for all elements of this collection. | ||
193 | * | ||
194 | * @param Closure $p The predicate. | ||
195 | * @psalm-param Closure(TKey, T):bool $p | ||
196 | * | ||
197 | * @return bool TRUE, if the predicate yields TRUE for all elements, FALSE otherwise. | ||
198 | */ | ||
199 | public function forAll(Closure $p); | ||
200 | |||
201 | /** | ||
202 | * Gets the index/key of a given element. The comparison of two elements is strict, | ||
203 | * that means not only the value but also the type must match. | ||
204 | * For objects this means reference equality. | ||
205 | * | ||
206 | * @param mixed $element The element to search for. | ||
207 | * @psalm-param TMaybeContained $element | ||
208 | * | ||
209 | * @return int|string|bool The key/index of the element or FALSE if the element was not found. | ||
210 | * @psalm-return (TMaybeContained is T ? TKey|false : false) | ||
211 | * | ||
212 | * @template TMaybeContained | ||
213 | */ | ||
214 | public function indexOf(mixed $element); | ||
215 | |||
216 | /** | ||
217 | * Returns the first element of this collection that satisfies the predicate p. | ||
218 | * | ||
219 | * @param Closure $p The predicate. | ||
220 | * @psalm-param Closure(TKey, T):bool $p | ||
221 | * | ||
222 | * @return mixed The first element respecting the predicate, | ||
223 | * null if no element respects the predicate. | ||
224 | * @psalm-return T|null | ||
225 | */ | ||
226 | public function findFirst(Closure $p); | ||
227 | |||
228 | /** | ||
229 | * Applies iteratively the given function to each element in the collection, | ||
230 | * so as to reduce the collection to a single value. | ||
231 | * | ||
232 | * @psalm-param Closure(TReturn|TInitial, T):TReturn $func | ||
233 | * @psalm-param TInitial $initial | ||
234 | * | ||
235 | * @return mixed | ||
236 | * @psalm-return TReturn|TInitial | ||
237 | * | ||
238 | * @psalm-template TReturn | ||
239 | * @psalm-template TInitial | ||
240 | */ | ||
241 | public function reduce(Closure $func, mixed $initial = null); | ||
242 | } | ||
diff --git a/vendor/doctrine/collections/src/Selectable.php b/vendor/doctrine/collections/src/Selectable.php new file mode 100644 index 0000000..5fa87cb --- /dev/null +++ b/vendor/doctrine/collections/src/Selectable.php | |||
@@ -0,0 +1,32 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Common\Collections; | ||
6 | |||
7 | /** | ||
8 | * Interface for collections that allow efficient filtering with an expression API. | ||
9 | * | ||
10 | * Goal of this interface is a backend independent method to fetch elements | ||
11 | * from a collections. {@link Expression} is crafted in a way that you can | ||
12 | * implement queries from both in-memory and database-backed collections. | ||
13 | * | ||
14 | * For database backed collections this allows very efficient access by | ||
15 | * utilizing the query APIs, for example SQL in the ORM. Applications using | ||
16 | * this API can implement efficient database access without having to ask the | ||
17 | * EntityManager or Repositories. | ||
18 | * | ||
19 | * @psalm-template TKey as array-key | ||
20 | * @psalm-template-covariant T | ||
21 | */ | ||
22 | interface Selectable | ||
23 | { | ||
24 | /** | ||
25 | * Selects all elements from a selectable that match the expression and | ||
26 | * returns a new collection containing these elements and preserved keys. | ||
27 | * | ||
28 | * @return ReadableCollection<mixed>&Selectable<mixed> | ||
29 | * @psalm-return ReadableCollection<TKey,T>&Selectable<TKey,T> | ||
30 | */ | ||
31 | public function matching(Criteria $criteria); | ||
32 | } | ||