* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ declare(strict_types=1); namespace Cwd\DataDoctrineORMBundle\Mapping\Driver; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver; class XmlDriverWithCollectionSupport extends SimplifiedXmlDriver { private $classMetadataFactory; public function setClassMetadataFactory(ClassMetadataFactory $classMetadataFactory): void { $this->classMetadataFactory = $classMetadataFactory; } public function loadMetadataForClass($className, \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata) { /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */ parent::loadMetadataForClass($className, $metadata); $options = $metadata->table['options'] ?? []; if (isset($options['collections'])) { $collectionMappings = $options['collections']; foreach ($collectionMappings as $fieldName => $collectionMapping) { if (isset($metadata->associationMappings[$fieldName])) { continue; } $metadata->associationMappings[$fieldName] = array( 'fieldName' => $fieldName, 'targetEntity' => $collectionMapping['entryClass'], 'mappedBy' => 'owner', 'cascade' => ['remove', 'persist', 'refresh', 'merge', 'detach'], 'orphanRemoval' => true, 'orderBy' => ['id' => 'ASC'], 'type' => ClassMetadata::ONE_TO_MANY, 'inversedBy' => null, 'isOwningSide' => false, 'sourceEntity' => $metadata->getName(), 'fetch' => ClassMetadata::FETCH_LAZY, 'isCascadeRemove' => true, 'isCascadePersist' => true, 'isCascadeRefresh' => true, 'isCascadeMerge' => true, 'isCascadeDetach' => true, ); } } if (isset($options['collectionEntry'])) { if (!isset($metadata->fieldMappings['id'], $metadata->identifier)) { $metadata->fieldMappings['id'] = [ 'id' => true, 'fieldName' => 'id', 'type' => 'integer', 'columnName' => 'id', ]; $metadata->identifier = ['id']; $metadata->fieldNames['id'] = 'id'; $metadata->columnNames['id'] = 'id'; $metadata->isIdentifierComposite = false; $metadata->generatorType = ClassMetadata::GENERATOR_TYPE_AUTO; } if (!isset($metadata->associationMappings['owner'])) { $metadata->associationMappings['owner'] = [ 'fieldName' => 'owner', 'targetEntity' => $options['collectionEntry']['ownerClass'], 'inversedBy' => $options['collectionEntry']['ownerField'], 'joinColumns' => [ [ 'name' => 'owner_id', 'referencedColumnName' => 'id', 'nullable' => false, 'onDelete' => 'CASCADE', ], ], 'type' => ClassMetadata::MANY_TO_ONE, 'mappedBy' => null, 'isOwningSide' => true, 'sourceEntity' => $className, 'fetch' => ClassMetadata::FETCH_LAZY, 'cascade' => [], 'isCascadeRemove' => false, 'isCascadePersist' => false, 'isCascadeRefresh' => false, 'isCascadeMerge' => false, 'isCascadeDetach' => false, 'sourceToTargetKeyColumns' => ['owner_id' => 'id'], 'joinColumnFieldNames' => ['owner_id' => 'owner_id'], 'targetToSourceKeyColumns' => ['id' => 'owner_id'], 'orphanRemoval' => false, ]; } } } }