1
|
|
|
<?php |
2
|
|
|
namespace Doctrine\Common\Persistence\Mapping\Driver; |
3
|
|
|
|
4
|
|
|
use Doctrine\Common\Persistence\Mapping\MappingException; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* The Symfony File Locator makes a simplifying assumptions compared |
8
|
|
|
* to the DefaultFileLocator. By assuming paths only contain entities of a certain |
9
|
|
|
* namespace the mapping files consists of the short classname only. |
10
|
|
|
* |
11
|
|
|
* @author Fabien Potencier <[email protected]> |
12
|
|
|
* @author Benjamin Eberlei <[email protected]> |
13
|
|
|
* @license MIT |
14
|
|
|
*/ |
15
|
|
|
class SymfonyFileLocator implements FileLocator |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* The paths where to look for mapping files. |
19
|
|
|
* |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $paths = []; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* A map of mapping directory path to namespace prefix used to expand class shortnames. |
26
|
|
|
* |
27
|
|
|
* @var array |
28
|
|
|
*/ |
29
|
|
|
protected $prefixes = []; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* File extension that is searched for. |
33
|
|
|
* |
34
|
|
|
* @var string|null |
35
|
|
|
*/ |
36
|
|
|
protected $fileExtension; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Represents PHP namespace delimiters when looking for files |
40
|
|
|
* |
41
|
|
|
* @var string |
42
|
|
|
*/ |
43
|
|
|
private $nsSeparator; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Constructor. |
47
|
|
|
* |
48
|
|
|
* @param array $prefixes |
49
|
|
|
* @param string|null $fileExtension |
50
|
|
|
* @param string $nsSeparator String which would be used when converting FQCN to filename and vice versa. Should not be empty |
51
|
|
|
*/ |
52
|
14 |
|
public function __construct(array $prefixes, $fileExtension = null, $nsSeparator = '.') |
53
|
|
|
{ |
54
|
14 |
|
$this->addNamespacePrefixes($prefixes); |
55
|
14 |
|
$this->fileExtension = $fileExtension; |
56
|
|
|
|
57
|
14 |
|
if (empty($nsSeparator)) { |
58
|
1 |
|
throw new \InvalidArgumentException('Namespace separator should not be empty'); |
59
|
|
|
} |
60
|
|
|
|
61
|
13 |
|
$this->nsSeparator = (string) $nsSeparator; |
62
|
13 |
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Adds Namespace Prefixes. |
66
|
|
|
* |
67
|
|
|
* @param array $prefixes |
68
|
|
|
* |
69
|
|
|
* @return void |
70
|
|
|
*/ |
71
|
14 |
|
public function addNamespacePrefixes(array $prefixes) |
72
|
|
|
{ |
73
|
14 |
|
$this->prefixes = array_merge($this->prefixes, $prefixes); |
74
|
14 |
|
$this->paths = array_merge($this->paths, array_keys($prefixes)); |
75
|
14 |
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Gets Namespace Prefixes. |
79
|
|
|
* |
80
|
|
|
* @return array |
81
|
|
|
*/ |
82
|
1 |
|
public function getNamespacePrefixes() |
83
|
|
|
{ |
84
|
1 |
|
return $this->prefixes; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* {@inheritDoc} |
89
|
|
|
*/ |
90
|
1 |
|
public function getPaths() |
91
|
|
|
{ |
92
|
1 |
|
return $this->paths; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* {@inheritDoc} |
97
|
|
|
*/ |
98
|
1 |
|
public function getFileExtension() |
99
|
|
|
{ |
100
|
1 |
|
return $this->fileExtension; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Sets the file extension used to look for mapping files under. |
105
|
|
|
* |
106
|
|
|
* @param string $fileExtension The file extension to set. |
107
|
|
|
* |
108
|
|
|
* @return void |
109
|
|
|
*/ |
110
|
1 |
|
public function setFileExtension($fileExtension) |
111
|
|
|
{ |
112
|
1 |
|
$this->fileExtension = $fileExtension; |
113
|
1 |
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* {@inheritDoc} |
117
|
|
|
*/ |
118
|
1 |
|
public function fileExists($className) |
119
|
|
|
{ |
120
|
1 |
|
$defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; |
121
|
1 |
|
foreach ($this->paths as $path) { |
122
|
1 |
|
if ( ! isset($this->prefixes[$path])) { |
123
|
|
|
// global namespace class |
124
|
|
|
if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { |
125
|
|
|
return true; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
continue; |
129
|
|
|
} |
130
|
|
|
|
131
|
1 |
|
$prefix = $this->prefixes[$path]; |
132
|
|
|
|
133
|
1 |
|
if (0 !== strpos($className, $prefix . '\\')) { |
134
|
|
|
continue; |
135
|
|
|
} |
136
|
|
|
|
137
|
1 |
|
$filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; |
138
|
1 |
|
if (is_file($filename)) { |
139
|
1 |
|
return true; |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
|
143
|
1 |
|
return false; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* {@inheritDoc} |
148
|
|
|
*/ |
149
|
3 |
|
public function getAllClassNames($globalBasename = null) |
150
|
|
|
{ |
151
|
3 |
|
$classes = []; |
152
|
|
|
|
153
|
3 |
|
if ($this->paths) { |
|
|
|
|
154
|
3 |
|
foreach ((array) $this->paths as $path) { |
155
|
3 |
|
if ( ! is_dir($path)) { |
156
|
|
|
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); |
157
|
|
|
} |
158
|
|
|
|
159
|
3 |
|
$iterator = new \RecursiveIteratorIterator( |
160
|
3 |
|
new \RecursiveDirectoryIterator($path), |
161
|
3 |
|
\RecursiveIteratorIterator::LEAVES_ONLY |
162
|
|
|
); |
163
|
|
|
|
164
|
3 |
|
foreach ($iterator as $file) { |
165
|
3 |
|
$fileName = $file->getBasename($this->fileExtension); |
166
|
|
|
|
167
|
3 |
|
if ($fileName == $file->getBasename() || $fileName == $globalBasename) { |
168
|
3 |
|
continue; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
// NOTE: All files found here means classes are not transient! |
172
|
3 |
|
if (isset($this->prefixes[$path])) { |
173
|
|
|
// Calculate namespace suffix for given prefix as a relative path from basepath to file path |
174
|
3 |
|
$nsSuffix = strtr( |
175
|
3 |
|
substr(realpath($file->getPath()), strlen(realpath($path))), |
176
|
3 |
|
$this->nsSeparator, |
177
|
3 |
|
'\\' |
178
|
|
|
); |
179
|
|
|
|
180
|
3 |
|
$classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName); |
181
|
|
|
} else { |
182
|
3 |
|
$classes[] = str_replace($this->nsSeparator, '\\', $fileName); |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
3 |
|
return $classes; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* {@inheritDoc} |
193
|
|
|
*/ |
194
|
6 |
|
public function findMappingFile($className) |
195
|
|
|
{ |
196
|
6 |
|
$defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; |
197
|
6 |
|
foreach ($this->paths as $path) { |
198
|
6 |
|
if ( ! isset($this->prefixes[$path])) { |
199
|
|
|
if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) { |
200
|
|
|
return $path . DIRECTORY_SEPARATOR . $defaultFileName; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
continue; |
204
|
|
|
} |
205
|
|
|
|
206
|
6 |
|
$prefix = $this->prefixes[$path]; |
207
|
|
|
|
208
|
6 |
|
if (0 !== strpos($className, $prefix . '\\')) { |
209
|
|
|
continue; |
210
|
|
|
} |
211
|
|
|
|
212
|
6 |
|
$filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension; |
213
|
6 |
|
if (is_file($filename)) { |
214
|
6 |
|
return $filename; |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
|
218
|
1 |
|
throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.