summaryrefslogtreecommitdiff
path: root/vendor/doctrine/collections/src
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
committerpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
commitbf6655a534a6775d30cafa67bd801276bda1d98d (patch)
treec6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/doctrine/collections/src
parent94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff)
downloadAppliGestionPHP-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.php414
-rw-r--r--vendor/doctrine/collections/src/ArrayCollection.php490
-rw-r--r--vendor/doctrine/collections/src/Collection.php117
-rw-r--r--vendor/doctrine/collections/src/Criteria.php285
-rw-r--r--vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php222
-rw-r--r--vendor/doctrine/collections/src/Expr/Comparison.php62
-rw-r--r--vendor/doctrine/collections/src/Expr/CompositeExpression.php70
-rw-r--r--vendor/doctrine/collections/src/Expr/Expression.php14
-rw-r--r--vendor/doctrine/collections/src/Expr/ExpressionVisitor.php52
-rw-r--r--vendor/doctrine/collections/src/Expr/Value.php26
-rw-r--r--vendor/doctrine/collections/src/ExpressionBuilder.php123
-rw-r--r--vendor/doctrine/collections/src/Order.php11
-rw-r--r--vendor/doctrine/collections/src/ReadableCollection.php242
-rw-r--r--vendor/doctrine/collections/src/Selectable.php32
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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use Closure;
8use LogicException;
9use ReturnTypeWillChange;
10use 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 */
19abstract 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use ArrayIterator;
8use Closure;
9use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
10use ReturnTypeWillChange;
11use Stringable;
12use Traversable;
13
14use function array_filter;
15use function array_key_exists;
16use function array_keys;
17use function array_map;
18use function array_reduce;
19use function array_reverse;
20use function array_search;
21use function array_slice;
22use function array_values;
23use function count;
24use function current;
25use function end;
26use function in_array;
27use function key;
28use function next;
29use function reset;
30use function spl_object_hash;
31use function uasort;
32
33use 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 */
49class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use ArrayAccess;
8use 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 */
32interface 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use Doctrine\Common\Collections\Expr\CompositeExpression;
8use Doctrine\Common\Collections\Expr\Expression;
9use Doctrine\Deprecations\Deprecation;
10
11use function array_map;
12use function func_num_args;
13use function strtoupper;
14
15/**
16 * Criteria for filtering Selectable collections.
17 *
18 * @psalm-consistent-constructor
19 */
20class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7use ArrayAccess;
8use Closure;
9use RuntimeException;
10
11use function explode;
12use function in_array;
13use function is_array;
14use function is_scalar;
15use function iterator_to_array;
16use function method_exists;
17use function preg_match;
18use function preg_replace_callback;
19use function str_contains;
20use function str_ends_with;
21use function str_starts_with;
22use 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 */
30class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7/**
8 * Comparison of a field with a value by the given operator.
9 */
10class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7use RuntimeException;
8
9use function count;
10
11/**
12 * Expression of Expressions combined by AND or OR operation.
13 */
14class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7/**
8 * Expression for the {@link Selectable} interface.
9 */
10interface 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7use RuntimeException;
8
9/**
10 * An Expression visitor walks a graph of expressions and turns them into a
11 * query for the underlying implementation.
12 */
13abstract 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections\Expr;
6
7class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use Doctrine\Common\Collections\Expr\Comparison;
8use Doctrine\Common\Collections\Expr\CompositeExpression;
9use Doctrine\Common\Collections\Expr\Expression;
10use 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 */
19class 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7enum 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
3declare(strict_types=1);
4
5namespace Doctrine\Common\Collections;
6
7use Closure;
8use Countable;
9use IteratorAggregate;
10
11/**
12 * @psalm-template TKey of array-key
13 * @template-covariant T
14 * @template-extends IteratorAggregate<TKey, T>
15 */
16interface 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
3declare(strict_types=1);
4
5namespace 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 */
22interface 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}