1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Metadata\Driver; 6 7use Doctrine\Common\Persistence\Mapping\ClassMetadata as DoctrineClassMetadata; 8use JMS\Serializer\Metadata\ClassMetadata; 9use JMS\Serializer\Metadata\PropertyMetadata; 10 11/** 12 * This class decorates any other driver. If the inner driver does not provide a 13 * a property type, the decorator will guess based on Doctrine 2 metadata. 14 */ 15class DoctrineTypeDriver extends AbstractDoctrineTypeDriver 16{ 17 protected function setDiscriminator(DoctrineClassMetadata $doctrineMetadata, ClassMetadata $classMetadata): void 18 { 19 if (empty($classMetadata->discriminatorMap) && !$classMetadata->discriminatorDisabled 20 && !empty($doctrineMetadata->discriminatorMap) && $doctrineMetadata->isRootEntity() 21 ) { 22 $classMetadata->setDiscriminator( 23 $doctrineMetadata->discriminatorColumn['name'], 24 $doctrineMetadata->discriminatorMap 25 ); 26 } 27 } 28 29 protected function setPropertyType(DoctrineClassMetadata $doctrineMetadata, PropertyMetadata $propertyMetadata): void 30 { 31 $propertyName = $propertyMetadata->name; 32 if ($doctrineMetadata->hasField($propertyName) 33 && ($typeOfFiled = $doctrineMetadata->getTypeOfField($propertyName)) 34 && ($fieldType = $this->normalizeFieldType($typeOfFiled))) { 35 $propertyMetadata->setType($this->typeParser->parse($fieldType)); 36 } elseif ($doctrineMetadata->hasAssociation($propertyName)) { 37 $targetEntity = $doctrineMetadata->getAssociationTargetClass($propertyName); 38 39 if (null === $targetMetadata = $this->tryLoadingDoctrineMetadata($targetEntity)) { 40 return; 41 } 42 43 // For inheritance schemes, we cannot add any type as we would only add the super-type of the hierarchy. 44 // On serialization, this would lead to only the supertype being serialized, and properties of subtypes 45 // being ignored. 46 if ($targetMetadata instanceof DoctrineClassMetadata && !$targetMetadata->isInheritanceTypeNone()) { 47 return; 48 } 49 50 if (!$doctrineMetadata->isSingleValuedAssociation($propertyName)) { 51 $targetEntity = sprintf('ArrayCollection<%s>', $targetEntity); 52 } 53 54 $propertyMetadata->setType($this->typeParser->parse($targetEntity)); 55 } 56 } 57} 58