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

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update validation message
  • Loading branch information
phansys committed Nov 29, 2018
commit 0491875763682690d0c10eb630a5b962c896390f
12 changes: 5 additions & 7 deletions src/Symfony/Component/Validator/Constraints/Timezone.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,21 @@ class Timezone extends Constraint
const NO_SUCH_TIMEZONE_IN_COUNTRY_ERROR = 'c4a22222-dc92-4fc0-abb0-d95b268c7d0b';

public $zone;

public $countryCode;

public $message = 'This value is not a valid timezone{{ extra_info }}.';
public $message = 'This value is not a valid timezone{{ zone_message }}{{ country_code_message }}.';
Copy link
Contributor

@ro0NL ro0NL Sep 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd say This value is not a valid timezone.

the standard seems to not include the value in the message (which in this case cannot be translated), see e.g. https://github.com/symfony/symfony/blob/v4.1.5/src/Symfony/Component/Validator/Constraints/Currency.php#L31

also the message should be added too validators.en.xml + any language you know


protected static $errorNames = array(
self::NO_SUCH_TIMEZONE_ERROR => 'NO_SUCH_TIMEZONE_ERROR',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing few codes here

self::NO_SUCH_TIMEZONE_IN_ZONE_ERROR => 'NO_SUCH_TIMEZONE_IN_ZONE_ERROR',
self::NO_SUCH_TIMEZONE_IN_COUNTRY_ERROR => 'NO_SUCH_TIMEZONE_IN_COUNTRY_ERROR',
);

/**
* {@inheritdoc}
*/
public function __construct($options = null)
public function __construct(array $options = null)
{
if (isset($options['zone'])) {
$this->zone = $options['zone'];
}
$this->zone = $options['zone'] ?? null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling the parent constructor actually sets the options on properties, so i think we should do the validation step after based on the property values set.


if (isset($options['countryCode'])) {
if (\DateTimeZone::PER_COUNTRY !== $this->zone) {
Expand Down
58 changes: 37 additions & 21 deletions src/Symfony/Component/Validator/Constraints/TimezoneValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ public function validate($value, Constraint $constraint)

$value = (string) $value;
$zone = null !== $constraint->zone ? $constraint->zone : \DateTimeZone::ALL;
$timezoneIds = \DateTimeZone::listIdentifiers($zone, $constraint->countryCode);

// @see: https://bugs.php.net/bug.php?id=75928
if ($constraint->countryCode) {
$timezoneIds = \DateTimeZone::listIdentifiers($zone, $constraint->countryCode);
} else {
$timezoneIds = \DateTimeZone::listIdentifiers($zone);
}

if ($timezoneIds && !in_array($value, $timezoneIds, true)) {
if ($constraint->countryCode) {
Expand All @@ -52,10 +58,16 @@ public function validate($value, Constraint $constraint)
$code = Timezone::NO_SUCH_TIMEZONE_ERROR;
}

$this->context->buildViolation($constraint->message)
->setParameter('{{ extra_info }}', $this->formatExtraInfo($constraint->zone, $constraint->countryCode))
$violation = $this->context->buildViolation($constraint->message);

foreach ($this->generateValidationMessage($constraint->zone, $constraint->countryCode) as $placeholder => $message) {
$violation->setParameter($placeholder, $message);
}

$violation
->setCode($code)
->addViolation();
->addViolation()
;
}
}

Expand All @@ -68,31 +80,35 @@ public function getDefaultOption()
}

/**
* Format the extra info which is appended to validation message based on
* constraint options.
* Generates the replace parameters which are used in validation message.
*
* @param int|null $zone
* @param string|null $countryCode
*
* @return string
* @return array
*/
private function formatExtraInfo($zone, $countryCode = null)
private function generateValidationMessage(int $zone = null, string $countryCode = null): array
Copy link
Contributor

@ro0NL ro0NL Sep 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd prefer not to have this method, the generated messages are also not translator friendly. Instead i would always set the (standard) {{ value }} parameter (being the zone ID in this case) see e.g. https://github.com/symfony/symfony/blob/v4.1.5/src/Symfony/Component/Validator/Constraints/CurrencyValidator.php#L48

{
if (null === $zone) {
return '';
}
if ($countryCode) {
$value = ' for ISO 3166-1 country code "'.$countryCode.'"';
} else {
$r = new \ReflectionClass('\DateTimeZone');
$consts = $r->getConstants();
if ($value = array_search($zone, $consts, true)) {
$value = ' for "'.$value.'" zone';
} else {
$value = ' for zone with identifier '.$zone;
$values = array(
'{{ country_code_message }}' => '',
'{{ zone_message }}' => '',
);

if (null !== $zone) {
if (\DateTimeZone::PER_COUNTRY !== $zone) {
$r = new \ReflectionClass(\DateTimeZone::class);
$consts = $r->getConstants();
if ($zoneFound = array_search($zone, $consts, true)) {
$values['{{ zone_message }}'] = ' at "'.$zoneFound.'" zone';
} else {
$values['{{ zone_message }}'] = ' at zone with identifier '.$zone;
}
}
if ($countryCode) {
$values['{{ country_code_message }}'] = ' for ISO 3166-1 country code "'.$countryCode.'"';
}
}

return $value;
return $values;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
class TimezoneValidatorTest extends ConstraintValidatorTestCase
{
protected function createValidator()
protected function createValidator(): TimezoneValidator
{
return new TimezoneValidator();
}
Expand Down Expand Up @@ -50,14 +50,14 @@ public function testExpectsStringCompatibleType()
/**
* @dataProvider getValidTimezones
*/
public function testValidTimezones($timezone)
public function testValidTimezones(string $timezone)
{
$this->validator->validate($timezone, new Timezone());

$this->assertNoViolation();
}

public function getValidTimezones()
public function getValidTimezones(): iterable
{
return array(
array('America/Argentina/Buenos_Aires'),
Expand All @@ -73,7 +73,7 @@ public function getValidTimezones()
/**
* @dataProvider getValidGroupedTimezones
*/
public function testValidGroupedTimezones($timezone, $what)
public function testValidGroupedTimezones(string $timezone, int $what)
{
$constraint = new Timezone(array(
'zone' => $what,
Expand All @@ -84,7 +84,7 @@ public function testValidGroupedTimezones($timezone, $what)
$this->assertNoViolation();
}

public function getValidGroupedTimezones()
public function getValidGroupedTimezones(): iterable
{
return array(
array('America/Argentina/Cordoba', \DateTimeZone::AMERICA),
Expand All @@ -106,7 +106,7 @@ public function getValidGroupedTimezones()
/**
* @dataProvider getInvalidTimezones
*/
public function testInvalidTimezonesWithoutZone($timezone, $extraInfo)
public function testInvalidTimezonesWithoutZone(string $timezone, string $zoneMessage, string $countryCodeMessage)
{
$constraint = new Timezone(array(
'message' => 'myMessage',
Expand All @@ -115,24 +115,25 @@ public function testInvalidTimezonesWithoutZone($timezone, $extraInfo)
$this->validator->validate($timezone, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ extra_info }}', $extraInfo)
->setParameter('{{ zone_message }}', $zoneMessage)
->setParameter('{{ country_code_message }}', $countryCodeMessage)
->setCode(Timezone::NO_SUCH_TIMEZONE_ERROR)
->assertRaised();
}

public function getInvalidTimezones()
public function getInvalidTimezones(): iterable
{
return array(
array('Buenos_Aires/Argentina/America', ''),
array('Mayotte/Indian', ''),
array('foobar', ''),
array('Buenos_Aires/Argentina/America', '', ''),
array('Mayotte/Indian', '', ''),
array('foobar', '', ''),
);
}

/**
* @dataProvider getInvalidGroupedTimezones
*/
public function testInvalidGroupedTimezones($timezone, $what, $extraInfo)
public function testInvalidGroupedTimezones(string $timezone, int $what, string $zoneMessage, string $countryCodeMessage)
{
$constraint = new Timezone(array(
'zone' => $what,
Expand All @@ -142,26 +143,27 @@ public function testInvalidGroupedTimezones($timezone, $what, $extraInfo)
$this->validator->validate($timezone, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ extra_info }}', $extraInfo)
->setParameter('{{ zone_message }}', $zoneMessage)
->setParameter('{{ country_code_message }}', $countryCodeMessage)
->setCode(Timezone::NO_SUCH_TIMEZONE_IN_ZONE_ERROR)
->assertRaised();
}

public function getInvalidGroupedTimezones()
public function getInvalidGroupedTimezones(): iterable
{
return array(
array('Antarctica/McMurdo', \DateTimeZone::AMERICA, ' for "AMERICA" zone'),
array('America/Barbados', \DateTimeZone::ANTARCTICA, ' for "ANTARCTICA" zone'),
array('Europe/Kiev', \DateTimeZone::ARCTIC, ' for "ARCTIC" zone'),
array('Asia/Ho_Chi_Minh', \DateTimeZone::INDIAN, ' for "INDIAN" zone'),
array('Asia/Ho_Chi_Minh', \DateTimeZone::INDIAN | \DateTimeZone::ANTARCTICA, ' for zone with identifier 260'),
array('Antarctica/McMurdo', \DateTimeZone::AMERICA, ' at "AMERICA" zone', ''),
array('America/Barbados', \DateTimeZone::ANTARCTICA, ' at "ANTARCTICA" zone', ''),
array('Europe/Kiev', \DateTimeZone::ARCTIC, ' at "ARCTIC" zone', ''),
array('Asia/Ho_Chi_Minh', \DateTimeZone::INDIAN, ' at "INDIAN" zone', ''),
array('Asia/Ho_Chi_Minh', \DateTimeZone::INDIAN | \DateTimeZone::ANTARCTICA, ' at zone with identifier 260', ''),
);
}

/**
* @dataProvider getValidGroupedTimezonesByCountry
*/
public function testValidGroupedTimezonesByCountry($timezone, $what, $country)
public function testValidGroupedTimezonesByCountry(string $timezone, int $what, string $country)
{
$constraint = new Timezone(array(
'zone' => $what,
Expand All @@ -173,7 +175,7 @@ public function testValidGroupedTimezonesByCountry($timezone, $what, $country)
$this->assertNoViolation();
}

public function getValidGroupedTimezonesByCountry()
public function getValidGroupedTimezonesByCountry(): iterable
{
return array(
array('America/Argentina/Cordoba', \DateTimeZone::PER_COUNTRY, 'AR'),
Expand All @@ -195,7 +197,7 @@ public function getValidGroupedTimezonesByCountry()
/**
* @dataProvider getInvalidGroupedTimezonesByCountry
*/
public function testInvalidGroupedTimezonesByCountry($timezone, $what, $country, $extraInfo)
public function testInvalidGroupedTimezonesByCountry(string $timezone, int $what, string $country, string $zoneMessage, string $countryCodeMessage)
{
$constraint = new Timezone(array(
'message' => 'myMessage',
Expand All @@ -206,23 +208,24 @@ public function testInvalidGroupedTimezonesByCountry($timezone, $what, $country,
$this->validator->validate($timezone, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ extra_info }}', $extraInfo)
->setParameter('{{ zone_message }}', $zoneMessage)
->setParameter('{{ country_code_message }}', $countryCodeMessage)
->setCode(Timezone::NO_SUCH_TIMEZONE_IN_COUNTRY_ERROR)
->assertRaised();
}

public function getInvalidGroupedTimezonesByCountry()
public function getInvalidGroupedTimezonesByCountry(): iterable
{
return array(
array('America/Argentina/Cordoba', \DateTimeZone::PER_COUNTRY, 'FR', ' for ISO 3166-1 country code "FR"'),
array('America/Barbados', \DateTimeZone::PER_COUNTRY, 'PT', ' for ISO 3166-1 country code "PT"'),
array('America/Argentina/Cordoba', \DateTimeZone::PER_COUNTRY, 'FR', '', ' for ISO 3166-1 country code "FR"'),
array('America/Barbados', \DateTimeZone::PER_COUNTRY, 'PT', '', ' for ISO 3166-1 country code "PT"'),
);
}

/**
* @dataProvider getDeprecatedTimezones
*/
public function testDeprecatedTimezonesAreVaildWithBC($timezone)
public function testDeprecatedTimezonesAreVaildWithBC(string $timezone)
{
$constraint = new Timezone(array(
'zone' => \DateTimeZone::ALL_WITH_BC,
Expand All @@ -236,7 +239,7 @@ public function testDeprecatedTimezonesAreVaildWithBC($timezone)
/**
* @dataProvider getDeprecatedTimezones
*/
public function testDeprecatedTimezonesAreInvaildWithoutBC($timezone)
public function testDeprecatedTimezonesAreInvaildWithoutBC(string $timezone)
{
$constraint = new Timezone(array(
'message' => 'myMessage',
Expand All @@ -245,12 +248,13 @@ public function testDeprecatedTimezonesAreInvaildWithoutBC($timezone)
$this->validator->validate($timezone, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ extra_info }}', '')
->setParameter('{{ zone_message }}', '')
->setParameter('{{ country_code_message }}', '')
->setCode(Timezone::NO_SUCH_TIMEZONE_ERROR)
->assertRaised();
}

public function getDeprecatedTimezones()
public function getDeprecatedTimezones(): iterable
{
return array(
array('America/Buenos_Aires'),
Expand Down