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( |
|||
0 ignored issues
–
show
|
|||||
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 | * @param class-string $classname |
||||
0 ignored issues
–
show
|
|||||
102 | * |
||||
103 | * @return array<ClassMetadata> |
||||
104 | */ |
||||
105 | public function loadClassname(string $classname): array |
||||
106 | { |
||||
107 | 1 | $metadata = $this->getClassMetadataForClassname($classname); |
|||
108 | |||||
109 | 1 | return $metadata ? [$metadata] : []; |
|||
110 | } |
||||
111 | |||||
112 | /** |
||||
113 | * @param class-string $classname |
||||
0 ignored issues
–
show
|
|||||
114 | * |
||||
115 | * @throws \ReflectionException |
||||
116 | */ |
||||
117 | private function getClassMetadataForClassname( |
||||
118 | string $classname |
||||
119 | ): ?ClassMetadata { |
||||
120 | 1 | $reader = new FileCacheReader( |
|||
0 ignored issues
–
show
The class
Doctrine\Common\Annotations\FileCacheReader has been deprecated: the FileCacheReader is deprecated and will be removed in version 2.0.0 of doctrine/annotations. Please use the {@see \Doctrine\Common\Annotations\CachedReader} instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
121 | 1 | new AnnotationReader(), |
|||
122 | 1 | $this->cachePath, |
|||
123 | 1 | $this->debug |
|||
124 | ); |
||||
125 | |||||
126 | 1 | $reflClass = new \ReflectionClass($classname); |
|||
127 | /** @var Annotations\Entity|null */ |
||||
128 | 1 | $classAnnotation = $reader->getClassAnnotation( |
|||
129 | 1 | $reflClass, |
|||
130 | 1 | Annotations\Entity::class |
|||
131 | ); |
||||
132 | |||||
133 | 1 | if (!$classAnnotation) { |
|||
134 | 1 | return null; |
|||
135 | } |
||||
136 | |||||
137 | 1 | $attributeList = []; |
|||
138 | 1 | $relationList = []; |
|||
139 | 1 | foreach ($reflClass->getProperties() as $property) { |
|||
140 | // manage attributes |
||||
141 | /** @var Annotations\Attribute|null */ |
||||
142 | 1 | $propertyAnnotation = $this->getPropertyAnnotation( |
|||
143 | 1 | $reader, |
|||
144 | $property, |
||||
145 | 1 | 'Attribute' |
|||
146 | ); |
||||
147 | |||||
148 | 1 | if ($propertyAnnotation) { |
|||
149 | 1 | $isId = $this->getPropertyAnnotation($reader, $property, 'Id'); |
|||
150 | |||||
151 | 1 | $attributeList[] = new Attribute( |
|||
152 | 1 | $propertyAnnotation->name, |
|||
153 | 1 | $property->getName(), |
|||
154 | 1 | $propertyAnnotation->type, |
|||
155 | 1 | (bool) $isId |
|||
156 | ); |
||||
157 | } else { |
||||
158 | // manage relations |
||||
159 | /** @var Annotations\OneToMany|null */ |
||||
160 | 1 | $relation = $this->getPropertyAnnotation( |
|||
161 | 1 | $reader, |
|||
162 | $property, |
||||
163 | 1 | 'OneToMany' |
|||
164 | ); |
||||
165 | 1 | if (!$relation) { |
|||
166 | /** @var Annotations\ManyToOne|null */ |
||||
167 | 1 | $relation = $this->getPropertyAnnotation( |
|||
168 | 1 | $reader, |
|||
169 | $property, |
||||
170 | 1 | 'ManyToOne' |
|||
171 | ); |
||||
172 | } |
||||
173 | |||||
174 | 1 | if ($relation) { |
|||
175 | 1 | $attributeList[] = new Attribute( |
|||
176 | 1 | $relation->name, |
|||
177 | 1 | $property->getName() |
|||
178 | ); |
||||
179 | |||||
180 | 1 | $targetEntity = $relation->targetEntity; |
|||
181 | 1 | if (false === mb_strpos($targetEntity, '/')) { |
|||
182 | $targetEntity = |
||||
183 | 1 | mb_substr( |
|||
184 | 1 | $classname, |
|||
185 | 1 | 0, |
|||
186 | 1 | mb_strrpos($classname, '\\') + 1 |
|||
187 | 1 | ) . $targetEntity; |
|||
188 | } |
||||
189 | |||||
190 | 1 | $relationList[] = new Relation( |
|||
191 | 1 | $relation->name, |
|||
192 | 1 | $relation->type, |
|||
193 | $targetEntity |
||||
194 | ); |
||||
195 | } |
||||
196 | } |
||||
197 | } |
||||
198 | |||||
199 | 1 | $classMetadata = new ClassMetadata( |
|||
200 | 1 | $classAnnotation->key, |
|||
201 | $classname, |
||||
202 | 1 | $classAnnotation->repository |
|||
203 | ); |
||||
204 | 1 | $classMetadata->setAttributeList($attributeList); |
|||
205 | 1 | $classMetadata->setRelationList($relationList); |
|||
206 | |||||
207 | 1 | return $classMetadata; |
|||
208 | } |
||||
209 | |||||
210 | /** |
||||
211 | * @return object|null the Annotation or NULL, if the requested annotation does not exist |
||||
212 | */ |
||||
213 | private function getPropertyAnnotation( |
||||
214 | Reader $reader, |
||||
215 | \ReflectionProperty $property, |
||||
216 | string $classname |
||||
217 | ): ?object { |
||||
218 | /** @var class-string $classname */ |
||||
219 | $classname = |
||||
220 | 1 | 'Mapado\\RestClientSdk\\Mapping\\Annotations\\' . $classname; |
|||
221 | |||||
222 | 1 | return $reader->getPropertyAnnotation($property, $classname); |
|||
223 | } |
||||
224 | } |
||||
225 |
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.