Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like XmlDriver 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 XmlDriver, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class XmlDriver extends FileDriver |
||
24 | { |
||
25 | const DEFAULT_FILE_EXTENSION = '.dcm.xml'; |
||
26 | |||
27 | /** |
||
28 | * {@inheritDoc} |
||
29 | */ |
||
30 | public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION) |
||
31 | { |
||
32 | parent::__construct($locator, $fileExtension); |
||
33 | } |
||
34 | |||
35 | /** |
||
36 | * {@inheritDoc} |
||
37 | */ |
||
38 | public function loadMetadataForClass( |
||
39 | string $className, |
||
40 | Mapping\ClassMetadata $metadata, |
||
41 | Mapping\ClassMetadataBuildingContext $metadataBuildingContext |
||
42 | ) |
||
43 | { |
||
44 | /* @var \SimpleXMLElement $xmlRoot */ |
||
45 | $xmlRoot = $this->getElement($className); |
||
46 | |||
47 | if ($xmlRoot->getName() === 'entity') { |
||
48 | 41 | if (isset($xmlRoot['repository-class'])) { |
|
49 | $metadata->setCustomRepositoryClassName( |
||
50 | 41 | $metadata->fullyQualifiedClassName((string) $xmlRoot['repository-class']) |
|
51 | 41 | ); |
|
52 | } |
||
53 | |||
54 | if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) { |
||
55 | $metadata->asReadOnly(); |
||
56 | 36 | } |
|
57 | } else if ($xmlRoot->getName() === 'mapped-superclass') { |
||
58 | if (isset($xmlRoot['repository-class'])) { |
||
59 | $metadata->setCustomRepositoryClassName( |
||
60 | 36 | $metadata->fullyQualifiedClassName((string) $xmlRoot['repository-class']) |
|
61 | ); |
||
62 | 34 | } |
|
63 | 33 | ||
64 | $metadata->isMappedSuperclass = true; |
||
65 | } else if ($xmlRoot->getName() === 'embeddable') { |
||
66 | 33 | $metadata->isEmbeddedClass = true; |
|
67 | 33 | } else { |
|
68 | throw Mapping\MappingException::classIsNotAValidEntityOrMappedSuperClass($className); |
||
69 | 6 | } |
|
70 | 5 | ||
71 | 5 | // Process table information |
|
72 | $parent = $metadata->getParent(); |
||
73 | 5 | ||
74 | 1 | if ($parent && $parent->inheritanceType === Mapping\InheritanceType::SINGLE_TABLE) { |
|
75 | 1 | $metadata->setTable($parent->table); |
|
76 | } else { |
||
77 | $namingStrategy = $metadataBuildingContext->getNamingStrategy(); |
||
78 | $tableMetadata = new Mapping\TableMetadata(); |
||
79 | |||
80 | $tableMetadata->setName($namingStrategy->classToTableName($metadata->getClassName())); |
||
81 | 34 | ||
82 | // Evaluate <entity...> attributes |
||
83 | 34 | if (isset($xmlRoot['table'])) { |
|
84 | 14 | $tableMetadata->setName((string) $xmlRoot['table']); |
|
85 | } |
||
86 | |||
87 | 34 | if (isset($xmlRoot['schema'])) { |
|
88 | 1 | $tableMetadata->setSchema((string) $xmlRoot['schema']); |
|
89 | } |
||
90 | |||
91 | 34 | if (isset($xmlRoot->options)) { |
|
92 | $options = $this->parseOptions($xmlRoot->options->children()); |
||
93 | |||
94 | 34 | foreach ($options as $optionName => $optionValue) { |
|
95 | 2 | $tableMetadata->addOption($optionName, $optionValue); |
|
96 | } |
||
97 | } |
||
98 | |||
99 | 34 | // Evaluate <indexes...> |
|
100 | 3 | if (isset($xmlRoot->indexes)) { |
|
101 | 3 | foreach ($xmlRoot->indexes->index as $indexXml) { |
|
102 | 3 | $indexName = isset($indexXml['name']) ? (string) $indexXml['name'] : null; |
|
103 | 3 | $columns = explode(',', (string) $indexXml['columns']); |
|
104 | $isUnique = isset($indexXml['unique']) && $indexXml['unique']; |
||
105 | $options = isset($indexXml->options) ? $this->parseOptions($indexXml->options->children()) : []; |
||
106 | $flags = isset($indexXml['flags']) ? explode(',', (string) $indexXml['flags']) : []; |
||
107 | |||
108 | $tableMetadata->addIndex([ |
||
109 | 34 | 'name' => $indexName, |
|
110 | 3 | 'columns' => $columns, |
|
111 | 3 | 'unique' => $isUnique, |
|
112 | 3 | 'options' => $options, |
|
113 | 3 | 'flags' => $flags, |
|
114 | 3 | ]); |
|
115 | 3 | } |
|
116 | } |
||
117 | |||
118 | // Evaluate <unique-constraints..> |
||
119 | |||
120 | if (isset($xmlRoot->{'unique-constraints'})) { |
||
121 | 34 | foreach ($xmlRoot->{'unique-constraints'}->{'unique-constraint'} as $uniqueXml) { |
|
122 | 3 | $indexName = isset($uniqueXml['name']) ? (string) $uniqueXml['name'] : null; |
|
123 | 3 | $columns = explode(',', (string) $uniqueXml['columns']); |
|
124 | 3 | $options = isset($uniqueXml->options) ? $this->parseOptions($uniqueXml->options->children()) : []; |
|
125 | $flags = isset($uniqueXml['flags']) ? explode(',', (string) $uniqueXml['flags']) : []; |
||
126 | 3 | ||
127 | $tableMetadata->addUniqueConstraint([ |
||
128 | 3 | 'name' => $indexName, |
|
129 | 'columns' => $columns, |
||
130 | 3 | 'options' => $options, |
|
131 | 3 | 'flags' => $flags, |
|
132 | 3 | ]); |
|
133 | } |
||
134 | } |
||
135 | 3 | ||
136 | 3 | $metadata->setTable($tableMetadata); |
|
137 | 3 | } |
|
138 | 3 | ||
139 | // Evaluate second level cache |
||
140 | if (isset($xmlRoot->cache)) { |
||
141 | $cache = $this->convertCacheElementToCacheMetadata($xmlRoot->cache, $metadata); |
||
142 | 3 | ||
143 | $metadata->setCache($cache); |
||
144 | } |
||
145 | |||
146 | 3 | // Evaluate named queries |
|
147 | 3 | if (isset($xmlRoot->{'named-queries'})) { |
|
148 | 3 | foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) { |
|
149 | $metadata->addNamedQuery((string) $namedQueryElement['name'], (string) $namedQueryElement['query']); |
||
150 | } |
||
151 | } |
||
152 | |||
153 | 3 | // Evaluate native named queries |
|
154 | 3 | if (isset($xmlRoot->{'named-native-queries'})) { |
|
155 | 3 | foreach ($xmlRoot->{'named-native-queries'}->{'named-native-query'} as $nativeQueryElement) { |
|
156 | 3 | $metadata->addNamedNativeQuery( |
|
157 | isset($nativeQueryElement['name']) ? (string) $nativeQueryElement['name'] : null, |
||
158 | isset($nativeQueryElement->query) ? (string) $nativeQueryElement->query : null, |
||
159 | [ |
||
160 | 'resultClass' => isset($nativeQueryElement['result-class']) ? (string) $nativeQueryElement['result-class'] : null, |
||
161 | 34 | 'resultSetMapping' => isset($nativeQueryElement['result-set-mapping']) ? (string) $nativeQueryElement['result-set-mapping'] : null, |
|
162 | 10 | ] |
|
163 | 10 | ); |
|
164 | } |
||
165 | 10 | } |
|
166 | 10 | ||
167 | // Evaluate sql result set mapping |
||
168 | 10 | if (isset($xmlRoot->{'sql-result-set-mappings'})) { |
|
169 | foreach ($xmlRoot->{'sql-result-set-mappings'}->{'sql-result-set-mapping'} as $rsmElement) { |
||
170 | $entities = []; |
||
171 | 10 | $columns = []; |
|
172 | 7 | ||
173 | foreach ($rsmElement as $entityElement) { |
||
174 | 7 | //<entity-result/> |
|
175 | 7 | if (isset($entityElement['entity-class'])) { |
|
176 | 7 | $entityResult = [ |
|
177 | 7 | 'fields' => [], |
|
178 | 'entityClass' => (string) $entityElement['entity-class'], |
||
179 | 6 | 'discriminatorColumn' => isset($entityElement['discriminator-column']) ? (string) $entityElement['discriminator-column'] : null, |
|
180 | 6 | ]; |
|
181 | 6 | ||
182 | foreach ($entityElement as $fieldElement) { |
||
183 | $entityResult['fields'][] = [ |
||
184 | 10 | 'name' => isset($fieldElement['name']) ? (string) $fieldElement['name'] : null, |
|
185 | 'column' => isset($fieldElement['column']) ? (string) $fieldElement['column'] : null, |
||
186 | ]; |
||
187 | 10 | } |
|
188 | 10 | ||
189 | $entities[] = $entityResult; |
||
190 | 10 | } |
|
191 | 10 | ||
192 | //<column-result/> |
||
193 | if (isset($entityElement['name'])) { |
||
194 | 10 | $columns[] = [ |
|
195 | 'name' => (string) $entityElement['name'], |
||
196 | ]; |
||
197 | } |
||
198 | } |
||
199 | |||
200 | $metadata->addSqlResultSetMapping( |
||
201 | 34 | [ |
|
202 | 'name' => (string) $rsmElement['name'], |
||
203 | 'entities' => $entities, |
||
204 | 'columns' => $columns |
||
205 | ] |
||
206 | ); |
||
207 | } |
||
208 | 34 | } |
|
209 | 3 | ||
210 | if (isset($xmlRoot['inheritance-type'])) { |
||
211 | 3 | $inheritanceType = strtoupper((string) $xmlRoot['inheritance-type']); |
|
212 | 3 | ||
213 | $metadata->setInheritanceType( |
||
214 | 3 | constant(sprintf('%s::%s', Mapping\InheritanceType::class, $inheritanceType)) |
|
215 | 1 | ); |
|
216 | |||
217 | if ($metadata->inheritanceType !== Mapping\InheritanceType::NONE) { |
||
218 | 3 | $discriminatorColumn = new Mapping\DiscriminatorColumnMetadata(); |
|
219 | 1 | ||
220 | $discriminatorColumn->setTableName($metadata->getTableName()); |
||
221 | $discriminatorColumn->setColumnName('dtype'); |
||
222 | 3 | $discriminatorColumn->setType(Type::getType('string')); |
|
223 | 2 | $discriminatorColumn->setLength(255); |
|
224 | |||
225 | 3 | // Evaluate <discriminator-column...> |
|
226 | if (isset($xmlRoot->{'discriminator-column'})) { |
||
227 | $discrColumn = $xmlRoot->{'discriminator-column'}; |
||
228 | $metadata->setDiscriminatorColumn( |
||
229 | [ |
||
230 | 'name' => isset($discrColumn['name']) ? (string) $discrColumn['name'] : null, |
||
231 | 34 | 'type' => (string) ($discrColumn['type'] ?? 'string'), |
|
232 | 2 | 'length' => isset($discrColumn['length']) ? (string) $discrColumn['length'] : 255, |
|
233 | 'columnDefinition' => isset($discrColumn['column-definition']) ? (string) $discrColumn['column-definition'] : null |
||
234 | 2 | ] |
|
235 | 2 | ); |
|
236 | } else { |
||
237 | $metadata->setDiscriminatorColumn(['name' => 'dtype', 'type' => 'string', 'length' => 255]); |
||
238 | 2 | } |
|
239 | 2 | ||
240 | $metadata->setDiscriminatorColumn($discriminatorColumn); |
||
241 | |||
242 | 2 | // Evaluate <discriminator-map...> |
|
243 | 2 | if (isset($xmlRoot->{'discriminator-map'})) { |
|
244 | $map = []; |
||
245 | 2 | ||
246 | foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} as $discrMapElement) { |
||
247 | $map[(string) $discrMapElement['value']] = $metadata->fullyQualifiedClassName((string) $discrMapElement['class']); |
||
248 | } |
||
249 | |||
250 | 34 | $metadata->setDiscriminatorMap($map); |
|
251 | 4 | } |
|
252 | } |
||
253 | } |
||
254 | |||
255 | 34 | ||
256 | 21 | // Evaluate <change-tracking-policy...> |
|
257 | 21 | if (isset($xmlRoot['change-tracking-policy'])) { |
|
258 | 21 | $changeTrackingPolicy = strtoupper((string) $xmlRoot['change-tracking-policy']); |
|
259 | 21 | ||
260 | 21 | $metadata->setChangeTrackingPolicy( |
|
261 | constant(sprintf('%s::%s', Mapping\ChangeTrackingPolicy::class, $changeTrackingPolicy)) |
||
262 | 21 | ); |
|
263 | 2 | } |
|
264 | |||
265 | 21 | // Evaluate <field ...> mappings |
|
266 | if (isset($xmlRoot->field)) { |
||
267 | foreach ($xmlRoot->field as $fieldElement) { |
||
268 | $fieldName = (string) $fieldElement['name']; |
||
269 | $isFieldVersioned = isset($fieldElement['version']) && $fieldElement['version']; |
||
270 | 34 | $fieldMetadata = $this->convertFieldElementToFieldMetadata($fieldElement, $fieldName, $isFieldVersioned); |
|
271 | 3 | ||
272 | 3 | $metadata->addProperty($fieldMetadata); |
|
273 | 3 | } |
|
274 | 3 | } |
|
275 | |||
276 | 3 | if (isset($xmlRoot->embedded)) { |
|
277 | 2 | foreach ($xmlRoot->embedded as $embeddedMapping) { |
|
278 | 3 | $columnPrefix = isset($embeddedMapping['column-prefix']) |
|
279 | ? (string) $embeddedMapping['column-prefix'] |
||
280 | : null; |
||
281 | 3 | ||
282 | 3 | $useColumnPrefix = isset($embeddedMapping['use-column-prefix']) |
|
283 | 3 | ? $this->evaluateBoolean($embeddedMapping['use-column-prefix']) |
|
284 | : true; |
||
285 | |||
286 | 3 | $mapping = [ |
|
287 | 'fieldName' => (string) $embeddedMapping['name'], |
||
288 | 'class' => (string) $embeddedMapping['class'], |
||
289 | 'columnPrefix' => $useColumnPrefix ? $columnPrefix : false |
||
290 | ]; |
||
291 | 34 | ||
292 | $metadata->mapEmbedded($mapping); |
||
293 | 34 | } |
|
294 | 31 | } |
|
295 | 2 | ||
296 | // Evaluate <id ...> mappings |
||
297 | 2 | $associationIds = []; |
|
298 | |||
299 | foreach ($xmlRoot->id as $idElement) { |
||
300 | 30 | $fieldName = (string) $idElement['name']; |
|
301 | 30 | ||
302 | 30 | if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) { |
|
303 | $associationIds[$fieldName] = true; |
||
304 | 30 | ||
305 | continue; |
||
306 | 30 | } |
|
307 | |||
308 | 30 | $fieldMetadata = $this->convertFieldElementToFieldMetadata($idElement, $fieldName, false); |
|
309 | 29 | ||
310 | 29 | $fieldMetadata->setPrimaryKey(true); |
|
311 | 29 | ||
312 | if (isset($idElement->generator)) { |
||
313 | 29 | $strategy = (string) ($idElement->generator['strategy'] ?? 'AUTO'); |
|
314 | 29 | ||
315 | $idGeneratorType = constant(sprintf('%s::%s', Mapping\GeneratorType::class, strtoupper($strategy))); |
||
316 | |||
317 | if ($idGeneratorType !== Mapping\GeneratorType::NONE) { |
||
318 | $idGeneratorDefinition = []; |
||
319 | 30 | ||
320 | 2 | // Check for SequenceGenerator/TableGenerator definition |
|
321 | if (isset($idElement->{'sequence-generator'})) { |
||
322 | 2 | $seqGenerator = $idElement->{'sequence-generator'}; |
|
323 | 2 | $idGeneratorDefinition = [ |
|
324 | 2 | 'sequenceName' => (string) $seqGenerator['sequence-name'], |
|
325 | 2 | 'allocationSize' => (string) $seqGenerator['allocation-size'], |
|
326 | ]; |
||
327 | 28 | } elseif (isset($idElement->{'custom-id-generator'})) { |
|
328 | 2 | $customGenerator = $idElement->{'custom-id-generator'}; |
|
329 | |||
330 | 2 | $idGeneratorDefinition = [ |
|
331 | 2 | 'class' => (string) $customGenerator['class'], |
|
332 | 'arguments' => [], |
||
333 | 26 | ]; |
|
334 | 30 | } elseif (isset($idElement->{'table-generator'})) { |
|
335 | throw Mapping\MappingException::tableIdGeneratorNotImplemented($className); |
||
336 | } |
||
337 | |||
338 | if (isset($idElement->generator)) { |
||
339 | 34 | $strategy = (string) ($idElement->generator['strategy'] ?? 'AUTO'); |
|
340 | 7 | $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' |
|
341 | . $strategy)); |
||
342 | 7 | } |
|
343 | 7 | ||
344 | $metadata->addProperty($fieldMetadata); |
||
345 | } |
||
346 | 7 | ||
347 | // Evaluate <one-to-one ...> mappings |
||
348 | if (isset($xmlRoot->{'one-to-one'})) { |
||
349 | foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) { |
||
350 | 7 | $association = new Mapping\OneToOneAssociationMetadata((string) $oneToOneElement['field']); |
|
351 | 2 | $targetEntity = $metadata->fullyQualifiedClassName((string) $oneToOneElement['target-entity']); |
|
352 | |||
353 | $association->setTargetEntity($targetEntity); |
||
354 | 7 | ||
355 | 2 | if (isset($associationIds[$association->getName()])) { |
|
356 | $association->setPrimaryKey(true); |
||
357 | 7 | } |
|
358 | 7 | ||
359 | if (isset($oneToOneElement['fetch'])) { |
||
360 | $association->setFetchMode( |
||
361 | 7 | constant(sprintf('%s::%s', Mapping\FetchMode::class, (string) $oneToOneElement['fetch'])) |
|
362 | ); |
||
363 | 7 | } |
|
364 | 6 | ||
365 | 1 | if (isset($oneToOneElement['mapped-by'])) { |
|
366 | 1 | $association->setMappedBy((string) $oneToOneElement['mapped-by']); |
|
367 | 1 | } else { |
|
368 | if (isset($oneToOneElement['inversed-by'])) { |
||
369 | $association->setInversedBy((string) $oneToOneElement['inversed-by']); |
||
370 | } |
||
371 | 7 | ||
372 | $joinColumns = []; |
||
373 | |||
374 | 7 | if (isset($oneToOneElement->{'join-column'})) { |
|
375 | 5 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnMetadata($oneToOneElement->{'join-column'}); |
|
376 | } else if (isset($oneToOneElement->{'join-columns'})) { |
||
377 | foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
||
378 | 7 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
|
379 | 3 | } |
|
380 | } |
||
381 | |||
382 | $association->setJoinColumns($joinColumns); |
||
383 | 7 | } |
|
384 | |||
385 | if (isset($oneToOneElement->cascade)) { |
||
386 | $association->setCascade($this->getCascadeMappings($oneToOneElement->cascade)); |
||
387 | 7 | } |
|
388 | |||
389 | if (isset($oneToOneElement['orphan-removal'])) { |
||
390 | $association->setOrphanRemoval($this->evaluateBoolean($oneToOneElement['orphan-removal'])); |
||
391 | } |
||
392 | 34 | ||
393 | 7 | // Evaluate second level cache |
|
394 | if (isset($oneToOneElement->cache)) { |
||
395 | 7 | $association->setCache( |
|
396 | 7 | $this->convertCacheElementToCacheMetadata( |
|
397 | 7 | $oneToOneElement->cache, |
|
398 | $metadata, |
||
399 | $association->getName() |
||
400 | 7 | ) |
|
401 | 2 | ); |
|
402 | } |
||
403 | |||
404 | 7 | $metadata->addProperty($association); |
|
405 | 5 | } |
|
406 | } |
||
407 | |||
408 | 7 | // Evaluate <one-to-many ...> mappings |
|
409 | 5 | if (isset($xmlRoot->{'one-to-many'})) { |
|
410 | foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) { |
||
411 | $association = new Mapping\OneToManyAssociationMetadata((string) $oneToManyElement['field']); |
||
412 | 7 | $targetEntity = $metadata->fullyQualifiedClassName((string) $oneToManyElement['target-entity']); |
|
413 | 5 | ||
414 | 5 | $association->setTargetEntity($targetEntity); |
|
415 | 5 | $association->setMappedBy((string) $oneToManyElement['mapped-by']); |
|
416 | |||
417 | 5 | if (isset($associationIds[$association->getName()])) { |
|
418 | throw Mapping\MappingException::illegalToManyIdentifierAssociation($className, $association->getName()); |
||
419 | } |
||
420 | 7 | ||
421 | 2 | if (isset($oneToManyElement['fetch'])) { |
|
422 | 5 | $association->setFetchMode( |
|
423 | constant(sprintf('%s::%s', Mapping\FetchMode::class, (string) $oneToManyElement['fetch'])) |
||
424 | ); |
||
425 | } |
||
426 | |||
427 | 7 | if (isset($oneToManyElement->cascade)) { |
|
428 | 1 | $association->setCascade($this->getCascadeMappings($oneToManyElement->cascade)); |
|
429 | } |
||
430 | |||
431 | 7 | if (isset($oneToManyElement['orphan-removal'])) { |
|
432 | $association->setOrphanRemoval($this->evaluateBoolean($oneToManyElement['orphan-removal'])); |
||
433 | } |
||
434 | |||
435 | if (isset($oneToManyElement->{'order-by'})) { |
||
436 | 34 | $orderBy = []; |
|
437 | 7 | ||
438 | foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) { |
||
439 | 7 | $orderBy[(string) $orderByField['name']] = (string) $orderByField['direction']; |
|
440 | 7 | } |
|
441 | |||
442 | $association->setOrderBy($orderBy); |
||
443 | 7 | } |
|
444 | 2 | ||
445 | if (isset($oneToManyElement['index-by'])) { |
||
446 | $association->setIndexedBy((string) $oneToManyElement['index-by']); |
||
447 | 7 | } else if (isset($oneToManyElement->{'index-by'})) { |
|
448 | 1 | throw new \InvalidArgumentException("<index-by /> is not a valid tag"); |
|
449 | } |
||
450 | |||
451 | 7 | // Evaluate second level cache |
|
452 | 1 | if (isset($oneToManyElement->cache)) { |
|
453 | $association->setCache( |
||
454 | $this->convertCacheElementToCacheMetadata( |
||
455 | 7 | $oneToManyElement->cache, |
|
456 | $metadata, |
||
457 | 7 | $association->getName() |
|
458 | 4 | ) |
|
459 | 3 | ); |
|
460 | 2 | } |
|
461 | 2 | ||
462 | $metadata->addProperty($association); |
||
463 | } |
||
464 | } |
||
465 | 7 | ||
466 | // Evaluate <many-to-one ...> mappings |
||
467 | 7 | if (isset($xmlRoot->{'many-to-one'})) { |
|
468 | 2 | foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) { |
|
469 | $association = new Mapping\ManyToOneAssociationMetadata((string) $manyToOneElement['field']); |
||
470 | $targetEntity = $metadata->fullyQualifiedClassName((string) $manyToOneElement['target-entity']); |
||
471 | |||
472 | 7 | $association->setTargetEntity($targetEntity); |
|
473 | 1 | ||
474 | if (isset($associationIds[$association->getName()])) { |
||
475 | $association->setPrimaryKey(true); |
||
476 | 7 | } |
|
477 | |||
478 | if (isset($manyToOneElement['fetch'])) { |
||
479 | $association->setFetchMode( |
||
480 | constant('Doctrine\ORM\Mapping\FetchMode::' . (string) $manyToOneElement['fetch']) |
||
481 | ); |
||
482 | 33 | } |
|
483 | 10 | ||
484 | if (isset($manyToOneElement['inversed-by'])) { |
||
485 | 10 | $association->setInversedBy((string) $manyToOneElement['inversed-by']); |
|
486 | 10 | } |
|
487 | |||
488 | $joinColumns = []; |
||
489 | 10 | ||
490 | 2 | if (isset($manyToOneElement->{'join-column'})) { |
|
491 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnMetadata($manyToOneElement->{'join-column'}); |
||
492 | } else if (isset($manyToOneElement->{'join-columns'})) { |
||
493 | 10 | foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
|
494 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
||
495 | } |
||
496 | } |
||
497 | 10 | ||
498 | 2 | $association->setJoinColumns($joinColumns); |
|
499 | 8 | ||
500 | 7 | if (isset($manyToOneElement->cascade)) { |
|
501 | 2 | $association->setCascade($this->getCascadeMappings($manyToOneElement->cascade)); |
|
502 | } |
||
503 | |||
504 | 7 | // Evaluate second level cache |
|
505 | if (isset($manyToOneElement->cache)) { |
||
506 | 7 | $association->setCache( |
|
507 | $this->convertCacheElementToCacheMetadata( |
||
508 | $manyToOneElement->cache, |
||
509 | 7 | $metadata, |
|
510 | $association->getName() |
||
511 | ) |
||
512 | ); |
||
513 | 7 | } |
|
514 | 7 | ||
515 | $metadata->addProperty($association); |
||
516 | } |
||
517 | 7 | } |
|
518 | 7 | ||
519 | // Evaluate <many-to-many ...> mappings |
||
520 | if (isset($xmlRoot->{'many-to-many'})) { |
||
521 | 7 | foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) { |
|
522 | $association = new Mapping\ManyToManyAssociationMetadata((string) $manyToManyElement['field']); |
||
523 | $targetEntity = $metadata->fullyQualifiedClassName((string) $manyToManyElement['target-entity']); |
||
524 | 10 | ||
525 | 7 | $association->setTargetEntity($targetEntity); |
|
526 | |||
527 | if (isset($associationIds[$association->getName()])) { |
||
528 | 10 | throw Mapping\MappingException::illegalToManyIdentifierAssociation($className, $association->getName()); |
|
529 | } |
||
530 | |||
531 | if (isset($manyToManyElement['fetch'])) { |
||
532 | $association->setFetchMode( |
||
533 | constant(sprintf('%s::%s', Mapping\FetchMode::class, (string) $manyToManyElement['fetch'])) |
||
534 | ); |
||
535 | } |
||
536 | |||
537 | if (isset($manyToManyElement['orphan-removal'])) { |
||
538 | 10 | $association->setOrphanRemoval($this->evaluateBoolean($manyToManyElement['orphan-removal'])); |
|
539 | } |
||
540 | 10 | ||
541 | if (isset($manyToManyElement['mapped-by'])) { |
||
542 | $association->setMappedBy((string) $manyToManyElement['mapped-by']); |
||
543 | } else if (isset($manyToManyElement->{'join-table'})) { |
||
544 | if (isset($manyToManyElement['inversed-by'])) { |
||
545 | 10 | $association->setInversedBy((string) $manyToManyElement['inversed-by']); |
|
546 | } |
||
547 | |||
548 | $joinTableElement = $manyToManyElement->{'join-table'}; |
||
549 | 10 | $joinTable = new Mapping\JoinTableMetadata(); |
|
550 | |||
551 | if (isset($joinTableElement['name'])) { |
||
552 | $joinTable->setName((string) $joinTableElement['name']); |
||
553 | } |
||
554 | 33 | ||
555 | 2 | if (isset($joinTableElement['schema'])) { |
|
556 | 2 | $joinTable->setSchema((string) $joinTableElement['schema']); |
|
557 | } |
||
558 | 2 | ||
559 | 2 | if (isset($joinTableElement->{'join-columns'})) { |
|
560 | foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
||
561 | 2 | $joinColumn = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
|
562 | |||
563 | $joinTable->addJoinColumn($joinColumn); |
||
564 | } |
||
565 | } |
||
566 | |||
567 | 33 | if (isset($joinTableElement->{'inverse-join-columns'})) { |
|
568 | 3 | foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) { |
|
569 | 3 | $joinColumn = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
|
570 | 3 | ||
571 | $joinTable->addInverseJoinColumn($joinColumn); |
||
572 | } |
||
573 | 3 | } |
|
574 | 2 | ||
575 | $association->setJoinTable($joinTable); |
||
576 | 2 | } |
|
577 | 2 | ||
578 | if (isset($manyToManyElement->cascade)) { |
||
579 | $association->setCascade($this->getCascadeMappings($manyToManyElement->cascade)); |
||
580 | 2 | } |
|
581 | |||
582 | if (isset($manyToManyElement->{'order-by'})) { |
||
583 | $orderBy = []; |
||
584 | 3 | ||
585 | 2 | foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) { |
|
586 | 2 | $orderBy[(string) $orderByField['name']] = (string) $orderByField['direction']; |
|
587 | } |
||
588 | |||
589 | 2 | $association->setOrderBy($orderBy); |
|
590 | 2 | } |
|
591 | |||
592 | if (isset($manyToManyElement['index-by'])) { |
||
593 | 2 | $association->setIndexedBy((string) $manyToManyElement['index-by']); |
|
594 | 2 | } else if (isset($manyToManyElement->{'index-by'})) { |
|
595 | 2 | throw new \InvalidArgumentException("<index-by /> is not a valid tag"); |
|
596 | } |
||
597 | |||
598 | // Evaluate second level cache |
||
599 | 2 | if (isset($manyToManyElement->cache)) { |
|
600 | 2 | $association->setCache( |
|
601 | 2 | $this->convertCacheElementToCacheMetadata( |
|
602 | $manyToManyElement->cache, |
||
603 | $metadata, |
||
604 | $association->getName() |
||
605 | 2 | ) |
|
606 | ); |
||
607 | } |
||
608 | |||
609 | 3 | $metadata->addProperty($association); |
|
610 | 1 | } |
|
611 | } |
||
612 | |||
613 | 3 | // Evaluate association-overrides |
|
614 | if (isset($xmlRoot->{'attribute-overrides'})) { |
||
615 | foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) { |
||
616 | $fieldName = (string) $overrideElement['name']; |
||
617 | |||
618 | 33 | foreach ($overrideElement->field as $fieldElement) { |
|
619 | 4 | $fieldMetadata = $this->convertFieldElementToFieldMetadata($fieldElement, $fieldName, false); |
|
620 | 4 | ||
621 | $metadata->setPropertyOverride($fieldMetadata); |
||
622 | } |
||
623 | } |
||
624 | } |
||
625 | 33 | ||
626 | 4 | // Evaluate association-overrides |
|
627 | 4 | if (isset($xmlRoot->{'association-overrides'})) { |
|
628 | foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) { |
||
629 | $fieldName = (string) $overrideElement['name']; |
||
630 | 4 | $property = $metadata->getProperty($fieldName); |
|
631 | 2 | ||
632 | if (! $property) { |
||
633 | 2 | throw Mapping\MappingException::invalidOverrideFieldName($metadata->getClassName(), $fieldName); |
|
634 | } |
||
635 | |||
636 | 2 | $existingClass = get_class($property); |
|
637 | 2 | $override = new $existingClass($fieldName); |
|
638 | 2 | ||
639 | // Check for join-columns |
||
640 | 2 | if (isset($overrideElement->{'join-columns'})) { |
|
641 | $joinColumns = []; |
||
642 | |||
643 | foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
||
644 | 33 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
|
645 | } |
||
646 | |||
647 | $override->setJoinColumns($joinColumns); |
||
648 | } |
||
649 | |||
650 | // Check for join-table |
||
651 | if ($overrideElement->{'join-table'}) { |
||
652 | $joinTableElement = $overrideElement->{'join-table'}; |
||
653 | 5 | $joinTable = new Mapping\JoinTableMetadata(); |
|
654 | |||
655 | 5 | if (isset($joinTableElement['name'])) { |
|
656 | $joinTable->setName((string) $joinTableElement['name']); |
||
657 | } |
||
658 | 5 | ||
659 | 5 | if (isset($joinTableElement['schema'])) { |
|
660 | 4 | $joinTable->setSchema((string) $joinTableElement['schema']); |
|
661 | } |
||
662 | 5 | ||
663 | if (isset($joinTableElement->{'join-columns'})) { |
||
664 | foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
||
665 | 5 | $joinColumn = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
|
666 | |||
667 | 5 | $joinTable->addJoinColumn($joinColumn); |
|
668 | 5 | } |
|
669 | } |
||
670 | 5 | ||
671 | if (isset($joinTableElement->{'inverse-join-columns'})) { |
||
672 | foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) { |
||
673 | $joinColumn = $this->convertJoinColumnElementToJoinColumnMetadata($joinColumnElement); |
||
674 | 5 | ||
675 | $joinTable->addInverseJoinColumn($joinColumn); |
||
676 | } |
||
677 | } |
||
678 | |||
679 | $override->setJoinTable($joinTable); |
||
680 | } |
||
681 | |||
682 | // Check for inversed-by |
||
683 | if (isset($overrideElement->{'inversed-by'})) { |
||
684 | $override->setInversedBy((string) $overrideElement->{'inversed-by'}['name']); |
||
685 | 12 | } |
|
686 | |||
687 | // Check for fetch |
||
688 | 12 | if (isset($overrideElement['fetch'])) { |
|
689 | 12 | $override->setFetchMode( |
|
690 | constant('Doctrine\ORM\Mapping\FetchMode::' . (string) $overrideElement['fetch']) |
||
691 | ); |
||
692 | 12 | } |
|
693 | 3 | ||
694 | $metadata->setPropertyOverride($override); |
||
695 | } |
||
696 | 12 | } |
|
697 | 5 | ||
698 | // Evaluate <lifecycle-callbacks...> |
||
699 | if (isset($xmlRoot->{'lifecycle-callbacks'})) { |
||
700 | 12 | foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) { |
|
701 | 4 | $eventName = constant(Events::class . '::' . (string) $lifecycleCallback['type']); |
|
702 | $methodName = (string) $lifecycleCallback['method']; |
||
703 | |||
704 | 12 | $metadata->addLifecycleCallback($methodName, $eventName); |
|
705 | 4 | } |
|
706 | } |
||
707 | |||
708 | 12 | // Evaluate entity listener |
|
709 | if (isset($xmlRoot->{'entity-listeners'})) { |
||
710 | foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { |
||
711 | $listenerClassName = $metadata->fullyQualifiedClassName((string) $listenerElement['class']); |
||
712 | |||
713 | if (! class_exists($listenerClassName)) { |
||
714 | throw Mapping\MappingException::entityListenerClassNotFound( |
||
715 | $listenerClassName, |
||
716 | $metadata->getClassName() |
||
717 | ); |
||
718 | 33 | } |
|
719 | |||
720 | $listenerClass = new \ReflectionClass($listenerClassName); |
||
721 | 33 | ||
722 | // Evaluate the listener using naming convention. |
||
723 | if ($listenerElement->count() === 0) { |
||
724 | 33 | /* @var $method \ReflectionMethod */ |
|
725 | 21 | foreach ($listenerClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { |
|
726 | foreach ($this->getMethodCallbacks($method) as $callback) { |
||
727 | 21 | $metadata->addEntityListener($callback, $listenerClassName, $method->getName()); |
|
728 | } |
||
729 | } |
||
730 | |||
731 | 21 | continue; |
|
732 | } |
||
733 | |||
734 | 33 | foreach ($listenerElement as $callbackElement) { |
|
735 | 23 | $eventName = (string) $callbackElement['type']; |
|
736 | $methodName = (string) $callbackElement['method']; |
||
737 | |||
738 | 33 | $metadata->addEntityListener($eventName, $listenerClassName, $methodName); |
|
739 | 10 | } |
|
740 | } |
||
741 | } |
||
742 | 33 | } |
|
743 | 1 | ||
744 | /** |
||
745 | * Parses (nested) option elements. |
||
746 | 33 | * |
|
747 | 1 | * @param SimpleXMLElement $options The XML element. |
|
748 | * |
||
749 | * @return array The options array. |
||
750 | 33 | */ |
|
751 | 9 | private function parseOptions(SimpleXMLElement $options) |
|
752 | { |
||
753 | $array = []; |
||
754 | 33 | ||
755 | 8 | /* @var $option SimpleXMLElement */ |
|
756 | foreach ($options as $option) { |
||
757 | if ($option->count()) { |
||
758 | 33 | $value = $this->parseOptions($option->children()); |
|
759 | 2 | } else { |
|
760 | $value = (string) $option; |
||
761 | } |
||
762 | 33 | ||
763 | 5 | $attributes = $option->attributes(); |
|
764 | |||
765 | if (isset($attributes->name)) { |
||
766 | 33 | $nameAttribute = (string) $attributes->name; |
|
767 | 4 | $array[$nameAttribute] = in_array($nameAttribute, ['unsigned', 'fixed']) |
|
768 | ? $this->evaluateBoolean($value) |
||
769 | : $value; |
||
770 | 33 | } else { |
|
771 | $array[] = $value; |
||
772 | } |
||
773 | |||
774 | } |
||
775 | |||
776 | return $array; |
||
777 | } |
||
778 | |||
779 | /** |
||
780 | 2 | * @param SimpleXMLElement $fieldElement |
|
781 | * @param string $fieldName |
||
782 | 2 | * @param bool $isVersioned |
|
783 | 2 | * |
|
784 | * @return Mapping\FieldMetadata |
||
785 | 2 | */ |
|
786 | private function convertFieldElementToFieldMetadata(SimpleXMLElement $fieldElement, string $fieldName, bool $isVersioned) |
||
787 | { |
||
788 | $fieldMetadata = $isVersioned |
||
789 | 2 | ? new Mapping\VersionFieldMetadata($fieldName) |
|
790 | 2 | : new Mapping\FieldMetadata($fieldName) |
|
791 | ; |
||
792 | |||
793 | $fieldMetadata->setType(Type::getType('string')); |
||
794 | 2 | ||
795 | 2 | if (isset($fieldElement['type'])) { |
|
796 | $fieldMetadata->setType(Type::getType((string) $fieldElement['type'])); |
||
797 | } |
||
798 | |||
799 | if (isset($fieldElement['column'])) { |
||
800 | $fieldMetadata->setColumnName((string) $fieldElement['column']); |
||
801 | } |
||
802 | |||
803 | if (isset($fieldElement['length'])) { |
||
804 | $fieldMetadata->setLength((int) $fieldElement['length']); |
||
805 | } |
||
806 | 7 | ||
807 | if (isset($fieldElement['precision'])) { |
||
808 | 7 | $fieldMetadata->setPrecision((int) $fieldElement['precision']); |
|
809 | } |
||
810 | |||
811 | 7 | if (isset($fieldElement['scale'])) { |
|
812 | $fieldMetadata->setScale((int) $fieldElement['scale']); |
||
813 | } |
||
814 | |||
815 | if (isset($fieldElement['unique'])) { |
||
816 | $fieldMetadata->setUnique($this->evaluateBoolean($fieldElement['unique'])); |
||
817 | 7 | } |
|
818 | |||
819 | if (isset($fieldElement['nullable'])) { |
||
820 | 7 | $fieldMetadata->setNullable($this->evaluateBoolean($fieldElement['nullable'])); |
|
821 | } |
||
822 | |||
823 | if (isset($fieldElement['column-definition'])) { |
||
824 | $fieldMetadata->setColumnDefinition((string) $fieldElement['column-definition']); |
||
825 | } |
||
826 | 36 | ||
827 | if (isset($fieldElement->options)) { |
||
828 | 36 | $fieldMetadata->setOptions($this->parseOptions($fieldElement->options->children())); |
|
829 | 36 | } |
|
830 | |||
831 | 36 | return $fieldMetadata; |
|
832 | 34 | } |
|
833 | 34 | ||
834 | 34 | /** |
|
835 | * Constructs a joinColumn mapping array based on the information |
||
836 | 7 | * found in the given SimpleXMLElement. |
|
837 | 5 | * |
|
838 | 5 | * @param SimpleXMLElement $joinColumnElement The XML element. |
|
839 | 5 | * |
|
840 | * @return Mapping\JoinColumnMetadata |
||
841 | 2 | */ |
|
842 | 1 | private function convertJoinColumnElementToJoinColumnMetadata(SimpleXMLElement $joinColumnElement) |
|
843 | 1 | { |
|
844 | 1 | $joinColumnMetadata = new Mapping\JoinColumnMetadata(); |
|
845 | |||
846 | $joinColumnMetadata->setColumnName((string) $joinColumnElement['name']); |
||
847 | $joinColumnMetadata->setReferencedColumnName((string) $joinColumnElement['referenced-column-name']); |
||
848 | 36 | ||
849 | if (isset($joinColumnElement['column-definition'])) { |
||
850 | $joinColumnMetadata->setColumnDefinition((string) $joinColumnElement['column-definition']); |
||
851 | } |
||
852 | |||
853 | if (isset($joinColumnElement['field-name'])) { |
||
854 | $joinColumnMetadata->setAliasedName((string) $joinColumnElement['field-name']); |
||
855 | } |
||
856 | 13 | ||
857 | if (isset($joinColumnElement['nullable'])) { |
||
858 | 13 | $joinColumnMetadata->setNullable($this->evaluateBoolean($joinColumnElement['nullable'])); |
|
859 | } |
||
860 | 13 | ||
861 | if (isset($joinColumnElement['unique'])) { |
||
862 | $joinColumnMetadata->setUnique($this->evaluateBoolean($joinColumnElement['unique'])); |
||
863 | } |
||
864 | |||
865 | if (isset($joinColumnElement['on-delete'])) { |
||
866 | $joinColumnMetadata->setOnDelete(strtoupper((string) $joinColumnElement['on-delete'])); |
||
867 | } |
||
868 | |||
869 | return $joinColumnMetadata; |
||
870 | } |
||
871 | |||
872 | /** |
||
873 | * Parse the given Cache as CacheMetadata |
||
874 | * |
||
875 | * @param \SimpleXMLElement $cacheMapping |
||
876 | * @param Mapping\ClassMetadata $metadata |
||
877 | * @param null|string $fieldName |
||
878 | * |
||
879 | * @return Mapping\CacheMetadata |
||
880 | */ |
||
881 | private function convertCacheElementToCacheMetadata( |
||
882 | SimpleXMLElement $cacheMapping, |
||
883 | Mapping\ClassMetadata $metadata, |
||
884 | $fieldName = null |
||
885 | ) |
||
886 | { |
||
887 | $baseRegion = strtolower(str_replace('\\', '_', $metadata->getRootClassName())); |
||
888 | $defaultRegion = $baseRegion . ($fieldName ? '__' . $fieldName : ''); |
||
889 | |||
890 | $region = (string) ($cacheMapping['region'] ?? $defaultRegion); |
||
891 | $usage = isset($cacheMapping['usage']) |
||
892 | ? constant(sprintf('%s::%s', Mapping\CacheUsage::class, strtoupper((string) $cacheMapping['usage']))) |
||
893 | : Mapping\CacheUsage::READ_ONLY |
||
894 | ; |
||
895 | |||
896 | return new Mapping\CacheMetadata($usage, $region); |
||
897 | } |
||
898 | |||
899 | /** |
||
900 | * Parses the given method. |
||
901 | * |
||
902 | * @param \ReflectionMethod $method |
||
903 | * |
||
904 | * @return array |
||
905 | */ |
||
906 | private function getMethodCallbacks(\ReflectionMethod $method) |
||
907 | { |
||
908 | $events = [ |
||
909 | Events::prePersist, |
||
910 | Events::postPersist, |
||
911 | Events::preUpdate, |
||
912 | Events::postUpdate, |
||
913 | Events::preRemove, |
||
914 | Events::postRemove, |
||
915 | Events::postLoad, |
||
916 | Events::preFlush, |
||
917 | ]; |
||
918 | |||
919 | return array_filter($events, function ($eventName) use ($method) { |
||
920 | return $eventName === $method->getName(); |
||
921 | }); |
||
922 | } |
||
923 | |||
924 | /** |
||
925 | * Gathers a list of cascade options found in the given cascade element. |
||
926 | * |
||
927 | * @param SimpleXMLElement $cascadeElement The cascade element. |
||
928 | * |
||
929 | * @return array The list of cascade options. |
||
930 | */ |
||
931 | private function getCascadeMappings(SimpleXMLElement $cascadeElement) |
||
932 | { |
||
933 | $cascades = []; |
||
934 | |||
935 | /* @var $action SimpleXmlElement */ |
||
936 | foreach ($cascadeElement->children() as $action) { |
||
937 | // According to the JPA specifications, XML uses "cascade-persist" |
||
938 | // instead of "persist". Here, both variations are supported |
||
939 | // because Annotation use "persist" and we want to make sure that |
||
940 | // this driver doesn't need to know anything about the supported |
||
941 | // cascading actions |
||
942 | $cascades[] = str_replace('cascade-', '', $action->getName()); |
||
943 | } |
||
944 | |||
945 | return $cascades; |
||
946 | } |
||
947 | |||
948 | /** |
||
949 | * {@inheritDoc} |
||
950 | */ |
||
951 | protected function loadMappingFile($file) |
||
952 | { |
||
953 | $result = []; |
||
954 | // Note: we do not use `simplexml_load_file()` because of https://bugs.php.net/bug.php?id=62577 |
||
955 | $xmlElement = simplexml_load_string(file_get_contents($file)); |
||
956 | |||
957 | if (isset($xmlElement->entity)) { |
||
958 | foreach ($xmlElement->entity as $entityElement) { |
||
959 | $entityName = (string) $entityElement['name']; |
||
960 | $result[$entityName] = $entityElement; |
||
961 | } |
||
962 | } else if (isset($xmlElement->{'mapped-superclass'})) { |
||
963 | foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) { |
||
964 | $className = (string) $mappedSuperClass['name']; |
||
965 | $result[$className] = $mappedSuperClass; |
||
966 | } |
||
967 | } else if (isset($xmlElement->embeddable)) { |
||
968 | foreach ($xmlElement->embeddable as $embeddableElement) { |
||
969 | $embeddableName = (string) $embeddableElement['name']; |
||
970 | $result[$embeddableName] = $embeddableElement; |
||
971 | } |
||
972 | } |
||
973 | |||
974 | return $result; |
||
975 | } |
||
976 | |||
977 | /** |
||
978 | * @param mixed $element |
||
979 | * |
||
980 | * @return bool |
||
981 | */ |
||
982 | protected function evaluateBoolean($element) |
||
983 | { |
||
984 | $flag = (string) $element; |
||
985 | |||
986 | return ($flag == "true" || $flag == "1"); |
||
987 | } |
||
988 | } |
||
989 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.