Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9f7ed5a

Browse files
phansyshhamon
authored andcommitted
[Validator] add new Timezone validation constraint.
1 parent f527acf commit 9f7ed5a

File tree

8 files changed

+495
-0
lines changed

8 files changed

+495
-0
lines changed
Lines 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 <[email protected]>
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 <[email protected]>
22+
* @author Hugo Hamon <[email protected]>
23+
*/
24+
class Timezone extends Constraint
25+
{
26+
public const NO_SUCH_TIMEZONE_IDENTIFIER_ERROR = '5ce113e6-5e64-4ea2-90fe-d2233956db13';
27+
public const NO_SUCH_TIMEZONE_IDENTIFIER_IN_ZONE_ERROR = 'b57767b1-36c0-40ac-a3d7-629420c775b8';
28+
public const NO_SUCH_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::NO_SUCH_TIMEZONE_IDENTIFIER_ERROR => 'NO_SUCH_TIMEZONE_IDENTIFIER_ERROR',
36+
self::NO_SUCH_TIMEZONE_IDENTIFIER_IN_ZONE_ERROR => 'NO_SUCH_TIMEZONE_IDENTIFIER_IN_ZONE_ERROR',
37+
self::NO_SUCH_TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR => 'NO_SUCH_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+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
18+
/**
19+
* Validates whether a value is a valid timezone identifier.
20+
*
21+
* @author Javier Spagnoletti <[email protected]>
22+
* @author Hugo Hamon <[email protected]>
23+
*/
24+
class TimezoneValidator extends ConstraintValidator
25+
{
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function validate($value, Constraint $constraint)
30+
{
31+
if (!$constraint instanceof Timezone) {
32+
throw new UnexpectedTypeException($constraint, Timezone::class);
33+
}
34+
35+
if (null === $value || '' === $value) {
36+
return;
37+
}
38+
39+
if (!is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
40+
throw new UnexpectedTypeException($value, 'string');
41+
}
42+
43+
$value = (string) $value;
44+
45+
// @see: https://bugs.php.net/bug.php?id=75928
46+
if ($constraint->countryCode) {
47+
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone, $constraint->countryCode);
48+
} else {
49+
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone);
50+
}
51+
52+
if ($timezoneIds && \in_array($value, $timezoneIds, true)) {
53+
return;
54+
}
55+
56+
if ($constraint->countryCode) {
57+
$code = Timezone::NO_SUCH_TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR;
58+
} elseif (\DateTimeZone::ALL !== $constraint->zone) {
59+
$code = Timezone::NO_SUCH_TIMEZONE_IDENTIFIER_IN_ZONE_ERROR;
60+
} else {
61+
$code = Timezone::NO_SUCH_TIMEZONE_IDENTIFIER_ERROR;
62+
}
63+
64+
$this->context->buildViolation($constraint->message)
65+
->setParameter('{{ value }}', $this->formatValue($value))
66+
->setCode($code)
67+
->addViolation();
68+
}
69+
70+
/**
71+
* {@inheritdoc}
72+
*/
73+
public function getDefaultOption()
74+
{
75+
return 'zone';
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
protected function formatValue($value, $format = 0)
82+
{
83+
$value = parent::formatValue($value, $format);
84+
85+
if (!$value || \DateTimeZone::PER_COUNTRY === $value) {
86+
return $value;
87+
}
88+
89+
return array_search($value, (new \ReflectionClass(\DateTimeZone::class))->getConstants(), true) ?: $value;
90+
}
91+
}

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

Lines 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

Lines 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

Lines 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

Lines 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>
Lines 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 <[email protected]>
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 <[email protected]>
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)