summaryrefslogtreecommitdiff
path: root/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php')
-rw-r--r--vendor/doctrine/persistence/src/Persistence/Mapping/Driver/FileDriver.php213
1 files changed, 213 insertions, 0 deletions
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}