fec0080fe02e9a0d029fa796ea227e6679d677cf
[yaffs-website] / vendor / symfony / validator / Constraints / AbstractComparisonValidator.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
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\PropertyAccess\Exception\NoSuchPropertyException;
15 use Symfony\Component\PropertyAccess\PropertyAccess;
16 use Symfony\Component\PropertyAccess\PropertyAccessor;
17 use Symfony\Component\Validator\Constraint;
18 use Symfony\Component\Validator\ConstraintValidator;
19 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
20 use Symfony\Component\Validator\Exception\UnexpectedTypeException;
21
22 /**
23  * Provides a base class for the validation of property comparisons.
24  *
25  * @author Daniel Holmes <daniel@danielholmes.org>
26  * @author Bernhard Schussek <bschussek@gmail.com>
27  */
28 abstract class AbstractComparisonValidator extends ConstraintValidator
29 {
30     private $propertyAccessor;
31
32     public function __construct(PropertyAccessor $propertyAccessor = null)
33     {
34         $this->propertyAccessor = $propertyAccessor;
35     }
36
37     /**
38      * {@inheritdoc}
39      */
40     public function validate($value, Constraint $constraint)
41     {
42         if (!$constraint instanceof AbstractComparison) {
43             throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\AbstractComparison');
44         }
45
46         if (null === $value) {
47             return;
48         }
49
50         if ($path = $constraint->propertyPath) {
51             if (null === $object = $this->context->getObject()) {
52                 return;
53             }
54
55             try {
56                 $comparedValue = $this->getPropertyAccessor()->getValue($object, $path);
57             } catch (NoSuchPropertyException $e) {
58                 throw new ConstraintDefinitionException(sprintf('Invalid property path "%s" provided to "%s" constraint: %s', $path, \get_class($constraint), $e->getMessage()), 0, $e);
59             }
60         } else {
61             $comparedValue = $constraint->value;
62         }
63
64         // Convert strings to DateTimes if comparing another DateTime
65         // This allows to compare with any date/time value supported by
66         // the DateTime constructor:
67         // http://php.net/manual/en/datetime.formats.php
68         if (\is_string($comparedValue)) {
69             if ($value instanceof \DateTimeImmutable) {
70                 // If $value is immutable, convert the compared value to a
71                 // DateTimeImmutable too
72                 $comparedValue = new \DateTimeImmutable($comparedValue);
73             } elseif ($value instanceof \DateTimeInterface) {
74                 // Otherwise use DateTime
75                 $comparedValue = new \DateTime($comparedValue);
76             }
77         }
78
79         if (!$this->compareValues($value, $comparedValue)) {
80             $this->context->buildViolation($constraint->message)
81                 ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE))
82                 ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE))
83                 ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue))
84                 ->setCode($this->getErrorCode())
85                 ->addViolation();
86         }
87     }
88
89     private function getPropertyAccessor()
90     {
91         if (null === $this->propertyAccessor) {
92             $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
93         }
94
95         return $this->propertyAccessor;
96     }
97
98     /**
99      * Compares the two given values to find if their relationship is valid.
100      *
101      * @param mixed $value1 The first value to compare
102      * @param mixed $value2 The second value to compare
103      *
104      * @return bool true if the relationship is valid, false otherwise
105      */
106     abstract protected function compareValues($value1, $value2);
107
108     /**
109      * Returns the error code used if the comparison fails.
110      *
111      * @return string|null The error code or `null` if no code should be set
112      */
113     protected function getErrorCode()
114     {
115     }
116 }