Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c73fd10

Browse filesBrowse files
committed
feature #30900 [Validator] add new Timezone validation constraint (phansys)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Validator] add new `Timezone` validation constraint | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | License | MIT | Doc PR | symfony/symfony-docs#11317 Rework of #22262. Commits ------- 536e53f [Validator] add new `Timezone` validation constraint.
2 parents 58d78ac + 536e53f commit c73fd10
Copy full SHA for c73fd10

File tree

9 files changed

+497
-0
lines changed
Filter options

9 files changed

+497
-0
lines changed

‎src/Symfony/Component/Validator/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.3.0
55
-----
66

7+
* added `Timezone` constraint
78
* added `NotCompromisedPassword` constraint
89
* added options `iban` and `ibanPropertyPath` to Bic constraint
910
* added UATP cards support to `CardSchemeValidator`
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
use Symfony\Component\Validator\Constraint;
15+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
16+
17+
/**
18+
* @Annotation
19+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
20+
*
21+
* @author Javier Spagnoletti <phansys@gmail.com>
22+
* @author Hugo Hamon <hugohamon@neuf.fr>
23+
*/
24+
class Timezone extends Constraint
25+
{
26+
public const TIMEZONE_IDENTIFIER_ERROR = '5ce113e6-5e64-4ea2-90fe-d2233956db13';
27+
public const TIMEZONE_IDENTIFIER_IN_ZONE_ERROR = 'b57767b1-36c0-40ac-a3d7-629420c775b8';
28+
public const TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR = 'c4a22222-dc92-4fc0-abb0-d95b268c7d0b';
29+
30+
public $zone = \DateTimeZone::ALL;
31+
public $countryCode;
32+
public $message = 'This value is not a valid timezone.';
33+
34+
protected static $errorNames = [
35+
self::TIMEZONE_IDENTIFIER_ERROR => 'TIMEZONE_IDENTIFIER_ERROR',
36+
self::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR => 'TIMEZONE_IDENTIFIER_IN_ZONE_ERROR',
37+
self::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR => 'TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR',
38+
];
39+
40+
/**
41+
* {@inheritdoc}
42+
*/
43+
public function __construct(array $options = null)
44+
{
45+
parent::__construct($options);
46+
47+
if ($this->countryCode && \DateTimeZone::PER_COUNTRY !== $this->zone) {
48+
throw new ConstraintDefinitionException('The option "countryCode" can only be used when "zone" option is configured with `\DateTimeZone::PER_COUNTRY`.');
49+
}
50+
}
51+
}
+92Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
use Symfony\Component\Validator\Constraint;
15+
use Symfony\Component\Validator\ConstraintValidator;
16+
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
17+
use Symfony\Component\Validator\Exception\UnexpectedValueException;
18+
19+
/**
20+
* Validates whether a value is a valid timezone identifier.
21+
*
22+
* @author Javier Spagnoletti <phansys@gmail.com>
23+
* @author Hugo Hamon <hugohamon@neuf.fr>
24+
*/
25+
class TimezoneValidator extends ConstraintValidator
26+
{
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
public function validate($value, Constraint $constraint)
31+
{
32+
if (!$constraint instanceof Timezone) {
33+
throw new UnexpectedTypeException($constraint, Timezone::class);
34+
}
35+
36+
if (null === $value || '' === $value) {
37+
return;
38+
}
39+
40+
if (!is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
41+
throw new UnexpectedValueException($value, 'string');
42+
}
43+
44+
$value = (string) $value;
45+
46+
// @see: https://bugs.php.net/bug.php?id=75928
47+
if ($constraint->countryCode) {
48+
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone, $constraint->countryCode);
49+
} else {
50+
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone);
51+
}
52+
53+
if ($timezoneIds && \in_array($value, $timezoneIds, true)) {
54+
return;
55+
}
56+
57+
if ($constraint->countryCode) {
58+
$code = Timezone::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR;
59+
} elseif (\DateTimeZone::ALL !== $constraint->zone) {
60+
$code = Timezone::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR;
61+
} else {
62+
$code = Timezone::TIMEZONE_IDENTIFIER_ERROR;
63+
}
64+
65+
$this->context->buildViolation($constraint->message)
66+
->setParameter('{{ value }}', $this->formatValue($value))
67+
->setCode($code)
68+
->addViolation();
69+
}
70+
71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function getDefaultOption()
75+
{
76+
return 'zone';
77+
}
78+
79+
/**
80+
* {@inheritdoc}
81+
*/
82+
protected function formatValue($value, $format = 0)
83+
{
84+
$value = parent::formatValue($value, $format);
85+
86+
if (!$value || \DateTimeZone::PER_COUNTRY === $value) {
87+
return $value;
88+
}
89+
90+
return array_search($value, (new \ReflectionClass(\DateTimeZone::class))->getConstants(), true) ?: $value;
91+
}
92+
}

‎src/Symfony/Component/Validator/Resources/translations/validators.de.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@
354354
<source>This collection should contain only unique elements.</source>
355355
<target>Diese Sammlung darf keine doppelten Elemente enthalten.</target>
356356
</trans-unit>
357+
<trans-unit id="92">
358+
<source>This value is not a valid timezone.</source>
359+
<target>Dieser Wert ist keine gültige Zeitzone.</target>
360+
</trans-unit>
357361
</body>
358362
</file>
359363
</xliff>

‎src/Symfony/Component/Validator/Resources/translations/validators.en.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@
354354
<source>This collection should contain only unique elements.</source>
355355
<target>This collection should contain only unique elements.</target>
356356
</trans-unit>
357+
<trans-unit id="92">
358+
<source>This value is not a valid timezone.</source>
359+
<target>This value is not a valid timezone.</target>
360+
</trans-unit>
357361
</body>
358362
</file>
359363
</xliff>

‎src/Symfony/Component/Validator/Resources/translations/validators.es.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.es.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@
330330
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
331331
<target>Este Código de Identificación Bancaria (BIC) no está asociado con el IBAN {{ iban }}.</target>
332332
</trans-unit>
333+
<trans-unit id="92">
334+
<source>This value is not a valid timezone.</source>
335+
<target>Este valor no es una zona horaria válida.</target>
336+
</trans-unit>
333337
</body>
334338
</file>
335339
</xliff>

‎src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@
334334
<source>This value should be valid JSON.</source>
335335
<target>Cette valeur doit être un JSON valide.</target>
336336
</trans-unit>
337+
<trans-unit id="92">
338+
<source>This value is not a valid timezone.</source>
339+
<target>Cette valeur n'est pas un fuseau horaire valide.</target>
340+
</trans-unit>
337341
</body>
338342
</file>
339343
</xliff>
+63Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Constraints;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Validator\Constraints\Timezone;
16+
17+
/**
18+
* @author Javier Spagnoletti <phansys@gmail.com>
19+
*/
20+
class TimezoneTest extends TestCase
21+
{
22+
public function testValidTimezoneConstraints()
23+
{
24+
$constraint = new Timezone();
25+
26+
$constraint = new Timezone([
27+
'message' => 'myMessage',
28+
'zone' => \DateTimeZone::PER_COUNTRY,
29+
'countryCode' => 'AR',
30+
]);
31+
32+
$constraint = new Timezone([
33+
'message' => 'myMessage',
34+
'zone' => \DateTimeZone::ALL,
35+
]);
36+
37+
// Make an assertion in order to avoid this test to be marked as risky
38+
$this->assertInstanceOf(Timezone::class, $constraint);
39+
}
40+
41+
/**
42+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
43+
*/
44+
public function testExceptionForGroupedTimezonesByCountryWithWrongTimezone()
45+
{
46+
$constraint = new Timezone([
47+
'message' => 'myMessage',
48+
'zone' => \DateTimeZone::ALL,
49+
'countryCode' => 'AR',
50+
]);
51+
}
52+
53+
/**
54+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
55+
*/
56+
public function testExceptionForGroupedTimezonesByCountryWithoutTimezone()
57+
{
58+
$constraint = new Timezone([
59+
'message' => 'myMessage',
60+
'countryCode' => 'AR',
61+
]);
62+
}
63+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.