简体   繁体   中英

How would one filter a form collection in Symfony2?

I'm rewriting an old application to Symfony2 and I'm a bit stuck. The application has TaskType and TagsType . The TaskType form has a collection of TagType . Some of the tags might be archived (ie Tag#archived=true ). If that's the case, the archived tags should not be shown in the form when you try to edit the task.

class TaskType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add(
                'tags',
                'collection',
                array(
                    'type'         => new TagType(),
                    'allow_add'    => true,
                    'allow_delete' => true,
                    'by_reference' => false,
               )
            )
        ;
    }

    // ...
}


class TagType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
        ;
    }

    // ...
}

Is there a way to filter the tags similar to using query_builder when having an entity instead of collection ? Is there any workaround at all?

If it is the case for the whole system that archived tags arent shown to the user, you might want to use a global filter since it's similar to "deletable" behaviour.

You can look at the code here

https://github.com/Atlantic18/DoctrineExtensions/blob/master/lib/Gedmo/SoftDeleteable/Filter/SoftDeleteableFilter.php

Softdeletable lets you ignore "softly deleted" entities, while you want to ignore "archived" tags. It's quite advanced example since it uses annotations and such, what you would need to check is only if queried class is "Tag" and simply return " AND Tag.archived = 0" or whatever

One way would be to mark archived tags as "soft-deleted", other option is to make a collection criteria. You can apply the criteria in getTags() method in the Task entity.

public function getTags()
{
    return $this->tags->matching(Criteria::create()->where(Criteria::expr()->eq('archived',true)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM