[Validator] Add invalid datetime message in Range validator

This commit is contained in:
Przemysław Bogusz 2020-04-02 22:03:50 +02:00 committed by Fabien Potencier
parent b5587b24b8
commit c77730699e
3 changed files with 127 additions and 11 deletions

View File

@ -41,6 +41,7 @@ class Range extends Constraint
public $minMessage = 'This value should be {{ limit }} or more.';
public $maxMessage = 'This value should be {{ limit }} or less.';
public $invalidMessage = 'This value should be a valid number.';
public $invalidDateTimeMessage = 'This value should be a valid datetime.';
public $min;
public $minPropertyPath;
public $max;

View File

@ -44,18 +44,25 @@ class RangeValidator extends ConstraintValidator
return;
}
$min = $this->getLimit($constraint->minPropertyPath, $constraint->min, $constraint);
$max = $this->getLimit($constraint->maxPropertyPath, $constraint->max, $constraint);
if (!is_numeric($value) && !$value instanceof \DateTimeInterface) {
$this->context->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setCode(Range::INVALID_CHARACTERS_ERROR)
->addViolation();
if ($this->isParsableDatetimeString($min) && $this->isParsableDatetimeString($max)) {
$this->context->buildViolation($constraint->invalidDateTimeMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setCode(Range::INVALID_CHARACTERS_ERROR)
->addViolation();
} else {
$this->context->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setCode(Range::INVALID_CHARACTERS_ERROR)
->addViolation();
}
return;
}
$min = $this->getLimit($constraint->minPropertyPath, $constraint->min, $constraint);
$max = $this->getLimit($constraint->maxPropertyPath, $constraint->max, $constraint);
// Convert strings to DateTimes if comparing another DateTime
// This allows to compare with any date/time value supported by
// the DateTime constructor:
@ -182,4 +189,23 @@ class RangeValidator extends ConstraintValidator
return $this->propertyAccessor;
}
private function isParsableDatetimeString($boundary): bool
{
if (null === $boundary) {
return true;
}
if (!\is_string($boundary)) {
return false;
}
try {
new \DateTime($boundary);
} catch (\Exception $e) {
return false;
}
return true;
}
}

View File

@ -379,13 +379,102 @@ class RangeValidatorTest extends ConstraintValidatorTestCase
public function testNonNumeric()
{
$this->validator->validate('abcd', new Range([
$constraint = new Range([
'min' => 10,
'max' => 20,
'invalidMessage' => 'myMessage',
]));
]);
$this->buildViolation('myMessage')
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithParsableDatetimeMinAndMaxNull()
{
$constraint = new Range([
'min' => 'March 10, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidDateTimeMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithParsableDatetimeMaxAndMinNull()
{
$constraint = new Range([
'max' => 'March 20, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidDateTimeMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithParsableDatetimeMinAndMax()
{
$constraint = new Range([
'min' => 'March 10, 2014',
'max' => 'March 20, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidDateTimeMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithNonParsableDatetimeMin()
{
$constraint = new Range([
'min' => 'March 40, 2014',
'max' => 'March 20, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithNonParsableDatetimeMax()
{
$constraint = new Range([
'min' => 'March 10, 2014',
'max' => 'March 50, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
public function testNonNumericWithNonParsableDatetimeMinAndMax()
{
$constraint = new Range([
'min' => 'March 40, 2014',
'max' => 'March 50, 2014',
]);
$this->validator->validate('abcd', $constraint);
$this->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', '"abcd"')
->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();