Created
July 5, 2012 13:52
-
-
Save pylebecq/3053790 to your computer and use it in GitHub Desktop.
[Symfony2][2.0] A validator which trigger validation constraints only if an entity has some values in its properties. All properties of the entity must have a getter or must be public, otherwise the PropertyPath will throw an exception.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Sensio\Bundle\FakeBundle\Entity; | |
use Sensio\Component\Validator\Constraints\ValidateIfNeeded; | |
use Symfony\Component\Validator\Constraints as Assert; | |
/** | |
* FakeEntity. | |
* | |
* @ValidateIfNeeded() | |
*/ | |
class FakeEntity | |
{ | |
/** | |
* @Assert\NotBlank(groups={"ValidateIfNeeded"}) | |
*/ | |
public $a; | |
/** | |
* @Assert\NotBlank(groups={"ValidateIfNeeded"}) | |
*/ | |
protected $b; | |
/** | |
* @Assert\NotBlank(groups={"ValidateIfNeeded"}) | |
*/ | |
private $c; | |
public function getB() | |
{ | |
return $this->b; | |
} | |
public function setB($b) | |
{ | |
$this->b = $b; | |
} | |
public function getC() | |
{ | |
return $this->c; | |
} | |
public function setC($c) | |
{ | |
$this->c = $c; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
validator.constraint.validate_if_needed: | |
class: Sensio\Component\Validator\Constraints\ValidateIfNeededValidator | |
arguments: [@validator] | |
tags: | |
- { name: validator.constraint_validator, alias: validate_if_needed } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Sensio\Component\Validator\Constraints; | |
use Symfony\Component\Validator\Constraint; | |
/** | |
* Constraint for the Validate if needed validator | |
* | |
* @Annotation | |
* @author Pierre-Yves LEBECQ <[email protected]> | |
*/ | |
class ValidateIfNeeded extends Constraint | |
{ | |
/** | |
* {@inheritDoc} | |
*/ | |
public function getTargets() | |
{ | |
return self::CLASS_CONSTRAINT; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function validatedBy() | |
{ | |
return 'validate_if_needed'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Sensio\Component\Validator\Constraints; | |
use Symfony\Component\Validator\ValidatorInterface; | |
use Symfony\Component\Form\Util\PropertyPath; | |
use Symfony\Component\Validator\Constraint; | |
use Symfony\Component\Validator\ConstraintValidator; | |
use Symfony\Component\Validator\Exception\UnexpectedTypeException; | |
/** | |
* Validates an entity only if it seems to contains some values. | |
* | |
* @author Pierre-Yves LEBECQ <[email protected]> | |
*/ | |
class ValidateIfNeededValidator extends ConstraintValidator | |
{ | |
/** @var ValidatorInterface */ | |
private $validator; | |
public function __construct(ValidatorInterface $validator) | |
{ | |
$this->validator = $validator; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function isValid($value, Constraint $constraint) | |
{ | |
if (null === $value) { | |
return true; | |
} | |
if (!is_object($value)) { | |
throw new UnexpectedTypeException($value, 'object'); | |
} | |
$hasSomeData = false; | |
$reflectionClass = new \ReflectionClass($value); | |
$properties = $reflectionClass->getProperties(); | |
foreach ($properties as $property) { | |
$propertyPath = new PropertyPath($property->getName()); | |
$propertyValue = $propertyPath->getValue($value); | |
if (null !== $propertyValue) { | |
$hasSomeData = true; | |
} | |
} | |
if (!$hasSomeData) { | |
return true; | |
} | |
$walker = $this->context->getGraphWalker(); | |
$propertyPath = $this->context->getPropertyPath(); | |
$metadata = $this->validator->getMetadataFactory()->getClassMetadata(get_class($value)); | |
$walker->walkObject($metadata, $value, 'ValidateIfNeeded', $propertyPath); | |
$this->context->setPropertyPath($propertyPath); // Reset property path modified by the $walker->walkObject() call | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment