Skip to content

Commit

Permalink
[Validator] Add ability to validate time without seconds
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz authored and nicolas-grekas committed Aug 1, 2023
1 parent a3414e4 commit 08c72e5
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CHANGELOG
* Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()`
* Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()`
* Add `number`, `finite-number` and `finite-float` types to `Type` constraint
* Add the `withSeconds` option to the `Time` constraint that allows to pass time without seconds

6.3
---
Expand Down
5 changes: 4 additions & 1 deletion src/Symfony/Component/Validator/Constraints/Time.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,19 @@ class Time extends Constraint
*/
protected static $errorNames = self::ERROR_NAMES;

public $withSeconds = true;
public $message = 'This value is not a valid time.';

public function __construct(
array $options = null,
string $message = null,
array $groups = null,
mixed $payload = null
mixed $payload = null,
bool $withSeconds = null
) {
parent::__construct($options, $groups, $payload);

$this->withSeconds = $withSeconds ?? $this->withSeconds;
$this->message = $message ?? $this->message;
}
}
5 changes: 3 additions & 2 deletions src/Symfony/Component/Validator/Constraints/TimeValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class TimeValidator extends ConstraintValidator
{
public const PATTERN = '/^(\d{2}):(\d{2}):(\d{2})$/';
public const PATTERN_WITHOUT_SECONDS = '/^(\d{2}):(\d{2})$/';

/**
* Checks whether a time is valid.
Expand Down Expand Up @@ -52,7 +53,7 @@ public function validate(mixed $value, Constraint $constraint)

$value = (string) $value;

if (!preg_match(static::PATTERN, $value, $matches)) {
if (!preg_match($constraint->withSeconds ? static::PATTERN : static::PATTERN_WITHOUT_SECONDS, $value, $matches)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setCode(Time::INVALID_FORMAT_ERROR)
Expand All @@ -61,7 +62,7 @@ public function validate(mixed $value, Constraint $constraint)
return;
}

if (!self::checkTime($matches[1], $matches[2], $matches[3])) {
if (!self::checkTime($matches[1], $matches[2], $constraint->withSeconds ? $matches[3] : 0)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setCode(Time::INVALID_TIME_ERROR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ public function testNullIsValid()
$this->assertNoViolation();
}

public function testDefaultWithSeconds()
{
$this->validator->validate('10:15:25', new Time());

$this->assertNoViolation();
}

public function testEmptyStringIsValid()
{
$this->validator->validate('', new Time());
Expand Down Expand Up @@ -62,6 +69,50 @@ public static function getValidTimes()
];
}

/**
* @dataProvider getValidTimesWithoutSeconds
*/
public function testValidTimesWithoutSeconds(string $time)
{
$this->validator->validate($time, new Time([
'withSeconds' => false,
]));

$this->assertNoViolation();
}

public static function getValidTimesWithoutSeconds()
{
return [
['01:02'],
['00:00'],
['23:59'],
];
}


/**
* @dataProvider getInvalidTimesWithoutSeconds
*/
public function testInvalidTimesWithoutSeconds(string $time)
{
$this->validator->validate($time, $constraint = new Time());

$this->buildViolation($constraint->message)
->setParameter('{{ value }}', '"'.$time.'"')
->setCode(Time::INVALID_FORMAT_ERROR)
->assertRaised();
}

public static function getInvalidTimesWithoutSeconds()
{
return [
['01:02'],
['00:00'],
['23:59'],
];
}

/**
* @dataProvider getInvalidTimes
*/
Expand Down

0 comments on commit 08c72e5

Please sign in to comment.