DateTimeValidator.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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\Validator\Constraint;
  12. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  13. use Symfony\Component\Validator\Exception\UnexpectedValueException;
  14. /**
  15. * @author Bernhard Schussek <bschussek@gmail.com>
  16. * @author Diego Saint Esteben <diego@saintesteben.me>
  17. */
  18. class DateTimeValidator extends DateValidator
  19. {
  20. /**
  21. * {@inheritdoc}
  22. */
  23. public function validate($value, Constraint $constraint)
  24. {
  25. if (!$constraint instanceof DateTime) {
  26. throw new UnexpectedTypeException($constraint, DateTime::class);
  27. }
  28. if (null === $value || '' === $value) {
  29. return;
  30. }
  31. if (!is_scalar($value) && !(\is_object($value) && method_exists($value, '__toString'))) {
  32. throw new UnexpectedValueException($value, 'string');
  33. }
  34. $value = (string) $value;
  35. \DateTime::createFromFormat($constraint->format, $value);
  36. $errors = \DateTime::getLastErrors();
  37. if (0 < $errors['error_count']) {
  38. $this->context->buildViolation($constraint->message)
  39. ->setParameter('{{ value }}', $this->formatValue($value))
  40. ->setCode(DateTime::INVALID_FORMAT_ERROR)
  41. ->addViolation();
  42. return;
  43. }
  44. if ('+' === substr($constraint->format, -1)) {
  45. $errors['warnings'] = array_filter($errors['warnings'], function ($warning) {
  46. return 'Trailing data' !== $warning;
  47. });
  48. }
  49. foreach ($errors['warnings'] as $warning) {
  50. if ('The parsed date was invalid' === $warning) {
  51. $this->context->buildViolation($constraint->message)
  52. ->setParameter('{{ value }}', $this->formatValue($value))
  53. ->setCode(DateTime::INVALID_DATE_ERROR)
  54. ->addViolation();
  55. } elseif ('The parsed time was invalid' === $warning) {
  56. $this->context->buildViolation($constraint->message)
  57. ->setParameter('{{ value }}', $this->formatValue($value))
  58. ->setCode(DateTime::INVALID_TIME_ERROR)
  59. ->addViolation();
  60. } else {
  61. $this->context->buildViolation($constraint->message)
  62. ->setParameter('{{ value }}', $this->formatValue($value))
  63. ->setCode(DateTime::INVALID_FORMAT_ERROR)
  64. ->addViolation();
  65. }
  66. }
  67. }
  68. }