Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2293556

Browse files
committed
feature #11657 [Validator] Added ConstraintViolation::getConstraint() (webmozart)
This PR was merged into the 2.6-dev branch. Discussion ---------- [Validator] Added ConstraintViolation::getConstraint() | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #5050 | License | MIT | Doc PR | - This PR adds a `getConstraint()` method to the `ConstraintViolation` in order to access the constraint causing the violation. Related to #7276, #7273 and #9691. Commits ------- ce1d209 [Validator] Added ConstraintViolation::getConstraint()
2 parents 1d7599d + ce1d209 commit 2293556

9 files changed

+121
-19
lines changed

UPGRADE-2.6.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
UPGRADE FROM 2.5 to 2.6
2+
=======================
3+
4+
Validator
5+
---------
6+
7+
* The internal method `setConstraint()` was added to
8+
`Symfony\Component\Validator\Context\ExecutionContextInterface`. With
9+
this method, the context is informed about the constraint that is currently
10+
being validated.
11+
12+
If you implement this interface, make sure to add the method to your
13+
implementation. The easiest solution is to just implement an empty method:
14+
15+
```php
16+
public function setConstraint(Constraint $constraint)
17+
{
18+
}
19+
```

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGELOG
66

77
* [BC BREAK] `FileValidator` disallow empty files
88
* [BC BREAK] `UserPasswordValidator` source message change
9+
* [BC BREAK] added internal `ExecutionContextInterface::setConstraint()`
10+
* added `ConstraintViolation::getConstraint()`
911

1012
2.5.0
1113
-----

src/Symfony/Component/Validator/ConstraintViolation.php

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ class ConstraintViolation implements ConstraintViolationInterface
5353
*/
5454
private $invalidValue;
5555

56+
/**
57+
* @var Constraint|null
58+
*/
59+
private $constraint;
60+
5661
/**
5762
* @var mixed
5863
*/
@@ -61,21 +66,23 @@ class ConstraintViolation implements ConstraintViolationInterface
6166
/**
6267
* Creates a new constraint violation.
6368
*
64-
* @param string $message The violation message
65-
* @param string $messageTemplate The raw violation message
66-
* @param array $parameters The parameters to substitute in the
67-
* raw violation message
68-
* @param mixed $root The value originally passed to the
69-
* validator
70-
* @param string $propertyPath The property path from the root
71-
* value to the invalid value
72-
* @param mixed $invalidValue The invalid value that caused this
73-
* violation
74-
* @param int|null $plural The number for determining the plural
75-
* form when translating the message
76-
* @param mixed $code The error code of the violation
77-
*/
78-
public function __construct($message, $messageTemplate, array $parameters, $root, $propertyPath, $invalidValue, $plural = null, $code = null)
69+
* @param string $message The violation message
70+
* @param string $messageTemplate The raw violation message
71+
* @param array $parameters The parameters to substitute in the
72+
* raw violation message
73+
* @param mixed $root The value originally passed to the
74+
* validator
75+
* @param string $propertyPath The property path from the root
76+
* value to the invalid value
77+
* @param mixed $invalidValue The invalid value that caused this
78+
* violation
79+
* @param int|null $plural The number for determining the plural
80+
* form when translating the message
81+
* @param mixed $code The error code of the violation
82+
* @param Constraint|null $constraint The constraint that caused the
83+
* violation
84+
*/
85+
public function __construct($message, $messageTemplate, array $parameters, $root, $propertyPath, $invalidValue, $plural = null, $code = null, Constraint $constraint = null)
7986
{
8087
$this->message = $message;
8188
$this->messageTemplate = $messageTemplate;
@@ -84,6 +91,7 @@ public function __construct($message, $messageTemplate, array $parameters, $root
8491
$this->root = $root;
8592
$this->propertyPath = $propertyPath;
8693
$this->invalidValue = $invalidValue;
94+
$this->constraint = $constraint;
8795
$this->code = $code;
8896
}
8997

@@ -188,6 +196,16 @@ public function getInvalidValue()
188196
return $this->invalidValue;
189197
}
190198

199+
/**
200+
* Returns the constraint that caused the violation.
201+
*
202+
* @return Constraint|null The constraint or null if it is not known
203+
*/
204+
public function getConstraint()
205+
{
206+
return $this->constraint;
207+
}
208+
191209
/**
192210
* {@inheritdoc}
193211
*/

src/Symfony/Component/Validator/Context/ExecutionContext.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Translation\TranslatorInterface;
1515
use Symfony\Component\Validator\ClassBasedInterface;
16+
use Symfony\Component\Validator\Constraint;
1617
use Symfony\Component\Validator\ConstraintViolation;
1718
use Symfony\Component\Validator\ConstraintViolationList;
1819
use Symfony\Component\Validator\Exception\BadMethodCallException;
@@ -99,6 +100,13 @@ class ExecutionContext implements ExecutionContextInterface
99100
*/
100101
private $group;
101102

103+
/**
104+
* The currently validated constraint.
105+
*
106+
* @var Constraint|null
107+
*/
108+
private $constraint;
109+
102110
/**
103111
* Stores which objects have been validated in which group.
104112
*
@@ -162,6 +170,14 @@ public function setGroup($group)
162170
$this->group = $group;
163171
}
164172

173+
/**
174+
* {@inheritdoc}
175+
*/
176+
public function setConstraint(Constraint $constraint)
177+
{
178+
$this->constraint = $constraint;
179+
}
180+
165181
/**
166182
* {@inheritdoc}
167183
*/
@@ -186,7 +202,8 @@ public function addViolation($message, array $parameters = array(), $invalidValu
186202
$this->propertyPath,
187203
$this->value,
188204
null,
189-
null
205+
null,
206+
$this->constraint
190207
));
191208
}
192209

@@ -197,6 +214,7 @@ public function buildViolation($message, array $parameters = array())
197214
{
198215
return new ConstraintViolationBuilder(
199216
$this->violations,
217+
$this->constraint,
200218
$message,
201219
$parameters,
202220
$this->root,

src/Symfony/Component/Validator/Context/ExecutionContextInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Validator\Context;
1313

14+
use Symfony\Component\Validator\Constraint;
1415
use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface;
1516
use Symfony\Component\Validator\Mapping\MetadataInterface;
1617
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -136,6 +137,16 @@ public function setNode($value, $object, MetadataInterface $metadata = null, $pr
136137
*/
137138
public function setGroup($group);
138139

140+
/**
141+
* Sets the currently validated constraint.
142+
*
143+
* @param Constraint $constraint The validated constraint
144+
*
145+
* @internal Used by the validator engine. Should not be called by user
146+
* code.
147+
*/
148+
public function setConstraint(Constraint $constraint);
149+
139150
/**
140151
* Marks an object as validated in a specific validation group.
141152
*

src/Symfony/Component/Validator/Tests/Constraints/AbstractConstraintValidatorTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Validator\Tests\Constraints;
1313

14+
use Symfony\Component\Validator\Constraints\NotNull;
1415
use Symfony\Component\Validator\ConstraintValidatorInterface;
1516
use Symfony\Component\Validator\ConstraintViolation;
1617
use Symfony\Component\Validator\Context\ExecutionContext;
@@ -49,6 +50,8 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa
4950

5051
protected $propertyPath;
5152

53+
protected $constraint;
54+
5255
protected function setUp()
5356
{
5457
$this->group = 'MyGroup';
@@ -57,6 +60,15 @@ protected function setUp()
5760
$this->value = 'InvalidValue';
5861
$this->root = 'root';
5962
$this->propertyPath = 'property.path';
63+
64+
// Initialize the context with some constraint so that we can
65+
// successfully build a violation.
66+
// The 2.4 API does not keep a reference to the current
67+
// constraint yet. There the violation stores null.
68+
$this->constraint = Validation::API_VERSION_2_4 === $this->getApiVersion()
69+
? null
70+
: new NotNull();
71+
6072
$this->context = $this->createContext();
6173
$this->validator = $this->createValidator();
6274
$this->validator->initialize($this->context);
@@ -108,6 +120,7 @@ protected function createContext()
108120

109121
$context->setGroup($this->group);
110122
$context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
123+
$context->setConstraint($this->constraint);
111124

112125
$validator->expects($this->any())
113126
->method('inContext')
@@ -127,7 +140,8 @@ protected function createViolation($message, array $parameters = array(), $prope
127140
$propertyPath,
128141
$invalidValue,
129142
$plural,
130-
$code
143+
$code,
144+
$this->constraint
131145
);
132146
}
133147

src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Validator\Mapping\ClassMetadata;
2121
use Symfony\Component\Validator\MetadataFactoryInterface;
2222
use Symfony\Component\Validator\Tests\Fixtures\Entity;
23+
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
2324
use Symfony\Component\Validator\Tests\Fixtures\FakeClassMetadata;
2425
use Symfony\Component\Validator\Tests\Fixtures\Reference;
2526
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -752,4 +753,13 @@ public function testInitializeObjectsOnFirstValidation()
752753

753754
$this->assertTrue($entity->initialized);
754755
}
756+
757+
public function testPassConstraintToViolation()
758+
{
759+
$constraint = new FailingConstraint();
760+
$violations = $this->validate('Foobar', $constraint);
761+
762+
$this->assertCount(1, $violations);
763+
$this->assertSame($constraint, $violations[0]->getConstraint());
764+
}
755765
}

src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,8 @@ private function validateInGroup($value, $cacheKey, MetadataInterface $metadata,
856856
$context->markConstraintAsValidated($cacheKey, $constraintHash);
857857
}
858858

859+
$context->setConstraint($constraint);
860+
859861
$validator = $this->validatorFactory->getInstance($constraint);
860862
$validator->initialize($context);
861863
$validator->validate($value, $constraint);

src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Validator\Violation;
1313

1414
use Symfony\Component\Translation\TranslatorInterface;
15+
use Symfony\Component\Validator\Constraint;
1516
use Symfony\Component\Validator\ConstraintViolation;
1617
use Symfony\Component\Validator\ConstraintViolationList;
1718
use Symfony\Component\Validator\Util\PropertyPath;
@@ -72,12 +73,17 @@ class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface
7273
*/
7374
private $plural;
7475

76+
/**
77+
* @var Constraint
78+
*/
79+
private $constraint;
80+
7581
/**
7682
* @var mixed
7783
*/
7884
private $code;
7985

80-
public function __construct(ConstraintViolationList $violations, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null)
86+
public function __construct(ConstraintViolationList $violations, Constraint $constraint, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null)
8187
{
8288
$this->violations = $violations;
8389
$this->message = $message;
@@ -87,6 +93,7 @@ public function __construct(ConstraintViolationList $violations, $message, array
8793
$this->invalidValue = $invalidValue;
8894
$this->translator = $translator;
8995
$this->translationDomain = $translationDomain;
96+
$this->constraint = $constraint;
9097
}
9198

9299
/**
@@ -195,7 +202,8 @@ public function addViolation()
195202
$this->propertyPath,
196203
$this->invalidValue,
197204
$this->plural,
198-
$this->code
205+
$this->code,
206+
$this->constraint
199207
));
200208
}
201209
}

0 commit comments

Comments
 (0)