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