summaryrefslogtreecommitdiff
path: root/vendor/doctrine/collections
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
parent94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff)
downloadAppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/doctrine/collections')
-rw-r--r--vendor/doctrine/collections/CONTRIBUTING.md44
-rw-r--r--vendor/doctrine/collections/LICENSE19
-rw-r--r--vendor/doctrine/collections/README.md6
-rw-r--r--vendor/doctrine/collections/UPGRADE.md112
-rw-r--r--vendor/doctrine/collections/composer.json63
-rw-r--r--vendor/doctrine/collections/docs/en/derived-collections.rst26
-rw-r--r--vendor/doctrine/collections/docs/en/expression-builder.rst185
-rw-r--r--vendor/doctrine/collections/docs/en/expressions.rst117
-rw-r--r--vendor/doctrine/collections/docs/en/index.rst357
-rw-r--r--vendor/doctrine/collections/docs/en/lazy-collections.rst26
-rw-r--r--vendor/doctrine/collections/docs/en/serialization.rst29
-rw-r--r--vendor/doctrine/collections/docs/en/sidebar.rst11
-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
26 files changed, 3155 insertions, 0 deletions
diff --git a/vendor/doctrine/collections/CONTRIBUTING.md b/vendor/doctrine/collections/CONTRIBUTING.md
new file mode 100644
index 0000000..7a0a8c9
--- /dev/null
+++ b/vendor/doctrine/collections/CONTRIBUTING.md
@@ -0,0 +1,44 @@
1# Contribute to Doctrine
2
3Thank you for contributing to Doctrine!
4
5Before we can merge your Pull-Request here are some guidelines that you need to follow.
6These guidelines exist not to annoy you, but to keep the code base clean,
7unified and future proof.
8
9## Coding Standard
10
11We use the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard).
12
13## Unit-Tests
14
15Please try to add a test for your pull-request.
16
17* If you want to contribute new functionality add unit- or functional tests
18 depending on the scope of the feature.
19
20You can run the unit-tests by calling ``vendor/bin/phpunit`` from the root of the project.
21It will run all the project tests.
22
23In order to do that, you will need a fresh copy of doctrine/collections, and you
24will have to run a composer installation in the project:
25
26```sh
27git clone git@github.com:doctrine/collections.git
28cd collections
29curl -sS https://getcomposer.org/installer | php --
30./composer.phar install
31```
32
33## Github Actions
34
35We automatically run your pull request through Github Actions against supported
36PHP versions. If you break the tests, we cannot merge your code, so please make
37sure that your code is working before opening up a Pull-Request.
38
39## Getting merged
40
41Please allow us time to review your pull requests. We will give our best to review
42everything as fast as possible, but cannot always live up to our own expectations.
43
44Thank you very much again for your contribution!
diff --git a/vendor/doctrine/collections/LICENSE b/vendor/doctrine/collections/LICENSE
new file mode 100644
index 0000000..5e781fc
--- /dev/null
+++ b/vendor/doctrine/collections/LICENSE
@@ -0,0 +1,19 @@
1Copyright (c) 2006-2013 Doctrine Project
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of
4this software and associated documentation files (the "Software"), to deal in
5the Software without restriction, including without limitation the rights to
6use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7of the Software, and to permit persons to whom the Software is furnished to do
8so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all
11copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19SOFTWARE.
diff --git a/vendor/doctrine/collections/README.md b/vendor/doctrine/collections/README.md
new file mode 100644
index 0000000..048fb61
--- /dev/null
+++ b/vendor/doctrine/collections/README.md
@@ -0,0 +1,6 @@
1# Doctrine Collections
2
3[![Build Status](https://github.com/doctrine/collections/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/collections/actions)
4[![Code Coverage](https://codecov.io/gh/doctrine/collections/branch/2.0.x/graph/badge.svg)](https://codecov.io/gh/doctrine/collections/branch/2.0.x)
5
6Collections Abstraction library
diff --git a/vendor/doctrine/collections/UPGRADE.md b/vendor/doctrine/collections/UPGRADE.md
new file mode 100644
index 0000000..44232f7
--- /dev/null
+++ b/vendor/doctrine/collections/UPGRADE.md
@@ -0,0 +1,112 @@
1Note about upgrading: Doctrine uses static and runtime mechanisms to raise
2awareness about deprecated code.
3
4- Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or
5 Static Analysis tools (like Psalm, phpstan)
6- Use of our low-overhead runtime deprecation API, details:
7 https://github.com/doctrine/deprecations/
8
9# Upgrade to 2.2
10
11## Deprecated string representation of sort order
12
13Criteria orderings direction is now represented by the
14`Doctrine\Common\Collection\Order` enum.
15
16As a consequence:
17
18- `Criteria::ASC` and `Criteria::DESC` are deprecated in favor of
19 `Order::Ascending` and `Order::Descending`, respectively.
20- `Criteria::getOrderings()` is deprecated in favor of `Criteria::orderings()`,
21 which returns `array<string, Order>`.
22- `Criteria::orderBy()` accepts `array<string, string|Order>`, but passing
23 anything other than `array<string, Order>` is deprecated.
24
25# Upgrade to 2.0
26
27## BC breaking changes
28
29Native parameter types were added. Native return types will be added in 3.0.x
30As a consequence, some signatures were changed and will have to be adjusted in sub-classes.
31
32Note that in order to keep compatibility with both 1.x and 2.x versions,
33extending code would have to omit the added parameter types.
34This would only work in PHP 7.2+ which is the first version featuring
35[parameter widening](https://wiki.php.net/rfc/parameter-no-type-variance).
36It is also recommended to add return types according to the tables below
37
38You can find a list of major changes to public API below.
39
40### Doctrine\Common\Collections\Collection
41
42| 1.0.x | 3.0.x |
43|---------------------------------:|:-------------------------------------------------|
44| `add($element)` | `add(mixed $element): void` |
45| `clear()` | `clear(): void` |
46| `contains($element)` | `contains(mixed $element): bool` |
47| `isEmpty()` | `isEmpty(): bool` |
48| `removeElement($element)` | `removeElement(mixed $element): bool` |
49| `containsKey($key)` | `containsKey(string\|int $key): bool` |
50| `get()` | `get(string\|int $key): mixed` |
51| `getKeys()` | `getKeys(): array` |
52| `getValues()` | `getValues(): array` |
53| `set($key, $value)` | `set(string\|int $key, $value): void` |
54| `toArray()` | `toArray(): array` |
55| `first()` | `first(): mixed` |
56| `last()` | `last(): mixed` |
57| `key()` | `key(): int\|string\|null` |
58| `current()` | `current(): mixed` |
59| `next()` | `next(): mixed` |
60| `exists(Closure $p)` | `exists(Closure $p): bool` |
61| `filter(Closure $p)` | `filter(Closure $p): self` |
62| `forAll(Closure $p)` | `forAll(Closure $p): bool` |
63| `map(Closure $func)` | `map(Closure $func): self` |
64| `partition(Closure $p)` | `partition(Closure $p): array` |
65| `indexOf($element)` | `indexOf(mixed $element): int\|string\|false` |
66| `slice($offset, $length = null)` | `slice(int $offset, ?int $length = null): array` |
67| `count()` | `count(): int` |
68| `getIterator()` | `getIterator(): \Traversable` |
69| `offsetSet($offset, $value)` | `offsetSet(mixed $offset, mixed $value): void` |
70| `offsetUnset($offset)` | `offsetUnset(mixed $offset): void` |
71| `offsetExists($offset)` | `offsetExists(mixed $offset): bool` |
72
73### Doctrine\Common\Collections\AbstractLazyCollection
74
75| 1.0.x | 3.0.x |
76|------------------:|:------------------------|
77| `isInitialized()` | `isInitialized(): bool` |
78| `initialize()` | `initialize(): void` |
79| `doInitialize()` | `doInitialize(): void` |
80
81### Doctrine\Common\Collections\ArrayCollection
82
83| 1.0.x | 3.0.x |
84|------------------------------:|:--------------------------------------|
85| `createFrom(array $elements)` | `createFrom(array $elements): static` |
86| `__toString()` | `__toString(): string` |
87
88### Doctrine\Common\Collections\Criteria
89
90| 1.0.x | 3.0.x |
91|------------------------------------------:|:--------------------------------------------|
92| `where(Expression $expression): self` | `where(Expression $expression): static` |
93| `andWhere(Expression $expression): self` | `andWhere(Expression $expression): static` |
94| `orWhere(Expression $expression): self` | `orWhere(Expression $expression): static` |
95| `orderBy(array $orderings): self` | `orderBy(array $orderings): static` |
96| `setFirstResult(?int $firstResult): self` | `setFirstResult(?int $firstResult): static` |
97| `setMaxResult(?int $maxResults): self` | `setMaxResults(?int $maxResults): static` |
98
99### Doctrine\Common\Collections\Selectable
100
101| 1.0.x | 3.0.x |
102|-------------------------------:|:-------------------------------------------|
103| `matching(Criteria $criteria)` | `matching(Criteria $criteria): Collection` |
104
105# Upgrade to 1.7
106
107## Deprecated null first result
108
109Passing null as `$firstResult` to
110`Doctrine\Common\Collections\Criteria::__construct()` and to
111`Doctrine\Common\Collections\Criteria::setFirstResult()` is deprecated.
112Use `0` instead.
diff --git a/vendor/doctrine/collections/composer.json b/vendor/doctrine/collections/composer.json
new file mode 100644
index 0000000..4c36229
--- /dev/null
+++ b/vendor/doctrine/collections/composer.json
@@ -0,0 +1,63 @@
1{
2 "name": "doctrine/collections",
3 "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.",
4 "license": "MIT",
5 "type": "library",
6 "keywords": [
7 "php",
8 "collections",
9 "array",
10 "iterators"
11 ],
12 "authors": [
13 {
14 "name": "Guilherme Blanco",
15 "email": "guilhermeblanco@gmail.com"
16 },
17 {
18 "name": "Roman Borschel",
19 "email": "roman@code-factory.org"
20 },
21 {
22 "name": "Benjamin Eberlei",
23 "email": "kontakt@beberlei.de"
24 },
25 {
26 "name": "Jonathan Wage",
27 "email": "jonwage@gmail.com"
28 },
29 {
30 "name": "Johannes Schmitt",
31 "email": "schmittjoh@gmail.com"
32 }
33 ],
34 "homepage": "https://www.doctrine-project.org/projects/collections.html",
35 "require": {
36 "php": "^8.1",
37 "doctrine/deprecations": "^1"
38 },
39 "require-dev": {
40 "ext-json": "*",
41 "doctrine/coding-standard": "^12",
42 "phpstan/phpstan": "^1.8",
43 "phpstan/phpstan-phpunit": "^1.0",
44 "phpunit/phpunit": "^10.5",
45 "vimeo/psalm": "^5.11"
46 },
47 "autoload": {
48 "psr-4": {
49 "Doctrine\\Common\\Collections\\": "src"
50 }
51 },
52 "autoload-dev": {
53 "psr-4": {
54 "Doctrine\\Tests\\Common\\Collections\\": "tests"
55 }
56 },
57 "config": {
58 "allow-plugins": {
59 "composer/package-versions-deprecated": true,
60 "dealerdirect/phpcodesniffer-composer-installer": true
61 }
62 }
63}
diff --git a/vendor/doctrine/collections/docs/en/derived-collections.rst b/vendor/doctrine/collections/docs/en/derived-collections.rst
new file mode 100644
index 0000000..03d9da5
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/derived-collections.rst
@@ -0,0 +1,26 @@
1Derived Collections
2===================
3
4You can create custom collection classes by extending the
5``Doctrine\Common\Collections\ArrayCollection`` class. If the
6``__construct`` semantics are different from the default ``ArrayCollection``
7you can override the ``createFrom`` method:
8
9.. code-block:: php
10 final class DerivedArrayCollection extends ArrayCollection
11 {
12 /** @var \stdClass */
13 private $foo;
14
15 public function __construct(\stdClass $foo, array $elements = [])
16 {
17 $this->foo = $foo;
18
19 parent::__construct($elements);
20 }
21
22 protected function createFrom(array $elements) : self
23 {
24 return new static($this->foo, $elements);
25 }
26 }
diff --git a/vendor/doctrine/collections/docs/en/expression-builder.rst b/vendor/doctrine/collections/docs/en/expression-builder.rst
new file mode 100644
index 0000000..e022441
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/expression-builder.rst
@@ -0,0 +1,185 @@
1Expression Builder
2==================
3
4The Expression Builder is a convenient fluent interface for
5building expressions to be used with the ``Doctrine\Common\Collections\Criteria``
6class:
7
8.. code-block:: php
9 $expressionBuilder = Criteria::expr();
10
11 $criteria = new Criteria();
12 $criteria->where($expressionBuilder->eq('name', 'jwage'));
13 $criteria->orWhere($expressionBuilder->eq('name', 'romanb'));
14
15 $collection->matching($criteria);
16
17The ``ExpressionBuilder`` has the following API:
18
19andX
20----
21
22.. code-block:: php
23 $expressionBuilder = Criteria::expr();
24
25 $expression = $expressionBuilder->andX(
26 $expressionBuilder->eq('foo', 1),
27 $expressionBuilder->eq('bar', 1)
28 );
29
30 $collection->matching(new Criteria($expression));
31
32orX
33---
34
35.. code-block:: php
36 $expressionBuilder = Criteria::expr();
37
38 $expression = $expressionBuilder->orX(
39 $expressionBuilder->eq('foo', 1),
40 $expressionBuilder->eq('bar', 1)
41 );
42
43 $collection->matching(new Criteria($expression));
44
45not
46---
47
48.. code-block:: php
49 $expressionBuilder = Criteria::expr();
50
51 $expression = $expressionBuilder->not(
52 $expressionBuilder->eq('foo', 1)
53 );
54
55 $collection->matching(new Criteria($expression));
56
57eq
58---
59
60.. code-block:: php
61 $expressionBuilder = Criteria::expr();
62
63 $expression = $expressionBuilder->eq('foo', 1);
64
65 $collection->matching(new Criteria($expression));
66
67gt
68---
69
70.. code-block:: php
71 $expressionBuilder = Criteria::expr();
72
73 $expression = $expressionBuilder->gt('foo', 1);
74
75 $collection->matching(new Criteria($expression));
76
77lt
78---
79
80.. code-block:: php
81 $expressionBuilder = Criteria::expr();
82
83 $expression = $expressionBuilder->lt('foo', 1);
84
85 $collection->matching(new Criteria($expression));
86
87gte
88---
89
90.. code-block:: php
91 $expressionBuilder = Criteria::expr();
92
93 $expression = $expressionBuilder->gte('foo', 1);
94
95 $collection->matching(new Criteria($expression));
96
97lte
98---
99
100.. code-block:: php
101 $expressionBuilder = Criteria::expr();
102
103 $expression = $expressionBuilder->lte('foo', 1);
104
105 $collection->matching(new Criteria($expression));
106
107neq
108---
109
110.. code-block:: php
111 $expressionBuilder = Criteria::expr();
112
113 $expression = $expressionBuilder->neq('foo', 1);
114
115 $collection->matching(new Criteria($expression));
116
117isNull
118------
119
120.. code-block:: php
121 $expressionBuilder = Criteria::expr();
122
123 $expression = $expressionBuilder->isNull('foo');
124
125 $collection->matching(new Criteria($expression));
126
127in
128---
129
130.. code-block:: php
131 $expressionBuilder = Criteria::expr();
132
133 $expression = $expressionBuilder->in('foo', ['value1', 'value2']);
134
135 $collection->matching(new Criteria($expression));
136
137notIn
138-----
139
140.. code-block:: php
141 $expressionBuilder = Criteria::expr();
142
143 $expression = $expressionBuilder->notIn('foo', ['value1', 'value2']);
144
145 $collection->matching(new Criteria($expression));
146
147contains
148--------
149
150.. code-block:: php
151 $expressionBuilder = Criteria::expr();
152
153 $expression = $expressionBuilder->contains('foo', 'value1');
154
155 $collection->matching(new Criteria($expression));
156
157memberOf
158--------
159
160.. code-block:: php
161 $expressionBuilder = Criteria::expr();
162
163 $expression = $expressionBuilder->memberOf('foo', ['value1', 'value2']);
164
165 $collection->matching(new Criteria($expression));
166
167startsWith
168----------
169
170.. code-block:: php
171 $expressionBuilder = Criteria::expr();
172
173 $expression = $expressionBuilder->startsWith('foo', 'hello');
174
175 $collection->matching(new Criteria($expression));
176
177endsWith
178--------
179
180.. code-block:: php
181 $expressionBuilder = Criteria::expr();
182
183 $expression = $expressionBuilder->endsWith('foo', 'world');
184
185 $collection->matching(new Criteria($expression));
diff --git a/vendor/doctrine/collections/docs/en/expressions.rst b/vendor/doctrine/collections/docs/en/expressions.rst
new file mode 100644
index 0000000..5587bfb
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/expressions.rst
@@ -0,0 +1,117 @@
1Expressions
2===========
3
4The ``Doctrine\Common\Collections\Expr\Comparison`` class
5can be used to create comparison expressions to be used with the
6``Doctrine\Common\Collections\Criteria`` class. It has the
7following operator constants:
8
9- ``Comparison::EQ``
10- ``Comparison::NEQ``
11- ``Comparison::LT``
12- ``Comparison::LTE``
13- ``Comparison::GT``
14- ``Comparison::GTE``
15- ``Comparison::IS``
16- ``Comparison::IN``
17- ``Comparison::NIN``
18- ``Comparison::CONTAINS``
19- ``Comparison::MEMBER_OF``
20- ``Comparison::STARTS_WITH``
21- ``Comparison::ENDS_WITH``
22
23The ``Doctrine\Common\Collections\Expr\CompositeExpression`` class
24can be used to create composite expressions to be used with the
25``Doctrine\Common\Collections\Criteria`` class. It has the
26following operator constants:
27
28- ``CompositeExpression::TYPE_AND``
29- ``CompositeExpression::TYPE_OR``
30- ``CompositeExpression::TYPE_NOT``
31
32When using the ``TYPE_OR`` and ``TYPE_AND`` operators the
33``CompositeExpression`` accepts multiple expressions as parameter
34but only one expression can be provided when using the ``NOT`` operator.
35
36The ``Doctrine\Common\Collections\Criteria`` class has the following
37API to be used with expressions:
38
39where
40-----
41
42Sets the where expression to evaluate when this Criteria is searched for.
43
44.. code-block:: php
45 $expr = new Comparison('key', Comparison::EQ, 'value');
46
47 $criteria->where($expr);
48
49andWhere
50--------
51
52Appends the where expression to evaluate when this Criteria is searched for
53using an AND with previous expression.
54
55.. code-block:: php
56 $expr = new Comparison('key', Comparison::EQ, 'value');
57
58 $criteria->andWhere($expr);
59
60orWhere
61-------
62
63Appends the where expression to evaluate when this Criteria is searched for
64using an OR with previous expression.
65
66.. code-block:: php
67 $expr1 = new Comparison('key', Comparison::EQ, 'value1');
68 $expr2 = new Comparison('key', Comparison::EQ, 'value2');
69
70 $criteria->where($expr1);
71 $criteria->orWhere($expr2);
72
73orderBy
74-------
75
76Sets the ordering of the result of this Criteria.
77
78.. code-block:: php
79 use Doctrine\Common\Collections\Order;
80
81 $criteria->orderBy(['name' => Order::Ascending]);
82
83setFirstResult
84--------------
85
86Set the number of first result that this Criteria should return.
87
88.. code-block:: php
89 $criteria->setFirstResult(0);
90
91getFirstResult
92--------------
93
94Gets the current first result option of this Criteria.
95
96.. code-block:: php
97 $criteria->setFirstResult(10);
98
99 echo $criteria->getFirstResult(); // 10
100
101setMaxResults
102-------------
103
104Sets the max results that this Criteria should return.
105
106.. code-block:: php
107 $criteria->setMaxResults(20);
108
109getMaxResults
110-------------
111
112Gets the current max results option of this Criteria.
113
114.. code-block:: php
115 $criteria->setMaxResults(20);
116
117 echo $criteria->getMaxResults(); // 20
diff --git a/vendor/doctrine/collections/docs/en/index.rst b/vendor/doctrine/collections/docs/en/index.rst
new file mode 100644
index 0000000..7f2e38c
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/index.rst
@@ -0,0 +1,357 @@
1Introduction
2============
3
4Doctrine Collections is a library that contains classes for working with
5arrays of data. Here is an example using the simple
6``Doctrine\Common\Collections\ArrayCollection`` class:
7
8.. code-block:: php
9 <?php
10
11 use Doctrine\Common\Collections\ArrayCollection;
12
13 $collection = new ArrayCollection([1, 2, 3]);
14
15 $filteredCollection = $collection->filter(function($element) {
16 return $element > 1;
17 }); // [2, 3]
18
19Collection Methods
20==================
21
22Doctrine Collections provides an interface named ``Doctrine\Common\Collections\Collection``
23that resembles the nature of a regular PHP array. That is,
24it is essentially an **ordered map** that can also be used
25like a list.
26
27A Collection has an internal iterator just like a PHP array. In addition,
28a Collection can be iterated with external iterators, which is preferable.
29To use an external iterator simply use the foreach language construct to
30iterate over the collection, which calls ``getIterator()`` internally, or
31explicitly retrieve an iterator though ``getIterator()`` which can then be
32used to iterate over the collection. You can not rely on the internal iterator
33of the collection being at a certain position unless you explicitly positioned it before.
34
35Methods that do not alter the collection or have template types
36appearing in invariant or contravariant positions are not directly
37defined in ``Doctrine\Common\Collections\Collection``, but are inherited
38from the ``Doctrine\Common\Collections\ReadableCollection`` interface.
39
40The methods available on the interface are:
41
42add
43---
44
45Adds an element at the end of the collection.
46
47.. code-block:: php
48 $collection->add('test');
49
50clear
51-----
52
53Clears the collection, removing all elements.
54
55.. code-block:: php
56 $collection->clear();
57
58contains
59--------
60
61Checks whether an element is contained in the collection. This is an O(n) operation, where n is the size of the collection.
62
63.. code-block:: php
64 $collection = new Collection(['test']);
65
66 $contains = $collection->contains('test'); // true
67
68containsKey
69-----------
70
71Checks whether the collection contains an element with the specified key/index.
72
73.. code-block:: php
74 $collection = new Collection(['test' => true]);
75
76 $contains = $collection->containsKey('test'); // true
77
78current
79-------
80
81Gets the element of the collection at the current iterator position.
82
83.. code-block:: php
84 $collection = new Collection(['first', 'second', 'third']);
85
86 $current = $collection->current(); // first
87
88get
89---
90
91Gets the element at the specified key/index.
92
93.. code-block:: php
94 $collection = new Collection([
95 'key' => 'value',
96 ]);
97
98 $value = $collection->get('key'); // value
99
100getKeys
101-------
102
103Gets all keys/indices of the collection.
104
105.. code-block:: php
106 $collection = new Collection(['a', 'b', 'c']);
107
108 $keys = $collection->getKeys(); // [0, 1, 2]
109
110getValues
111---------
112
113Gets all values of the collection.
114
115.. code-block:: php
116 $collection = new Collection([
117 'key1' => 'value1',
118 'key2' => 'value2',
119 'key3' => 'value3',
120 ]);
121
122 $values = $collection->getValues(); // ['value1', 'value2', 'value3']
123
124isEmpty
125-------
126
127Checks whether the collection is empty (contains no elements).
128
129.. code-block:: php
130 $collection = new Collection(['a', 'b', 'c']);
131
132 $isEmpty = $collection->isEmpty(); // false
133
134first
135-----
136
137Sets the internal iterator to the first element in the collection and returns this element.
138
139.. code-block:: php
140 $collection = new Collection(['first', 'second', 'third']);
141
142 $first = $collection->first(); // first
143
144exists
145------
146
147Tests for the existence of an element that satisfies the given predicate.
148
149.. code-block:: php
150 $collection = new Collection(['first', 'second', 'third']);
151
152 $exists = $collection->exists(function($key, $value) {
153 return $value === 'first';
154 }); // true
155
156findFirst
157---------
158
159Returns the first element of this collection that satisfies the given predicate.
160
161.. code-block:: php
162 $collection = new Collection([1, 2, 3, 2, 1]);
163
164 $one = $collection->findFirst(function(int $key, int $value): bool {
165 return $value > 2 && $key > 1;
166 }); // 3
167
168filter
169------
170
171Returns all the elements of this collection for which your callback function returns `true`.
172The order and keys of the elements are preserved.
173
174.. code-block:: php
175 $collection = new ArrayCollection([1, 2, 3]);
176
177 $filteredCollection = $collection->filter(function($element) {
178 return $element > 1;
179 }); // [2, 3]
180
181forAll
182------
183
184Tests whether the given predicate holds for all elements of this collection.
185
186.. code-block:: php
187 $collection = new ArrayCollection([1, 2, 3]);
188
189 $forAll = $collection->forAll(function($key, $value) {
190 return $value > 1;
191 }); // false
192
193indexOf
194-------
195
196Gets the index/key of a given element. The comparison of two elements is strict, that means not only the value but also the type must match. For objects this means reference equality.
197
198.. code-block:: php
199 $collection = new ArrayCollection([1, 2, 3]);
200
201 $indexOf = $collection->indexOf(3); // 2
202
203key
204---
205
206Gets the key/index of the element at the current iterator position.
207
208.. code-block:: php
209 $collection = new ArrayCollection([1, 2, 3]);
210
211 $collection->next();
212
213 $key = $collection->key(); // 1
214
215last
216----
217
218Sets the internal iterator to the last element in the collection and returns this element.
219
220.. code-block:: php
221 $collection = new ArrayCollection([1, 2, 3]);
222
223 $last = $collection->last(); // 3
224
225map
226---
227
228Applies the given function to each element in the collection and returns a new collection with the elements returned by the function.
229
230.. code-block:: php
231 $collection = new ArrayCollection([1, 2, 3]);
232
233 $mappedCollection = $collection->map(function($value) {
234 return $value + 1;
235 }); // [2, 3, 4]
236
237reduce
238------
239
240Applies iteratively the given function to each element in the collection, so as to reduce the collection to a single value.
241
242.. code-block:: php
243 $collection = new ArrayCollection([1, 2, 3]);
244
245 $reduce = $collection->reduce(function(int $accumulator, int $value): int {
246 return $accumulator + $value;
247 }, 0); // 6
248
249next
250----
251
252Moves the internal iterator position to the next element and returns this element.
253
254.. code-block:: php
255 $collection = new ArrayCollection([1, 2, 3]);
256
257 $next = $collection->next(); // 2
258
259partition
260---------
261
262Partitions this collection in two collections according to a predicate. Keys are preserved in the resulting collections.
263
264.. code-block:: php
265 $collection = new ArrayCollection([1, 2, 3]);
266
267 $mappedCollection = $collection->partition(function($key, $value) {
268 return $value > 1
269 }); // [[2, 3], [1]]
270
271remove
272------
273
274Removes the element at the specified index from the collection.
275
276.. code-block:: php
277 $collection = new ArrayCollection([1, 2, 3]);
278
279 $collection->remove(0); // [2, 3]
280
281removeElement
282-------------
283
284Removes the specified element from the collection, if it is found.
285
286.. code-block:: php
287 $collection = new ArrayCollection([1, 2, 3]);
288
289 $collection->removeElement(3); // [1, 2]
290
291set
292---
293
294Sets an element in the collection at the specified key/index.
295
296.. code-block:: php
297 $collection = new ArrayCollection();
298
299 $collection->set('name', 'jwage');
300
301slice
302-----
303
304Extracts a slice of $length elements starting at position $offset from the Collection. If $length is null it returns all elements from $offset to the end of the Collection. Keys have to be preserved by this method. Calling this method will only return the selected slice and NOT change the elements contained in the collection slice is called on.
305
306.. code-block:: php
307 $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]);
308
309 $slice = $collection->slice(1, 2); // [1, 2]
310
311toArray
312-------
313
314Gets a native PHP array representation of the collection.
315
316.. code-block:: php
317 $collection = new ArrayCollection([0, 1, 2, 3, 4, 5]);
318
319 $array = $collection->toArray(); // [0, 1, 2, 3, 4, 5]
320
321Selectable Methods
322==================
323
324Some Doctrine Collections, like ``Doctrine\Common\Collections\ArrayCollection``,
325implement an interface named ``Doctrine\Common\Collections\Selectable``
326that offers the usage of a powerful expressions API, where conditions
327can be applied to a collection to get a result with matching elements
328only.
329
330matching
331--------
332
333Selects all elements from a selectable that match the expression and
334returns a new collection containing these elements and preserved keys.
335
336.. code-block:: php
337 use Doctrine\Common\Collections\Criteria;
338 use Doctrine\Common\Collections\Expr\Comparison;
339
340 $collection = new ArrayCollection([
341 'wage' => [
342 'name' => 'jwage',
343 ],
344 'roman' => [
345 'name' => 'romanb',
346 ],
347 ]);
348
349 $expr = new Comparison('name', '=', 'jwage');
350
351 $criteria = new Criteria();
352
353 $criteria->where($expr);
354
355 $matchingCollection = $collection->matching($criteria); // [ 'wage' => [ 'name' => 'jwage' ]]
356
357You can read more about expressions :ref:`here <expressions>`.
diff --git a/vendor/doctrine/collections/docs/en/lazy-collections.rst b/vendor/doctrine/collections/docs/en/lazy-collections.rst
new file mode 100644
index 0000000..b9cafb6
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/lazy-collections.rst
@@ -0,0 +1,26 @@
1Lazy Collections
2================
3
4To create a lazy collection you can extend the
5``Doctrine\Common\Collections\AbstractLazyCollection`` class
6and define the ``doInitialize`` method. Here is an example where
7we lazily query the database for a collection of user records:
8
9.. code-block:: php
10 use Doctrine\DBAL\Connection;
11
12 class UsersLazyCollection extends AbstractLazyCollection
13 {
14 /** @var Connection */
15 private $connection;
16
17 public function __construct(Connection $connection)
18 {
19 $this->connection = $connection;
20 }
21
22 protected function doInitialize() : void
23 {
24 $this->collection = $this->connection->fetchAll('SELECT * FROM users');
25 }
26 }
diff --git a/vendor/doctrine/collections/docs/en/serialization.rst b/vendor/doctrine/collections/docs/en/serialization.rst
new file mode 100644
index 0000000..be53d6e
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/serialization.rst
@@ -0,0 +1,29 @@
1Serialization
2=============
3
4Using (un-)serialize() on a collection is not a supported use-case
5and may break when changes on the collection's internals happen in the future.
6If a collection needs to be serialized, use ``toArray()`` and reconstruct
7the collection manually.
8
9.. code-block:: php
10
11 $collection = new ArrayCollection([1, 2, 3]);
12 $serialized = serialize($collection->toArray());
13
14A reconstruction is also necessary when the collection contains objects with
15infinite recursion of dependencies like in this ``json_serialize()`` example:
16
17.. code-block:: php
18
19 $foo = new Foo();
20 $bar = new Bar();
21
22 $foo->setBar($bar);
23 $bar->setFoo($foo);
24
25 $collection = new ArrayCollection([$foo]);
26 $json = json_serialize($collection->toArray()); // recursion detected
27
28Serializer libraries can be used to create the serialization-output to prevent
29errors.
diff --git a/vendor/doctrine/collections/docs/en/sidebar.rst b/vendor/doctrine/collections/docs/en/sidebar.rst
new file mode 100644
index 0000000..ebfb11c
--- /dev/null
+++ b/vendor/doctrine/collections/docs/en/sidebar.rst
@@ -0,0 +1,11 @@
1:orphan:
2
3.. toctree::
4 :depth: 3
5
6 index
7 expressions
8 expression-builder
9 derived-collections
10 lazy-collections
11 serialization
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}