Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 - choice constraint using Doctrine repository

I have an entity, one of which properties I would like to validate based on a database query. I have it defined as a method in my repository, for example:

class EntryRepository extends EntityRepository {

    /**
     * Gets valid entries for validation
     */
    public function getValidEntries() {
        return $this->createQueryBuilder('s')
            ->where('s.isAvailable = :isAvailable')
            ->setParameter('isAvailable', true)
            ->getQuery()
            ->getResult();
    }

    ...
}

How can I use this to provide available choices for the choice constraint? I could define it in my entity class like this:

use Symfony\Component\Validator\Constraints as Assert;

class SomeEntity {

    /**
     * @Assert\Choice(callback = {"Acme\MyBundle\Entity\EntryRepository", "getValidEntries"})
     * ...
     */
    private $entry;

    ...

    }

However, this would require me to make this method static in the repository, which isn't a good way to define repository methods.

Is there a way to do it properly? Or maybe I'm trying to reinvent the wheel and there is a better way to do what I'm trying to do here?

like image 827
Przemek Avatar asked Nov 01 '22 09:11

Przemek


1 Answers

Well, I contemplated creating a custom validation constraint, as Cerad suggested, but I've come up with something a little simpler - Callback constraint.

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Acme\MyBundle\Entity\Entry;

class SomeEntity {

    /**
     * @var Entry
     */
    private $entry;

    ...

    /**
     * @Assert\Callback
     */
    public function validate(ExecutionContextInterface $context) {
        if (!$this->entry->isAvailable()) {
            $context
            ->buildViolation('Entry is not available')
            ->addViolation();
        }
    }

}
like image 93
Przemek Avatar answered Nov 15 '22 06:11

Przemek