summaryrefslogtreecommitdiff
path: root/vendor/doctrine/persistence
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/persistence')
-rw-r--r--vendor/doctrine/persistence/CONTRIBUTING.md11
-rw-r--r--vendor/doctrine/persistence/LICENSE19
-rw-r--r--vendor/doctrine/persistence/README.md17
-rw-r--r--vendor/doctrine/persistence/UPGRADE.md154
-rw-r--r--vendor/doctrine/persistence/composer.json58
-rw-r--r--vendor/doctrine/persistence/src/Persistence/AbstractManagerRegistry.php269
-rw-r--r--vendor/doctrine/persistence/src/Persistence/ConnectionRegistry.php41
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Event/LifecycleEventArgs.php54
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Event/LoadClassMetadataEventArgs.php61
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Event/ManagerEventArgs.php39
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Event/OnClearEventArgs.php42
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Event/PreUpdateEventArgs.php110
-rw-r--r--vendor/doctrine/persistence/src/Persistence/ManagerRegistry.php89
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php499
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadata.php141
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadataFactory.php61
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php212
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/DefaultFileLocator.php175
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php213
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileLocator.php52
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriver.php43
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriverChain.php142
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/PHPDriver.php49
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/StaticPHPDriver.php132
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/SymfonyFileLocator.php265
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php88
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/ProxyClassNameResolver.php19
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/ReflectionService.php75
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/RuntimeReflectionService.php111
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/StaticReflectionService.php78
-rw-r--r--vendor/doctrine/persistence/src/Persistence/NotifyPropertyChanged.php22
-rw-r--r--vendor/doctrine/persistence/src/Persistence/ObjectManager.php145
-rw-r--r--vendor/doctrine/persistence/src/Persistence/ObjectManagerDecorator.php92
-rw-r--r--vendor/doctrine/persistence/src/Persistence/ObjectRepository.php73
-rw-r--r--vendor/doctrine/persistence/src/Persistence/PropertyChangedListener.php24
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Proxy.php39
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/EnumReflectionProperty.php181
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/RuntimePublicReflectionProperty.php61
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/RuntimeReflectionProperty.php87
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionProperty.php13
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionPropertyBase.php68
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultRuntimePublicReflectionProperty.php15
42 files changed, 4139 insertions, 0 deletions
diff --git a/vendor/doctrine/persistence/CONTRIBUTING.md b/vendor/doctrine/persistence/CONTRIBUTING.md
new file mode 100644
index 0000000..268200a
--- /dev/null
+++ b/vendor/doctrine/persistence/CONTRIBUTING.md
@@ -0,0 +1,11 @@
1# Circular dependency
2
3This package has a development dependency on `doctrine/common`, which has a
4regular dependency on this package (`^2.0` at the time of writing).
5
6To be able to use Composer, one has to let it understand that this is version 2
7(even when developing on 3.0.x), as follows:
8
9```shell
10COMPOSER_ROOT_VERSION=2.0 composer update -v
11```
diff --git a/vendor/doctrine/persistence/LICENSE b/vendor/doctrine/persistence/LICENSE
new file mode 100644
index 0000000..8c38cc1
--- /dev/null
+++ b/vendor/doctrine/persistence/LICENSE
@@ -0,0 +1,19 @@
1Copyright (c) 2006-2015 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/persistence/README.md b/vendor/doctrine/persistence/README.md
new file mode 100644
index 0000000..aeaaad3
--- /dev/null
+++ b/vendor/doctrine/persistence/README.md
@@ -0,0 +1,17 @@
1# Doctrine Persistence
2
3[![GitHub Actions][GA 3.3 image]][GA 3.3]
4[![Code Coverage][Coverage 3.3 image]][CodeCov 3.3]
5
6The Doctrine Persistence project is a library that provides common abstractions for object mapper persistence.
7
8## More resources:
9
10* [Website](https://www.doctrine-project.org/)
11* [Documentation](https://www.doctrine-project.org/projects/doctrine-persistence/en/latest/index.html)
12* [Downloads](https://github.com/doctrine/persistence/releases)
13
14 [Coverage 3.3 image]: https://codecov.io/gh/doctrine/persistence/branch/3.3.x/graph/badge.svg
15 [CodeCov 3.3]: https://codecov.io/gh/doctrine/persistence/branch/3.3.x
16 [GA 3.3 image]: https://github.com/doctrine/persistence/workflows/Continuous%20Integration/badge.svg?branch=3.3.x
17 [GA 3.3]: https://github.com/doctrine/persistence/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.3.x
diff --git a/vendor/doctrine/persistence/UPGRADE.md b/vendor/doctrine/persistence/UPGRADE.md
new file mode 100644
index 0000000..d7f5b04
--- /dev/null
+++ b/vendor/doctrine/persistence/UPGRADE.md
@@ -0,0 +1,154 @@
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 3.3
10
11## Added method `ObjectManager::isUninitializedObject()`
12
13Classes implementing `Doctrine\Persistence\ObjectManager` should implement the new
14method. This method will be added to the interface in 4.0.
15
16# Upgrade to 3.1
17
18## Deprecated `RuntimePublicReflectionProperty`
19
20Use `RuntimeReflectionProperty` instead.
21
22# Upgrade to 3.0
23
24## Removed `OnClearEventArgs::clearsAllEntities()` and `OnClearEventArgs::getEntityClass()`
25
26These methods only make sense when partially clearing the object manager, which
27is no longer possible.
28The second argument of the constructor of `OnClearEventArgs` is removed as well.
29
30## BC Break: removed `ObjectManagerAware`
31
32Implement active record style functionality directly in your application, by
33using a `postLoad` event.
34
35## BC Break: removed `AnnotationDriver`
36
37Use `ColocatedMappingDriver` instead.
38
39## BC Break: Removed `MappingException::pathRequired()`
40
41Use `MappingException::pathRequiredForDriver()` instead.
42
43## BC Break: removed `LifecycleEventArgs::getEntity()`
44
45Use `LifecycleEventArgs::getObject()` instead.
46
47## BC Break: removed support for short namespace aliases
48
49- `AbstractClassMetadataFactory::getFqcnFromAlias()` is removed.
50- `ClassMetadataFactory` methods now require their `$className` argument to be an
51actual FQCN.
52
53## BC Break: removed `ObjectManager::merge()`
54
55`ObjectManagerDecorator::merge()` is removed without replacement.
56
57## BC Break: removed support for `doctrine/cache`
58
59Removed support for using doctrine/cache for metadata caching. The
60`setCacheDriver` and `getCacheDriver` methods have been removed from
61`Doctrine\Persistence\Mapping\AbstractMetadata`. Please use `getCache` and
62`setCache` with a PSR-6 implementation instead.
63
64## BC Break: changed signatures
65
66`$objectName` has been dropped from the signature of `ObjectManager::clear()`.
67
68```diff
69- public function clear($objectName = null)
70+ public function clear(): void
71```
72
73Also, native parameter type declarations have been added on all public APIs.
74Native return type declarations have not been added so that it is possible to
75implement types compatible with both 2.x and 3.x.
76
77## BC Break: Removed `PersistentObject`
78
79Please implement this functionality directly in your application if you want
80ActiveRecord style functionality.
81
82# Upgrade to 2.5
83
84## Deprecated `OnClearEventArgs::clearsAllEntities()` and `OnClearEventArgs::getEntityClass()`
85
86These methods only make sense when partially clearing the object manager, which
87is deprecated.
88Passing a second argument to the constructor of `OnClearEventArgs` is
89deprecated as well.
90
91## Deprecated `ObjectManagerAware`
92
93Along with deprecating `PersistentObject`, deprecating `ObjectManagerAware`
94means deprecating support for active record, which already came with a word of
95warning. Please implement this directly in your application with a `postLoad`
96event if you need active record style functionality.
97
98## Deprecated `MappingException::pathRequired()`
99
100`MappingException::pathRequiredForDriver()` should be used instead.
101
102# Upgrade to 2.4
103
104## Deprecated `AnnotationDriver`
105
106Since attributes were introduced in PHP 8.0, annotations are deprecated.
107`AnnotationDriver` is an abstract class that is used when implementing concrete
108annotation drivers in dependent packages. It is deprecated in favor of using
109`ColocatedMappingDriver` to implement both annotation and attribute based
110drivers. This will involve implementing `isTransient()` as well as
111`__construct()` and `getReader()` to retain backward compatibility.
112
113# Upgrade to 2.3
114
115## Deprecated using short namespace alias syntax in favor of `::class` syntax.
116
117Before:
118
119```php
120$objectManager->find('MyPackage:MyClass', $id);
121$objectManager->createQuery('SELECT u FROM MyPackage:MyClass');
122```
123
124After:
125
126```php
127$objectManager->find(MyClass::class, $id);
128$objectManager->createQuery('SELECT u FROM '. MyClass::class);
129```
130
131# Upgrade to 2.2
132
133## Deprecated `doctrine/cache` usage for metadata caching
134
135The `setCacheDriver` and `getCacheDriver` methods in
136`Doctrine\Persistence\Mapping\AbstractMetadata` have been deprecated. Please
137use `getCache` and `setCache` with a PSR-6 implementation instead. Note that
138even after switching to PSR-6, `getCacheDriver` will return a cache instance
139that wraps the PSR-6 cache. Note that if you use a custom implementation of
140doctrine/cache, the library may not be able to provide a forward compatibility
141layer. The cache implementation MUST extend the
142`Doctrine\Common\Cache\CacheProvider` class.
143
144# Upgrade to 1.2
145
146## Deprecated `ObjectManager::merge()` and `ObjectManager::detach()`
147
148Please handle merge operations in your application, and use
149`ObjectManager::clear()` instead.
150
151## Deprecated `PersistentObject`
152
153Please implement this functionality directly in your application if you want
154ActiveRecord style functionality.
diff --git a/vendor/doctrine/persistence/composer.json b/vendor/doctrine/persistence/composer.json
new file mode 100644
index 0000000..03d832f
--- /dev/null
+++ b/vendor/doctrine/persistence/composer.json
@@ -0,0 +1,58 @@
1{
2 "name": "doctrine/persistence",
3 "type": "library",
4 "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.",
5 "keywords": [
6 "persistence",
7 "object",
8 "mapper",
9 "orm",
10 "odm"
11 ],
12 "homepage": "https://www.doctrine-project.org/projects/persistence.html",
13 "license": "MIT",
14 "authors": [
15 {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
16 {"name": "Roman Borschel", "email": "roman@code-factory.org"},
17 {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
18 {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
19 {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"},
20 {"name": "Marco Pivetta", "email": "ocramius@gmail.com"}
21 ],
22 "require": {
23 "php": "^7.2 || ^8.0",
24 "doctrine/event-manager": "^1 || ^2",
25 "psr/cache": "^1.0 || ^2.0 || ^3.0"
26 },
27 "require-dev": {
28 "phpstan/phpstan": "1.11.1",
29 "phpstan/phpstan-phpunit": "^1",
30 "phpstan/phpstan-strict-rules": "^1.1",
31 "doctrine/coding-standard": "^12",
32 "doctrine/common": "^3.0",
33 "phpunit/phpunit": "^8.5 || ^9.5",
34 "symfony/cache": "^4.4 || ^5.4 || ^6.0",
35 "vimeo/psalm": "4.30.0 || 5.24.0"
36 },
37 "conflict": {
38 "doctrine/common": "<2.10"
39 },
40 "autoload": {
41 "psr-4": {
42 "Doctrine\\Persistence\\": "src/Persistence"
43 }
44 },
45 "autoload-dev": {
46 "psr-4": {
47 "Doctrine\\Tests\\": "tests",
48 "Doctrine\\Tests_PHP74\\": "tests_php74",
49 "Doctrine\\Tests_PHP81\\": "tests_php81"
50 }
51 },
52 "config": {
53 "allow-plugins": {
54 "dealerdirect/phpcodesniffer-composer-installer": true,
55 "composer/package-versions-deprecated": true
56 }
57 }
58}
diff --git a/vendor/doctrine/persistence/src/Persistence/AbstractManagerRegistry.php b/vendor/doctrine/persistence/src/Persistence/AbstractManagerRegistry.php
new file mode 100644
index 0000000..cc245ba
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/AbstractManagerRegistry.php
@@ -0,0 +1,269 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7use InvalidArgumentException;
8use ReflectionClass;
9
10use function assert;
11use function sprintf;
12
13/**
14 * Abstract implementation of the ManagerRegistry contract.
15 */
16abstract class AbstractManagerRegistry implements ManagerRegistry
17{
18 /** @var string */
19 private $name;
20
21 /** @var array<string, string> */
22 private $connections;
23
24 /** @var array<string, string> */
25 private $managers;
26
27 /** @var string */
28 private $defaultConnection;
29
30 /** @var string */
31 private $defaultManager;
32
33 /**
34 * @var string
35 * @psalm-var class-string
36 */
37 private $proxyInterfaceName;
38
39 /**
40 * @param array<string, string> $connections
41 * @param array<string, string> $managers
42 * @psalm-param class-string $proxyInterfaceName
43 */
44 public function __construct(
45 string $name,
46 array $connections,
47 array $managers,
48 string $defaultConnection,
49 string $defaultManager,
50 string $proxyInterfaceName
51 ) {
52 $this->name = $name;
53 $this->connections = $connections;
54 $this->managers = $managers;
55 $this->defaultConnection = $defaultConnection;
56 $this->defaultManager = $defaultManager;
57 $this->proxyInterfaceName = $proxyInterfaceName;
58 }
59
60 /**
61 * Fetches/creates the given services.
62 *
63 * A service in this context is connection or a manager instance.
64 *
65 * @param string $name The name of the service.
66 *
67 * @return object The instance of the given service.
68 */
69 abstract protected function getService(string $name);
70
71 /**
72 * Resets the given services.
73 *
74 * A service in this context is connection or a manager instance.
75 *
76 * @param string $name The name of the service.
77 *
78 * @return void
79 */
80 abstract protected function resetService(string $name);
81
82 /**
83 * Gets the name of the registry.
84 *
85 * @return string
86 */
87 public function getName()
88 {
89 return $this->name;
90 }
91
92 /**
93 * {@inheritDoc}
94 */
95 public function getConnection(?string $name = null)
96 {
97 if ($name === null) {
98 $name = $this->defaultConnection;
99 }
100
101 if (! isset($this->connections[$name])) {
102 throw new InvalidArgumentException(
103 sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name)
104 );
105 }
106
107 return $this->getService($this->connections[$name]);
108 }
109
110 /**
111 * {@inheritDoc}
112 */
113 public function getConnectionNames()
114 {
115 return $this->connections;
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 public function getConnections()
122 {
123 $connections = [];
124 foreach ($this->connections as $name => $id) {
125 $connections[$name] = $this->getService($id);
126 }
127
128 return $connections;
129 }
130
131 /**
132 * {@inheritDoc}
133 */
134 public function getDefaultConnectionName()
135 {
136 return $this->defaultConnection;
137 }
138
139 /**
140 * {@inheritDoc}
141 */
142 public function getDefaultManagerName()
143 {
144 return $this->defaultManager;
145 }
146
147 /**
148 * {@inheritDoc}
149 *
150 * @throws InvalidArgumentException
151 */
152 public function getManager(?string $name = null)
153 {
154 if ($name === null) {
155 $name = $this->defaultManager;
156 }
157
158 if (! isset($this->managers[$name])) {
159 throw new InvalidArgumentException(
160 sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name)
161 );
162 }
163
164 $service = $this->getService($this->managers[$name]);
165 assert($service instanceof ObjectManager);
166
167 return $service;
168 }
169
170 /**
171 * {@inheritDoc}
172 */
173 public function getManagerForClass(string $class)
174 {
175 $proxyClass = new ReflectionClass($class);
176 if ($proxyClass->isAnonymous()) {
177 return null;
178 }
179
180 if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
181 $parentClass = $proxyClass->getParentClass();
182
183 if ($parentClass === false) {
184 return null;
185 }
186
187 $class = $parentClass->getName();
188 }
189
190 foreach ($this->managers as $id) {
191 $manager = $this->getService($id);
192 assert($manager instanceof ObjectManager);
193
194 if (! $manager->getMetadataFactory()->isTransient($class)) {
195 return $manager;
196 }
197 }
198
199 return null;
200 }
201
202 /**
203 * {@inheritDoc}
204 */
205 public function getManagerNames()
206 {
207 return $this->managers;
208 }
209
210 /**
211 * {@inheritDoc}
212 */
213 public function getManagers()
214 {
215 $managers = [];
216
217 foreach ($this->managers as $name => $id) {
218 $manager = $this->getService($id);
219 assert($manager instanceof ObjectManager);
220 $managers[$name] = $manager;
221 }
222
223 return $managers;
224 }
225
226 /**
227 * {@inheritDoc}
228 */
229 public function getRepository(
230 string $persistentObject,
231 ?string $persistentManagerName = null
232 ) {
233 return $this
234 ->selectManager($persistentObject, $persistentManagerName)
235 ->getRepository($persistentObject);
236 }
237
238 /**
239 * {@inheritDoc}
240 */
241 public function resetManager(?string $name = null)
242 {
243 if ($name === null) {
244 $name = $this->defaultManager;
245 }
246
247 if (! isset($this->managers[$name])) {
248 throw new InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
249 }
250
251 // force the creation of a new document manager
252 // if the current one is closed
253 $this->resetService($this->managers[$name]);
254
255 return $this->getManager($name);
256 }
257
258 /** @psalm-param class-string $persistentObject */
259 private function selectManager(
260 string $persistentObject,
261 ?string $persistentManagerName = null
262 ): ObjectManager {
263 if ($persistentManagerName !== null) {
264 return $this->getManager($persistentManagerName);
265 }
266
267 return $this->getManagerForClass($persistentObject) ?? $this->getManager();
268 }
269}
diff --git a/vendor/doctrine/persistence/src/Persistence/ConnectionRegistry.php b/vendor/doctrine/persistence/src/Persistence/ConnectionRegistry.php
new file mode 100644
index 0000000..59d9a74
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/ConnectionRegistry.php
@@ -0,0 +1,41 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7/**
8 * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement.
9 */
10interface ConnectionRegistry
11{
12 /**
13 * Gets the default connection name.
14 *
15 * @return string The default connection name.
16 */
17 public function getDefaultConnectionName();
18
19 /**
20 * Gets the named connection.
21 *
22 * @param string|null $name The connection name (null for the default one).
23 *
24 * @return object
25 */
26 public function getConnection(?string $name = null);
27
28 /**
29 * Gets an array of all registered connections.
30 *
31 * @return array<string, object> An array of Connection instances.
32 */
33 public function getConnections();
34
35 /**
36 * Gets all connection names.
37 *
38 * @return array<string, string> An array of connection names.
39 */
40 public function getConnectionNames();
41}
diff --git a/vendor/doctrine/persistence/src/Persistence/Event/LifecycleEventArgs.php b/vendor/doctrine/persistence/src/Persistence/Event/LifecycleEventArgs.php
new file mode 100644
index 0000000..1654de4
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Event/LifecycleEventArgs.php
@@ -0,0 +1,54 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Event;
6
7use Doctrine\Common\EventArgs;
8use Doctrine\Persistence\ObjectManager;
9
10/**
11 * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
12 * of entities.
13 *
14 * @template-covariant TObjectManager of ObjectManager
15 */
16class LifecycleEventArgs extends EventArgs
17{
18 /**
19 * @var ObjectManager
20 * @psalm-var TObjectManager
21 */
22 private $objectManager;
23
24 /** @var object */
25 private $object;
26
27 /** @psalm-param TObjectManager $objectManager */
28 public function __construct(object $object, ObjectManager $objectManager)
29 {
30 $this->object = $object;
31 $this->objectManager = $objectManager;
32 }
33
34 /**
35 * Retrieves the associated object.
36 *
37 * @return object
38 */
39 public function getObject()
40 {
41 return $this->object;
42 }
43
44 /**
45 * Retrieves the associated ObjectManager.
46 *
47 * @return ObjectManager
48 * @psalm-return TObjectManager
49 */
50 public function getObjectManager()
51 {
52 return $this->objectManager;
53 }
54}
diff --git a/vendor/doctrine/persistence/src/Persistence/Event/LoadClassMetadataEventArgs.php b/vendor/doctrine/persistence/src/Persistence/Event/LoadClassMetadataEventArgs.php
new file mode 100644
index 0000000..aa92d5d
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Event/LoadClassMetadataEventArgs.php
@@ -0,0 +1,61 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Event;
6
7use Doctrine\Common\EventArgs;
8use Doctrine\Persistence\Mapping\ClassMetadata;
9use Doctrine\Persistence\ObjectManager;
10
11/**
12 * Class that holds event arguments for a loadMetadata event.
13 *
14 * @template-covariant TClassMetadata of ClassMetadata<object>
15 * @template-covariant TObjectManager of ObjectManager
16 */
17class LoadClassMetadataEventArgs extends EventArgs
18{
19 /**
20 * @var ClassMetadata
21 * @psalm-var TClassMetadata
22 */
23 private $classMetadata;
24
25 /**
26 * @var ObjectManager
27 * @psalm-var TObjectManager
28 */
29 private $objectManager;
30
31 /**
32 * @psalm-param TClassMetadata $classMetadata
33 * @psalm-param TObjectManager $objectManager
34 */
35 public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager)
36 {
37 $this->classMetadata = $classMetadata;
38 $this->objectManager = $objectManager;
39 }
40
41 /**
42 * Retrieves the associated ClassMetadata.
43 *
44 * @return ClassMetadata
45 * @psalm-return TClassMetadata
46 */
47 public function getClassMetadata()
48 {
49 return $this->classMetadata;
50 }
51
52 /**
53 * Retrieves the associated ObjectManager.
54 *
55 * @return TObjectManager
56 */
57 public function getObjectManager()
58 {
59 return $this->objectManager;
60 }
61}
diff --git a/vendor/doctrine/persistence/src/Persistence/Event/ManagerEventArgs.php b/vendor/doctrine/persistence/src/Persistence/Event/ManagerEventArgs.php
new file mode 100644
index 0000000..5156013
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Event/ManagerEventArgs.php
@@ -0,0 +1,39 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Event;
6
7use Doctrine\Common\EventArgs;
8use Doctrine\Persistence\ObjectManager;
9
10/**
11 * Provides event arguments for the preFlush event.
12 *
13 * @template-covariant TObjectManager of ObjectManager
14 */
15class ManagerEventArgs extends EventArgs
16{
17 /**
18 * @var ObjectManager
19 * @psalm-var TObjectManager
20 */
21 private $objectManager;
22
23 /** @psalm-param TObjectManager $objectManager */
24 public function __construct(ObjectManager $objectManager)
25 {
26 $this->objectManager = $objectManager;
27 }
28
29 /**
30 * Retrieves the associated ObjectManager.
31 *
32 * @return ObjectManager
33 * @psalm-return TObjectManager
34 */
35 public function getObjectManager()
36 {
37 return $this->objectManager;
38 }
39}
diff --git a/vendor/doctrine/persistence/src/Persistence/Event/OnClearEventArgs.php b/vendor/doctrine/persistence/src/Persistence/Event/OnClearEventArgs.php
new file mode 100644
index 0000000..519a887
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Event/OnClearEventArgs.php
@@ -0,0 +1,42 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Event;
6
7use Doctrine\Common\EventArgs;
8use Doctrine\Persistence\ObjectManager;
9
10/**
11 * Provides event arguments for the onClear event.
12 *
13 * @template-covariant TObjectManager of ObjectManager
14 */
15class OnClearEventArgs extends EventArgs
16{
17 /**
18 * @var ObjectManager
19 * @psalm-var TObjectManager
20 */
21 private $objectManager;
22
23 /**
24 * @param ObjectManager $objectManager The object manager.
25 * @psalm-param TObjectManager $objectManager
26 */
27 public function __construct(ObjectManager $objectManager)
28 {
29 $this->objectManager = $objectManager;
30 }
31
32 /**
33 * Retrieves the associated ObjectManager.
34 *
35 * @return ObjectManager
36 * @psalm-return TObjectManager
37 */
38 public function getObjectManager()
39 {
40 return $this->objectManager;
41 }
42}
diff --git a/vendor/doctrine/persistence/src/Persistence/Event/PreUpdateEventArgs.php b/vendor/doctrine/persistence/src/Persistence/Event/PreUpdateEventArgs.php
new file mode 100644
index 0000000..95ecbd4
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Event/PreUpdateEventArgs.php
@@ -0,0 +1,110 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Event;
6
7use Doctrine\Persistence\ObjectManager;
8use InvalidArgumentException;
9
10use function get_class;
11use function sprintf;
12
13/**
14 * Class that holds event arguments for a preUpdate event.
15 *
16 * @template-covariant TObjectManager of ObjectManager
17 * @extends LifecycleEventArgs<TObjectManager>
18 */
19class PreUpdateEventArgs extends LifecycleEventArgs
20{
21 /** @var array<string, array<int, mixed>> */
22 private $entityChangeSet;
23
24 /**
25 * @param array<string, array<int, mixed>> $changeSet
26 * @psalm-param TObjectManager $objectManager
27 */
28 public function __construct(object $entity, ObjectManager $objectManager, array &$changeSet)
29 {
30 parent::__construct($entity, $objectManager);
31
32 $this->entityChangeSet = &$changeSet;
33 }
34
35 /**
36 * Retrieves the entity changeset.
37 *
38 * @return array<string, array<int, mixed>>
39 */
40 public function getEntityChangeSet()
41 {
42 return $this->entityChangeSet;
43 }
44
45 /**
46 * Checks if field has a changeset.
47 *
48 * @return bool
49 */
50 public function hasChangedField(string $field)
51 {
52 return isset($this->entityChangeSet[$field]);
53 }
54
55 /**
56 * Gets the old value of the changeset of the changed field.
57 *
58 * @return mixed
59 */
60 public function getOldValue(string $field)
61 {
62 $this->assertValidField($field);
63
64 return $this->entityChangeSet[$field][0];
65 }
66
67 /**
68 * Gets the new value of the changeset of the changed field.
69 *
70 * @return mixed
71 */
72 public function getNewValue(string $field)
73 {
74 $this->assertValidField($field);
75
76 return $this->entityChangeSet[$field][1];
77 }
78
79 /**
80 * Sets the new value of this field.
81 *
82 * @param mixed $value
83 *
84 * @return void
85 */
86 public function setNewValue(string $field, $value)
87 {
88 $this->assertValidField($field);
89
90 $this->entityChangeSet[$field][1] = $value;
91 }
92
93 /**
94 * Asserts the field exists in changeset.
95 *
96 * @return void
97 *
98 * @throws InvalidArgumentException
99 */
100 private function assertValidField(string $field)
101 {
102 if (! isset($this->entityChangeSet[$field])) {
103 throw new InvalidArgumentException(sprintf(
104 'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
105 $field,
106 get_class($this->getObject())
107 ));
108 }
109 }
110}
diff --git a/vendor/doctrine/persistence/src/Persistence/ManagerRegistry.php b/vendor/doctrine/persistence/src/Persistence/ManagerRegistry.php
new file mode 100644
index 0000000..46599a5
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/ManagerRegistry.php
@@ -0,0 +1,89 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7/**
8 * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement.
9 */
10interface ManagerRegistry extends ConnectionRegistry
11{
12 /**
13 * Gets the default object manager name.
14 *
15 * @return string The default object manager name.
16 */
17 public function getDefaultManagerName();
18
19 /**
20 * Gets a named object manager.
21 *
22 * @param string|null $name The object manager name (null for the default one).
23 *
24 * @return ObjectManager
25 */
26 public function getManager(?string $name = null);
27
28 /**
29 * Gets an array of all registered object managers.
30 *
31 * @return array<string, ObjectManager> An array of ObjectManager instances
32 */
33 public function getManagers();
34
35 /**
36 * Resets a named object manager.
37 *
38 * This method is useful when an object manager has been closed
39 * because of a rollbacked transaction AND when you think that
40 * it makes sense to get a new one to replace the closed one.
41 *
42 * Be warned that you will get a brand new object manager as
43 * the existing one is not useable anymore. This means that any
44 * other object with a dependency on this object manager will
45 * hold an obsolete reference. You can inject the registry instead
46 * to avoid this problem.
47 *
48 * @param string|null $name The object manager name (null for the default one).
49 *
50 * @return ObjectManager
51 */
52 public function resetManager(?string $name = null);
53
54 /**
55 * Gets all object manager names and associated service IDs. A service ID
56 * is a string that allows to obtain an object manager, typically from a
57 * PSR-11 container.
58 *
59 * @return array<string,string> An array with object manager names as keys,
60 * and service IDs as values.
61 */
62 public function getManagerNames();
63
64 /**
65 * Gets the ObjectRepository for a persistent object.
66 *
67 * @param string $persistentObject The name of the persistent object.
68 * @param string|null $persistentManagerName The object manager name (null for the default one).
69 * @psalm-param class-string<T> $persistentObject
70 *
71 * @return ObjectRepository
72 * @psalm-return ObjectRepository<T>
73 *
74 * @template T of object
75 */
76 public function getRepository(
77 string $persistentObject,
78 ?string $persistentManagerName = null
79 );
80
81 /**
82 * Gets the object manager associated with a given class.
83 *
84 * @param class-string $class A persistent object class name.
85 *
86 * @return ObjectManager|null
87 */
88 public function getManagerForClass(string $class);
89}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php b/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php
new file mode 100644
index 0000000..e8f6aca
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php
@@ -0,0 +1,499 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use Doctrine\Persistence\Mapping\Driver\MappingDriver;
8use Doctrine\Persistence\Proxy;
9use Psr\Cache\CacheItemPoolInterface;
10use ReflectionClass;
11use ReflectionException;
12
13use function array_combine;
14use function array_keys;
15use function array_map;
16use function array_reverse;
17use function array_unshift;
18use function assert;
19use function class_exists;
20use function ltrim;
21use function str_replace;
22use function strpos;
23use function strrpos;
24use function substr;
25
26/**
27 * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
28 * metadata mapping informations of a class which describes how a class should be mapped
29 * to a relational database.
30 *
31 * This class was abstracted from the ORM ClassMetadataFactory.
32 *
33 * @template CMTemplate of ClassMetadata
34 * @template-implements ClassMetadataFactory<CMTemplate>
35 */
36abstract class AbstractClassMetadataFactory implements ClassMetadataFactory
37{
38 /**
39 * Salt used by specific Object Manager implementation.
40 *
41 * @var string
42 */
43 protected $cacheSalt = '__CLASSMETADATA__';
44
45 /** @var CacheItemPoolInterface|null */
46 private $cache;
47
48 /**
49 * @var array<string, ClassMetadata>
50 * @psalm-var CMTemplate[]
51 */
52 private $loadedMetadata = [];
53
54 /** @var bool */
55 protected $initialized = false;
56
57 /** @var ReflectionService|null */
58 private $reflectionService = null;
59
60 /** @var ProxyClassNameResolver|null */
61 private $proxyClassNameResolver = null;
62
63 public function setCache(CacheItemPoolInterface $cache): void
64 {
65 $this->cache = $cache;
66 }
67
68 final protected function getCache(): ?CacheItemPoolInterface
69 {
70 return $this->cache;
71 }
72
73 /**
74 * Returns an array of all the loaded metadata currently in memory.
75 *
76 * @return ClassMetadata[]
77 * @psalm-return CMTemplate[]
78 */
79 public function getLoadedMetadata()
80 {
81 return $this->loadedMetadata;
82 }
83
84 /**
85 * {@inheritDoc}
86 */
87 public function getAllMetadata()
88 {
89 if (! $this->initialized) {
90 $this->initialize();
91 }
92
93 $driver = $this->getDriver();
94 $metadata = [];
95 foreach ($driver->getAllClassNames() as $className) {
96 $metadata[] = $this->getMetadataFor($className);
97 }
98
99 return $metadata;
100 }
101
102 public function setProxyClassNameResolver(ProxyClassNameResolver $resolver): void
103 {
104 $this->proxyClassNameResolver = $resolver;
105 }
106
107 /**
108 * Lazy initialization of this stuff, especially the metadata driver,
109 * since these are not needed at all when a metadata cache is active.
110 *
111 * @return void
112 */
113 abstract protected function initialize();
114
115 /**
116 * Returns the mapping driver implementation.
117 *
118 * @return MappingDriver
119 */
120 abstract protected function getDriver();
121
122 /**
123 * Wakes up reflection after ClassMetadata gets unserialized from cache.
124 *
125 * @psalm-param CMTemplate $class
126 *
127 * @return void
128 */
129 abstract protected function wakeupReflection(
130 ClassMetadata $class,
131 ReflectionService $reflService
132 );
133
134 /**
135 * Initializes Reflection after ClassMetadata was constructed.
136 *
137 * @psalm-param CMTemplate $class
138 *
139 * @return void
140 */
141 abstract protected function initializeReflection(
142 ClassMetadata $class,
143 ReflectionService $reflService
144 );
145
146 /**
147 * Checks whether the class metadata is an entity.
148 *
149 * This method should return false for mapped superclasses or embedded classes.
150 *
151 * @psalm-param CMTemplate $class
152 *
153 * @return bool
154 */
155 abstract protected function isEntity(ClassMetadata $class);
156
157 /**
158 * Removes the prepended backslash of a class string to conform with how php outputs class names
159 *
160 * @psalm-param class-string $className
161 *
162 * @psalm-return class-string
163 */
164 private function normalizeClassName(string $className): string
165 {
166 return ltrim($className, '\\');
167 }
168
169 /**
170 * {@inheritDoc}
171 *
172 * @throws ReflectionException
173 * @throws MappingException
174 */
175 public function getMetadataFor(string $className)
176 {
177 $className = $this->normalizeClassName($className);
178
179 if (isset($this->loadedMetadata[$className])) {
180 return $this->loadedMetadata[$className];
181 }
182
183 if (class_exists($className, false) && (new ReflectionClass($className))->isAnonymous()) {
184 throw MappingException::classIsAnonymous($className);
185 }
186
187 if (! class_exists($className, false) && strpos($className, ':') !== false) {
188 throw MappingException::nonExistingClass($className);
189 }
190
191 $realClassName = $this->getRealClass($className);
192
193 if (isset($this->loadedMetadata[$realClassName])) {
194 // We do not have the alias name in the map, include it
195 return $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
196 }
197
198 try {
199 if ($this->cache !== null) {
200 $cached = $this->cache->getItem($this->getCacheKey($realClassName))->get();
201 if ($cached instanceof ClassMetadata) {
202 /** @psalm-var CMTemplate $cached */
203 $this->loadedMetadata[$realClassName] = $cached;
204
205 $this->wakeupReflection($cached, $this->getReflectionService());
206 } else {
207 $loadedMetadata = $this->loadMetadata($realClassName);
208 $classNames = array_combine(
209 array_map([$this, 'getCacheKey'], $loadedMetadata),
210 $loadedMetadata
211 );
212
213 foreach ($this->cache->getItems(array_keys($classNames)) as $item) {
214 if (! isset($classNames[$item->getKey()])) {
215 continue;
216 }
217
218 $item->set($this->loadedMetadata[$classNames[$item->getKey()]]);
219 $this->cache->saveDeferred($item);
220 }
221
222 $this->cache->commit();
223 }
224 } else {
225 $this->loadMetadata($realClassName);
226 }
227 } catch (MappingException $loadingException) {
228 $fallbackMetadataResponse = $this->onNotFoundMetadata($realClassName);
229
230 if ($fallbackMetadataResponse === null) {
231 throw $loadingException;
232 }
233
234 $this->loadedMetadata[$realClassName] = $fallbackMetadataResponse;
235 }
236
237 if ($className !== $realClassName) {
238 // We do not have the alias name in the map, include it
239 $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
240 }
241
242 return $this->loadedMetadata[$className];
243 }
244
245 /**
246 * {@inheritDoc}
247 */
248 public function hasMetadataFor(string $className)
249 {
250 $className = $this->normalizeClassName($className);
251
252 return isset($this->loadedMetadata[$className]);
253 }
254
255 /**
256 * Sets the metadata descriptor for a specific class.
257 *
258 * NOTE: This is only useful in very special cases, like when generating proxy classes.
259 *
260 * @psalm-param class-string $className
261 * @psalm-param CMTemplate $class
262 *
263 * @return void
264 */
265 public function setMetadataFor(string $className, ClassMetadata $class)
266 {
267 $this->loadedMetadata[$this->normalizeClassName($className)] = $class;
268 }
269
270 /**
271 * Gets an array of parent classes for the given entity class.
272 *
273 * @psalm-param class-string $name
274 *
275 * @return string[]
276 * @psalm-return list<class-string>
277 */
278 protected function getParentClasses(string $name)
279 {
280 // Collect parent classes, ignoring transient (not-mapped) classes.
281 $parentClasses = [];
282
283 foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
284 if ($this->getDriver()->isTransient($parentClass)) {
285 continue;
286 }
287
288 $parentClasses[] = $parentClass;
289 }
290
291 return $parentClasses;
292 }
293
294 /**
295 * Loads the metadata of the class in question and all it's ancestors whose metadata
296 * is still not loaded.
297 *
298 * Important: The class $name does not necessarily exist at this point here.
299 * Scenarios in a code-generation setup might have access to XML/YAML
300 * Mapping files without the actual PHP code existing here. That is why the
301 * {@see \Doctrine\Persistence\Mapping\ReflectionService} interface
302 * should be used for reflection.
303 *
304 * @param string $name The name of the class for which the metadata should get loaded.
305 * @psalm-param class-string $name
306 *
307 * @return array<int, string>
308 * @psalm-return list<string>
309 */
310 protected function loadMetadata(string $name)
311 {
312 if (! $this->initialized) {
313 $this->initialize();
314 }
315
316 $loaded = [];
317
318 $parentClasses = $this->getParentClasses($name);
319 $parentClasses[] = $name;
320
321 // Move down the hierarchy of parent classes, starting from the topmost class
322 $parent = null;
323 $rootEntityFound = false;
324 $visited = [];
325 $reflService = $this->getReflectionService();
326
327 foreach ($parentClasses as $className) {
328 if (isset($this->loadedMetadata[$className])) {
329 $parent = $this->loadedMetadata[$className];
330
331 if ($this->isEntity($parent)) {
332 $rootEntityFound = true;
333
334 array_unshift($visited, $className);
335 }
336
337 continue;
338 }
339
340 $class = $this->newClassMetadataInstance($className);
341 $this->initializeReflection($class, $reflService);
342
343 $this->doLoadMetadata($class, $parent, $rootEntityFound, $visited);
344
345 $this->loadedMetadata[$className] = $class;
346
347 $parent = $class;
348
349 if ($this->isEntity($class)) {
350 $rootEntityFound = true;
351
352 array_unshift($visited, $className);
353 }
354
355 $this->wakeupReflection($class, $reflService);
356
357 $loaded[] = $className;
358 }
359
360 return $loaded;
361 }
362
363 /**
364 * Provides a fallback hook for loading metadata when loading failed due to reflection/mapping exceptions
365 *
366 * Override this method to implement a fallback strategy for failed metadata loading
367 *
368 * @return ClassMetadata|null
369 * @psalm-return CMTemplate|null
370 */
371 protected function onNotFoundMetadata(string $className)
372 {
373 return null;
374 }
375
376 /**
377 * Actually loads the metadata from the underlying metadata.
378 *
379 * @param bool $rootEntityFound True when there is another entity (non-mapped superclass) class above the current class in the PHP class hierarchy.
380 * @param list<class-string> $nonSuperclassParents All parent class names that are not marked as mapped superclasses, with the direct parent class being the first and the root entity class the last element.
381 * @psalm-param CMTemplate $class
382 * @psalm-param CMTemplate|null $parent
383 *
384 * @return void
385 */
386 abstract protected function doLoadMetadata(
387 ClassMetadata $class,
388 ?ClassMetadata $parent,
389 bool $rootEntityFound,
390 array $nonSuperclassParents
391 );
392
393 /**
394 * Creates a new ClassMetadata instance for the given class name.
395 *
396 * @psalm-param class-string<T> $className
397 *
398 * @return ClassMetadata<T>
399 * @psalm-return CMTemplate
400 *
401 * @template T of object
402 */
403 abstract protected function newClassMetadataInstance(string $className);
404
405 /**
406 * {@inheritDoc}
407 */
408 public function isTransient(string $className)
409 {
410 if (! $this->initialized) {
411 $this->initialize();
412 }
413
414 if (class_exists($className, false) && (new ReflectionClass($className))->isAnonymous()) {
415 return false;
416 }
417
418 if (! class_exists($className, false) && strpos($className, ':') !== false) {
419 throw MappingException::nonExistingClass($className);
420 }
421
422 /** @psalm-var class-string $className */
423 return $this->getDriver()->isTransient($className);
424 }
425
426 /**
427 * Sets the reflectionService.
428 *
429 * @return void
430 */
431 public function setReflectionService(ReflectionService $reflectionService)
432 {
433 $this->reflectionService = $reflectionService;
434 }
435
436 /**
437 * Gets the reflection service associated with this metadata factory.
438 *
439 * @return ReflectionService
440 */
441 public function getReflectionService()
442 {
443 if ($this->reflectionService === null) {
444 $this->reflectionService = new RuntimeReflectionService();
445 }
446
447 return $this->reflectionService;
448 }
449
450 protected function getCacheKey(string $realClassName): string
451 {
452 return str_replace('\\', '__', $realClassName) . $this->cacheSalt;
453 }
454
455 /**
456 * Gets the real class name of a class name that could be a proxy.
457 *
458 * @psalm-param class-string<Proxy<T>>|class-string<T> $class
459 *
460 * @psalm-return class-string<T>
461 *
462 * @template T of object
463 */
464 private function getRealClass(string $class): string
465 {
466 if ($this->proxyClassNameResolver === null) {
467 $this->createDefaultProxyClassNameResolver();
468 }
469
470 assert($this->proxyClassNameResolver !== null);
471
472 return $this->proxyClassNameResolver->resolveClassName($class);
473 }
474
475 private function createDefaultProxyClassNameResolver(): void
476 {
477 $this->proxyClassNameResolver = new class implements ProxyClassNameResolver {
478 /**
479 * @psalm-param class-string<Proxy<T>>|class-string<T> $className
480 *
481 * @psalm-return class-string<T>
482 *
483 * @template T of object
484 */
485 public function resolveClassName(string $className): string
486 {
487 $pos = strrpos($className, '\\' . Proxy::MARKER . '\\');
488
489 if ($pos === false) {
490 /** @psalm-var class-string<T> */
491 return $className;
492 }
493
494 /** @psalm-var class-string<T> */
495 return substr($className, $pos + Proxy::MARKER_LENGTH + 2);
496 }
497 };
498 }
499}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadata.php b/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadata.php
new file mode 100644
index 0000000..f407ba3
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadata.php
@@ -0,0 +1,141 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use ReflectionClass;
8
9/**
10 * Contract for a Doctrine persistence layer ClassMetadata class to implement.
11 *
12 * @template-covariant T of object
13 */
14interface ClassMetadata
15{
16 /**
17 * Gets the fully-qualified class name of this persistent class.
18 *
19 * @return string
20 * @psalm-return class-string<T>
21 */
22 public function getName();
23
24 /**
25 * Gets the mapped identifier field name.
26 *
27 * The returned structure is an array of the identifier field names.
28 *
29 * @return array<int, string>
30 * @psalm-return list<string>
31 */
32 public function getIdentifier();
33
34 /**
35 * Gets the ReflectionClass instance for this mapped class.
36 *
37 * @return ReflectionClass<T>
38 */
39 public function getReflectionClass();
40
41 /**
42 * Checks if the given field name is a mapped identifier for this class.
43 *
44 * @return bool
45 */
46 public function isIdentifier(string $fieldName);
47
48 /**
49 * Checks if the given field is a mapped property for this class.
50 *
51 * @return bool
52 */
53 public function hasField(string $fieldName);
54
55 /**
56 * Checks if the given field is a mapped association for this class.
57 *
58 * @return bool
59 */
60 public function hasAssociation(string $fieldName);
61
62 /**
63 * Checks if the given field is a mapped single valued association for this class.
64 *
65 * @return bool
66 */
67 public function isSingleValuedAssociation(string $fieldName);
68
69 /**
70 * Checks if the given field is a mapped collection valued association for this class.
71 *
72 * @return bool
73 */
74 public function isCollectionValuedAssociation(string $fieldName);
75
76 /**
77 * A numerically indexed list of field names of this persistent class.
78 *
79 * This array includes identifier fields if present on this class.
80 *
81 * @return array<int, string>
82 */
83 public function getFieldNames();
84
85 /**
86 * Returns an array of identifier field names numerically indexed.
87 *
88 * @return array<int, string>
89 */
90 public function getIdentifierFieldNames();
91
92 /**
93 * Returns a numerically indexed list of association names of this persistent class.
94 *
95 * This array includes identifier associations if present on this class.
96 *
97 * @return array<int, string>
98 */
99 public function getAssociationNames();
100
101 /**
102 * Returns a type name of this field.
103 *
104 * This type names can be implementation specific but should at least include the php types:
105 * integer, string, boolean, float/double, datetime.
106 *
107 * @return string|null
108 */
109 public function getTypeOfField(string $fieldName);
110
111 /**
112 * Returns the target class name of the given association.
113 *
114 * @return string|null
115 * @psalm-return class-string|null
116 */
117 public function getAssociationTargetClass(string $assocName);
118
119 /**
120 * Checks if the association is the inverse side of a bidirectional association.
121 *
122 * @return bool
123 */
124 public function isAssociationInverseSide(string $assocName);
125
126 /**
127 * Returns the target field of the owning side of the association.
128 *
129 * @return string
130 */
131 public function getAssociationMappedByTargetField(string $assocName);
132
133 /**
134 * Returns the identifier of this object as an array with field name as key.
135 *
136 * Has to return an empty array if no identifier isset.
137 *
138 * @return array<string, mixed>
139 */
140 public function getIdentifierValues(object $object);
141}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadataFactory.php b/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadataFactory.php
new file mode 100644
index 0000000..28b8303
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/ClassMetadataFactory.php
@@ -0,0 +1,61 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7/**
8 * Contract for a Doctrine persistence layer ClassMetadata class to implement.
9 *
10 * @template T of ClassMetadata
11 */
12interface ClassMetadataFactory
13{
14 /**
15 * Forces the factory to load the metadata of all classes known to the underlying
16 * mapping driver.
17 *
18 * @return ClassMetadata[] The ClassMetadata instances of all mapped classes.
19 * @psalm-return list<T>
20 */
21 public function getAllMetadata();
22
23 /**
24 * Gets the class metadata descriptor for a class.
25 *
26 * @param class-string $className The name of the class.
27 *
28 * @return ClassMetadata
29 * @psalm-return T
30 */
31 public function getMetadataFor(string $className);
32
33 /**
34 * Checks whether the factory has the metadata for a class loaded already.
35 *
36 * @param class-string $className
37 *
38 * @return bool TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
39 */
40 public function hasMetadataFor(string $className);
41
42 /**
43 * Sets the metadata descriptor for a specific class.
44 *
45 * @param class-string $className
46 * @psalm-param T $class
47 *
48 * @return void
49 */
50 public function setMetadataFor(string $className, ClassMetadata $class);
51
52 /**
53 * Returns whether the class with the specified name should have its metadata loaded.
54 * This is only the case if it is either mapped directly or as a MappedSuperclass.
55 *
56 * @psalm-param class-string $className
57 *
58 * @return bool
59 */
60 public function isTransient(string $className);
61}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php
new file mode 100644
index 0000000..e85ba70
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php
@@ -0,0 +1,212 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\MappingException;
8use FilesystemIterator;
9use RecursiveDirectoryIterator;
10use RecursiveIteratorIterator;
11use RecursiveRegexIterator;
12use ReflectionClass;
13use RegexIterator;
14
15use function array_merge;
16use function array_unique;
17use function assert;
18use function get_declared_classes;
19use function in_array;
20use function is_dir;
21use function preg_match;
22use function preg_quote;
23use function realpath;
24use function str_replace;
25use function strpos;
26
27/**
28 * The ColocatedMappingDriver reads the mapping metadata located near the code.
29 */
30trait ColocatedMappingDriver
31{
32 /**
33 * The paths where to look for mapping files.
34 *
35 * @var array<int, string>
36 */
37 protected $paths = [];
38
39 /**
40 * The paths excluded from path where to look for mapping files.
41 *
42 * @var array<int, string>
43 */
44 protected $excludePaths = [];
45
46 /**
47 * The file extension of mapping documents.
48 *
49 * @var string
50 */
51 protected $fileExtension = '.php';
52
53 /**
54 * Cache for getAllClassNames().
55 *
56 * @var array<int, string>|null
57 * @psalm-var list<class-string>|null
58 */
59 protected $classNames;
60
61 /**
62 * Appends lookup paths to metadata driver.
63 *
64 * @param array<int, string> $paths
65 *
66 * @return void
67 */
68 public function addPaths(array $paths)
69 {
70 $this->paths = array_unique(array_merge($this->paths, $paths));
71 }
72
73 /**
74 * Retrieves the defined metadata lookup paths.
75 *
76 * @return array<int, string>
77 */
78 public function getPaths()
79 {
80 return $this->paths;
81 }
82
83 /**
84 * Append exclude lookup paths to metadata driver.
85 *
86 * @param string[] $paths
87 *
88 * @return void
89 */
90 public function addExcludePaths(array $paths)
91 {
92 $this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
93 }
94
95 /**
96 * Retrieve the defined metadata lookup exclude paths.
97 *
98 * @return array<int, string>
99 */
100 public function getExcludePaths()
101 {
102 return $this->excludePaths;
103 }
104
105 /**
106 * Gets the file extension used to look for mapping files under.
107 *
108 * @return string
109 */
110 public function getFileExtension()
111 {
112 return $this->fileExtension;
113 }
114
115 /**
116 * Sets the file extension used to look for mapping files under.
117 *
118 * @return void
119 */
120 public function setFileExtension(string $fileExtension)
121 {
122 $this->fileExtension = $fileExtension;
123 }
124
125 /**
126 * {@inheritDoc}
127 *
128 * Returns whether the class with the specified name is transient. Only non-transient
129 * classes, that is entities and mapped superclasses, should have their metadata loaded.
130 *
131 * @psalm-param class-string $className
132 *
133 * @return bool
134 */
135 abstract public function isTransient(string $className);
136
137 /**
138 * Gets the names of all mapped classes known to this driver.
139 *
140 * @return string[] The names of all mapped classes known to this driver.
141 * @psalm-return list<class-string>
142 */
143 public function getAllClassNames()
144 {
145 if ($this->classNames !== null) {
146 return $this->classNames;
147 }
148
149 if ($this->paths === []) {
150 throw MappingException::pathRequiredForDriver(static::class);
151 }
152
153 $classes = [];
154 $includedFiles = [];
155
156 foreach ($this->paths as $path) {
157 if (! is_dir($path)) {
158 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
159 }
160
161 $iterator = new RegexIterator(
162 new RecursiveIteratorIterator(
163 new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
164 RecursiveIteratorIterator::LEAVES_ONLY
165 ),
166 '/^.+' . preg_quote($this->fileExtension) . '$/i',
167 RecursiveRegexIterator::GET_MATCH
168 );
169
170 foreach ($iterator as $file) {
171 $sourceFile = $file[0];
172
173 if (preg_match('(^phar:)i', $sourceFile) === 0) {
174 $sourceFile = realpath($sourceFile);
175 }
176
177 foreach ($this->excludePaths as $excludePath) {
178 $realExcludePath = realpath($excludePath);
179 assert($realExcludePath !== false);
180 $exclude = str_replace('\\', '/', $realExcludePath);
181 $current = str_replace('\\', '/', $sourceFile);
182
183 if (strpos($current, $exclude) !== false) {
184 continue 2;
185 }
186 }
187
188 require_once $sourceFile;
189
190 $includedFiles[] = $sourceFile;
191 }
192 }
193
194 $declared = get_declared_classes();
195
196 foreach ($declared as $className) {
197 $rc = new ReflectionClass($className);
198
199 $sourceFile = $rc->getFileName();
200
201 if (! in_array($sourceFile, $includedFiles, true) || $this->isTransient($className)) {
202 continue;
203 }
204
205 $classes[] = $className;
206 }
207
208 $this->classNames = $classes;
209
210 return $classes;
211 }
212}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/DefaultFileLocator.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/DefaultFileLocator.php
new file mode 100644
index 0000000..9b00e74
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/DefaultFileLocator.php
@@ -0,0 +1,175 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\MappingException;
8use RecursiveDirectoryIterator;
9use RecursiveIteratorIterator;
10
11use function array_merge;
12use function array_unique;
13use function assert;
14use function is_dir;
15use function is_file;
16use function is_string;
17use function str_replace;
18
19use const DIRECTORY_SEPARATOR;
20
21/**
22 * Locates the file that contains the metadata information for a given class name.
23 *
24 * This behavior is independent of the actual content of the file. It just detects
25 * the file which is responsible for the given class name.
26 */
27class DefaultFileLocator implements FileLocator
28{
29 /**
30 * The paths where to look for mapping files.
31 *
32 * @var array<int, string>
33 */
34 protected $paths = [];
35
36 /**
37 * The file extension of mapping documents.
38 *
39 * @var string|null
40 */
41 protected $fileExtension;
42
43 /**
44 * Initializes a new FileDriver that looks in the given path(s) for mapping
45 * documents and operates in the specified operating mode.
46 *
47 * @param string|array<int, string> $paths One or multiple paths where mapping documents
48 * can be found.
49 * @param string|null $fileExtension The file extension of mapping documents,
50 * usually prefixed with a dot.
51 */
52 public function __construct($paths, ?string $fileExtension = null)
53 {
54 $this->addPaths((array) $paths);
55 $this->fileExtension = $fileExtension;
56 }
57
58 /**
59 * Appends lookup paths to metadata driver.
60 *
61 * @param array<int, string> $paths
62 *
63 * @return void
64 */
65 public function addPaths(array $paths)
66 {
67 $this->paths = array_unique(array_merge($this->paths, $paths));
68 }
69
70 /**
71 * Retrieves the defined metadata lookup paths.
72 *
73 * @return array<int, string>
74 */
75 public function getPaths()
76 {
77 return $this->paths;
78 }
79
80 /**
81 * Gets the file extension used to look for mapping files under.
82 *
83 * @return string|null
84 */
85 public function getFileExtension()
86 {
87 return $this->fileExtension;
88 }
89
90 /**
91 * Sets the file extension used to look for mapping files under.
92 *
93 * @param string|null $fileExtension The file extension to set.
94 *
95 * @return void
96 */
97 public function setFileExtension(?string $fileExtension)
98 {
99 $this->fileExtension = $fileExtension;
100 }
101
102 /**
103 * {@inheritDoc}
104 */
105 public function findMappingFile(string $className)
106 {
107 $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
108
109 // Check whether file exists
110 foreach ($this->paths as $path) {
111 if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
112 return $path . DIRECTORY_SEPARATOR . $fileName;
113 }
114 }
115
116 throw MappingException::mappingFileNotFound($className, $fileName);
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 public function getAllClassNames(string $globalBasename)
123 {
124 if ($this->paths === []) {
125 return [];
126 }
127
128 $classes = [];
129
130 foreach ($this->paths as $path) {
131 if (! is_dir($path)) {
132 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
133 }
134
135 $iterator = new RecursiveIteratorIterator(
136 new RecursiveDirectoryIterator($path),
137 RecursiveIteratorIterator::LEAVES_ONLY
138 );
139
140 foreach ($iterator as $file) {
141 $fileName = $file->getBasename($this->fileExtension);
142
143 if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
144 continue;
145 }
146
147 // NOTE: All files found here means classes are not transient!
148
149 assert(is_string($fileName));
150 /** @psalm-var class-string */
151 $class = str_replace('.', '\\', $fileName);
152 $classes[] = $class;
153 }
154 }
155
156 return $classes;
157 }
158
159 /**
160 * {@inheritDoc}
161 */
162 public function fileExists(string $className)
163 {
164 $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
165
166 // Check whether file exists
167 foreach ($this->paths as $path) {
168 if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
169 return true;
170 }
171 }
172
173 return false;
174 }
175}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php
new file mode 100644
index 0000000..c116233
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php
@@ -0,0 +1,213 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8use Doctrine\Persistence\Mapping\MappingException;
9
10use function array_keys;
11use function array_merge;
12use function array_unique;
13use function array_values;
14use function is_file;
15use function str_replace;
16
17/**
18 * Base driver for file-based metadata drivers.
19 *
20 * A file driver operates in a mode where it loads the mapping files of individual
21 * classes on demand. This requires the user to adhere to the convention of 1 mapping
22 * file per class and the file names of the mapping files must correspond to the full
23 * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
24 *
25 * @template T
26 */
27abstract class FileDriver implements MappingDriver
28{
29 /** @var FileLocator */
30 protected $locator;
31
32 /**
33 * @var mixed[]|null
34 * @psalm-var array<class-string, T>|null
35 */
36 protected $classCache;
37
38 /** @var string */
39 protected $globalBasename = '';
40
41 /**
42 * Initializes a new FileDriver that looks in the given path(s) for mapping
43 * documents and operates in the specified operating mode.
44 *
45 * @param string|array<int, string>|FileLocator $locator A FileLocator or one/multiple paths
46 * where mapping documents can be found.
47 */
48 public function __construct($locator, ?string $fileExtension = null)
49 {
50 if ($locator instanceof FileLocator) {
51 $this->locator = $locator;
52 } else {
53 $this->locator = new DefaultFileLocator((array) $locator, $fileExtension);
54 }
55 }
56
57 /**
58 * Sets the global basename.
59 *
60 * @return void
61 */
62 public function setGlobalBasename(string $file)
63 {
64 $this->globalBasename = $file;
65 }
66
67 /**
68 * Retrieves the global basename.
69 *
70 * @return string|null
71 */
72 public function getGlobalBasename()
73 {
74 return $this->globalBasename;
75 }
76
77 /**
78 * Gets the element of schema meta data for the class from the mapping file.
79 * This will lazily load the mapping file if it is not loaded yet.
80 *
81 * @psalm-param class-string $className
82 *
83 * @return T The element of schema meta data.
84 *
85 * @throws MappingException
86 */
87 public function getElement(string $className)
88 {
89 if ($this->classCache === null) {
90 $this->initialize();
91 }
92
93 if (isset($this->classCache[$className])) {
94 return $this->classCache[$className];
95 }
96
97 $result = $this->loadMappingFile($this->locator->findMappingFile($className));
98
99 if (! isset($result[$className])) {
100 throw MappingException::invalidMappingFile(
101 $className,
102 str_replace('\\', '.', $className) . $this->locator->getFileExtension()
103 );
104 }
105
106 $this->classCache[$className] = $result[$className];
107
108 return $result[$className];
109 }
110
111 /**
112 * {@inheritDoc}
113 */
114 public function isTransient(string $className)
115 {
116 if ($this->classCache === null) {
117 $this->initialize();
118 }
119
120 if (isset($this->classCache[$className])) {
121 return false;
122 }
123
124 return ! $this->locator->fileExists($className);
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 public function getAllClassNames()
131 {
132 if ($this->classCache === null) {
133 $this->initialize();
134 }
135
136 if ($this->classCache === []) {
137 return $this->locator->getAllClassNames($this->globalBasename);
138 }
139
140 /** @psalm-var array<class-string, ClassMetadata<object>> $classCache */
141 $classCache = $this->classCache;
142
143 /** @var list<class-string> $keys */
144 $keys = array_keys($classCache);
145
146 return array_values(array_unique(array_merge(
147 $keys,
148 $this->locator->getAllClassNames($this->globalBasename)
149 )));
150 }
151
152 /**
153 * Loads a mapping file with the given name and returns a map
154 * from class/entity names to their corresponding file driver elements.
155 *
156 * @param string $file The mapping file to load.
157 *
158 * @return mixed[]
159 * @psalm-return array<class-string, T>
160 */
161 abstract protected function loadMappingFile(string $file);
162
163 /**
164 * Initializes the class cache from all the global files.
165 *
166 * Using this feature adds a substantial performance hit to file drivers as
167 * more metadata has to be loaded into memory than might actually be
168 * necessary. This may not be relevant to scenarios where caching of
169 * metadata is in place, however hits very hard in scenarios where no
170 * caching is used.
171 *
172 * @return void
173 */
174 protected function initialize()
175 {
176 $this->classCache = [];
177 if ($this->globalBasename === '') {
178 return;
179 }
180
181 foreach ($this->locator->getPaths() as $path) {
182 $file = $path . '/' . $this->globalBasename . $this->locator->getFileExtension();
183 if (! is_file($file)) {
184 continue;
185 }
186
187 $this->classCache = array_merge(
188 $this->classCache,
189 $this->loadMappingFile($file)
190 );
191 }
192 }
193
194 /**
195 * Retrieves the locator used to discover mapping files by className.
196 *
197 * @return FileLocator
198 */
199 public function getLocator()
200 {
201 return $this->locator;
202 }
203
204 /**
205 * Sets the locator used to discover mapping files by className.
206 *
207 * @return void
208 */
209 public function setLocator(FileLocator $locator)
210 {
211 $this->locator = $locator;
212 }
213}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileLocator.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileLocator.php
new file mode 100644
index 0000000..e57d539
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileLocator.php
@@ -0,0 +1,52 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7/**
8 * Locates the file that contains the metadata information for a given class name.
9 *
10 * This behavior is independent of the actual content of the file. It just detects
11 * the file which is responsible for the given class name.
12 */
13interface FileLocator
14{
15 /**
16 * Locates mapping file for the given class name.
17 *
18 * @return string
19 */
20 public function findMappingFile(string $className);
21
22 /**
23 * Gets all class names that are found with this file locator.
24 *
25 * @param string $globalBasename Passed to allow excluding the basename.
26 *
27 * @return array<int, string>
28 * @psalm-return list<class-string>
29 */
30 public function getAllClassNames(string $globalBasename);
31
32 /**
33 * Checks if a file can be found for this class name.
34 *
35 * @return bool
36 */
37 public function fileExists(string $className);
38
39 /**
40 * Gets all the paths that this file locator looks for mapping files.
41 *
42 * @return array<int, string>
43 */
44 public function getPaths();
45
46 /**
47 * Gets the file extension that mapping files are suffixed with.
48 *
49 * @return string|null
50 */
51 public function getFileExtension();
52}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriver.php
new file mode 100644
index 0000000..9b6f0c8
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriver.php
@@ -0,0 +1,43 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8
9/**
10 * Contract for metadata drivers.
11 */
12interface MappingDriver
13{
14 /**
15 * Loads the metadata for the specified class into the provided container.
16 *
17 * @psalm-param class-string<T> $className
18 * @psalm-param ClassMetadata<T> $metadata
19 *
20 * @return void
21 *
22 * @template T of object
23 */
24 public function loadMetadataForClass(string $className, ClassMetadata $metadata);
25
26 /**
27 * Gets the names of all mapped classes known to this driver.
28 *
29 * @return array<int, string> The names of all mapped classes known to this driver.
30 * @psalm-return list<class-string>
31 */
32 public function getAllClassNames();
33
34 /**
35 * Returns whether the class with the specified name should have its metadata loaded.
36 * This is only the case if it is either mapped as an Entity or a MappedSuperclass.
37 *
38 * @psalm-param class-string $className
39 *
40 * @return bool
41 */
42 public function isTransient(string $className);
43}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriverChain.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriverChain.php
new file mode 100644
index 0000000..8563dd2
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriverChain.php
@@ -0,0 +1,142 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8use Doctrine\Persistence\Mapping\MappingException;
9
10use function array_keys;
11use function spl_object_hash;
12use function strpos;
13
14/**
15 * The DriverChain allows you to add multiple other mapping drivers for
16 * certain namespaces.
17 */
18class MappingDriverChain implements MappingDriver
19{
20 /**
21 * The default driver.
22 *
23 * @var MappingDriver|null
24 */
25 private $defaultDriver;
26
27 /** @var array<string, MappingDriver> */
28 private $drivers = [];
29
30 /**
31 * Gets the default driver.
32 *
33 * @return MappingDriver|null
34 */
35 public function getDefaultDriver()
36 {
37 return $this->defaultDriver;
38 }
39
40 /**
41 * Set the default driver.
42 *
43 * @return void
44 */
45 public function setDefaultDriver(MappingDriver $driver)
46 {
47 $this->defaultDriver = $driver;
48 }
49
50 /**
51 * Adds a nested driver.
52 *
53 * @return void
54 */
55 public function addDriver(MappingDriver $nestedDriver, string $namespace)
56 {
57 $this->drivers[$namespace] = $nestedDriver;
58 }
59
60 /**
61 * Gets the array of nested drivers.
62 *
63 * @return array<string, MappingDriver> $drivers
64 */
65 public function getDrivers()
66 {
67 return $this->drivers;
68 }
69
70 /**
71 * {@inheritDoc}
72 */
73 public function loadMetadataForClass(string $className, ClassMetadata $metadata)
74 {
75 foreach ($this->drivers as $namespace => $driver) {
76 if (strpos($className, $namespace) === 0) {
77 $driver->loadMetadataForClass($className, $metadata);
78
79 return;
80 }
81 }
82
83 if ($this->defaultDriver !== null) {
84 $this->defaultDriver->loadMetadataForClass($className, $metadata);
85
86 return;
87 }
88
89 throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers));
90 }
91
92 /**
93 * {@inheritDoc}
94 */
95 public function getAllClassNames()
96 {
97 $classNames = [];
98 $driverClasses = [];
99
100 foreach ($this->drivers as $namespace => $driver) {
101 $oid = spl_object_hash($driver);
102
103 if (! isset($driverClasses[$oid])) {
104 $driverClasses[$oid] = $driver->getAllClassNames();
105 }
106
107 foreach ($driverClasses[$oid] as $className) {
108 if (strpos($className, $namespace) !== 0) {
109 continue;
110 }
111
112 $classNames[$className] = true;
113 }
114 }
115
116 if ($this->defaultDriver !== null) {
117 foreach ($this->defaultDriver->getAllClassNames() as $className) {
118 $classNames[$className] = true;
119 }
120 }
121
122 return array_keys($classNames);
123 }
124
125 /**
126 * {@inheritDoc}
127 */
128 public function isTransient(string $className)
129 {
130 foreach ($this->drivers as $namespace => $driver) {
131 if (strpos($className, $namespace) === 0) {
132 return $driver->isTransient($className);
133 }
134 }
135
136 if ($this->defaultDriver !== null) {
137 return $this->defaultDriver->isTransient($className);
138 }
139
140 return true;
141 }
142}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/PHPDriver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/PHPDriver.php
new file mode 100644
index 0000000..1c1ab9c
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/PHPDriver.php
@@ -0,0 +1,49 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8
9/**
10 * The PHPDriver includes php files which just populate ClassMetadataInfo
11 * instances with plain PHP code.
12 *
13 * @template-extends FileDriver<ClassMetadata<object>>
14 */
15class PHPDriver extends FileDriver
16{
17 /**
18 * @var ClassMetadata
19 * @psalm-var ClassMetadata<object>
20 */
21 protected $metadata;
22
23 /** @param string|array<int, string>|FileLocator $locator */
24 public function __construct($locator)
25 {
26 parent::__construct($locator, '.php');
27 }
28
29 /**
30 * {@inheritDoc}
31 */
32 public function loadMetadataForClass(string $className, ClassMetadata $metadata)
33 {
34 $this->metadata = $metadata;
35
36 $this->loadMappingFile($this->locator->findMappingFile($className));
37 }
38
39 /**
40 * {@inheritDoc}
41 */
42 protected function loadMappingFile(string $file)
43 {
44 $metadata = $this->metadata;
45 include $file;
46
47 return [$metadata->getName() => $metadata];
48 }
49}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/StaticPHPDriver.php
new file mode 100644
index 0000000..bbcff75
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/StaticPHPDriver.php
@@ -0,0 +1,132 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8use Doctrine\Persistence\Mapping\MappingException;
9use RecursiveDirectoryIterator;
10use RecursiveIteratorIterator;
11use ReflectionClass;
12
13use function array_merge;
14use function array_unique;
15use function get_declared_classes;
16use function in_array;
17use function is_dir;
18use function method_exists;
19use function realpath;
20
21/**
22 * The StaticPHPDriver calls a static loadMetadata() method on your entity
23 * classes where you can manually populate the ClassMetadata instance.
24 */
25class StaticPHPDriver implements MappingDriver
26{
27 /**
28 * Paths of entity directories.
29 *
30 * @var array<int, string>
31 */
32 private $paths = [];
33
34 /**
35 * Map of all class names.
36 *
37 * @var array<int, string>
38 * @psalm-var list<class-string>
39 */
40 private $classNames;
41
42 /** @param array<int, string>|string $paths */
43 public function __construct($paths)
44 {
45 $this->addPaths((array) $paths);
46 }
47
48 /**
49 * @param array<int, string> $paths
50 *
51 * @return void
52 */
53 public function addPaths(array $paths)
54 {
55 $this->paths = array_unique(array_merge($this->paths, $paths));
56 }
57
58 /**
59 * {@inheritDoc}
60 */
61 public function loadMetadataForClass(string $className, ClassMetadata $metadata)
62 {
63 $className::loadMetadata($metadata);
64 }
65
66 /**
67 * {@inheritDoc}
68 *
69 * @todo Same code exists in ColocatedMappingDriver, should we re-use it
70 * somehow or not worry about it?
71 */
72 public function getAllClassNames()
73 {
74 if ($this->classNames !== null) {
75 return $this->classNames;
76 }
77
78 if ($this->paths === []) {
79 throw MappingException::pathRequiredForDriver(static::class);
80 }
81
82 $classes = [];
83 $includedFiles = [];
84
85 foreach ($this->paths as $path) {
86 if (! is_dir($path)) {
87 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
88 }
89
90 $iterator = new RecursiveIteratorIterator(
91 new RecursiveDirectoryIterator($path),
92 RecursiveIteratorIterator::LEAVES_ONLY
93 );
94
95 foreach ($iterator as $file) {
96 if ($file->getBasename('.php') === $file->getBasename()) {
97 continue;
98 }
99
100 $sourceFile = realpath($file->getPathName());
101 require_once $sourceFile;
102 $includedFiles[] = $sourceFile;
103 }
104 }
105
106 $declared = get_declared_classes();
107
108 foreach ($declared as $className) {
109 $rc = new ReflectionClass($className);
110
111 $sourceFile = $rc->getFileName();
112
113 if (! in_array($sourceFile, $includedFiles, true) || $this->isTransient($className)) {
114 continue;
115 }
116
117 $classes[] = $className;
118 }
119
120 $this->classNames = $classes;
121
122 return $classes;
123 }
124
125 /**
126 * {@inheritDoc}
127 */
128 public function isTransient(string $className)
129 {
130 return ! method_exists($className, 'loadMetadata');
131 }
132}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/SymfonyFileLocator.php b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/SymfonyFileLocator.php
new file mode 100644
index 0000000..428d5fb
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/SymfonyFileLocator.php
@@ -0,0 +1,265 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping\Driver;
6
7use Doctrine\Persistence\Mapping\MappingException;
8use InvalidArgumentException;
9use RecursiveDirectoryIterator;
10use RecursiveIteratorIterator;
11use RuntimeException;
12
13use function array_keys;
14use function array_merge;
15use function assert;
16use function is_dir;
17use function is_file;
18use function is_int;
19use function realpath;
20use function sprintf;
21use function str_replace;
22use function strlen;
23use function strpos;
24use function strrpos;
25use function strtr;
26use function substr;
27
28use const DIRECTORY_SEPARATOR;
29
30/**
31 * The Symfony File Locator makes a simplifying assumptions compared
32 * to the DefaultFileLocator. By assuming paths only contain entities of a certain
33 * namespace the mapping files consists of the short classname only.
34 */
35class SymfonyFileLocator implements FileLocator
36{
37 /**
38 * The paths where to look for mapping files.
39 *
40 * @var array<int, string>
41 */
42 protected $paths = [];
43
44 /**
45 * A map of mapping directory path to namespace prefix used to expand class shortnames.
46 *
47 * @var array<string, string>
48 */
49 protected $prefixes = [];
50
51 /**
52 * File extension that is searched for.
53 *
54 * @var string|null
55 */
56 protected $fileExtension;
57
58 /**
59 * Represents PHP namespace delimiters when looking for files
60 *
61 * @var string
62 */
63 private $nsSeparator;
64
65 /**
66 * @param array<string, string> $prefixes
67 * @param string $nsSeparator String which would be used when converting FQCN
68 * to filename and vice versa. Should not be empty
69 */
70 public function __construct(
71 array $prefixes,
72 string $fileExtension = '',
73 string $nsSeparator = '.'
74 ) {
75 $this->addNamespacePrefixes($prefixes);
76 $this->fileExtension = $fileExtension;
77
78 if ($nsSeparator === '') {
79 throw new InvalidArgumentException('Namespace separator should not be empty');
80 }
81
82 $this->nsSeparator = $nsSeparator;
83 }
84
85 /**
86 * Adds Namespace Prefixes.
87 *
88 * @param array<string, string> $prefixes
89 *
90 * @return void
91 */
92 public function addNamespacePrefixes(array $prefixes)
93 {
94 $this->prefixes = array_merge($this->prefixes, $prefixes);
95 $this->paths = array_merge($this->paths, array_keys($prefixes));
96 }
97
98 /**
99 * Gets Namespace Prefixes.
100 *
101 * @return string[]
102 */
103 public function getNamespacePrefixes()
104 {
105 return $this->prefixes;
106 }
107
108 /**
109 * {@inheritDoc}
110 */
111 public function getPaths()
112 {
113 return $this->paths;
114 }
115
116 /**
117 * {@inheritDoc}
118 */
119 public function getFileExtension()
120 {
121 return $this->fileExtension;
122 }
123
124 /**
125 * Sets the file extension used to look for mapping files under.
126 *
127 * @param string $fileExtension The file extension to set.
128 *
129 * @return void
130 */
131 public function setFileExtension(string $fileExtension)
132 {
133 $this->fileExtension = $fileExtension;
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 public function fileExists(string $className)
140 {
141 $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
142 foreach ($this->paths as $path) {
143 if (! isset($this->prefixes[$path])) {
144 // global namespace class
145 if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
146 return true;
147 }
148
149 continue;
150 }
151
152 $prefix = $this->prefixes[$path];
153
154 if (strpos($className, $prefix . '\\') !== 0) {
155 continue;
156 }
157
158 $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
159
160 if (is_file($filename)) {
161 return true;
162 }
163 }
164
165 return false;
166 }
167
168 /**
169 * {@inheritDoc}
170 */
171 public function getAllClassNames(?string $globalBasename = null)
172 {
173 if ($this->paths === []) {
174 return [];
175 }
176
177 $classes = [];
178
179 foreach ($this->paths as $path) {
180 if (! is_dir($path)) {
181 throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
182 }
183
184 $iterator = new RecursiveIteratorIterator(
185 new RecursiveDirectoryIterator($path),
186 RecursiveIteratorIterator::LEAVES_ONLY
187 );
188
189 foreach ($iterator as $file) {
190 $fileName = $file->getBasename($this->fileExtension);
191
192 if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
193 continue;
194 }
195
196 // NOTE: All files found here means classes are not transient!
197 if (isset($this->prefixes[$path])) {
198 // Calculate namespace suffix for given prefix as a relative path from basepath to file path
199 $nsSuffix = strtr(
200 substr($this->realpath($file->getPath()), strlen($this->realpath($path))),
201 $this->nsSeparator,
202 '\\'
203 );
204
205 /** @psalm-var class-string */
206 $class = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName);
207 } else {
208 /** @psalm-var class-string */
209 $class = str_replace($this->nsSeparator, '\\', $fileName);
210 }
211
212 $classes[] = $class;
213 }
214 }
215
216 return $classes;
217 }
218
219 /**
220 * {@inheritDoc}
221 */
222 public function findMappingFile(string $className)
223 {
224 $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
225 foreach ($this->paths as $path) {
226 if (! isset($this->prefixes[$path])) {
227 if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
228 return $path . DIRECTORY_SEPARATOR . $defaultFileName;
229 }
230
231 continue;
232 }
233
234 $prefix = $this->prefixes[$path];
235
236 if (strpos($className, $prefix . '\\') !== 0) {
237 continue;
238 }
239
240 $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
241 if (is_file($filename)) {
242 return $filename;
243 }
244 }
245
246 $pos = strrpos($className, '\\');
247 assert(is_int($pos));
248
249 throw MappingException::mappingFileNotFound(
250 $className,
251 substr($className, $pos + 1) . $this->fileExtension
252 );
253 }
254
255 private function realpath(string $path): string
256 {
257 $realpath = realpath($path);
258
259 if ($realpath === false) {
260 throw new RuntimeException(sprintf('Could not get realpath for %s', $path));
261 }
262
263 return $realpath;
264 }
265}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php b/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php
new file mode 100644
index 0000000..f0bc4eb
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php
@@ -0,0 +1,88 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use Exception;
8
9use function implode;
10use function sprintf;
11
12/**
13 * A MappingException indicates that something is wrong with the mapping setup.
14 */
15class MappingException extends Exception
16{
17 /**
18 * @param array<int, string> $namespaces
19 *
20 * @return self
21 */
22 public static function classNotFoundInNamespaces(
23 string $className,
24 array $namespaces
25 ) {
26 return new self(sprintf(
27 "The class '%s' was not found in the chain configured namespaces %s",
28 $className,
29 implode(', ', $namespaces)
30 ));
31 }
32
33 /** @param class-string $driverClassName */
34 public static function pathRequiredForDriver(string $driverClassName): self
35 {
36 return new self(sprintf(
37 'Specifying the paths to your entities is required when using %s to retrieve all class names.',
38 $driverClassName
39 ));
40 }
41
42 /** @return self */
43 public static function fileMappingDriversRequireConfiguredDirectoryPath(
44 ?string $path = null
45 ) {
46 if ($path !== null) {
47 $path = '[' . $path . ']';
48 }
49
50 return new self(sprintf(
51 'File mapping drivers must have a valid directory path, ' .
52 'however the given path %s seems to be incorrect!',
53 (string) $path
54 ));
55 }
56
57 /** @return self */
58 public static function mappingFileNotFound(string $entityName, string $fileName)
59 {
60 return new self(sprintf(
61 "No mapping file found named '%s' for class '%s'.",
62 $fileName,
63 $entityName
64 ));
65 }
66
67 /** @return self */
68 public static function invalidMappingFile(string $entityName, string $fileName)
69 {
70 return new self(sprintf(
71 "Invalid mapping file '%s' for class '%s'.",
72 $fileName,
73 $entityName
74 ));
75 }
76
77 /** @return self */
78 public static function nonExistingClass(string $className)
79 {
80 return new self(sprintf("Class '%s' does not exist", $className));
81 }
82
83 /** @param class-string $className */
84 public static function classIsAnonymous(string $className): self
85 {
86 return new self(sprintf('Class "%s" is anonymous', $className));
87 }
88}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/ProxyClassNameResolver.php b/vendor/doctrine/persistence/src/Persistence/Mapping/ProxyClassNameResolver.php
new file mode 100644
index 0000000..2801d90
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/ProxyClassNameResolver.php
@@ -0,0 +1,19 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use Doctrine\Persistence\Proxy;
8
9interface ProxyClassNameResolver
10{
11 /**
12 * @psalm-param class-string<Proxy<T>>|class-string<T> $className
13 *
14 * @psalm-return class-string<T>
15 *
16 * @template T of object
17 */
18 public function resolveClassName(string $className): string;
19}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/ReflectionService.php b/vendor/doctrine/persistence/src/Persistence/Mapping/ReflectionService.php
new file mode 100644
index 0000000..9484e1f
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/ReflectionService.php
@@ -0,0 +1,75 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use ReflectionClass;
8use ReflectionProperty;
9
10/**
11 * Very simple reflection service abstraction.
12 *
13 * This is required inside metadata layers that may require either
14 * static or runtime reflection.
15 */
16interface ReflectionService
17{
18 /**
19 * Returns an array of the parent classes (not interfaces) for the given class.
20 *
21 * @psalm-param class-string $class
22 *
23 * @return string[]
24 * @psalm-return class-string[]
25 *
26 * @throws MappingException
27 */
28 public function getParentClasses(string $class);
29
30 /**
31 * Returns the shortname of a class.
32 *
33 * @psalm-param class-string $class
34 *
35 * @return string
36 */
37 public function getClassShortName(string $class);
38
39 /**
40 * @psalm-param class-string $class
41 *
42 * @return string
43 */
44 public function getClassNamespace(string $class);
45
46 /**
47 * Returns a reflection class instance or null.
48 *
49 * @psalm-param class-string<T> $class
50 *
51 * @return ReflectionClass|null
52 * @psalm-return ReflectionClass<T>|null
53 *
54 * @template T of object
55 */
56 public function getClass(string $class);
57
58 /**
59 * Returns an accessible property (setAccessible(true)) or null.
60 *
61 * @psalm-param class-string $class
62 *
63 * @return ReflectionProperty|null
64 */
65 public function getAccessibleProperty(string $class, string $property);
66
67 /**
68 * Checks if the class have a public method with the given name.
69 *
70 * @psalm-param class-string $class
71 *
72 * @return bool
73 */
74 public function hasPublicMethod(string $class, string $method);
75}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/RuntimeReflectionService.php b/vendor/doctrine/persistence/src/Persistence/Mapping/RuntimeReflectionService.php
new file mode 100644
index 0000000..399e057
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/RuntimeReflectionService.php
@@ -0,0 +1,111 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use Doctrine\Persistence\Reflection\RuntimeReflectionProperty;
8use Doctrine\Persistence\Reflection\TypedNoDefaultReflectionProperty;
9use ReflectionClass;
10use ReflectionException;
11use ReflectionMethod;
12
13use function array_key_exists;
14use function assert;
15use function class_exists;
16use function class_parents;
17use function phpversion;
18use function version_compare;
19
20/**
21 * PHP Runtime Reflection Service.
22 */
23class RuntimeReflectionService implements ReflectionService
24{
25 /** @var bool */
26 private $supportsTypedPropertiesWorkaround;
27
28 public function __construct()
29 {
30 $this->supportsTypedPropertiesWorkaround = version_compare(phpversion(), '7.4.0') >= 0;
31 }
32
33 /**
34 * {@inheritDoc}
35 */
36 public function getParentClasses(string $class)
37 {
38 if (! class_exists($class)) {
39 throw MappingException::nonExistingClass($class);
40 }
41
42 $parents = class_parents($class);
43
44 assert($parents !== false);
45
46 return $parents;
47 }
48
49 /**
50 * {@inheritDoc}
51 */
52 public function getClassShortName(string $class)
53 {
54 $reflectionClass = new ReflectionClass($class);
55
56 return $reflectionClass->getShortName();
57 }
58
59 /**
60 * {@inheritDoc}
61 */
62 public function getClassNamespace(string $class)
63 {
64 $reflectionClass = new ReflectionClass($class);
65
66 return $reflectionClass->getNamespaceName();
67 }
68
69 /**
70 * @psalm-param class-string<T> $class
71 *
72 * @return ReflectionClass
73 * @psalm-return ReflectionClass<T>
74 *
75 * @template T of object
76 */
77 public function getClass(string $class)
78 {
79 return new ReflectionClass($class);
80 }
81
82 /**
83 * {@inheritDoc}
84 */
85 public function getAccessibleProperty(string $class, string $property)
86 {
87 $reflectionProperty = new RuntimeReflectionProperty($class, $property);
88
89 if ($this->supportsTypedPropertiesWorkaround && ! array_key_exists($property, $this->getClass($class)->getDefaultProperties())) {
90 $reflectionProperty = new TypedNoDefaultReflectionProperty($class, $property);
91 }
92
93 $reflectionProperty->setAccessible(true);
94
95 return $reflectionProperty;
96 }
97
98 /**
99 * {@inheritDoc}
100 */
101 public function hasPublicMethod(string $class, string $method)
102 {
103 try {
104 $reflectionMethod = new ReflectionMethod($class, $method);
105 } catch (ReflectionException $e) {
106 return false;
107 }
108
109 return $reflectionMethod->isPublic();
110 }
111}
diff --git a/vendor/doctrine/persistence/src/Persistence/Mapping/StaticReflectionService.php b/vendor/doctrine/persistence/src/Persistence/Mapping/StaticReflectionService.php
new file mode 100644
index 0000000..c9f2147
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Mapping/StaticReflectionService.php
@@ -0,0 +1,78 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Mapping;
6
7use function strpos;
8use function strrev;
9use function strrpos;
10use function substr;
11
12/**
13 * PHP Runtime Reflection Service.
14 */
15class StaticReflectionService implements ReflectionService
16{
17 /**
18 * {@inheritDoc}
19 */
20 public function getParentClasses(string $class)
21 {
22 return [];
23 }
24
25 /**
26 * {@inheritDoc}
27 */
28 public function getClassShortName(string $class)
29 {
30 $nsSeparatorLastPosition = strrpos($class, '\\');
31
32 if ($nsSeparatorLastPosition !== false) {
33 $class = substr($class, $nsSeparatorLastPosition + 1);
34 }
35
36 return $class;
37 }
38
39 /**
40 * {@inheritDoc}
41 */
42 public function getClassNamespace(string $class)
43 {
44 $namespace = '';
45
46 if (strpos($class, '\\') !== false) {
47 $namespace = strrev(substr(strrev($class), (int) strpos(strrev($class), '\\') + 1));
48 }
49
50 return $namespace;
51 }
52
53 /**
54 * {@inheritDoc}
55 *
56 * @return null
57 */
58 public function getClass(string $class)
59 {
60 return null;
61 }
62
63 /**
64 * {@inheritDoc}
65 */
66 public function getAccessibleProperty(string $class, string $property)
67 {
68 return null;
69 }
70
71 /**
72 * {@inheritDoc}
73 */
74 public function hasPublicMethod(string $class, string $method)
75 {
76 return true;
77 }
78}
diff --git a/vendor/doctrine/persistence/src/Persistence/NotifyPropertyChanged.php b/vendor/doctrine/persistence/src/Persistence/NotifyPropertyChanged.php
new file mode 100644
index 0000000..8eecf9b
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/NotifyPropertyChanged.php
@@ -0,0 +1,22 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7/**
8 * Interface for classes that notify event listeners of changes to their managed properties.
9 *
10 * This interface is implemented by objects that manually want to notify their object manager or
11 * other listeners when properties change, instead of relying on the object manager to compute
12 * property changes itself when changes are to be persisted.
13 */
14interface NotifyPropertyChanged
15{
16 /**
17 * Adds a listener that wants to be notified about property changes.
18 *
19 * @return void
20 */
21 public function addPropertyChangedListener(PropertyChangedListener $listener);
22}
diff --git a/vendor/doctrine/persistence/src/Persistence/ObjectManager.php b/vendor/doctrine/persistence/src/Persistence/ObjectManager.php
new file mode 100644
index 0000000..efac5c3
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/ObjectManager.php
@@ -0,0 +1,145 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8use Doctrine\Persistence\Mapping\ClassMetadataFactory;
9
10/**
11 * Contract for a Doctrine persistence layer ObjectManager class to implement.
12 *
13 * @method bool isUninitializedObject(mixed $value) Implementing this method will be mandatory in version 4.
14 */
15interface ObjectManager
16{
17 /**
18 * Finds an object by its identifier.
19 *
20 * This is just a convenient shortcut for getRepository($className)->find($id).
21 *
22 * @param string $className The class name of the object to find.
23 * @param mixed $id The identity of the object to find.
24 * @psalm-param class-string<T> $className
25 *
26 * @return object|null The found object.
27 * @psalm-return T|null
28 *
29 * @template T of object
30 */
31 public function find(string $className, $id);
32
33 /**
34 * Tells the ObjectManager to make an instance managed and persistent.
35 *
36 * The object will be entered into the database as a result of the flush operation.
37 *
38 * NOTE: The persist operation always considers objects that are not yet known to
39 * this ObjectManager as NEW. Do not pass detached objects to the persist operation.
40 *
41 * @param object $object The instance to make managed and persistent.
42 *
43 * @return void
44 */
45 public function persist(object $object);
46
47 /**
48 * Removes an object instance.
49 *
50 * A removed object will be removed from the database as a result of the flush operation.
51 *
52 * @param object $object The object instance to remove.
53 *
54 * @return void
55 */
56 public function remove(object $object);
57
58 /**
59 * Clears the ObjectManager. All objects that are currently managed
60 * by this ObjectManager become detached.
61 *
62 * @return void
63 */
64 public function clear();
65
66 /**
67 * Detaches an object from the ObjectManager, causing a managed object to
68 * become detached. Unflushed changes made to the object if any
69 * (including removal of the object), will not be synchronized to the database.
70 * Objects which previously referenced the detached object will continue to
71 * reference it.
72 *
73 * @param object $object The object to detach.
74 *
75 * @return void
76 */
77 public function detach(object $object);
78
79 /**
80 * Refreshes the persistent state of an object from the database,
81 * overriding any local changes that have not yet been persisted.
82 *
83 * @param object $object The object to refresh.
84 *
85 * @return void
86 */
87 public function refresh(object $object);
88
89 /**
90 * Flushes all changes to objects that have been queued up to now to the database.
91 * This effectively synchronizes the in-memory state of managed objects with the
92 * database.
93 *
94 * @return void
95 */
96 public function flush();
97
98 /**
99 * Gets the repository for a class.
100 *
101 * @psalm-param class-string<T> $className
102 *
103 * @psalm-return ObjectRepository<T>
104 *
105 * @template T of object
106 */
107 public function getRepository(string $className);
108
109 /**
110 * Returns the ClassMetadata descriptor for a class.
111 *
112 * The class name must be the fully-qualified class name without a leading backslash
113 * (as it is returned by get_class($obj)).
114 *
115 * @psalm-param class-string<T> $className
116 *
117 * @psalm-return ClassMetadata<T>
118 *
119 * @template T of object
120 */
121 public function getClassMetadata(string $className);
122
123 /**
124 * Gets the metadata factory used to gather the metadata of classes.
125 *
126 * @psalm-return ClassMetadataFactory<ClassMetadata<object>>
127 */
128 public function getMetadataFactory();
129
130 /**
131 * Helper method to initialize a lazy loading proxy or persistent collection.
132 *
133 * This method is a no-op for other objects.
134 *
135 * @return void
136 */
137 public function initializeObject(object $obj);
138
139 /**
140 * Checks if the object is part of the current UnitOfWork and therefore managed.
141 *
142 * @return bool
143 */
144 public function contains(object $object);
145}
diff --git a/vendor/doctrine/persistence/src/Persistence/ObjectManagerDecorator.php b/vendor/doctrine/persistence/src/Persistence/ObjectManagerDecorator.php
new file mode 100644
index 0000000..8c038b8
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/ObjectManagerDecorator.php
@@ -0,0 +1,92 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7use Doctrine\Persistence\Mapping\ClassMetadata;
8use Doctrine\Persistence\Mapping\ClassMetadataFactory;
9
10/**
11 * Base class to simplify ObjectManager decorators
12 *
13 * @template-covariant TObjectManager of ObjectManager
14 */
15abstract class ObjectManagerDecorator implements ObjectManager
16{
17 /** @var TObjectManager */
18 protected $wrapped;
19
20 /**
21 * {@inheritDoc}
22 */
23 public function find(string $className, $id)
24 {
25 return $this->wrapped->find($className, $id);
26 }
27
28 public function persist(object $object)
29 {
30 $this->wrapped->persist($object);
31 }
32
33 public function remove(object $object)
34 {
35 $this->wrapped->remove($object);
36 }
37
38 public function clear(): void
39 {
40 $this->wrapped->clear();
41 }
42
43 public function detach(object $object)
44 {
45 $this->wrapped->detach($object);
46 }
47
48 public function refresh(object $object)
49 {
50 $this->wrapped->refresh($object);
51 }
52
53 public function flush()
54 {
55 $this->wrapped->flush();
56 }
57
58 /**
59 * {@inheritDoc}
60 */
61 public function getRepository(string $className)
62 {
63 return $this->wrapped->getRepository($className);
64 }
65
66 /**
67 * {@inheritDoc}
68 */
69 public function getClassMetadata(string $className)
70 {
71 return $this->wrapped->getClassMetadata($className);
72 }
73
74 /** @psalm-return ClassMetadataFactory<ClassMetadata<object>> */
75 public function getMetadataFactory()
76 {
77 return $this->wrapped->getMetadataFactory();
78 }
79
80 public function initializeObject(object $obj)
81 {
82 $this->wrapped->initializeObject($obj);
83 }
84
85 /**
86 * {@inheritDoc}
87 */
88 public function contains(object $object)
89 {
90 return $this->wrapped->contains($object);
91 }
92}
diff --git a/vendor/doctrine/persistence/src/Persistence/ObjectRepository.php b/vendor/doctrine/persistence/src/Persistence/ObjectRepository.php
new file mode 100644
index 0000000..a714731
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/ObjectRepository.php
@@ -0,0 +1,73 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7use UnexpectedValueException;
8
9/**
10 * Contract for a Doctrine persistence layer ObjectRepository class to implement.
11 *
12 * @template-covariant T of object
13 */
14interface ObjectRepository
15{
16 /**
17 * Finds an object by its primary key / identifier.
18 *
19 * @param mixed $id The identifier.
20 *
21 * @return object|null The object.
22 * @psalm-return T|null
23 */
24 public function find($id);
25
26 /**
27 * Finds all objects in the repository.
28 *
29 * @return array<int, object> The objects.
30 * @psalm-return T[]
31 */
32 public function findAll();
33
34 /**
35 * Finds objects by a set of criteria.
36 *
37 * Optionally sorting and limiting details can be passed. An implementation may throw
38 * an UnexpectedValueException if certain values of the sorting or limiting details are
39 * not supported.
40 *
41 * @param array<string, mixed> $criteria
42 * @param array<string, string>|null $orderBy
43 * @psalm-param array<string, 'asc'|'desc'|'ASC'|'DESC'>|null $orderBy
44 *
45 * @return array<int, object> The objects.
46 * @psalm-return T[]
47 *
48 * @throws UnexpectedValueException
49 */
50 public function findBy(
51 array $criteria,
52 ?array $orderBy = null,
53 ?int $limit = null,
54 ?int $offset = null
55 );
56
57 /**
58 * Finds a single object by a set of criteria.
59 *
60 * @param array<string, mixed> $criteria The criteria.
61 *
62 * @return object|null The object.
63 * @psalm-return T|null
64 */
65 public function findOneBy(array $criteria);
66
67 /**
68 * Returns the class name of the object managed by the repository.
69 *
70 * @psalm-return class-string<T>
71 */
72 public function getClassName();
73}
diff --git a/vendor/doctrine/persistence/src/Persistence/PropertyChangedListener.php b/vendor/doctrine/persistence/src/Persistence/PropertyChangedListener.php
new file mode 100644
index 0000000..6b50707
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/PropertyChangedListener.php
@@ -0,0 +1,24 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7/**
8 * Contract for classes that are potential listeners of a {@see NotifyPropertyChanged}
9 * implementor.
10 */
11interface PropertyChangedListener
12{
13 /**
14 * Collect information about a property change.
15 *
16 * @param object $sender The object on which the property changed.
17 * @param string $propertyName The name of the property that changed.
18 * @param mixed $oldValue The old value of the property that changed.
19 * @param mixed $newValue The new value of the property that changed.
20 *
21 * @return void
22 */
23 public function propertyChanged(object $sender, string $propertyName, $oldValue, $newValue);
24}
diff --git a/vendor/doctrine/persistence/src/Persistence/Proxy.php b/vendor/doctrine/persistence/src/Persistence/Proxy.php
new file mode 100644
index 0000000..2c02f23
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Proxy.php
@@ -0,0 +1,39 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence;
6
7/**
8 * Interface for proxy classes.
9 *
10 * @template T of object
11 */
12interface Proxy
13{
14 /**
15 * Marker for Proxy class names.
16 */
17 public const MARKER = '__CG__';
18
19 /**
20 * Length of the proxy marker.
21 */
22 public const MARKER_LENGTH = 6;
23
24 /**
25 * Initializes this proxy if its not yet initialized.
26 *
27 * Acts as a no-op if already initialized.
28 *
29 * @return void
30 */
31 public function __load();
32
33 /**
34 * Returns whether this proxy is initialized or not.
35 *
36 * @return bool
37 */
38 public function __isInitialized();
39}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/EnumReflectionProperty.php b/vendor/doctrine/persistence/src/Persistence/Reflection/EnumReflectionProperty.php
new file mode 100644
index 0000000..114b9db
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/EnumReflectionProperty.php
@@ -0,0 +1,181 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7use BackedEnum;
8use ReflectionClass;
9use ReflectionProperty;
10use ReflectionType;
11use ReturnTypeWillChange;
12
13use function array_map;
14use function is_array;
15use function reset;
16
17/**
18 * PHP Enum Reflection Property - special override for backed enums.
19 */
20class EnumReflectionProperty extends ReflectionProperty
21{
22 /** @var ReflectionProperty */
23 private $originalReflectionProperty;
24
25 /** @var class-string<BackedEnum> */
26 private $enumType;
27
28 /** @param class-string<BackedEnum> $enumType */
29 public function __construct(ReflectionProperty $originalReflectionProperty, string $enumType)
30 {
31 $this->originalReflectionProperty = $originalReflectionProperty;
32 $this->enumType = $enumType;
33 }
34
35 /**
36 * {@inheritDoc}
37 *
38 * @psalm-external-mutation-free
39 */
40 public function getDeclaringClass(): ReflectionClass
41 {
42 return $this->originalReflectionProperty->getDeclaringClass();
43 }
44
45 /**
46 * {@inheritDoc}
47 *
48 * @psalm-external-mutation-free
49 */
50 public function getName(): string
51 {
52 return $this->originalReflectionProperty->getName();
53 }
54
55 /**
56 * {@inheritDoc}
57 *
58 * @psalm-external-mutation-free
59 */
60 public function getType(): ?ReflectionType
61 {
62 return $this->originalReflectionProperty->getType();
63 }
64
65 /**
66 * {@inheritDoc}
67 */
68 public function getAttributes(?string $name = null, int $flags = 0): array
69 {
70 return $this->originalReflectionProperty->getAttributes($name, $flags);
71 }
72
73 /**
74 * {@inheritDoc}
75 *
76 * Converts enum instance to its value.
77 *
78 * @param object|null $object
79 *
80 * @return int|string|int[]|string[]|null
81 */
82 #[ReturnTypeWillChange]
83 public function getValue($object = null)
84 {
85 if ($object === null) {
86 return null;
87 }
88
89 $enum = $this->originalReflectionProperty->getValue($object);
90
91 if ($enum === null) {
92 return null;
93 }
94
95 return $this->fromEnum($enum);
96 }
97
98 /**
99 * Converts enum value to enum instance.
100 *
101 * @param object $object
102 * @param mixed $value
103 */
104 public function setValue($object, $value = null): void
105 {
106 if ($value !== null) {
107 $value = $this->toEnum($value);
108 }
109
110 $this->originalReflectionProperty->setValue($object, $value);
111 }
112
113 /**
114 * @param BackedEnum|BackedEnum[] $enum
115 *
116 * @return ($enum is BackedEnum ? (string|int) : (string[]|int[]))
117 */
118 private function fromEnum($enum)
119 {
120 if (is_array($enum)) {
121 return array_map(static function (BackedEnum $enum) {
122 return $enum->value;
123 }, $enum);
124 }
125
126 return $enum->value;
127 }
128
129 /**
130 * @param int|string|int[]|string[]|BackedEnum|BackedEnum[] $value
131 *
132 * @return ($value is int|string|BackedEnum ? BackedEnum : BackedEnum[])
133 */
134 private function toEnum($value)
135 {
136 if ($value instanceof BackedEnum) {
137 return $value;
138 }
139
140 if (is_array($value)) {
141 $v = reset($value);
142 if ($v instanceof BackedEnum) {
143 return $value;
144 }
145
146 return array_map([$this->enumType, 'from'], $value);
147 }
148
149 return $this->enumType::from($value);
150 }
151
152 /**
153 * {@inheritDoc}
154 *
155 * @psalm-external-mutation-free
156 */
157 public function getModifiers(): int
158 {
159 return $this->originalReflectionProperty->getModifiers();
160 }
161
162 /**
163 * {@inheritDoc}
164 *
165 * @psalm-external-mutation-free
166 */
167 public function getDocComment(): string|false
168 {
169 return $this->originalReflectionProperty->getDocComment();
170 }
171
172 /**
173 * {@inheritDoc}
174 *
175 * @psalm-external-mutation-free
176 */
177 public function isPrivate(): bool
178 {
179 return $this->originalReflectionProperty->isPrivate();
180 }
181}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimePublicReflectionProperty.php b/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimePublicReflectionProperty.php
new file mode 100644
index 0000000..e2367ec
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimePublicReflectionProperty.php
@@ -0,0 +1,61 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7use Doctrine\Common\Proxy\Proxy;
8use ReflectionProperty;
9use ReturnTypeWillChange;
10
11/**
12 * PHP Runtime Reflection Public Property - special overrides for public properties.
13 *
14 * @deprecated since version 3.1, use RuntimeReflectionProperty instead.
15 */
16class RuntimePublicReflectionProperty extends ReflectionProperty
17{
18 /**
19 * {@inheritDoc}
20 *
21 * Returns the value of a public property without calling
22 * `__get` on the provided $object if it exists.
23 *
24 * @return mixed
25 */
26 #[ReturnTypeWillChange]
27 public function getValue($object = null)
28 {
29 return $object !== null ? ((array) $object)[$this->getName()] ?? null : parent::getValue();
30 }
31
32 /**
33 * {@inheritDoc}
34 *
35 * Avoids triggering lazy loading via `__set` if the provided object
36 * is a {@see \Doctrine\Common\Proxy\Proxy}.
37 *
38 * @link https://bugs.php.net/bug.php?id=63463
39 *
40 * @param object|null $object
41 * @param mixed $value
42 *
43 * @return void
44 */
45 #[ReturnTypeWillChange]
46 public function setValue($object, $value = null)
47 {
48 if (! ($object instanceof Proxy && ! $object->__isInitialized())) {
49 parent::setValue($object, $value);
50
51 return;
52 }
53
54 $originalInitializer = $object->__getInitializer();
55 $object->__setInitializer(null);
56
57 parent::setValue($object, $value);
58
59 $object->__setInitializer($originalInitializer);
60 }
61}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimeReflectionProperty.php b/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimeReflectionProperty.php
new file mode 100644
index 0000000..5f52056
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/RuntimeReflectionProperty.php
@@ -0,0 +1,87 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7use Doctrine\Common\Proxy\Proxy as CommonProxy;
8use Doctrine\Persistence\Proxy;
9use ReflectionProperty;
10use ReturnTypeWillChange;
11
12use function ltrim;
13use function method_exists;
14
15/**
16 * PHP Runtime Reflection Property.
17 *
18 * Avoids triggering lazy loading if the provided object
19 * is a {@see \Doctrine\Persistence\Proxy}.
20 */
21class RuntimeReflectionProperty extends ReflectionProperty
22{
23 /** @var string */
24 private $key;
25
26 /** @param class-string $class */
27 public function __construct(string $class, string $name)
28 {
29 parent::__construct($class, $name);
30
31 $this->key = $this->isPrivate() ? "\0" . ltrim($class, '\\') . "\0" . $name : ($this->isProtected() ? "\0*\0" . $name : $name);
32 }
33
34 /**
35 * {@inheritDoc}
36 *
37 * @return mixed
38 */
39 #[ReturnTypeWillChange]
40 public function getValue($object = null)
41 {
42 if ($object === null) {
43 return parent::getValue($object);
44 }
45
46 return ((array) $object)[$this->key] ?? null;
47 }
48
49 /**
50 * {@inheritDoc}
51 *
52 * @param object|null $object
53 * @param mixed $value
54 *
55 * @return void
56 */
57 #[ReturnTypeWillChange]
58 public function setValue($object, $value = null)
59 {
60 if (! ($object instanceof Proxy && ! $object->__isInitialized())) {
61 parent::setValue($object, $value);
62
63 return;
64 }
65
66 if ($object instanceof CommonProxy) {
67 $originalInitializer = $object->__getInitializer();
68 $object->__setInitializer(null);
69
70 parent::setValue($object, $value);
71
72 $object->__setInitializer($originalInitializer);
73
74 return;
75 }
76
77 if (! method_exists($object, '__setInitialized')) {
78 return;
79 }
80
81 $object->__setInitialized(true);
82
83 parent::setValue($object, $value);
84
85 $object->__setInitialized(false);
86 }
87}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionProperty.php b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionProperty.php
new file mode 100644
index 0000000..5e70620
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionProperty.php
@@ -0,0 +1,13 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7/**
8 * PHP Typed No Default Reflection Property - special override for typed properties without a default value.
9 */
10class TypedNoDefaultReflectionProperty extends RuntimeReflectionProperty
11{
12 use TypedNoDefaultReflectionPropertyBase;
13}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionPropertyBase.php b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionPropertyBase.php
new file mode 100644
index 0000000..fff68a4
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultReflectionPropertyBase.php
@@ -0,0 +1,68 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7use Closure;
8use ReturnTypeWillChange;
9
10use function assert;
11
12/**
13 * PHP Typed No Default Reflection Property Base - special override for typed properties without a default value.
14 *
15 * @internal since version 3.1
16 */
17trait TypedNoDefaultReflectionPropertyBase
18{
19 /**
20 * {@inheritDoc}
21 *
22 * Checks that a typed property is initialized before accessing its value.
23 * This is necessary to avoid PHP error "Error: Typed property must not be accessed before initialization".
24 * Should be used only for reflecting typed properties without a default value.
25 *
26 * @param object|null $object
27 *
28 * @return mixed
29 */
30 #[ReturnTypeWillChange]
31 public function getValue($object = null)
32 {
33 return $object !== null && $this->isInitialized($object) ? parent::getValue($object) : null;
34 }
35
36 /**
37 * {@inheritDoc}
38 *
39 * Works around the problem with setting typed no default properties to
40 * NULL which is not supported, instead unset() to uninitialize.
41 *
42 * @link https://github.com/doctrine/orm/issues/7999
43 *
44 * @param object|null $object
45 *
46 * @return void
47 */
48 #[ReturnTypeWillChange]
49 public function setValue($object, $value = null)
50 {
51 if ($value === null && $this->hasType() && ! $this->getType()->allowsNull()) {
52 $propertyName = $this->getName();
53
54 $unsetter = function () use ($propertyName): void {
55 unset($this->$propertyName);
56 };
57 $unsetter = $unsetter->bindTo($object, $this->getDeclaringClass()->getName());
58
59 assert($unsetter instanceof Closure);
60
61 $unsetter();
62
63 return;
64 }
65
66 parent::setValue($object, $value);
67 }
68}
diff --git a/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultRuntimePublicReflectionProperty.php b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultRuntimePublicReflectionProperty.php
new file mode 100644
index 0000000..181172f
--- /dev/null
+++ b/vendor/doctrine/persistence/src/Persistence/Reflection/TypedNoDefaultRuntimePublicReflectionProperty.php
@@ -0,0 +1,15 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\Persistence\Reflection;
6
7/**
8 * PHP Typed No Default Runtime Public Reflection Property - special override for public typed properties without a default value.
9 *
10 * @deprecated since version 3.1, use TypedNoDefaultReflectionProperty instead.
11 */
12class TypedNoDefaultRuntimePublicReflectionProperty extends RuntimePublicReflectionProperty
13{
14 use TypedNoDefaultReflectionPropertyBase;
15}