diff options
Diffstat (limited to 'vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php')
-rw-r--r-- | vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php | 212 |
1 files changed, 212 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 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\Persistence\Mapping\Driver; | ||
6 | |||
7 | use Doctrine\Persistence\Mapping\MappingException; | ||
8 | use FilesystemIterator; | ||
9 | use RecursiveDirectoryIterator; | ||
10 | use RecursiveIteratorIterator; | ||
11 | use RecursiveRegexIterator; | ||
12 | use ReflectionClass; | ||
13 | use RegexIterator; | ||
14 | |||
15 | use function array_merge; | ||
16 | use function array_unique; | ||
17 | use function assert; | ||
18 | use function get_declared_classes; | ||
19 | use function in_array; | ||
20 | use function is_dir; | ||
21 | use function preg_match; | ||
22 | use function preg_quote; | ||
23 | use function realpath; | ||
24 | use function str_replace; | ||
25 | use function strpos; | ||
26 | |||
27 | /** | ||
28 | * The ColocatedMappingDriver reads the mapping metadata located near the code. | ||
29 | */ | ||
30 | trait 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 | } | ||