2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Validator\Constraints ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException ;
use Symfony\Component\PropertyAccess\PropertyAccess ;
use Symfony\Component\PropertyAccess\PropertyAccessor ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Validator\Constraint ;
use Symfony\Component\Validator\ConstraintValidator ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\Validator\Exception\ConstraintDefinitionException ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Validator\Exception\UnexpectedTypeException ;
/**
* Provides a base class for the validation of property comparisons .
*
* @ author Daniel Holmes < daniel @ danielholmes . org >
* @ author Bernhard Schussek < bschussek @ gmail . com >
*/
abstract class AbstractComparisonValidator extends ConstraintValidator
{
2018-11-23 12:29:20 +00:00
private $propertyAccessor ;
public function __construct ( PropertyAccessor $propertyAccessor = null )
{
$this -> propertyAccessor = $propertyAccessor ;
}
2015-08-17 17:00:26 -07:00
/**
* { @ inheritdoc }
*/
public function validate ( $value , Constraint $constraint )
{
if ( ! $constraint instanceof AbstractComparison ) {
throw new UnexpectedTypeException ( $constraint , __NAMESPACE__ . '\AbstractComparison' );
}
if ( null === $value ) {
return ;
}
2018-11-23 12:29:20 +00:00
if ( $path = $constraint -> propertyPath ) {
if ( null === $object = $this -> context -> getObject ()) {
return ;
}
try {
$comparedValue = $this -> getPropertyAccessor () -> getValue ( $object , $path );
} catch ( NoSuchPropertyException $e ) {
throw new ConstraintDefinitionException ( sprintf ( 'Invalid property path "%s" provided to "%s" constraint: %s' , $path , \get_class ( $constraint ), $e -> getMessage ()), 0 , $e );
}
} else {
$comparedValue = $constraint -> value ;
}
2015-08-17 17:00:26 -07:00
// Convert strings to DateTimes if comparing another DateTime
// This allows to compare with any date/time value supported by
// the DateTime constructor:
// http://php.net/manual/en/datetime.formats.php
2018-11-23 12:29:20 +00:00
if ( \is_string ( $comparedValue )) {
2017-02-02 16:28:38 -08:00
if ( $value instanceof \DateTimeImmutable ) {
2015-08-17 17:00:26 -07:00
// If $value is immutable, convert the compared value to a
// DateTimeImmutable too
2018-11-23 12:29:20 +00:00
$comparedValue = new \DateTimeImmutable ( $comparedValue );
} elseif ( $value instanceof \DateTimeInterface ) {
2015-08-17 17:00:26 -07:00
// Otherwise use DateTime
$comparedValue = new \DateTime ( $comparedValue );
}
}
if ( ! $this -> compareValues ( $value , $comparedValue )) {
2018-11-23 12:29:20 +00:00
$this -> context -> buildViolation ( $constraint -> message )
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value , self :: OBJECT_TO_STRING | self :: PRETTY_DATE ))
-> setParameter ( '{{ compared_value }}' , $this -> formatValue ( $comparedValue , self :: OBJECT_TO_STRING | self :: PRETTY_DATE ))
-> setParameter ( '{{ compared_value_type }}' , $this -> formatTypeOf ( $comparedValue ))
-> setCode ( $this -> getErrorCode ())
-> addViolation ();
2015-08-17 17:00:26 -07:00
}
}
2018-11-23 12:29:20 +00:00
private function getPropertyAccessor ()
{
if ( null === $this -> propertyAccessor ) {
$this -> propertyAccessor = PropertyAccess :: createPropertyAccessor ();
}
return $this -> propertyAccessor ;
}
2015-08-17 17:00:26 -07:00
/**
* Compares the two given values to find if their relationship is valid .
*
* @ param mixed $value1 The first value to compare
* @ param mixed $value2 The second value to compare
*
* @ return bool true if the relationship is valid , false otherwise
*/
abstract protected function compareValues ( $value1 , $value2 );
2016-04-20 09:56:34 -07:00
/**
* Returns the error code used if the comparison fails .
*
* @ return string | null The error code or `null` if no code should be set
*/
protected function getErrorCode ()
{
}
2015-08-17 17:00:26 -07:00
}