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.