summaryrefslogtreecommitdiff
path: root/vendor/doctrine/persistence/src/Persistence/Mapping/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/persistence/src/Persistence/Mapping/Driver')
-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
9 files changed, 1283 insertions, 0 deletions
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}