From fc7c7f645869e30010f3f8e050189303bfd5c2c8 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Mon, 19 Mar 2012 23:57:21 +0100 Subject: [PATCH] [Form] Fix min/max length guessing for numeric types (fix #3091) --- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 16 +- .../Validator/ValidatorTypeGuesser.php | 239 +++++------------- src/Symfony/Component/Form/FormFactory.php | 16 +- 3 files changed, 92 insertions(+), 179 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index 83986dabe9..04b2b426fb 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -60,6 +60,8 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE); case 'date': return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE); + case 'time': + return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE); case 'decimal': case 'float': return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); @@ -71,8 +73,6 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE); case 'text': return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE); - case 'time': - return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE); default: return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); } @@ -105,6 +105,10 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface if (isset($mapping['length'])) { return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE); } + + if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } } } @@ -113,6 +117,14 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface */ public function guessMinLength($class, $property) { + $ret = $this->getMetadata($class); + if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) { + $mapping = $ret[0]->getFieldMapping($property); + + if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + } } protected function getMetadata($class) diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php index 3d60ab052a..dd65a6c392 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php @@ -89,150 +89,68 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface switch ($constraint->type) { case 'boolean': case 'bool': - return new TypeGuess( - 'checkbox', - array(), - Guess::MEDIUM_CONFIDENCE - ); + return new TypeGuess('checkbox', array(), Guess::MEDIUM_CONFIDENCE); + case 'double': case 'float': case 'numeric': case 'real': - return new TypeGuess( - 'number', - array(), - Guess::MEDIUM_CONFIDENCE - ); + return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); + case 'integer': case 'int': case 'long': - return new TypeGuess( - 'integer', - array(), - Guess::MEDIUM_CONFIDENCE - ); - case 'string': - return new TypeGuess( - 'text', - array(), - Guess::LOW_CONFIDENCE - ); + return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE); + case '\DateTime': - return new TypeGuess( - 'date', - array(), - Guess::MEDIUM_CONFIDENCE - ); + return new TypeGuess('date', array(), Guess::MEDIUM_CONFIDENCE); + + case 'string': + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); } break; + case 'Symfony\Component\Validator\Constraints\Country': - return new TypeGuess( - 'country', - array(), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('country', array(), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Date': - return new TypeGuess( - 'date', - array('type' => 'string'), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('date', array('type' => 'string'), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\DateTime': - return new TypeGuess( - 'datetime', - array('type' => 'string'), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('datetime', array('type' => 'string'), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Email': - return new TypeGuess( - 'email', - array(), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('email', array(), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\File': - return new TypeGuess( - 'file', - array(), - Guess::HIGH_CONFIDENCE - ); case 'Symfony\Component\Validator\Constraints\Image': - return new TypeGuess( - 'file', - array(), - Guess::HIGH_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Ip': - return new TypeGuess( - 'text', - array(), - Guess::MEDIUM_CONFIDENCE - ); + return new TypeGuess('file', array(), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Language': - return new TypeGuess( - 'language', - array(), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('language', array(), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Locale': - return new TypeGuess( - 'locale', - array(), - Guess::HIGH_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Max': - return new TypeGuess( - 'number', - array(), - Guess::LOW_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\MaxLength': - return new TypeGuess( - 'text', - array(), - Guess::LOW_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Min': - return new TypeGuess( - 'number', - array(), - Guess::LOW_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\MinLength': - return new TypeGuess( - 'text', - array(), - Guess::LOW_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Regex': - return new TypeGuess( - 'text', - array(), - Guess::LOW_CONFIDENCE - ); + return new TypeGuess('locale', array(), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Time': - return new TypeGuess( - 'time', - array('type' => 'string'), - Guess::HIGH_CONFIDENCE - ); + return new TypeGuess('time', array('type' => 'string'), Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Url': - return new TypeGuess( - 'url', - array(), - Guess::HIGH_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Size': - return new TypeGuess( - 'number', - array(), - Guess::LOW_CONFIDENCE - ); + return new TypeGuess('url', array(), Guess::HIGH_CONFIDENCE); + + case 'Symfony\Component\Validator\Constraints\Ip': + return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE); + + case 'Symfony\Component\Validator\Constraints\MaxLength': + case 'Symfony\Component\Validator\Constraints\MinLength': + case 'Symfony\Component\Validator\Constraints\Regex': case 'Symfony\Component\Validator\Constraints\SizeLength': - return new TypeGuess( - 'text', - array(), - Guess::LOW_CONFIDENCE - ); + return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); + + case 'Symfony\Component\Validator\Constraints\Min': + case 'Symfony\Component\Validator\Constraints\Size': + case 'Symfony\Component\Validator\Constraints\Max': + return new TypeGuess('number', array(), Guess::LOW_CONFIDENCE); } } @@ -247,20 +165,11 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface { switch (get_class($constraint)) { case 'Symfony\Component\Validator\Constraints\NotNull': - return new ValueGuess( - true, - Guess::HIGH_CONFIDENCE - ); case 'Symfony\Component\Validator\Constraints\NotBlank': - return new ValueGuess( - true, - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess(true, Guess::HIGH_CONFIDENCE); + default: - return new ValueGuess( - false, - Guess::LOW_CONFIDENCE - ); + return new ValueGuess(false, Guess::LOW_CONFIDENCE); } } @@ -275,25 +184,21 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface { switch (get_class($constraint)) { case 'Symfony\Component\Validator\Constraints\MaxLength': - return new ValueGuess( - $constraint->limit, - Guess::HIGH_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Max': - return new ValueGuess( - strlen((string) $constraint->limit), - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess($constraint->limit, Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\SizeLength': - return new ValueGuess( - $constraint->max, - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess($constraint->max, Guess::HIGH_CONFIDENCE); + + case 'Symfony\Component\Validator\Constraints\Type': + if (in_array($constraint->type, array('double', 'float', 'numeric', 'real'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + + case 'Symfony\Component\Validator\Constraints\Max': + return new ValueGuess(strlen((string) $constraint->limit), Guess::LOW_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Size': - return new ValueGuess( - strlen((string) $constraint->max), - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess(strlen((string) $constraint->max), Guess::LOW_CONFIDENCE); } } @@ -308,25 +213,21 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface { switch (get_class($constraint)) { case 'Symfony\Component\Validator\Constraints\MinLength': - return new ValueGuess( - $constraint->limit, - Guess::HIGH_CONFIDENCE - ); - case 'Symfony\Component\Validator\Constraints\Min': - return new ValueGuess( - strlen((string) $constraint->limit), - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess($constraint->limit, Guess::HIGH_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\SizeLength': - return new ValueGuess( - $constraint->min, - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess($constraint->min, Guess::HIGH_CONFIDENCE); + + case 'Symfony\Component\Validator\Constraints\Type': + if (in_array($constraint->type, array('double', 'float', 'numeric', 'real'))) { + return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); + } + + case 'Symfony\Component\Validator\Constraints\Min': + return new ValueGuess(strlen((string) $constraint->limit), Guess::LOW_CONFIDENCE); + case 'Symfony\Component\Validator\Constraints\Size': - return new ValueGuess( - strlen((string) $constraint->min), - Guess::HIGH_CONFIDENCE - ); + return new ValueGuess(strlen((string) $constraint->min), Guess::LOW_CONFIDENCE); } } diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index e82e0567ed..a474c0ab90 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/src/Symfony/Component/Form/FormFactory.php @@ -349,16 +349,16 @@ class FormFactory implements FormFactoryInterface $type = $typeGuess ? $typeGuess->getType() : 'text'; - if ($maxLengthGuess) { - $options = array_merge(array('max_length' => $maxLengthGuess->getValue()), $options); + $maxLength = $maxLengthGuess ? $maxLengthGuess->getValue() : null; + $minLength = $minLengthGuess ? $minLengthGuess->getValue() : null; + $minLength = $minLength ?: 0; + + if (null !== $maxLength) { + $options = array_merge(array('max_length' => $maxLength), $options); } - if ($minLengthGuess) { - if ($maxLengthGuess) { - $options = array_merge(array('pattern' => '.{'.$minLengthGuess->getValue().','.$maxLengthGuess->getValue().'}'), $options); - } else { - $options = array_merge(array('pattern' => '.{'.$minLengthGuess->getValue().',}'), $options); - } + if ($minLength > 0) { + $options = array_merge(array('pattern' => '.{'.$minLength.','.$maxLength.'}'), $options); } if ($requiredGuess) {