vendor/symfony/validator/Constraints/TimezoneValidator.php line 88

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Validator\Constraints;
  11. use Symfony\Component\Intl\Exception\MissingResourceException;
  12. use Symfony\Component\Intl\Timezones;
  13. use Symfony\Component\Validator\Constraint;
  14. use Symfony\Component\Validator\ConstraintValidator;
  15. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  16. use Symfony\Component\Validator\Exception\UnexpectedValueException;
  17. /**
  18.  * Validates whether a value is a valid timezone identifier.
  19.  *
  20.  * @author Javier Spagnoletti <phansys@gmail.com>
  21.  * @author Hugo Hamon <hugohamon@neuf.fr>
  22.  */
  23. class TimezoneValidator extends ConstraintValidator
  24. {
  25.     public function validate(mixed $valueConstraint $constraint)
  26.     {
  27.         if (!$constraint instanceof Timezone) {
  28.             throw new UnexpectedTypeException($constraintTimezone::class);
  29.         }
  30.         if (null === $value || '' === $value) {
  31.             return;
  32.         }
  33.         if (!\is_scalar($value) && !$value instanceof \Stringable) {
  34.             throw new UnexpectedValueException($value'string');
  35.         }
  36.         $value = (string) $value;
  37.         if ($constraint->intlCompatible && 'Etc/Unknown' === \IntlTimeZone::createTimeZone($value)->getID()) {
  38.             $this->context->buildViolation($constraint->message)
  39.                 ->setParameter('{{ value }}'$this->formatValue($value))
  40.                 ->setCode(Timezone::TIMEZONE_IDENTIFIER_INTL_ERROR)
  41.                 ->addViolation();
  42.             return;
  43.         }
  44.         if (
  45.             \in_array($valueself::getPhpTimezones($constraint->zone$constraint->countryCode), true) ||
  46.             \in_array($valueself::getIntlTimezones($constraint->zone$constraint->countryCode), true)
  47.         ) {
  48.             return;
  49.         }
  50.         if ($constraint->countryCode) {
  51.             $code Timezone::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR;
  52.         } elseif (\DateTimeZone::ALL !== $constraint->zone) {
  53.             $code Timezone::TIMEZONE_IDENTIFIER_IN_ZONE_ERROR;
  54.         } else {
  55.             $code Timezone::TIMEZONE_IDENTIFIER_ERROR;
  56.         }
  57.         $this->context->buildViolation($constraint->message)
  58.               ->setParameter('{{ value }}'$this->formatValue($value))
  59.               ->setCode($code)
  60.               ->addViolation();
  61.     }
  62.     private static function getPhpTimezones(int $zonestring $countryCode null): array
  63.     {
  64.         if (null !== $countryCode) {
  65.             try {
  66.                 return @\DateTimeZone::listIdentifiers($zone$countryCode) ?: [];
  67.             } catch (\ValueError) {
  68.                 return [];
  69.             }
  70.         }
  71.         return \DateTimeZone::listIdentifiers($zone);
  72.     }
  73.     private static function getIntlTimezones(int $zonestring $countryCode null): array
  74.     {
  75.         if (!class_exists(Timezones::class)) {
  76.             return [];
  77.         }
  78.         if (null !== $countryCode) {
  79.             try {
  80.                 return Timezones::forCountryCode($countryCode);
  81.             } catch (MissingResourceException) {
  82.                 return [];
  83.             }
  84.         }
  85.         $timezones Timezones::getIds();
  86.         if (\DateTimeZone::ALL === (\DateTimeZone::ALL $zone)) {
  87.             return $timezones;
  88.         }
  89.         $filtered = [];
  90.         foreach ((new \ReflectionClass(\DateTimeZone::class))->getConstants() as $const => $flag) {
  91.             if ($flag !== ($flag $zone)) {
  92.                 continue;
  93.             }
  94.             $filtered[] = array_filter($timezones, static function ($id) use ($const) {
  95.                 return === stripos($id$const.'/');
  96.             });
  97.         }
  98.         return $filtered array_merge(...$filtered) : [];
  99.     }
  100. }