3

I have difficulties integrating the Symfony validator component with Doctrine (standalone, not using the complete Symfony framework). So far I have managed to register the annotation contraints in Doctrine's AnnotationRegistry and hook into the lifecycle callbacks, but how would I actually retrieve a validator and parse the annotations in the lifecycle method?

My entity looks like this:

<?php
namespace App\Model;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * User
 *
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="id_UNIQUE", columns={"id"}), @ORM\UniqueConstraint(name="username_UNIQUE", columns={"username"})})
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User extends AbstractEntity
{
    /**
     * @ORM\PreUpdate
     * @ORM\PrePersist
     */
    public function validate()
    {
        // how do I retrieve the validator?

        // $validator->validate($this);
    }

    /**
     * @var string
     *
     * @ORM\Column(name="username", type="string", length=45, nullable=false)
     * @Assert\Length(min=3, max=45)
     */
    protected $username;

    /** ... */
}

1 Answer 1

8

As you are not using symfony fullstack, you should manually create a validator servie to use it.

See Usage Section of Validator component readme

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;

class User
{
    /**
     * @Assert\Length(min = 3)
     * @Assert\NotBlank
     */
    private $name;

    /**
     * @Assert\Email
     * @Assert\NotBlank
     */
    private $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    /**
     * @Assert\True(message = "The user should have a Google Mail account")
     */
    public function isGmailUser()
    {
        return false !== strpos($this->email, '@gmail.com');
    }
}

The validator

$validator = Validation::createValidatorBuilder()
    ->enableAnnotationMapping()
    ->getValidator();

$user = new User('John Doe', '[email protected]');

$violations = $validator->validate($user);
Sign up to request clarification or add additional context in comments.

2 Comments

That worked, thanks! However, if an exception is thrown in the lifecycle callback due to failed validation, the entity manager will close. Is there a way to prevent this? For now I just removed the lifecycle callbacks and manually validate the entity in my repositorie's save method, which seems to be working, but doesn't strike me as the most elegant solution.
Not sure it is not to late, but just use try..catch to handle this manually. Expect some validation exception and handle it properly.

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.