[Validator] Set Length::$allowEmptyString to false when a NotBlank contraint is defined

This commit is contained in:
Nicolas Grekas 2019-10-23 12:49:33 +02:00
parent bfd308ff4a
commit 840f7e7d88
3 changed files with 35 additions and 11 deletions

View File

@ -57,13 +57,6 @@ class Length extends Constraint
parent::__construct($options); parent::__construct($options);
if (null === $this->allowEmptyString) {
$this->allowEmptyString = true;
if (null !== $this->min) {
@trigger_error(sprintf('Using the "%s" constraint with the "min" option without setting the "allowEmptyString" one is deprecated and defaults to true. In 5.0, it will become optional and default to false.', self::class), E_USER_DEPRECATED);
}
}
if (null === $this->min && null === $this->max) { if (null === $this->min && null === $this->max) {
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']); throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']);
} }

View File

@ -30,7 +30,11 @@ class LengthValidator extends ConstraintValidator
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Length'); throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Length');
} }
if (null === $value || ('' === $value && $constraint->allowEmptyString)) { if (null !== $constraint->min && null === $constraint->allowEmptyString) {
@trigger_error(sprintf('Using the "%s" constraint with the "min" option without setting the "allowEmptyString" one is deprecated and defaults to true. In 5.0, it will become optional and default to false.', Length::class), E_USER_DEPRECATED);
}
if (null === $value || ('' === $value && ($constraint->allowEmptyString ?? true))) {
return; return;
} }

View File

@ -12,6 +12,8 @@
namespace Symfony\Component\Validator\Mapping; namespace Symfony\Component\Validator\Mapping;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Traverse; use Symfony\Component\Validator\Constraints\Traverse;
use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
@ -167,6 +169,8 @@ class GenericMetadata implements MetadataInterface
*/ */
public function getConstraints() public function getConstraints()
{ {
$this->configureLengthConstraints($this->constraints);
return $this->constraints; return $this->constraints;
} }
@ -187,9 +191,10 @@ class GenericMetadata implements MetadataInterface
*/ */
public function findConstraints($group) public function findConstraints($group)
{ {
return isset($this->constraintsByGroup[$group]) $constraints = $this->constraintsByGroup[$group] ?? [];
? $this->constraintsByGroup[$group] $this->configureLengthConstraints($constraints);
: [];
return $constraints;
} }
/** /**
@ -207,4 +212,26 @@ class GenericMetadata implements MetadataInterface
{ {
return $this->traversalStrategy; return $this->traversalStrategy;
} }
private function configureLengthConstraints(array $constraints): void
{
$allowEmptyString = true;
foreach ($constraints as $constraint) {
if ($constraint instanceof NotBlank) {
$allowEmptyString = false;
break;
}
}
if ($allowEmptyString) {
return;
}
foreach ($constraints as $constraint) {
if ($constraint instanceof Length && null === $constraint->allowEmptyString) {
$constraint->allowEmptyString = false;
}
}
}
} }