Skip to content

Commit

Permalink
[Validator] Added ConstraintViolation::getConstraint()
Browse files Browse the repository at this point in the history
  • Loading branch information
webmozart committed Aug 19, 2014
1 parent 1d7599d commit ce1d209
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 19 deletions.
19 changes: 19 additions & 0 deletions UPGRADE-2.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
UPGRADE FROM 2.5 to 2.6
=======================

Validator
---------

* The internal method `setConstraint()` was added to
`Symfony\Component\Validator\Context\ExecutionContextInterface`. With
this method, the context is informed about the constraint that is currently
being validated.

If you implement this interface, make sure to add the method to your
implementation. The easiest solution is to just implement an empty method:

```php
public function setConstraint(Constraint $constraint)
{
}
```
2 changes: 2 additions & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ CHANGELOG

* [BC BREAK] `FileValidator` disallow empty files
* [BC BREAK] `UserPasswordValidator` source message change
* [BC BREAK] added internal `ExecutionContextInterface::setConstraint()`
* added `ConstraintViolation::getConstraint()`

2.5.0
-----
Expand Down
48 changes: 33 additions & 15 deletions src/Symfony/Component/Validator/ConstraintViolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class ConstraintViolation implements ConstraintViolationInterface
*/
private $invalidValue;

/**
* @var Constraint|null
*/
private $constraint;

/**
* @var mixed
*/
Expand All @@ -61,21 +66,23 @@ class ConstraintViolation implements ConstraintViolationInterface
/**
* Creates a new constraint violation.
*
* @param string $message The violation message
* @param string $messageTemplate The raw violation message
* @param array $parameters The parameters to substitute in the
* raw violation message
* @param mixed $root The value originally passed to the
* validator
* @param string $propertyPath The property path from the root
* value to the invalid value
* @param mixed $invalidValue The invalid value that caused this
* violation
* @param int|null $plural The number for determining the plural
* form when translating the message
* @param mixed $code The error code of the violation
*/
public function __construct($message, $messageTemplate, array $parameters, $root, $propertyPath, $invalidValue, $plural = null, $code = null)
* @param string $message The violation message
* @param string $messageTemplate The raw violation message
* @param array $parameters The parameters to substitute in the
* raw violation message
* @param mixed $root The value originally passed to the
* validator
* @param string $propertyPath The property path from the root
* value to the invalid value
* @param mixed $invalidValue The invalid value that caused this
* violation
* @param int|null $plural The number for determining the plural
* form when translating the message
* @param mixed $code The error code of the violation
* @param Constraint|null $constraint The constraint that caused the
* violation
*/
public function __construct($message, $messageTemplate, array $parameters, $root, $propertyPath, $invalidValue, $plural = null, $code = null, Constraint $constraint = null)
{
$this->message = $message;
$this->messageTemplate = $messageTemplate;
Expand All @@ -84,6 +91,7 @@ public function __construct($message, $messageTemplate, array $parameters, $root
$this->root = $root;
$this->propertyPath = $propertyPath;
$this->invalidValue = $invalidValue;
$this->constraint = $constraint;
$this->code = $code;
}

Expand Down Expand Up @@ -188,6 +196,16 @@ public function getInvalidValue()
return $this->invalidValue;
}

/**
* Returns the constraint that caused the violation.
*
* @return Constraint|null The constraint or null if it is not known
*/
public function getConstraint()
{
return $this->constraint;
}

/**
* {@inheritdoc}
*/
Expand Down
20 changes: 19 additions & 1 deletion src/Symfony/Component/Validator/Context/ExecutionContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\ClassBasedInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Exception\BadMethodCallException;
Expand Down Expand Up @@ -99,6 +100,13 @@ class ExecutionContext implements ExecutionContextInterface
*/
private $group;

/**
* The currently validated constraint.
*
* @var Constraint|null
*/
private $constraint;

/**
* Stores which objects have been validated in which group.
*
Expand Down Expand Up @@ -162,6 +170,14 @@ public function setGroup($group)
$this->group = $group;
}

/**
* {@inheritdoc}
*/
public function setConstraint(Constraint $constraint)
{
$this->constraint = $constraint;
}

/**
* {@inheritdoc}
*/
Expand All @@ -186,7 +202,8 @@ public function addViolation($message, array $parameters = array(), $invalidValu
$this->propertyPath,
$this->value,
null,
null
null,
$this->constraint
));
}

Expand All @@ -197,6 +214,7 @@ public function buildViolation($message, array $parameters = array())
{
return new ConstraintViolationBuilder(
$this->violations,
$this->constraint,
$message,
$parameters,
$this->root,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Validator\Context;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface;
use Symfony\Component\Validator\Mapping\MetadataInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
Expand Down Expand Up @@ -136,6 +137,16 @@ public function setNode($value, $object, MetadataInterface $metadata = null, $pr
*/
public function setGroup($group);

/**
* Sets the currently validated constraint.
*
* @param Constraint $constraint The validated constraint
*
* @internal Used by the validator engine. Should not be called by user
* code.
*/
public function setConstraint(Constraint $constraint);

/**
* Marks an object as validated in a specific validation group.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Validator\Tests\Constraints;

use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Context\ExecutionContext;
Expand Down Expand Up @@ -49,6 +50,8 @@ abstract class AbstractConstraintValidatorTest extends \PHPUnit_Framework_TestCa

protected $propertyPath;

protected $constraint;

protected function setUp()
{
$this->group = 'MyGroup';
Expand All @@ -57,6 +60,15 @@ protected function setUp()
$this->value = 'InvalidValue';
$this->root = 'root';
$this->propertyPath = 'property.path';

// Initialize the context with some constraint so that we can
// successfully build a violation.
// The 2.4 API does not keep a reference to the current
// constraint yet. There the violation stores null.
$this->constraint = Validation::API_VERSION_2_4 === $this->getApiVersion()
? null
: new NotNull();

$this->context = $this->createContext();
$this->validator = $this->createValidator();
$this->validator->initialize($this->context);
Expand Down Expand Up @@ -108,6 +120,7 @@ protected function createContext()

$context->setGroup($this->group);
$context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
$context->setConstraint($this->constraint);

$validator->expects($this->any())
->method('inContext')
Expand All @@ -127,7 +140,8 @@ protected function createViolation($message, array $parameters = array(), $prope
$propertyPath,
$invalidValue,
$plural,
$code
$code,
$this->constraint
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\MetadataFactoryInterface;
use Symfony\Component\Validator\Tests\Fixtures\Entity;
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
use Symfony\Component\Validator\Tests\Fixtures\FakeClassMetadata;
use Symfony\Component\Validator\Tests\Fixtures\Reference;
use Symfony\Component\Validator\Validator\ValidatorInterface;
Expand Down Expand Up @@ -752,4 +753,13 @@ public function testInitializeObjectsOnFirstValidation()

$this->assertTrue($entity->initialized);
}

public function testPassConstraintToViolation()
{
$constraint = new FailingConstraint();
$violations = $this->validate('Foobar', $constraint);

$this->assertCount(1, $violations);
$this->assertSame($constraint, $violations[0]->getConstraint());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,8 @@ private function validateInGroup($value, $cacheKey, MetadataInterface $metadata,
$context->markConstraintAsValidated($cacheKey, $constraintHash);
}

$context->setConstraint($constraint);

$validator = $this->validatorFactory->getInstance($constraint);
$validator->initialize($context);
$validator->validate($value, $constraint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Violation;

use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Util\PropertyPath;
Expand Down Expand Up @@ -72,12 +73,17 @@ class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface
*/
private $plural;

/**
* @var Constraint
*/
private $constraint;

/**
* @var mixed
*/
private $code;

public function __construct(ConstraintViolationList $violations, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null)
public function __construct(ConstraintViolationList $violations, Constraint $constraint, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null)
{
$this->violations = $violations;
$this->message = $message;
Expand All @@ -87,6 +93,7 @@ public function __construct(ConstraintViolationList $violations, $message, array
$this->invalidValue = $invalidValue;
$this->translator = $translator;
$this->translationDomain = $translationDomain;
$this->constraint = $constraint;
}

/**
Expand Down Expand Up @@ -195,7 +202,8 @@ public function addViolation()
$this->propertyPath,
$this->invalidValue,
$this->plural,
$this->code
$this->code,
$this->constraint
));
}
}

0 comments on commit ce1d209

Please sign in to comment.