1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Doctrine\Common\Persistence\Mapping\Driver; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Persistence\Mapping\ClassMetadata; |
6
|
|
|
use Doctrine\Common\Persistence\Mapping\MappingException; |
7
|
|
|
use function array_merge; |
8
|
|
|
use function array_unique; |
9
|
|
|
use function get_declared_classes; |
10
|
|
|
use function in_array; |
11
|
|
|
use function is_dir; |
12
|
|
|
use function method_exists; |
13
|
|
|
use function realpath; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* The StaticPHPDriver calls a static loadMetadata() method on your entity |
17
|
|
|
* classes where you can manually populate the ClassMetadata instance. |
18
|
|
|
*/ |
19
|
|
|
class StaticPHPDriver implements MappingDriver |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* Paths of entity directories. |
23
|
|
|
* |
24
|
|
|
* @var string[] |
25
|
|
|
*/ |
26
|
|
|
private $paths = []; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Map of all class names. |
30
|
|
|
* |
31
|
|
|
* @var string[] |
32
|
|
|
*/ |
33
|
|
|
private $classNames; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param string[]|string $paths |
37
|
|
|
*/ |
38
|
2 |
|
public function __construct($paths) |
39
|
|
|
{ |
40
|
2 |
|
$this->addPaths((array) $paths); |
41
|
2 |
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Adds paths. |
45
|
|
|
* |
46
|
|
|
* @param string[] $paths |
47
|
|
|
* |
48
|
|
|
* @return void |
49
|
|
|
*/ |
50
|
2 |
|
public function addPaths(array $paths) |
51
|
|
|
{ |
52
|
2 |
|
$this->paths = array_unique(array_merge($this->paths, $paths)); |
53
|
2 |
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* {@inheritdoc} |
57
|
|
|
*/ |
58
|
1 |
|
public function loadMetadataForClass($className, ClassMetadata $metadata) |
59
|
|
|
{ |
60
|
1 |
|
$className::loadMetadata($metadata); |
61
|
1 |
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* {@inheritDoc} |
65
|
|
|
* @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it? |
66
|
|
|
*/ |
67
|
1 |
|
public function getAllClassNames() |
68
|
|
|
{ |
69
|
1 |
|
if ($this->classNames !== null) { |
70
|
|
|
return $this->classNames; |
71
|
|
|
} |
72
|
|
|
|
73
|
1 |
|
if (! $this->paths) { |
|
|
|
|
74
|
|
|
throw MappingException::pathRequired(); |
75
|
|
|
} |
76
|
|
|
|
77
|
1 |
|
$classes = []; |
78
|
1 |
|
$includedFiles = []; |
79
|
|
|
|
80
|
1 |
|
foreach ($this->paths as $path) { |
81
|
1 |
|
if (! is_dir($path)) { |
82
|
|
|
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); |
83
|
|
|
} |
84
|
|
|
|
85
|
1 |
|
$iterator = new \RecursiveIteratorIterator( |
86
|
1 |
|
new \RecursiveDirectoryIterator($path), |
87
|
1 |
|
\RecursiveIteratorIterator::LEAVES_ONLY |
88
|
|
|
); |
89
|
|
|
|
90
|
1 |
|
foreach ($iterator as $file) { |
91
|
1 |
|
if ($file->getBasename('.php') === $file->getBasename()) { |
92
|
1 |
|
continue; |
93
|
|
|
} |
94
|
|
|
|
95
|
1 |
|
$sourceFile = realpath($file->getPathName()); |
96
|
1 |
|
require_once $sourceFile; |
97
|
1 |
|
$includedFiles[] = $sourceFile; |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
1 |
|
$declared = get_declared_classes(); |
102
|
|
|
|
103
|
1 |
|
foreach ($declared as $className) { |
104
|
1 |
|
$rc = new \ReflectionClass($className); |
105
|
1 |
|
$sourceFile = $rc->getFileName(); |
106
|
1 |
|
if (! in_array($sourceFile, $includedFiles) || $this->isTransient($className)) { |
107
|
1 |
|
continue; |
108
|
|
|
} |
109
|
|
|
|
110
|
1 |
|
$classes[] = $className; |
111
|
|
|
} |
112
|
|
|
|
113
|
1 |
|
$this->classNames = $classes; |
114
|
|
|
|
115
|
1 |
|
return $classes; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* {@inheritdoc} |
120
|
|
|
*/ |
121
|
1 |
|
public function isTransient($className) |
122
|
|
|
{ |
123
|
1 |
|
return ! method_exists($className, 'loadMetadata'); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
|
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.