vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php line 190

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bridge\Doctrine\Form;
  11. use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry;
  12. use Doctrine\Common\Persistence\Mapping\MappingException as LegacyCommonMappingException;
  13. use Doctrine\Common\Util\ClassUtils;
  14. use Doctrine\DBAL\Types\Type;
  15. use Doctrine\DBAL\Types\Types;
  16. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  17. use Doctrine\ORM\Mapping\MappingException as LegacyMappingException;
  18. use Doctrine\Persistence\ManagerRegistry;
  19. use Doctrine\Persistence\Mapping\MappingException;
  20. use Symfony\Component\Form\FormTypeGuesserInterface;
  21. use Symfony\Component\Form\Guess\Guess;
  22. use Symfony\Component\Form\Guess\TypeGuess;
  23. use Symfony\Component\Form\Guess\ValueGuess;
  24. class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
  25. {
  26.     protected $registry;
  27.     private $cache = [];
  28.     private static $useDeprecatedConstants;
  29.     /**
  30.      * @param ManagerRegistry|LegacyManagerRegistry $registry
  31.      */
  32.     public function __construct($registry)
  33.     {
  34.         $this->registry $registry;
  35.         if (null === self::$useDeprecatedConstants) {
  36.             self::$useDeprecatedConstants = !class_exists(Types::class);
  37.         }
  38.     }
  39.     /**
  40.      * {@inheritdoc}
  41.      */
  42.     public function guessType($class$property)
  43.     {
  44.         if (!$ret $this->getMetadata($class)) {
  45.             return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE);
  46.         }
  47.         list($metadata$name) = $ret;
  48.         if ($metadata->hasAssociation($property)) {
  49.             $multiple $metadata->isCollectionValuedAssociation($property);
  50.             $mapping $metadata->getAssociationMapping($property);
  51.             return new TypeGuess('Symfony\Bridge\Doctrine\Form\Type\EntityType', ['em' => $name'class' => $mapping['targetEntity'], 'multiple' => $multiple], Guess::HIGH_CONFIDENCE);
  52.         }
  53.         switch ($metadata->getTypeOfField($property)) {
  54.             case self::$useDeprecatedConstants Type::TARRAY 'array':
  55.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::MEDIUM_CONFIDENCE);
  56.             case self::$useDeprecatedConstants Type::BOOLEAN Types::BOOLEAN:
  57.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::HIGH_CONFIDENCE);
  58.             case self::$useDeprecatedConstants Type::DATETIME Types::DATETIME_MUTABLE:
  59.             // no break
  60.             case self::$useDeprecatedConstants Type::DATETIMETZ Types::DATETIMETZ_MUTABLE:
  61.             // no break
  62.             case 'vardatetime':
  63.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE);
  64.             case 'dateinterval':
  65.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateIntervalType', [], Guess::HIGH_CONFIDENCE);
  66.             case self::$useDeprecatedConstants Type::DATE Types::DATE_MUTABLE:
  67.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::HIGH_CONFIDENCE);
  68.             case self::$useDeprecatedConstants Type::TIME Types::TIME_MUTABLE:
  69.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', [], Guess::HIGH_CONFIDENCE);
  70.             case self::$useDeprecatedConstants Type::DECIMAL Types::DECIMAL:
  71.             // no break
  72.             case self::$useDeprecatedConstants Type::FLOAT Types::FLOAT:
  73.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::MEDIUM_CONFIDENCE);
  74.             case self::$useDeprecatedConstants Type::INTEGER Types::INTEGER:
  75.             // no break
  76.             case self::$useDeprecatedConstants Type::BIGINT Types::BIGINT:
  77.             // no break
  78.             case self::$useDeprecatedConstants Type::SMALLINT Types::SMALLINT:
  79.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE);
  80.             case self::$useDeprecatedConstants Type::STRING Types::STRING:
  81.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::MEDIUM_CONFIDENCE);
  82.             case self::$useDeprecatedConstants Type::TEXT Types::TEXT:
  83.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextareaType', [], Guess::MEDIUM_CONFIDENCE);
  84.             default:
  85.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE);
  86.         }
  87.     }
  88.     /**
  89.      * {@inheritdoc}
  90.      */
  91.     public function guessRequired($class$property)
  92.     {
  93.         $classMetadatas $this->getMetadata($class);
  94.         if (!$classMetadatas) {
  95.             return null;
  96.         }
  97.         /** @var ClassMetadataInfo $classMetadata */
  98.         $classMetadata $classMetadatas[0];
  99.         // Check whether the field exists and is nullable or not
  100.         if (isset($classMetadata->fieldMappings[$property])) {
  101.             if (!$classMetadata->isNullable($property) && (self::$useDeprecatedConstants Type::BOOLEAN Types::BOOLEAN) !== $classMetadata->getTypeOfField($property)) {
  102.                 return new ValueGuess(trueGuess::HIGH_CONFIDENCE);
  103.             }
  104.             return new ValueGuess(falseGuess::MEDIUM_CONFIDENCE);
  105.         }
  106.         // Check whether the association exists, is a to-one association and its
  107.         // join column is nullable or not
  108.         if ($classMetadata->isAssociationWithSingleJoinColumn($property)) {
  109.             $mapping $classMetadata->getAssociationMapping($property);
  110.             if (!isset($mapping['joinColumns'][0]['nullable'])) {
  111.                 // The "nullable" option defaults to true, in that case the
  112.                 // field should not be required.
  113.                 return new ValueGuess(falseGuess::HIGH_CONFIDENCE);
  114.             }
  115.             return new ValueGuess(!$mapping['joinColumns'][0]['nullable'], Guess::HIGH_CONFIDENCE);
  116.         }
  117.         return null;
  118.     }
  119.     /**
  120.      * {@inheritdoc}
  121.      */
  122.     public function guessMaxLength($class$property)
  123.     {
  124.         $ret $this->getMetadata($class);
  125.         if ($ret && isset($ret[0]->fieldMappings[$property]) && !$ret[0]->hasAssociation($property)) {
  126.             $mapping $ret[0]->getFieldMapping($property);
  127.             if (isset($mapping['length'])) {
  128.                 return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE);
  129.             }
  130.             if (\in_array($ret[0]->getTypeOfField($property), self::$useDeprecatedConstants ? [Type::DECIMALType::FLOAT] : [Types::DECIMALTypes::FLOAT])) {
  131.                 return new ValueGuess(nullGuess::MEDIUM_CONFIDENCE);
  132.             }
  133.         }
  134.         return null;
  135.     }
  136.     /**
  137.      * {@inheritdoc}
  138.      */
  139.     public function guessPattern($class$property)
  140.     {
  141.         $ret $this->getMetadata($class);
  142.         if ($ret && isset($ret[0]->fieldMappings[$property]) && !$ret[0]->hasAssociation($property)) {
  143.             if (\in_array($ret[0]->getTypeOfField($property), self::$useDeprecatedConstants ? [Type::DECIMALType::FLOAT] : [Types::DECIMALTypes::FLOAT])) {
  144.                 return new ValueGuess(nullGuess::MEDIUM_CONFIDENCE);
  145.             }
  146.         }
  147.         return null;
  148.     }
  149.     protected function getMetadata($class)
  150.     {
  151.         // normalize class name
  152.         $class ClassUtils::getRealClass(ltrim($class'\\'));
  153.         if (\array_key_exists($class$this->cache)) {
  154.             return $this->cache[$class];
  155.         }
  156.         $this->cache[$class] = null;
  157.         foreach ($this->registry->getManagers() as $name => $em) {
  158.             try {
  159.                 return $this->cache[$class] = [$em->getClassMetadata($class), $name];
  160.             } catch (MappingException $e) {
  161.                 // not an entity or mapped super class
  162.             } catch (LegacyCommonMappingException $e) {
  163.                 // not an entity or mapped super class
  164.             } catch (LegacyMappingException $e) {
  165.                 // not an entity or mapped super class, using Doctrine ORM 2.2
  166.             }
  167.         }
  168.         return null;
  169.     }
  170. }