AbstractComparisonValidator.php 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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\Context\ExecutionContextInterface;
  12. use Symfony\Component\Validator\Constraint;
  13. use Symfony\Component\Validator\ConstraintValidator;
  14. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  15. /**
  16. * Provides a base class for the validation of property comparisons.
  17. *
  18. * @author Daniel Holmes <daniel@danielholmes.org>
  19. * @author Bernhard Schussek <bschussek@gmail.com>
  20. */
  21. abstract class AbstractComparisonValidator extends ConstraintValidator
  22. {
  23. /**
  24. * {@inheritdoc}
  25. */
  26. public function validate($value, Constraint $constraint)
  27. {
  28. if (!$constraint instanceof AbstractComparison) {
  29. throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\AbstractComparison');
  30. }
  31. if (null === $value) {
  32. return;
  33. }
  34. $comparedValue = $constraint->value;
  35. // Convert strings to DateTimes if comparing another DateTime
  36. // This allows to compare with any date/time value supported by
  37. // the DateTime constructor:
  38. // http://php.net/manual/en/datetime.formats.php
  39. if (is_string($comparedValue)) {
  40. if ($value instanceof \DateTimeImmutable) {
  41. // If $value is immutable, convert the compared value to a
  42. // DateTimeImmutable too
  43. $comparedValue = new \DatetimeImmutable($comparedValue);
  44. } elseif ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
  45. // Otherwise use DateTime
  46. $comparedValue = new \DateTime($comparedValue);
  47. }
  48. }
  49. if (!$this->compareValues($value, $comparedValue)) {
  50. if ($this->context instanceof ExecutionContextInterface) {
  51. $this->context->buildViolation($constraint->message)
  52. ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE))
  53. ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE))
  54. ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue))
  55. ->setCode($this->getErrorCode())
  56. ->addViolation();
  57. } else {
  58. $this->buildViolation($constraint->message)
  59. ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE))
  60. ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE))
  61. ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue))
  62. ->setCode($this->getErrorCode())
  63. ->addViolation();
  64. }
  65. }
  66. }
  67. /**
  68. * Compares the two given values to find if their relationship is valid.
  69. *
  70. * @param mixed $value1 The first value to compare
  71. * @param mixed $value2 The second value to compare
  72. *
  73. * @return bool true if the relationship is valid, false otherwise
  74. */
  75. abstract protected function compareValues($value1, $value2);
  76. /**
  77. * Returns the error code used if the comparison fails.
  78. *
  79. * @return string|null The error code or `null` if no code should be set
  80. */
  81. protected function getErrorCode()
  82. {
  83. }
  84. }