From 273671ec59be31b08445af1e8ca7714e8e452a53 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 4 Aug 2014 12:36:09 +0200 Subject: [PATCH] [Validator] Convert objects to string in comparison validators. Reapplies 6cf5e0812e6f20d60acbc0324abf96475e89b6ef --- .../Validator/ConstraintValidator.php | 39 ++++++++++++++----- .../AbstractComparisonValidator.php | 4 +- .../AbstractComparisonValidatorTestCase.php | 15 +++++++ .../Constraints/EqualToValidatorTest.php | 4 +- .../Constraints/GreaterThanValidatorTest.php | 3 ++ .../Constraints/IdenticalToValidatorTest.php | 5 ++- .../LessThanOrEqualValidatorTest.php | 3 ++ .../Constraints/LessThanValidatorTest.php | 3 ++ .../Constraints/NotEqualToValidatorTest.php | 4 +- .../NotIdenticalToValidatorTest.php | 4 +- 10 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index ac50f7e0e2..58c0902e13 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -20,6 +20,21 @@ namespace Symfony\Component\Validator; */ abstract class ConstraintValidator implements ConstraintValidatorInterface { + /** + * Whether to format {@link \DateTime} objects as RFC-3339 dates + * ("Y-m-d H:i:s"). + * + * @var integer + */ + const PRETTY_DATE = 1; + + /** + * Whether to cast objects with a "__toString()" method to strings. + * + * @var integer + */ + const OBJECT_TO_STRING = 2; + /** * @var ExecutionContextInterface */ @@ -66,15 +81,15 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface * won't know what an "object", "array" or "resource" is and will be * confused by the violation message. * - * @param mixed $value The value to format as string - * @param bool $prettyDateTime Whether to format {@link \DateTime} - * objects as RFC-3339 dates ("Y-m-d H:i:s") + * @param mixed $value The value to format as string + * @param integer $format A bitwise combination of the format + * constants in this class * * @return string The string representation of the passed value */ - protected function formatValue($value, $prettyDateTime = false) + protected function formatValue($value, $format = 0) { - if ($prettyDateTime && $value instanceof \DateTime) { + if (($format & self::PRETTY_DATE) && $value instanceof \DateTime) { if (class_exists('IntlDateFormatter')) { $locale = \Locale::getDefault(); $formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT); @@ -86,6 +101,10 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface } if (is_object($value)) { + if ($format & self::OBJECT_TO_STRING && method_exists($value, '__toString')) { + return $value->__toString(); + } + return 'object'; } @@ -122,18 +141,18 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface * Each of the values is converted to a string using * {@link formatValue()}. The values are then concatenated with commas. * - * @param array $values A list of values - * @param bool $prettyDateTime Whether to format {@link \DateTime} - * objects as RFC-3339 dates ("Y-m-d H:i:s") + * @param array $values A list of values + * @param integer $format A bitwise combination of the format + * constants in this class * * @return string The string representation of the value list * * @see formatValue() */ - protected function formatValues(array $values, $prettyDateTime = false) + protected function formatValues(array $values, $format = 0) { foreach ($values as $key => $value) { - $values[$key] = $this->formatValue($value, $prettyDateTime); + $values[$key] = $this->formatValue($value, $format); } return implode(', ', $values); diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php index d2b15f2162..2e8230bb83 100644 --- a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php +++ b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php @@ -32,8 +32,8 @@ abstract class AbstractComparisonValidator extends ConstraintValidator if (!$this->compareValues($value, $constraint->value)) { $this->context->addViolation($constraint->message, array( - '{{ value }}' => $this->formatValue($value, true), - '{{ compared_value }}' => $this->formatValue($constraint->value, true), + '{{ value }}' => $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE), + '{{ compared_value }}' => $this->formatValue($constraint->value, self::OBJECT_TO_STRING | self::PRETTY_DATE), '{{ compared_value_type }}' => $this->formatTypeOf($constraint->value) )); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php index 80690d29e0..a1c573baa4 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php @@ -15,6 +15,21 @@ use Symfony\Component\Intl\Util\IntlTestHelper; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\AbstractComparisonValidator; +class ComparisonTest_Class +{ + protected $value; + + public function __construct($value) + { + $this->value = $value; + } + + public function __toString() + { + return (string) $this->value; + } +} + /** * @author Daniel Holmes */ diff --git a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php index 783e5508d7..997ed74023 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php @@ -39,6 +39,7 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase array(3, '3'), array('a', 'a'), array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')), + array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)), array(null, 1), ); } @@ -51,7 +52,8 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase return array( array(1, '1', 2, '2', 'integer'), array('22', '"22"', '333', '"333"', 'string'), - array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime') + array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), ); } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php index 14a7a6d16f..64c5dbff65 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php @@ -37,6 +37,7 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase return array( array(2, 1), array(new \DateTime('2005/01/01'), new \DateTime('2001/01/01')), + array(new ComparisonTest_Class(5), new ComparisonTest_Class(4)), array('333', '22'), array(null, 1), ); @@ -52,6 +53,8 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase array(2, '2', 2, '2', 'integer'), array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'), array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), + array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), array('22', '"22"', '333', '"333"', 'string'), array('22', '"22"', '22', '"22"', 'string') ); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php index 9c08523386..dfe0f97af6 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php @@ -35,11 +35,13 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase public function provideValidComparisons() { $date = new \DateTime('2000-01-01'); + $object = new ComparisonTest_Class(2); return array( array(3, 3), array('a', 'a'), array($date, $date), + array($object, $object), array(null, 1), ); } @@ -54,7 +56,8 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase array(2, '2', '2', '"2"', 'string'), array('22', '"22"', '333', '"333"', 'string'), array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', 'DateTime'), - array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('1999-01-01'), 'Jan 1, 1999, 12:00 AM', 'DateTime') + array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('1999-01-01'), 'Jan 1, 1999, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), ); } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php index fc41811a76..0f4f749b8b 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php @@ -39,6 +39,8 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase array(1, 1), array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01')), array(new \DateTime('2000-01-01'), new \DateTime('2020-01-01')), + array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)), + array(new ComparisonTest_Class(5), new ComparisonTest_Class(5)), array('a', 'a'), array('a', 'z'), array(null, 1), @@ -53,6 +55,7 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase return array( array(2, '2', 1, '1', 'integer'), array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(4), '4', __NAMESPACE__.'\ComparisonTest_Class'), array('c', '"c"', 'b', '"b"', 'string') ); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php index 5cb5673c81..408251d214 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php @@ -37,6 +37,7 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase return array( array(1, 2), array(new \DateTime('2000-01-01'), new \DateTime('2010-01-01')), + array(new ComparisonTest_Class(4), new ComparisonTest_Class(5)), array('22', '333'), array(null, 1), ); @@ -52,6 +53,8 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase array(2, '2', 2, '2', 'integer'), array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), + array(new ComparisonTest_Class(6), '6', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), array('333', '"333"', '22', '"22"', 'string'), ); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php index e0db97a0e7..d0342bfe35 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php @@ -38,6 +38,7 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase array(1, 2), array('22', '333'), array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01')), + array(new ComparisonTest_Class(6), new ComparisonTest_Class(5)), array(null, 1), ); } @@ -51,7 +52,8 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase array(3, '3', 3, '3', 'integer'), array('2', '"2"', 2, '2', 'integer'), array('a', '"a"', 'a', '"a"', 'string'), - array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime') + array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array(new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'), ); } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php index ad2865c457..b1e31a40b7 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php @@ -50,11 +50,13 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase public function provideInvalidComparisons() { $date = new \DateTime('2000-01-01'); + $object = new ComparisonTest_Class(2); return array( array(3, '3', 3, '3', 'integer'), array('a', '"a"', 'a', '"a"', 'string'), - array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime') + array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime'), + array($object, '2', $object, '2', __NAMESPACE__.'\ComparisonTest_Class'), ); } }