vendor/jms/serializer/src/Metadata/Driver/AbstractDoctrineTypeDriver.php line 85

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace JMS\Serializer\Metadata\Driver;
  4. use Doctrine\Persistence\ManagerRegistry;
  5. use Doctrine\Persistence\Mapping\ClassMetadata as DoctrineClassMetadata;
  6. use JMS\Serializer\Metadata\ClassMetadata;
  7. use JMS\Serializer\Metadata\ExpressionPropertyMetadata;
  8. use JMS\Serializer\Metadata\PropertyMetadata;
  9. use JMS\Serializer\Metadata\StaticPropertyMetadata;
  10. use JMS\Serializer\Metadata\VirtualPropertyMetadata;
  11. use JMS\Serializer\Type\Parser;
  12. use JMS\Serializer\Type\ParserInterface;
  13. use Metadata\ClassMetadata as BaseClassMetadata;
  14. use Metadata\Driver\DriverInterface;
  15. /**
  16.  * This class decorates any other driver. If the inner driver does not provide a
  17.  * a property type, the decorator will guess based on Doctrine 2 metadata.
  18.  */
  19. abstract class AbstractDoctrineTypeDriver implements DriverInterface
  20. {
  21.     /**
  22.      * Map of doctrine 2 field types to JMS\Serializer types
  23.      *
  24.      * @var array
  25.      */
  26.     protected $fieldMapping = [
  27.         'string' => 'string',
  28.         'ascii_string' => 'string',
  29.         'text' => 'string',
  30.         'blob' => 'string',
  31.         'guid' => 'string',
  32.         'decimal' => 'string',
  33.         'integer' => 'integer',
  34.         'smallint' => 'integer',
  35.         'bigint' => 'integer',
  36.         'datetime' => 'DateTime',
  37.         'datetimetz' => 'DateTime',
  38.         'time' => 'DateTime',
  39.         'date' => 'DateTime',
  40.         'datetime_immutable' => 'DateTimeImmutable',
  41.         'datetimetz_immutable' => 'DateTimeImmutable',
  42.         'time_immutable' => 'DateTimeImmutable',
  43.         'date_immutable' => 'DateTimeImmutable',
  44.         'dateinterval' => 'DateInterval',
  45.         'float' => 'float',
  46.         'boolean' => 'boolean',
  47.         'array' => 'array',
  48.         'json_array' => 'array',
  49.         'simple_array' => 'array<string>',
  50.     ];
  51.     /**
  52.      * @var DriverInterface
  53.      */
  54.     protected $delegate;
  55.     /**
  56.      * @var ManagerRegistry
  57.      */
  58.     protected $registry;
  59.     /**
  60.      * @var ParserInterface
  61.      */
  62.     protected $typeParser;
  63.     public function __construct(DriverInterface $delegateManagerRegistry $registry, ?ParserInterface $typeParser null)
  64.     {
  65.         $this->delegate $delegate;
  66.         $this->registry $registry;
  67.         $this->typeParser $typeParser ?: new Parser();
  68.     }
  69.     public function loadMetadataForClass(\ReflectionClass $class): ?BaseClassMetadata
  70.     {
  71.         $classMetadata $this->delegate->loadMetadataForClass($class);
  72.         \assert($classMetadata instanceof ClassMetadata);
  73.         // Abort if the given class is not a mapped entity
  74.         if (!$doctrineMetadata $this->tryLoadingDoctrineMetadata($class->name)) {
  75.             return $classMetadata;
  76.         }
  77.         $this->setDiscriminator($doctrineMetadata$classMetadata);
  78.         // We base our scan on the internal driver's property list so that we
  79.         // respect any internal allow/blocklist like in the AnnotationDriver
  80.         foreach ($classMetadata->propertyMetadata as $key => $propertyMetadata) {
  81.             // If the inner driver provides a type, don't guess anymore.
  82.             if ($propertyMetadata->type || $this->isVirtualProperty($propertyMetadata)) {
  83.                 continue;
  84.             }
  85.             if ($this->hideProperty($doctrineMetadata$propertyMetadata)) {
  86.                 unset($classMetadata->propertyMetadata[$key]);
  87.             }
  88.             $this->setPropertyType($doctrineMetadata$propertyMetadata);
  89.         }
  90.         return $classMetadata;
  91.     }
  92.     private function isVirtualProperty(PropertyMetadata $propertyMetadata): bool
  93.     {
  94.         return $propertyMetadata instanceof VirtualPropertyMetadata
  95.             || $propertyMetadata instanceof StaticPropertyMetadata
  96.             || $propertyMetadata instanceof ExpressionPropertyMetadata;
  97.     }
  98.     protected function setDiscriminator(DoctrineClassMetadata $doctrineMetadataClassMetadata $classMetadata): void
  99.     {
  100.     }
  101.     protected function hideProperty(DoctrineClassMetadata $doctrineMetadataPropertyMetadata $propertyMetadata): bool
  102.     {
  103.         return false;
  104.     }
  105.     protected function setPropertyType(DoctrineClassMetadata $doctrineMetadataPropertyMetadata $propertyMetadata): void
  106.     {
  107.     }
  108.     protected function tryLoadingDoctrineMetadata(string $className): ?DoctrineClassMetadata
  109.     {
  110.         if (!$manager $this->registry->getManagerForClass($className)) {
  111.             return null;
  112.         }
  113.         if ($manager->getMetadataFactory()->isTransient($className)) {
  114.             return null;
  115.         }
  116.         return $manager->getClassMetadata($className);
  117.     }
  118.     protected function normalizeFieldType(string $type): ?string
  119.     {
  120.         if (!isset($this->fieldMapping[$type])) {
  121.             return null;
  122.         }
  123.         return $this->fieldMapping[$type];
  124.     }
  125. }