1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Mapado\RestClientSdk\Mapping\Driver; |
6
|
|
|
|
7
|
|
|
use Doctrine\Common\Annotations\AnnotationReader; |
8
|
|
|
use Doctrine\Common\Annotations\AnnotationRegistry; |
9
|
|
|
use Doctrine\Common\Annotations\FileCacheReader; |
10
|
|
|
use Doctrine\Common\Annotations\Reader; |
11
|
|
|
use Mapado\RestClientSdk\Exception\MappingException; |
12
|
|
|
use Mapado\RestClientSdk\Mapping\Annotations; |
13
|
|
|
use Mapado\RestClientSdk\Mapping\Attribute; |
14
|
|
|
use Mapado\RestClientSdk\Mapping\ClassMetadata; |
15
|
|
|
use Mapado\RestClientSdk\Mapping\Relation; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class AnnotationDriver |
19
|
|
|
* |
20
|
|
|
* @author Julien Deniau <[email protected]> |
21
|
|
|
*/ |
22
|
|
|
class AnnotationDriver |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var string |
26
|
|
|
*/ |
27
|
|
|
private $cachePath; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var bool |
31
|
|
|
*/ |
32
|
|
|
private $debug; |
33
|
|
|
|
34
|
|
|
public function __construct(string $cachePath, bool $debug = false) |
35
|
|
|
{ |
36
|
1 |
|
$this->cachePath = $cachePath; |
37
|
1 |
|
$this->debug = $debug; |
38
|
|
|
|
39
|
1 |
|
AnnotationRegistry::registerFile( |
|
|
|
|
40
|
1 |
|
__DIR__ . '/../Annotations/AllAnnotations.php' |
41
|
|
|
); |
42
|
1 |
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @return array<ClassMetadata> |
46
|
|
|
* |
47
|
|
|
* @throws MappingException |
48
|
|
|
*/ |
49
|
|
|
public function loadDirectory(string $path): array |
50
|
|
|
{ |
51
|
1 |
|
if (!is_dir($path)) { |
52
|
|
|
throw new MappingException($path . ' is not a valid directory'); |
53
|
|
|
} |
54
|
|
|
|
55
|
1 |
|
$iterator = new \RegexIterator( |
56
|
1 |
|
new \RecursiveIteratorIterator( |
57
|
1 |
|
new \RecursiveDirectoryIterator( |
58
|
1 |
|
$path, |
59
|
1 |
|
\FilesystemIterator::SKIP_DOTS |
60
|
|
|
), |
61
|
1 |
|
\RecursiveIteratorIterator::LEAVES_ONLY |
62
|
|
|
), |
63
|
1 |
|
'/^.+\.php$/i', |
64
|
1 |
|
\RecursiveRegexIterator::GET_MATCH |
65
|
|
|
); |
66
|
|
|
|
67
|
1 |
|
$classes = []; |
68
|
1 |
|
$includedFiles = []; |
69
|
|
|
|
70
|
1 |
|
foreach ($iterator as $file) { |
71
|
1 |
|
$sourceFile = $file[0]; |
72
|
1 |
|
if (!preg_match('(^phar:)i', $sourceFile)) { |
73
|
1 |
|
$sourceFile = realpath($sourceFile); |
74
|
|
|
} |
75
|
|
|
|
76
|
1 |
|
require_once $sourceFile; |
77
|
1 |
|
$includedFiles[] = $sourceFile; |
78
|
|
|
} |
79
|
|
|
|
80
|
1 |
|
$declared = get_declared_classes(); |
81
|
1 |
|
foreach ($declared as $className) { |
82
|
1 |
|
$rc = new \ReflectionClass($className); |
83
|
1 |
|
$sourceFile = $rc->getFileName(); |
84
|
1 |
|
if (in_array($sourceFile, $includedFiles)) { |
85
|
1 |
|
$classes[] = $className; |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
|
89
|
1 |
|
$mapping = []; |
90
|
1 |
|
foreach ($classes as $class) { |
91
|
1 |
|
$metadata = $this->getClassMetadataForClassname($class); |
92
|
1 |
|
if ($metadata) { |
93
|
1 |
|
$mapping[] = $metadata; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
1 |
|
return $mapping; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @return array<ClassMetadata> |
102
|
|
|
*/ |
103
|
|
|
public function loadClassname(string $classname): array |
104
|
|
|
{ |
105
|
1 |
|
$metadata = $this->getClassMetadataForClassname($classname); |
106
|
|
|
|
107
|
1 |
|
return $metadata ? [$metadata] : []; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
private function getClassMetadataForClassname( |
111
|
|
|
string $classname |
112
|
|
|
): ?ClassMetadata { |
113
|
1 |
|
$reader = new FileCacheReader( |
|
|
|
|
114
|
1 |
|
new AnnotationReader(), |
115
|
1 |
|
$this->cachePath, |
116
|
1 |
|
$this->debug |
117
|
|
|
); |
118
|
|
|
|
119
|
1 |
|
$reflClass = new \ReflectionClass($classname); |
120
|
|
|
/** @var Annotations\Entity|null */ |
121
|
1 |
|
$classAnnotation = $reader->getClassAnnotation( |
122
|
1 |
|
$reflClass, |
123
|
1 |
|
Annotations\Entity::class |
124
|
|
|
); |
125
|
|
|
|
126
|
1 |
|
if (!$classAnnotation) { |
127
|
1 |
|
return null; |
128
|
|
|
} |
129
|
|
|
|
130
|
1 |
|
$attributeList = []; |
131
|
1 |
|
$relationList = []; |
132
|
1 |
|
foreach ($reflClass->getProperties() as $property) { |
133
|
|
|
// manage attributes |
134
|
|
|
/** @var Annotations\Attribute|null */ |
135
|
1 |
|
$propertyAnnotation = $this->getPropertyAnnotation( |
136
|
1 |
|
$reader, |
137
|
|
|
$property, |
138
|
1 |
|
'Attribute' |
139
|
|
|
); |
140
|
|
|
|
141
|
1 |
|
if ($propertyAnnotation) { |
142
|
1 |
|
$isId = $this->getPropertyAnnotation($reader, $property, 'Id'); |
143
|
|
|
|
144
|
1 |
|
$attributeList[] = new Attribute( |
145
|
1 |
|
$propertyAnnotation->name, |
146
|
1 |
|
$property->getName(), |
147
|
1 |
|
$propertyAnnotation->type, |
148
|
1 |
|
(bool) $isId |
149
|
|
|
); |
150
|
|
|
} else { |
151
|
|
|
// manage relations |
152
|
|
|
/** @var Annotations\OneToMany|null */ |
153
|
1 |
|
$relation = $this->getPropertyAnnotation( |
154
|
1 |
|
$reader, |
155
|
|
|
$property, |
156
|
1 |
|
'OneToMany' |
157
|
|
|
); |
158
|
1 |
|
if (!$relation) { |
159
|
|
|
/** @var Annotations\ManyToOne|null */ |
160
|
1 |
|
$relation = $this->getPropertyAnnotation( |
161
|
1 |
|
$reader, |
162
|
|
|
$property, |
163
|
1 |
|
'ManyToOne' |
164
|
|
|
); |
165
|
|
|
} |
166
|
|
|
|
167
|
1 |
|
if ($relation) { |
168
|
1 |
|
$attributeList[] = new Attribute( |
169
|
1 |
|
$relation->name, |
170
|
1 |
|
$property->getName() |
171
|
|
|
); |
172
|
|
|
|
173
|
1 |
|
$targetEntity = $relation->targetEntity; |
174
|
1 |
|
if (false === mb_strpos($targetEntity, '/')) { |
175
|
|
|
$targetEntity = |
176
|
1 |
|
mb_substr( |
177
|
1 |
|
$classname, |
178
|
1 |
|
0, |
179
|
1 |
|
mb_strrpos($classname, '\\') + 1 |
180
|
1 |
|
) . $targetEntity; |
181
|
|
|
} |
182
|
|
|
|
183
|
1 |
|
$relationList[] = new Relation( |
184
|
1 |
|
$relation->name, |
185
|
1 |
|
$relation->type, |
186
|
|
|
$targetEntity |
187
|
|
|
); |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
1 |
|
$classMetadata = new ClassMetadata( |
193
|
1 |
|
$classAnnotation->key, |
194
|
|
|
$classname, |
195
|
1 |
|
$classAnnotation->repository |
196
|
|
|
); |
197
|
1 |
|
$classMetadata->setAttributeList($attributeList); |
198
|
1 |
|
$classMetadata->setRelationList($relationList); |
199
|
|
|
|
200
|
1 |
|
return $classMetadata; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
private function getPropertyAnnotation( |
204
|
|
|
Reader $reader, |
205
|
|
|
\ReflectionProperty $property, |
206
|
|
|
string $classname |
207
|
|
|
): ?object { |
208
|
1 |
|
return $reader->getPropertyAnnotation( |
209
|
1 |
|
$property, |
210
|
1 |
|
'Mapado\\RestClientSdk\\Mapping\\Annotations\\' . $classname |
211
|
|
|
); |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.