vendor/symfony/form/Extension/Validator/ValidatorTypeGuesser.php line 38

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\Component\Form\Extension\Validator;
  11. use Symfony\Component\Form\FormTypeGuesserInterface;
  12. use Symfony\Component\Form\Guess\Guess;
  13. use Symfony\Component\Form\Guess\TypeGuess;
  14. use Symfony\Component\Form\Guess\ValueGuess;
  15. use Symfony\Component\Validator\Constraint;
  16. use Symfony\Component\Validator\Mapping\ClassMetadataInterface;
  17. use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
  18. class ValidatorTypeGuesser implements FormTypeGuesserInterface
  19. {
  20.     private $metadataFactory;
  21.     public function __construct(MetadataFactoryInterface $metadataFactory)
  22.     {
  23.         $this->metadataFactory $metadataFactory;
  24.     }
  25.     /**
  26.      * {@inheritdoc}
  27.      */
  28.     public function guessType(string $classstring $property)
  29.     {
  30.         return $this->guess($class$property, function (Constraint $constraint) {
  31.             return $this->guessTypeForConstraint($constraint);
  32.         });
  33.     }
  34.     /**
  35.      * {@inheritdoc}
  36.      */
  37.     public function guessRequired(string $classstring $property)
  38.     {
  39.         return $this->guess($class$property, function (Constraint $constraint) {
  40.             return $this->guessRequiredForConstraint($constraint);
  41.         // If we don't find any constraint telling otherwise, we can assume
  42.         // that a field is not required (with LOW_CONFIDENCE)
  43.         }, false);
  44.     }
  45.     /**
  46.      * {@inheritdoc}
  47.      */
  48.     public function guessMaxLength(string $classstring $property)
  49.     {
  50.         return $this->guess($class$property, function (Constraint $constraint) {
  51.             return $this->guessMaxLengthForConstraint($constraint);
  52.         });
  53.     }
  54.     /**
  55.      * {@inheritdoc}
  56.      */
  57.     public function guessPattern(string $classstring $property)
  58.     {
  59.         return $this->guess($class$property, function (Constraint $constraint) {
  60.             return $this->guessPatternForConstraint($constraint);
  61.         });
  62.     }
  63.     /**
  64.      * Guesses a field class name for a given constraint.
  65.      *
  66.      * @return TypeGuess|null
  67.      */
  68.     public function guessTypeForConstraint(Constraint $constraint)
  69.     {
  70.         switch (\get_class($constraint)) {
  71.             case 'Symfony\Component\Validator\Constraints\Type':
  72.                 switch ($constraint->type) {
  73.                     case 'array':
  74.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::MEDIUM_CONFIDENCE);
  75.                     case 'boolean':
  76.                     case 'bool':
  77.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::MEDIUM_CONFIDENCE);
  78.                     case 'double':
  79.                     case 'float':
  80.                     case 'numeric':
  81.                     case 'real':
  82.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::MEDIUM_CONFIDENCE);
  83.                     case 'integer':
  84.                     case 'int':
  85.                     case 'long':
  86.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE);
  87.                     case \DateTime::class:
  88.                     case '\DateTime':
  89.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::MEDIUM_CONFIDENCE);
  90.                     case 'string':
  91.                         return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE);
  92.                 }
  93.                 break;
  94.             case 'Symfony\Component\Validator\Constraints\Country':
  95.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CountryType', [], Guess::HIGH_CONFIDENCE);
  96.             case 'Symfony\Component\Validator\Constraints\Currency':
  97.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CurrencyType', [], Guess::HIGH_CONFIDENCE);
  98.             case 'Symfony\Component\Validator\Constraints\Date':
  99.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', ['input' => 'string'], Guess::HIGH_CONFIDENCE);
  100.             case 'Symfony\Component\Validator\Constraints\DateTime':
  101.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', ['input' => 'string'], Guess::HIGH_CONFIDENCE);
  102.             case 'Symfony\Component\Validator\Constraints\Email':
  103.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\EmailType', [], Guess::HIGH_CONFIDENCE);
  104.             case 'Symfony\Component\Validator\Constraints\File':
  105.             case 'Symfony\Component\Validator\Constraints\Image':
  106.                 $options = [];
  107.                 if ($constraint->mimeTypes) {
  108.                     $options = ['attr' => ['accept' => implode(',', (array) $constraint->mimeTypes)]];
  109.                 }
  110.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\FileType'$optionsGuess::HIGH_CONFIDENCE);
  111.             case 'Symfony\Component\Validator\Constraints\Language':
  112.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\LanguageType', [], Guess::HIGH_CONFIDENCE);
  113.             case 'Symfony\Component\Validator\Constraints\Locale':
  114.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\LocaleType', [], Guess::HIGH_CONFIDENCE);
  115.             case 'Symfony\Component\Validator\Constraints\Time':
  116.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', ['input' => 'string'], Guess::HIGH_CONFIDENCE);
  117.             case 'Symfony\Component\Validator\Constraints\Url':
  118.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\UrlType', [], Guess::HIGH_CONFIDENCE);
  119.             case 'Symfony\Component\Validator\Constraints\Ip':
  120.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::MEDIUM_CONFIDENCE);
  121.             case 'Symfony\Component\Validator\Constraints\Length':
  122.             case 'Symfony\Component\Validator\Constraints\Regex':
  123.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE);
  124.             case 'Symfony\Component\Validator\Constraints\Range':
  125.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::LOW_CONFIDENCE);
  126.             case 'Symfony\Component\Validator\Constraints\Count':
  127.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::LOW_CONFIDENCE);
  128.             case 'Symfony\Component\Validator\Constraints\IsTrue':
  129.             case 'Symfony\Component\Validator\Constraints\IsFalse':
  130.                 return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::MEDIUM_CONFIDENCE);
  131.         }
  132.         return null;
  133.     }
  134.     /**
  135.      * Guesses whether a field is required based on the given constraint.
  136.      *
  137.      * @return ValueGuess|null
  138.      */
  139.     public function guessRequiredForConstraint(Constraint $constraint)
  140.     {
  141.         switch (\get_class($constraint)) {
  142.             case 'Symfony\Component\Validator\Constraints\NotNull':
  143.             case 'Symfony\Component\Validator\Constraints\NotBlank':
  144.             case 'Symfony\Component\Validator\Constraints\IsTrue':
  145.                 return new ValueGuess(trueGuess::HIGH_CONFIDENCE);
  146.         }
  147.         return null;
  148.     }
  149.     /**
  150.      * Guesses a field's maximum length based on the given constraint.
  151.      *
  152.      * @return ValueGuess|null
  153.      */
  154.     public function guessMaxLengthForConstraint(Constraint $constraint)
  155.     {
  156.         switch (\get_class($constraint)) {
  157.             case 'Symfony\Component\Validator\Constraints\Length':
  158.                 if (is_numeric($constraint->max)) {
  159.                     return new ValueGuess($constraint->maxGuess::HIGH_CONFIDENCE);
  160.                 }
  161.                 break;
  162.             case 'Symfony\Component\Validator\Constraints\Type':
  163.                 if (\in_array($constraint->type, ['double''float''numeric''real'])) {
  164.                     return new ValueGuess(nullGuess::MEDIUM_CONFIDENCE);
  165.                 }
  166.                 break;
  167.             case 'Symfony\Component\Validator\Constraints\Range':
  168.                 if (is_numeric($constraint->max)) {
  169.                     return new ValueGuess(\strlen((string) $constraint->max), Guess::LOW_CONFIDENCE);
  170.                 }
  171.                 break;
  172.         }
  173.         return null;
  174.     }
  175.     /**
  176.      * Guesses a field's pattern based on the given constraint.
  177.      *
  178.      * @return ValueGuess|null
  179.      */
  180.     public function guessPatternForConstraint(Constraint $constraint)
  181.     {
  182.         switch (\get_class($constraint)) {
  183.             case 'Symfony\Component\Validator\Constraints\Length':
  184.                 if (is_numeric($constraint->min)) {
  185.                     return new ValueGuess(sprintf('.{%s,}', (string) $constraint->min), Guess::LOW_CONFIDENCE);
  186.                 }
  187.                 break;
  188.             case 'Symfony\Component\Validator\Constraints\Regex':
  189.                 $htmlPattern $constraint->getHtmlPattern();
  190.                 if (null !== $htmlPattern) {
  191.                     return new ValueGuess($htmlPatternGuess::HIGH_CONFIDENCE);
  192.                 }
  193.                 break;
  194.             case 'Symfony\Component\Validator\Constraints\Range':
  195.                 if (is_numeric($constraint->min)) {
  196.                     return new ValueGuess(sprintf('.{%s,}', \strlen((string) $constraint->min)), Guess::LOW_CONFIDENCE);
  197.                 }
  198.                 break;
  199.             case 'Symfony\Component\Validator\Constraints\Type':
  200.                 if (\in_array($constraint->type, ['double''float''numeric''real'])) {
  201.                     return new ValueGuess(nullGuess::MEDIUM_CONFIDENCE);
  202.                 }
  203.                 break;
  204.         }
  205.         return null;
  206.     }
  207.     /**
  208.      * Iterates over the constraints of a property, executes a constraints on
  209.      * them and returns the best guess.
  210.      *
  211.      * @param \Closure $closure      The closure that returns a guess
  212.      *                               for a given constraint
  213.      * @param mixed    $defaultValue The default value assumed if no other value
  214.      *                               can be guessed
  215.      *
  216.      * @return Guess|null
  217.      */
  218.     protected function guess(string $classstring $property, \Closure $closure$defaultValue null)
  219.     {
  220.         $guesses = [];
  221.         $classMetadata $this->metadataFactory->getMetadataFor($class);
  222.         if ($classMetadata instanceof ClassMetadataInterface && $classMetadata->hasPropertyMetadata($property)) {
  223.             foreach ($classMetadata->getPropertyMetadata($property) as $memberMetadata) {
  224.                 foreach ($memberMetadata->getConstraints() as $constraint) {
  225.                     if ($guess $closure($constraint)) {
  226.                         $guesses[] = $guess;
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.         if (null !== $defaultValue) {
  232.             $guesses[] = new ValueGuess($defaultValueGuess::LOW_CONFIDENCE);
  233.         }
  234.         return Guess::getBestGuess($guesses);
  235.     }
  236. }