From 2aa3e7cd2fa3b2cade25eda0453ab0a0141588f2 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Sun, 11 Jun 2017 16:28:26 +0200 Subject: [PATCH 01/10] Fix #12315 * add dataPath Property to extract "this" in a different way from the context --- .../Component/Validator/Constraints/Expression.php | 1 + .../Validator/Constraints/ExpressionValidator.php | 13 +++++++++++++ .../Tests/Constraints/ExpressionValidatorTest.php | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php index 3329bd2494028..e115540fe46f5 100644 --- a/src/Symfony/Component/Validator/Constraints/Expression.php +++ b/src/Symfony/Component/Validator/Constraints/Expression.php @@ -30,6 +30,7 @@ class Expression extends Constraint public $message = 'This value is not valid.'; public $expression; + public $dataPath; /** * {@inheritdoc} diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index e2f3139af73b8..65eff8c15429a 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\RuntimeException; @@ -46,6 +47,10 @@ public function validate($value, Constraint $constraint) $variables['value'] = $value; $variables['this'] = $this->context->getObject(); + if (strlen($constraint->dataPath) > 0) { + $variables['this'] = $this->getPropertyAccessor()->getValue($this->context, $constraint->dataPath); + } + if (!$this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) @@ -65,4 +70,12 @@ private function getExpressionLanguage() return $this->expressionLanguage; } + + private function getPropertyAccessor() + { + if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { + throw new RuntimeException('Unable to use expressions with data path as the Symfony PropertyAccess component is not installed.'); + } + return PropertyAccess::createPropertyAccessor(); + } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php index e4316243e5580..9245a8baad6e8 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php @@ -235,4 +235,17 @@ public function testExpressionLanguageUsage() $this->assertTrue($used, 'Failed asserting that custom ExpressionLanguage instance is used.'); } + + public function testExpressionLanguageUsageWithCustomDataPath() + { + $constraint = new Expression(['expression' => 'value <= this["dateEnd"]', 'dataPath' => 'root[data]']); + + $this->setRoot(['data' => ['dateEnd' => '2011-06-07', 'dateStart' => '2011-06-05']]); + $this->setPropertyPath(''); + $this->setProperty(null, 'property'); + + $this->validator->validate('2011-06-05', $constraint); + + $this->assertNoViolation(); + } } From c6d83d5e15420641e4203a5ddc3c381ccad99490 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Sun, 11 Jun 2017 16:33:10 +0200 Subject: [PATCH 02/10] Fix #12315 * update changelog --- src/Symfony/Component/Validator/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index f886b1133a7b9..5edaf495643fe 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * not setting the `strict` option of the `Choice` constraint to `true` is deprecated and will throw an exception in Symfony 4.0 * setting the `checkDNS` option of the `Url` constraint to `true` is deprecated in favor of constant values and will throw an exception in Symfony 4.0 + * added a `dataPath` option to the `Expression` constraint to allow an other way to get "this" from the context 3.3.0 ----- From 9e0882bc878d7d4eab7189c6ff08fa7c140bc2af Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Sun, 11 Jun 2017 16:47:25 +0200 Subject: [PATCH 03/10] * fix cs --- .../Component/Validator/Constraints/ExpressionValidator.php | 1 + .../Validator/Tests/Constraints/ExpressionValidatorTest.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index 65eff8c15429a..b354c66118a22 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -76,6 +76,7 @@ private function getPropertyAccessor() if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { throw new RuntimeException('Unable to use expressions with data path as the Symfony PropertyAccess component is not installed.'); } + return PropertyAccess::createPropertyAccessor(); } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php index 9245a8baad6e8..98b193e7e406b 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php @@ -238,9 +238,9 @@ public function testExpressionLanguageUsage() public function testExpressionLanguageUsageWithCustomDataPath() { - $constraint = new Expression(['expression' => 'value <= this["dateEnd"]', 'dataPath' => 'root[data]']); + $constraint = new Expression(array('expression' => 'value <= this["dateEnd"]', 'dataPath' => 'root[data]')); - $this->setRoot(['data' => ['dateEnd' => '2011-06-07', 'dateStart' => '2011-06-05']]); + $this->setRoot(array('data' => array('dateEnd' => '2011-06-07', 'dateStart' => '2011-06-05'))); $this->setPropertyPath(''); $this->setProperty(null, 'property'); From c964fcb42885bfc5acac0b9fa60b485c5bd4a95c Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Sun, 11 Jun 2017 17:33:17 +0200 Subject: [PATCH 04/10] * fix issue with test lowest --- src/Symfony/Component/Validator/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 2b0a0cab2971f..695deef439a7e 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -30,6 +30,7 @@ "symfony/dependency-injection": "~3.3|~4.0", "symfony/expression-language": "~2.8|~3.0|~4.0", "symfony/cache": "~3.1|~4.0", + "symfony/property-access": "~3.4|~4.0", "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", "egulias/email-validator": "^1.2.8|~2.0" From 53016a52594ebe64afaeba4935e0789fc7a458c3 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 19 Jun 2017 11:30:09 +0200 Subject: [PATCH 05/10] Fix #12315 * change string check --- .../Component/Validator/Constraints/ExpressionValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index b354c66118a22..f6bc6340cdbe6 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -47,7 +47,7 @@ public function validate($value, Constraint $constraint) $variables['value'] = $value; $variables['this'] = $this->context->getObject(); - if (strlen($constraint->dataPath) > 0) { + if (null !== $constraint->dataPath && '' !== $constraint->dataPath) { $variables['this'] = $this->getPropertyAccessor()->getValue($this->context, $constraint->dataPath); } From 1907d8b3707b0bb0830c49b21e3a18473527b6cf Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Tue, 20 Jun 2017 09:25:29 +0200 Subject: [PATCH 06/10] Fix #12315 * change test method name to a better name --- .../Validator/Tests/Constraints/ExpressionValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php index 98b193e7e406b..4dc9737cd97f3 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php @@ -236,7 +236,7 @@ public function testExpressionLanguageUsage() $this->assertTrue($used, 'Failed asserting that custom ExpressionLanguage instance is used.'); } - public function testExpressionLanguageUsageWithCustomDataPath() + public function testExpressionWithCustomDataPath() { $constraint = new Expression(array('expression' => 'value <= this["dateEnd"]', 'dataPath' => 'root[data]')); From afd240648d40625ad3ea26283da847dc802f17d2 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 9 Oct 2017 09:53:31 +0200 Subject: [PATCH 07/10] Fix #12315 * moved check if property access component is installed to constraint * improve readability --- src/Symfony/Component/Validator/CHANGELOG.md | 2 +- .../Component/Validator/Constraints/Expression.php | 14 ++++++++++++++ .../Validator/Constraints/ExpressionValidator.php | 7 ++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 68edd1c899107..214f671358157 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -11,7 +11,7 @@ CHANGELOG the `Url::CHECK_DNS_TYPE_*` constants values and will throw an exception in Symfony 4.0 * added min/max amount of pixels check to `Image` constraint via `minPixels` and `maxPixels` * added a new "propertyPath" option to comparison constraints in order to get the value to compare from an array or object - * added a `dataPath` option to the `Expression` constraint to allow an other way to get "this" from the context + * added a `dataPath` option to the `Expression` constraint to allow an other way to get `this` from the context 3.3.0 ----- diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php index e115540fe46f5..0b4a45326d2af 100644 --- a/src/Symfony/Component/Validator/Constraints/Expression.php +++ b/src/Symfony/Component/Validator/Constraints/Expression.php @@ -11,7 +11,9 @@ namespace Symfony\Component\Validator\Constraints; +use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\RuntimeException; /** * @Annotation @@ -32,6 +34,18 @@ class Expression extends Constraint public $expression; public $dataPath; + /** + * @inheritdoc + */ + public function __construct($options = null) + { + parent::__construct($options); + + if (null !== $this->dataPath && '' !== $this->dataPath && !class_exists(PropertyAccess::class)) { + throw new RuntimeException('Unable to use expressions with data path as the Symfony PropertyAccess component is not installed.'); + } + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index f6bc6340cdbe6..d33cdb912f331 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -45,10 +45,11 @@ public function validate($value, Constraint $constraint) $variables = array(); $variables['value'] = $value; - $variables['this'] = $this->context->getObject(); if (null !== $constraint->dataPath && '' !== $constraint->dataPath) { $variables['this'] = $this->getPropertyAccessor()->getValue($this->context, $constraint->dataPath); + } else { + $variables['this'] = $this->context->getObject(); } if (!$this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { @@ -73,10 +74,6 @@ private function getExpressionLanguage() private function getPropertyAccessor() { - if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { - throw new RuntimeException('Unable to use expressions with data path as the Symfony PropertyAccess component is not installed.'); - } - return PropertyAccess::createPropertyAccessor(); } } From 26f4505587be86db249e78ce916b593ac9900dd4 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 9 Oct 2017 09:58:35 +0200 Subject: [PATCH 08/10] Fix #12315 * cs --- src/Symfony/Component/Validator/Constraints/Expression.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php index 0b4a45326d2af..06f4e481d5fe1 100644 --- a/src/Symfony/Component/Validator/Constraints/Expression.php +++ b/src/Symfony/Component/Validator/Constraints/Expression.php @@ -35,7 +35,7 @@ class Expression extends Constraint public $dataPath; /** - * @inheritdoc + * {@inheritdoc} */ public function __construct($options = null) { From bd3abc9456078d3e8e26b90b64599dc22df202a3 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 9 Oct 2017 11:34:21 +0200 Subject: [PATCH 09/10] Fix #12315 * made dataPath private --- .../Component/Validator/Constraints/Expression.php | 13 +++++++++++-- .../Validator/Constraints/ExpressionValidator.php | 9 ++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php index 06f4e481d5fe1..a6a2a175e34d1 100644 --- a/src/Symfony/Component/Validator/Constraints/Expression.php +++ b/src/Symfony/Component/Validator/Constraints/Expression.php @@ -32,7 +32,7 @@ class Expression extends Constraint public $message = 'This value is not valid.'; public $expression; - public $dataPath; + private $dataPath; /** * {@inheritdoc} @@ -41,11 +41,20 @@ public function __construct($options = null) { parent::__construct($options); - if (null !== $this->dataPath && '' !== $this->dataPath && !class_exists(PropertyAccess::class)) { + if ($this->dataPath && !class_exists(PropertyAccess::class)) { throw new RuntimeException('Unable to use expressions with data path as the Symfony PropertyAccess component is not installed.'); } } + public function __get($option) + { + if ('dataPath' === $option) { + return $this->dataPath; + } + + return parent::__get($option); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index d33cdb912f331..2fafa471c80ba 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -46,8 +46,8 @@ public function validate($value, Constraint $constraint) $variables = array(); $variables['value'] = $value; - if (null !== $constraint->dataPath && '' !== $constraint->dataPath) { - $variables['this'] = $this->getPropertyAccessor()->getValue($this->context, $constraint->dataPath); + if ($constraint->dataPath) { + $variables['this'] = PropertyAccess::createPropertyAccessor()->getValue($this->context, $constraint->dataPath); } else { $variables['this'] = $this->context->getObject(); } @@ -71,9 +71,4 @@ private function getExpressionLanguage() return $this->expressionLanguage; } - - private function getPropertyAccessor() - { - return PropertyAccess::createPropertyAccessor(); - } } From 5c849fed8c560dc0fc73d78d9fb8bbf1848cf8c7 Mon Sep 17 00:00:00 2001 From: Alexander Miehe Date: Mon, 9 Oct 2017 13:07:50 +0200 Subject: [PATCH 10/10] Fix #12315 * made dataPath protected so test is not failing --- src/Symfony/Component/Validator/Constraints/Expression.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php index a6a2a175e34d1..d95f279aa2636 100644 --- a/src/Symfony/Component/Validator/Constraints/Expression.php +++ b/src/Symfony/Component/Validator/Constraints/Expression.php @@ -32,7 +32,7 @@ class Expression extends Constraint public $message = 'This value is not valid.'; public $expression; - private $dataPath; + protected $dataPath; /** * {@inheritdoc}