Complex classes like AnnotationDriver often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AnnotationDriver, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class AnnotationDriver extends AbstractAnnotationDriver |
||
41 | { |
||
42 | /** |
||
43 | * {@inheritDoc} |
||
44 | */ |
||
45 | protected $entityAnnotationClasses = array( |
||
46 | 'Doctrine\ORM\Mapping\Entity' => 1, |
||
47 | 'Doctrine\ORM\Mapping\MappedSuperclass' => 2, |
||
48 | ); |
||
49 | |||
50 | /** |
||
51 | * {@inheritDoc} |
||
52 | */ |
||
53 | 365 | public function loadMetadataForClass($className, ClassMetadata $metadata) |
|
54 | { |
||
55 | /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */ |
||
56 | 365 | $class = $metadata->getReflectionClass(); |
|
57 | |||
58 | 365 | if ( ! $class) { |
|
59 | // this happens when running annotation driver in combination with |
||
60 | // static reflection services. This is not the nicest fix |
||
61 | 1 | $class = new \ReflectionClass($metadata->name); |
|
62 | } |
||
63 | |||
64 | 365 | $classAnnotations = $this->reader->getClassAnnotations($class); |
|
65 | |||
66 | 365 | if ($classAnnotations) { |
|
|
|||
67 | 361 | foreach ($classAnnotations as $key => $annot) { |
|
68 | 361 | if ( ! is_numeric($key)) { |
|
69 | continue; |
||
70 | } |
||
71 | |||
72 | 361 | $classAnnotations[get_class($annot)] = $annot; |
|
73 | } |
||
74 | } |
||
75 | |||
76 | // Evaluate Entity annotation |
||
77 | 365 | if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) { |
|
78 | 356 | $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity']; |
|
79 | 356 | if ($entityAnnot->repositoryClass !== null) { |
|
80 | 8 | $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); |
|
81 | } |
||
82 | |||
83 | 356 | if ($entityAnnot->readOnly) { |
|
84 | 356 | $metadata->markReadOnly(); |
|
85 | } |
||
86 | 45 | } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) { |
|
87 | 32 | $mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']; |
|
88 | |||
89 | 32 | $metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass); |
|
90 | 32 | $metadata->isMappedSuperclass = true; |
|
91 | 15 | } else if (isset($classAnnotations['Doctrine\ORM\Mapping\Embeddable'])) { |
|
92 | 11 | $metadata->isEmbeddedClass = true; |
|
93 | } else { |
||
94 | 4 | throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className); |
|
95 | } |
||
96 | |||
97 | // Evaluate Table annotation |
||
98 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) { |
|
99 | 189 | $tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table']; |
|
100 | $primaryTable = array( |
||
101 | 189 | 'name' => $tableAnnot->name, |
|
102 | 189 | 'schema' => $tableAnnot->schema |
|
103 | ); |
||
104 | |||
105 | 189 | if ($tableAnnot->indexes !== null) { |
|
106 | 13 | foreach ($tableAnnot->indexes as $indexAnnot) { |
|
107 | 13 | $index = array('columns' => $indexAnnot->columns); |
|
108 | |||
109 | 13 | if ( ! empty($indexAnnot->flags)) { |
|
110 | 1 | $index['flags'] = $indexAnnot->flags; |
|
111 | } |
||
112 | |||
113 | 13 | if ( ! empty($indexAnnot->options)) { |
|
114 | 1 | $index['options'] = $indexAnnot->options; |
|
115 | } |
||
116 | |||
117 | 13 | if ( ! empty($indexAnnot->name)) { |
|
118 | 12 | $primaryTable['indexes'][$indexAnnot->name] = $index; |
|
119 | } else { |
||
120 | 13 | $primaryTable['indexes'][] = $index; |
|
121 | } |
||
122 | } |
||
123 | } |
||
124 | |||
125 | 189 | if ($tableAnnot->uniqueConstraints !== null) { |
|
126 | 8 | foreach ($tableAnnot->uniqueConstraints as $uniqueConstraintAnnot) { |
|
127 | 8 | $uniqueConstraint = array('columns' => $uniqueConstraintAnnot->columns); |
|
128 | |||
129 | 8 | if ( ! empty($uniqueConstraintAnnot->options)) { |
|
130 | 2 | $uniqueConstraint['options'] = $uniqueConstraintAnnot->options; |
|
131 | } |
||
132 | |||
133 | 8 | if ( ! empty($uniqueConstraintAnnot->name)) { |
|
134 | 8 | $primaryTable['uniqueConstraints'][$uniqueConstraintAnnot->name] = $uniqueConstraint; |
|
135 | } else { |
||
136 | 8 | $primaryTable['uniqueConstraints'][] = $uniqueConstraint; |
|
137 | } |
||
138 | } |
||
139 | } |
||
140 | |||
141 | 189 | if ($tableAnnot->options) { |
|
142 | 5 | $primaryTable['options'] = $tableAnnot->options; |
|
143 | } |
||
144 | |||
145 | 189 | $metadata->setPrimaryTable($primaryTable); |
|
146 | } |
||
147 | |||
148 | // Evaluate @Cache annotation |
||
149 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\Cache'])) { |
|
150 | 14 | $cacheAnnot = $classAnnotations['Doctrine\ORM\Mapping\Cache']; |
|
151 | $cacheMap = array( |
||
152 | 14 | 'region' => $cacheAnnot->region, |
|
153 | 14 | 'usage' => constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $cacheAnnot->usage), |
|
154 | ); |
||
155 | |||
156 | 14 | $metadata->enableCache($cacheMap); |
|
157 | } |
||
158 | |||
159 | // Evaluate NamedNativeQueries annotation |
||
160 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'])) { |
|
161 | 14 | $namedNativeQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries']; |
|
162 | |||
163 | 14 | foreach ($namedNativeQueriesAnnot->value as $namedNativeQuery) { |
|
164 | 14 | $metadata->addNamedNativeQuery(array( |
|
165 | 14 | 'name' => $namedNativeQuery->name, |
|
166 | 14 | 'query' => $namedNativeQuery->query, |
|
167 | 14 | 'resultClass' => $namedNativeQuery->resultClass, |
|
168 | 14 | 'resultSetMapping' => $namedNativeQuery->resultSetMapping, |
|
169 | )); |
||
170 | } |
||
171 | } |
||
172 | |||
173 | // Evaluate SqlResultSetMappings annotation |
||
174 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'])) { |
|
175 | 14 | $sqlResultSetMappingsAnnot = $classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings']; |
|
176 | |||
177 | 14 | foreach ($sqlResultSetMappingsAnnot->value as $resultSetMapping) { |
|
178 | 14 | $entities = array(); |
|
179 | 14 | $columns = array(); |
|
180 | 14 | foreach ($resultSetMapping->entities as $entityResultAnnot) { |
|
181 | $entityResult = array( |
||
182 | 14 | 'fields' => array(), |
|
183 | 14 | 'entityClass' => $entityResultAnnot->entityClass, |
|
184 | 14 | 'discriminatorColumn' => $entityResultAnnot->discriminatorColumn, |
|
185 | ); |
||
186 | |||
187 | 14 | foreach ($entityResultAnnot->fields as $fieldResultAnnot) { |
|
188 | 14 | $entityResult['fields'][] = array( |
|
189 | 14 | 'name' => $fieldResultAnnot->name, |
|
190 | 14 | 'column' => $fieldResultAnnot->column |
|
191 | ); |
||
192 | } |
||
193 | |||
194 | 14 | $entities[] = $entityResult; |
|
195 | } |
||
196 | |||
197 | 14 | foreach ($resultSetMapping->columns as $columnResultAnnot) { |
|
198 | 9 | $columns[] = array( |
|
199 | 9 | 'name' => $columnResultAnnot->name, |
|
200 | ); |
||
201 | } |
||
202 | |||
203 | 14 | $metadata->addSqlResultSetMapping(array( |
|
204 | 14 | 'name' => $resultSetMapping->name, |
|
205 | 14 | 'entities' => $entities, |
|
206 | 14 | 'columns' => $columns |
|
207 | )); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | // Evaluate NamedQueries annotation |
||
212 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) { |
|
213 | 9 | $namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries']; |
|
214 | |||
215 | 9 | if ( ! is_array($namedQueriesAnnot->value)) { |
|
216 | throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations."); |
||
217 | } |
||
218 | |||
219 | 9 | foreach ($namedQueriesAnnot->value as $namedQuery) { |
|
220 | 9 | if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) { |
|
221 | throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations."); |
||
222 | } |
||
223 | 9 | $metadata->addNamedQuery(array( |
|
224 | 9 | 'name' => $namedQuery->name, |
|
225 | 9 | 'query' => $namedQuery->query |
|
226 | )); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | // Evaluate InheritanceType annotation |
||
231 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) { |
|
232 | 65 | $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType']; |
|
233 | |||
234 | 65 | $metadata->setInheritanceType( |
|
235 | 65 | constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value) |
|
236 | ); |
||
237 | |||
238 | 65 | if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { |
|
239 | // Evaluate DiscriminatorColumn annotation |
||
240 | 65 | if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) { |
|
241 | 48 | $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn']; |
|
242 | |||
243 | 48 | $metadata->setDiscriminatorColumn(array( |
|
244 | 48 | 'name' => $discrColumnAnnot->name, |
|
245 | 48 | 'type' => $discrColumnAnnot->type ?: 'string', |
|
246 | 48 | 'length' => $discrColumnAnnot->length ?: 255, |
|
247 | 48 | 'columnDefinition' => $discrColumnAnnot->columnDefinition, |
|
248 | )); |
||
249 | } else { |
||
250 | 20 | $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255)); |
|
251 | } |
||
252 | |||
253 | // Evaluate DiscriminatorMap annotation |
||
254 | 65 | if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) { |
|
255 | 64 | $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap']; |
|
256 | 64 | $metadata->setDiscriminatorMap($discrMapAnnot->value); |
|
257 | } |
||
258 | } |
||
259 | } |
||
260 | |||
261 | |||
262 | // Evaluate DoctrineChangeTrackingPolicy annotation |
||
263 | 361 | if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) { |
|
264 | 5 | $changeTrackingAnnot = $classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy']; |
|
265 | 5 | $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' . $changeTrackingAnnot->value)); |
|
266 | } |
||
267 | |||
268 | // Evaluate annotations on properties/fields |
||
269 | /* @var $property \ReflectionProperty */ |
||
270 | 361 | foreach ($class->getProperties() as $property) { |
|
271 | 359 | if ($metadata->isMappedSuperclass && ! $property->isPrivate() |
|
272 | || |
||
273 | 359 | $metadata->isInheritedField($property->name) |
|
274 | || |
||
275 | 359 | $metadata->isInheritedAssociation($property->name) |
|
276 | || |
||
277 | 359 | $metadata->isInheritedEmbeddedClass($property->name)) { |
|
278 | 69 | continue; |
|
279 | } |
||
280 | |||
281 | 359 | $mapping = array(); |
|
282 | 359 | $mapping['fieldName'] = $property->getName(); |
|
283 | |||
284 | // Evaluate @Cache annotation |
||
285 | 359 | if (($cacheAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Cache')) !== null) { |
|
286 | 12 | $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], array( |
|
287 | 12 | 'usage' => constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $cacheAnnot->usage), |
|
288 | 12 | 'region' => $cacheAnnot->region, |
|
289 | )); |
||
290 | } |
||
291 | // Check for JoinColumn/JoinColumns annotations |
||
292 | 358 | $joinColumns = array(); |
|
293 | |||
294 | 358 | if ($joinColumnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) { |
|
295 | 136 | $joinColumns[] = $this->joinColumnToArray($joinColumnAnnot); |
|
296 | 357 | } else if ($joinColumnsAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) { |
|
297 | 19 | foreach ($joinColumnsAnnot->value as $joinColumn) { |
|
298 | 19 | $joinColumns[] = $this->joinColumnToArray($joinColumn); |
|
299 | } |
||
300 | } |
||
301 | |||
302 | // Field can only be annotated with one of: |
||
303 | // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany |
||
304 | 358 | if ($columnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) { |
|
305 | 350 | if ($columnAnnot->type == null) { |
|
306 | throw MappingException::propertyTypeIsRequired($className, $property->getName()); |
||
307 | } |
||
308 | |||
309 | 350 | $mapping = $this->columnToArray($property->getName(), $columnAnnot); |
|
310 | |||
311 | 350 | if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { |
|
312 | 343 | $mapping['id'] = true; |
|
313 | } |
||
314 | |||
315 | 350 | if ($generatedValueAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) { |
|
316 | 292 | $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy)); |
|
317 | } |
||
318 | |||
319 | 350 | if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) { |
|
320 | 13 | $metadata->setVersionMapping($mapping); |
|
321 | } |
||
322 | |||
323 | 350 | $metadata->mapField($mapping); |
|
324 | |||
325 | // Check for SequenceGenerator/TableGenerator definition |
||
326 | 350 | if ($seqGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) { |
|
327 | 8 | $metadata->setSequenceGeneratorDefinition(array( |
|
328 | 8 | 'sequenceName' => $seqGeneratorAnnot->sequenceName, |
|
329 | 8 | 'allocationSize' => $seqGeneratorAnnot->allocationSize, |
|
330 | 8 | 'initialValue' => $seqGeneratorAnnot->initialValue |
|
331 | )); |
||
332 | 347 | } else if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) { |
|
333 | throw MappingException::tableIdGeneratorNotImplemented($className); |
||
334 | 347 | } else if ($customGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\CustomIdGenerator')) { |
|
335 | 2 | $metadata->setCustomGeneratorDefinition(array( |
|
336 | 350 | 'class' => $customGeneratorAnnot->class |
|
337 | )); |
||
338 | } |
||
339 | 256 | } else if ($oneToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) { |
|
340 | 106 | if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { |
|
341 | 9 | $mapping['id'] = true; |
|
342 | } |
||
343 | |||
344 | 106 | $mapping['targetEntity'] = $oneToOneAnnot->targetEntity; |
|
345 | 106 | $mapping['joinColumns'] = $joinColumns; |
|
346 | 106 | $mapping['mappedBy'] = $oneToOneAnnot->mappedBy; |
|
347 | 106 | $mapping['inversedBy'] = $oneToOneAnnot->inversedBy; |
|
348 | 106 | $mapping['cascade'] = $oneToOneAnnot->cascade; |
|
349 | 106 | $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval; |
|
350 | 106 | $mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch); |
|
351 | 106 | $metadata->mapOneToOne($mapping); |
|
352 | 207 | } else if ($oneToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) { |
|
353 | 102 | $mapping['mappedBy'] = $oneToManyAnnot->mappedBy; |
|
354 | 102 | $mapping['targetEntity'] = $oneToManyAnnot->targetEntity; |
|
355 | 102 | $mapping['cascade'] = $oneToManyAnnot->cascade; |
|
356 | 102 | $mapping['indexBy'] = $oneToManyAnnot->indexBy; |
|
357 | 102 | $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval; |
|
358 | 102 | $mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch); |
|
359 | |||
360 | 102 | if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) { |
|
361 | 15 | $mapping['orderBy'] = $orderByAnnot->value; |
|
362 | } |
||
363 | |||
364 | 102 | $metadata->mapOneToMany($mapping); |
|
365 | 204 | } else if ($manyToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) { |
|
366 | 133 | if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { |
|
367 | 30 | $mapping['id'] = true; |
|
368 | } |
||
369 | |||
370 | 133 | $mapping['joinColumns'] = $joinColumns; |
|
371 | 133 | $mapping['cascade'] = $manyToOneAnnot->cascade; |
|
372 | 133 | $mapping['inversedBy'] = $manyToOneAnnot->inversedBy; |
|
373 | 133 | $mapping['targetEntity'] = $manyToOneAnnot->targetEntity; |
|
374 | 133 | $mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch); |
|
375 | 133 | $metadata->mapManyToOne($mapping); |
|
376 | 114 | } else if ($manyToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) { |
|
377 | 85 | $joinTable = array(); |
|
378 | |||
379 | 85 | if ($joinTableAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) { |
|
380 | $joinTable = array( |
||
381 | 66 | 'name' => $joinTableAnnot->name, |
|
382 | 66 | 'schema' => $joinTableAnnot->schema |
|
383 | ); |
||
384 | |||
385 | 66 | foreach ($joinTableAnnot->joinColumns as $joinColumn) { |
|
386 | 65 | $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn); |
|
387 | } |
||
388 | |||
389 | 66 | foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) { |
|
390 | 65 | $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn); |
|
391 | } |
||
392 | } |
||
393 | |||
394 | 85 | $mapping['joinTable'] = $joinTable; |
|
395 | 85 | $mapping['targetEntity'] = $manyToManyAnnot->targetEntity; |
|
396 | 85 | $mapping['mappedBy'] = $manyToManyAnnot->mappedBy; |
|
397 | 85 | $mapping['inversedBy'] = $manyToManyAnnot->inversedBy; |
|
398 | 85 | $mapping['cascade'] = $manyToManyAnnot->cascade; |
|
399 | 85 | $mapping['indexBy'] = $manyToManyAnnot->indexBy; |
|
400 | 85 | $mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval; |
|
401 | 85 | $mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch); |
|
402 | |||
403 | 85 | if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) { |
|
404 | 3 | $mapping['orderBy'] = $orderByAnnot->value; |
|
405 | } |
||
406 | |||
407 | 85 | $metadata->mapManyToMany($mapping); |
|
408 | 46 | } else if ($embeddedAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Embedded')) { |
|
409 | 12 | $mapping['class'] = $embeddedAnnot->class; |
|
410 | 12 | $mapping['columnPrefix'] = $embeddedAnnot->columnPrefix; |
|
411 | |||
412 | 357 | $metadata->mapEmbedded($mapping); |
|
413 | } |
||
414 | } |
||
415 | |||
416 | // Evaluate AssociationOverrides annotation |
||
417 | 359 | if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) { |
|
418 | 4 | $associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides']; |
|
419 | |||
420 | 4 | foreach ($associationOverridesAnnot->value as $associationOverride) { |
|
421 | 4 | $override = array(); |
|
422 | 4 | $fieldName = $associationOverride->name; |
|
423 | |||
424 | // Check for JoinColumn/JoinColumns annotations |
||
425 | 4 | if ($associationOverride->joinColumns) { |
|
426 | 3 | $joinColumns = array(); |
|
427 | |||
428 | 3 | foreach ($associationOverride->joinColumns as $joinColumn) { |
|
429 | 3 | $joinColumns[] = $this->joinColumnToArray($joinColumn); |
|
430 | } |
||
431 | |||
432 | 3 | $override['joinColumns'] = $joinColumns; |
|
433 | } |
||
434 | |||
435 | // Check for JoinTable annotations |
||
436 | 4 | if ($associationOverride->joinTable) { |
|
437 | 2 | $joinTableAnnot = $associationOverride->joinTable; |
|
438 | $joinTable = array( |
||
439 | 2 | 'name' => $joinTableAnnot->name, |
|
440 | 2 | 'schema' => $joinTableAnnot->schema |
|
441 | ); |
||
442 | |||
443 | 2 | foreach ($joinTableAnnot->joinColumns as $joinColumn) { |
|
444 | 2 | $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn); |
|
445 | } |
||
446 | |||
447 | 2 | foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) { |
|
448 | 2 | $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn); |
|
449 | } |
||
450 | |||
451 | 2 | $override['joinTable'] = $joinTable; |
|
452 | } |
||
453 | |||
454 | // Check for inversedBy |
||
455 | 4 | if ($associationOverride->inversedBy) { |
|
456 | 1 | $override['inversedBy'] = $associationOverride->inversedBy; |
|
457 | } |
||
458 | |||
459 | // Check for `fetch` |
||
460 | 4 | if ($associationOverride->fetch) { |
|
461 | $override['fetch'] = $associationOverride->fetch; |
||
462 | } |
||
463 | |||
464 | 4 | $metadata->setAssociationOverride($fieldName, $override); |
|
465 | } |
||
466 | } |
||
467 | |||
468 | // Evaluate AttributeOverrides annotation |
||
469 | 359 | if (isset($classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'])) { |
|
470 | 3 | $attributeOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides']; |
|
471 | |||
472 | 3 | foreach ($attributeOverridesAnnot->value as $attributeOverrideAnnot) { |
|
473 | 3 | $attributeOverride = $this->columnToArray($attributeOverrideAnnot->name, $attributeOverrideAnnot->column); |
|
474 | |||
475 | 3 | $metadata->setAttributeOverride($attributeOverrideAnnot->name, $attributeOverride); |
|
476 | } |
||
477 | } |
||
478 | |||
479 | // Evaluate EntityListeners annotation |
||
480 | 359 | if (isset($classAnnotations['Doctrine\ORM\Mapping\EntityListeners'])) { |
|
481 | 10 | $entityListenersAnnot = $classAnnotations['Doctrine\ORM\Mapping\EntityListeners']; |
|
482 | |||
483 | 10 | foreach ($entityListenersAnnot->value as $item) { |
|
484 | 10 | $listenerClassName = $metadata->fullyQualifiedClassName($item); |
|
485 | |||
486 | 10 | if ( ! class_exists($listenerClassName)) { |
|
487 | throw MappingException::entityListenerClassNotFound($listenerClassName, $className); |
||
488 | } |
||
489 | |||
490 | 10 | $hasMapping = false; |
|
491 | 10 | $listenerClass = new \ReflectionClass($listenerClassName); |
|
492 | |||
493 | /* @var $method \ReflectionMethod */ |
||
494 | 10 | foreach ($listenerClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { |
|
495 | // find method callbacks. |
||
496 | 10 | $callbacks = $this->getMethodCallbacks($method); |
|
497 | 10 | $hasMapping = $hasMapping ?: ( ! empty($callbacks)); |
|
498 | |||
499 | 10 | foreach ($callbacks as $value) { |
|
500 | 10 | $metadata->addEntityListener($value[1], $listenerClassName, $value[0]); |
|
501 | } |
||
502 | } |
||
503 | |||
504 | // Evaluate the listener using naming convention. |
||
505 | 10 | if ( ! $hasMapping ) { |
|
506 | 10 | EntityListenerBuilder::bindEntityListener($metadata, $listenerClassName); |
|
507 | } |
||
508 | } |
||
509 | } |
||
510 | |||
511 | // Evaluate @HasLifecycleCallbacks annotation |
||
512 | 359 | if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { |
|
513 | /* @var $method \ReflectionMethod */ |
||
514 | 18 | foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { |
|
515 | 17 | foreach ($this->getMethodCallbacks($method) as $value) { |
|
516 | 17 | $metadata->addLifecycleCallback($value[0], $value[1]); |
|
517 | } |
||
518 | } |
||
519 | } |
||
520 | 359 | } |
|
521 | |||
522 | /** |
||
523 | * Attempts to resolve the fetch mode. |
||
524 | * |
||
525 | * @param string $className The class name. |
||
526 | * @param string $fetchMode The fetch mode. |
||
527 | * |
||
528 | * @return integer The fetch mode as defined in ClassMetadata. |
||
529 | * |
||
530 | * @throws MappingException If the fetch mode is not valid. |
||
531 | */ |
||
532 | 242 | private function getFetchMode($className, $fetchMode) |
|
540 | |||
541 | /** |
||
542 | * Parses the given method. |
||
543 | * |
||
544 | * @param \ReflectionMethod $method |
||
545 | * |
||
546 | * @return array |
||
547 | */ |
||
548 | 27 | private function getMethodCallbacks(\ReflectionMethod $method) |
|
589 | |||
590 | /** |
||
591 | * Parse the given JoinColumn as array |
||
592 | * |
||
593 | * @param JoinColumn $joinColumn |
||
594 | * @return array |
||
595 | */ |
||
596 | 174 | private function joinColumnToArray(JoinColumn $joinColumn) |
|
607 | |||
608 | /** |
||
609 | * Parse the given Column as array |
||
610 | * |
||
611 | * @param string $fieldName |
||
612 | * @param Column $column |
||
613 | * |
||
614 | * @return array |
||
615 | */ |
||
616 | 350 | private function columnToArray($fieldName, Column $column) |
|
642 | |||
643 | /** |
||
644 | * Factory method for the Annotation Driver. |
||
645 | * |
||
646 | * @param array|string $paths |
||
647 | * @param AnnotationReader|null $reader |
||
648 | * |
||
649 | * @return AnnotationDriver |
||
650 | */ |
||
651 | static public function create($paths = array(), AnnotationReader $reader = null) |
||
659 | } |
||
660 |
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.