11

Is there a way to access the entity of the property currently being validated in a custom constraint validator, and if so, how? As far as i can see, I only have access to the value (and any services I might choose to inject, of course).

4 Answers 4

11

In case if you have property validator, you can also access validated object in Validator through ExecutionContext:

http://api.symfony.com/2.8/Symfony/Component/Validator/Context/ExecutionContextInterface.html#method_getObject

class SomeValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        $object = $this->context->getObject();
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This returns null. Any idea why?
8

Yes, there is a way. Class constraint validator has an entire entity in scope.

2 Comments

Thanks! The documentation was somewhat unclear so I didn't quote catch that.
@EirikA.Johansen, could you please provide an example? I am trying to do the same thing as described in the Symfony example but without success. A more detaild example will be perfect.
5

I was in need for that too. Please find below a full example :

The entity:

<?php
namespace AppBundle\Entity\MarketPlace;

use Doctrine\ORM\Mapping AS ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Model\BaseCategoryClass as BaseCategory;
use AppBundle\Validator\Constraints as FMUAssert;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MarketPlace\ProductRepository")
 * @Gedmo\Tree(type="nested")
 * @FMUAssert\UnitConstraint()
 */
class Product extends BaseCategory
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

The constraint:

<?php
namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class UnitConstraint extends Constraint
{
    public $message = 'La chaîne "%string%" contient un caractère non autorisé : elle ne peut contenir que des lettres et des chiffres.';

    public function validatedBy()
    {
        return 'unit_validator';
    }

    public function getTargets()
    {
        return self::CLASS_CONSTRAINT;
    }
}

The constraint Validator:

<?php
namespace AppBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UnitConstraintValidator extends ConstraintValidator
{
    public function validate($entity, Constraint $constraint)
    {
        exit(var_dump(get_class($entity)));
        $this->context->addViolation($constraint->message, array('%string%' => $value));
    }
}

And the declaration as a service:

services:
    unit_validator:
        class: %unit_validator.class%
        tags:
            - { name: validator.constraint_validator, alias: unit_validator }

The exit vardump I've put does get me the entity class name, it's working!

1 Comment

Great! Just one little remark: you could also use dump instead of var_dump. It shows the output very nicely formatted and styled.
2

Ey, well it depends on how are you validating the entity. For example, I'm validating my entity through a Form so, to get the entity in the ConstraintValidator I just need to get de context root and get the data from my form:

/**
 * @Annotation
 */
class ValidDnieValidator extends ConstraintValidator
{

    public function validate($value, Constraint $constraint)
    {

        $user = $this->context->getRoot()->getData();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.