"Fossies" - the Fresh Open Source Software Archive

Member "drupal-9.4.5/vendor/symfony/validator/Constraints/AbstractComparisonValidator.php" (20 Jul 2022, 4559 Bytes) of package /linux/www/drupal-9.4.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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\PropertyAccessorInterface;
   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(PropertyAccessorInterface $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, AbstractComparison::class);
   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: ', $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         // https://php.net/datetime.formats
   68         if (\is_string($comparedValue) && $value instanceof \DateTimeInterface) {
   69             // If $value is immutable, convert the compared value to a DateTimeImmutable too, otherwise use DateTime
   70             $dateTimeClass = $value instanceof \DateTimeImmutable ? \DateTimeImmutable::class : \DateTime::class;
   71 
   72             try {
   73                 $comparedValue = new $dateTimeClass($comparedValue);
   74             } catch (\Exception $e) {
   75                 throw new ConstraintDefinitionException(sprintf('The compared value "%s" could not be converted to a "%s" instance in the "%s" constraint.', $comparedValue, $dateTimeClass, \get_class($constraint)));
   76             }
   77         }
   78 
   79         if (!$this->compareValues($value, $comparedValue)) {
   80             $violationBuilder = $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 
   86             if (null !== $path) {
   87                 $violationBuilder->setParameter('{{ compared_value_path }}', $path);
   88             }
   89 
   90             $violationBuilder->addViolation();
   91         }
   92     }
   93 
   94     private function getPropertyAccessor(): PropertyAccessorInterface
   95     {
   96         if (null === $this->propertyAccessor) {
   97             $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
   98         }
   99 
  100         return $this->propertyAccessor;
  101     }
  102 
  103     /**
  104      * Compares the two given values to find if their relationship is valid.
  105      *
  106      * @param mixed $value1 The first value to compare
  107      * @param mixed $value2 The second value to compare
  108      *
  109      * @return bool true if the relationship is valid, false otherwise
  110      */
  111     abstract protected function compareValues($value1, $value2);
  112 
  113     /**
  114      * Returns the error code used if the comparison fails.
  115      *
  116      * @return string|null The error code or `null` if no code should be set
  117      */
  118     protected function getErrorCode()
  119     {
  120         return null;
  121     }
  122 }