symfonydoctrine-ormdoctrinesymfony-formssymfony-2.4

Symfony2: How to filter the options of an entity-choice form field by a certain attribute?


1.) The Situation (simplified)

I have two entities: a Container-entity, which has exactly 1 Content-entity. The content_id is stored in the Container-entity.

2.) Soft-Delete Content-entities

I implemented a function to soft-delete Content-entities, so I added a "deleted"-attribute to the Content-entity. Everything works fine.

3.) The problem

Now, when I want to create a new Container-entity, the auto-generated choices show ALL the Content-entities - even those ones, which I "marked as deleted" (delete-attribute = 1).

4.) The question

Where is the correct place to add a "filter"/"query" to only show the elements which are not marked as deleted? (delete != 1)

5.) What I've tried

a.) view/twig approach: I tried to modify the rendering of the {{ form_widget(form.contentId) }} with no success

b.) controller approach: I tried to manipulate the form-data in the newAction where the form is being created ($form = $this->createCreateForm($entity)) with no success

c.) type/buildForm approach: I tried to change the buildForm()-method ... again, no success

If would be GREAT if you could give me a hint and/or a short code example of where I could hook into the action to remove the soft-deleted choices.

Thank you very much in advance!


Solution

  • You're looking for the query_builder option of the entity field.

    You can create a custom query that filters the resultset in there.

    example:

    $builder->add('users', 'entity', array(
        'class' => 'AcmeHelloBundle:User',
        'query_builder' => function(EntityRepository $repository) {
            $qb = $repository->createQueryBuilder('u');
            // the function returns a QueryBuilder object
            return $qb
                // find all users where 'deleted' is NOT '1'
                ->where($qb->expr()->neq('u.deleted', '?1'))
                ->setParameter('1', '1')
                ->orderBy('u.username', 'ASC')
            ;
        },
    ));
    

    You could go for a more general approach that filters all select statements using doctrine filters, too.