Easyadminbundle: Filter choices on select2

Created on 11 Feb 2016  路  11Comments  路  Source: EasyCorp/EasyAdminBundle

I have differents users and they can define his own categories (entity Category, OneToMany with User)

After, when they come to add a new BlogPost, I want to filter the Category by assigned to the user

How can I do this?

Most helpful comment

Well I have been solved this adding a repository dynamic call inside EasyAdminFormType:

// EasyAdminBundle/Form/Type/EasyAdminFormType.php

//...
class EasyAdminFormType extends AbstractType
{
    //...
    protected $repository_function;
    protected $repository_arguments;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //...
        foreach ($entityProperties as $name => $metadata) {
           //...
            if(isset($metadata["repository"])) {
                $this->repository_function = $metadata["repository"]["function"];
                $this->repository_arguments = $metadata["repository"]["params"];
                $formFieldOptions["query_builder"] = function ($repository) {
                    return call_user_func_array(array($repository, $this->repository_function), $this->repository_arguments);
                };
            }

            $formFieldType = $this->useLegacyFormComponent() ? $metadata['fieldType'] : $this->getFormTypeFqcn($metadata['fieldType']);
            $builder->add($name, $formFieldType, $formFieldOptions);
        }
    }
//...
# easy_admin.yml

easy_admin:
    entities:
        BlogPost:
            class: AppBundle\Entity\BlogPost
            form:
                fields:
                    #...
                    - { property: category, type_options: {required: true}, repository: {function: 'findAllByUsers', params: ['this could be optional', 'but arguments are awesome']} }
// AppBundle/Repository/CategoryRepository.php

//...

class CategoryRepository extends \Doctrine\ORM\EntityRepository
{
    public function findAllByUsers($param1, $param2)
    {
        // do stuff
        // important: needs return a queryBuilder object
        $qb = $this->createQueryBuilder('c');
        return $qb->->where('c.user = '$param1);
    }
}

Edit: I have been post basically the concept of this, of course I will need send the user id as parameter

But would be interesting that easyadmin support repository function calls

All 11 comments

Well I have been solved this adding a repository dynamic call inside EasyAdminFormType:

// EasyAdminBundle/Form/Type/EasyAdminFormType.php

//...
class EasyAdminFormType extends AbstractType
{
    //...
    protected $repository_function;
    protected $repository_arguments;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //...
        foreach ($entityProperties as $name => $metadata) {
           //...
            if(isset($metadata["repository"])) {
                $this->repository_function = $metadata["repository"]["function"];
                $this->repository_arguments = $metadata["repository"]["params"];
                $formFieldOptions["query_builder"] = function ($repository) {
                    return call_user_func_array(array($repository, $this->repository_function), $this->repository_arguments);
                };
            }

            $formFieldType = $this->useLegacyFormComponent() ? $metadata['fieldType'] : $this->getFormTypeFqcn($metadata['fieldType']);
            $builder->add($name, $formFieldType, $formFieldOptions);
        }
    }
//...
# easy_admin.yml

easy_admin:
    entities:
        BlogPost:
            class: AppBundle\Entity\BlogPost
            form:
                fields:
                    #...
                    - { property: category, type_options: {required: true}, repository: {function: 'findAllByUsers', params: ['this could be optional', 'but arguments are awesome']} }
// AppBundle/Repository/CategoryRepository.php

//...

class CategoryRepository extends \Doctrine\ORM\EntityRepository
{
    public function findAllByUsers($param1, $param2)
    {
        // do stuff
        // important: needs return a queryBuilder object
        $qb = $this->createQueryBuilder('c');
        return $qb->->where('c.user = '$param1);
    }
}

Edit: I have been post basically the concept of this, of course I will need send the user id as parameter

But would be interesting that easyadmin support repository function calls

If @javiereguiluz not think it necessary to include this feature, It can be closed

Sorry, I still don't have an opinion about this.

:+1:

@rubengc Did you have to copy/paste the original code for this? If yes, we might think about specific events we could throw from the FormType for example

@rubengc an awesome snippet, thanks! Added a compiler pass to replace EasyAdminFormType with the modified one and it works like a charm.

@Gyvastis i'm really fluent with compiler passes ;-)
Can you share your code or give a little explanation on how to do this ?
Thank you by advance

@dfinfo copy the EasyAdminFormType to your bundle, change the namespace & add the code that @rubengc suggested. Then add a compiler pass class to override the original form type service:

class OverrideEasyAdminFormTypeCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('easyadmin.form.type');
        $definition->setClass(EasyAdminFormType::class); //this is your modified form class
    }
}

And add the compiler pass to your main bundle class:

class YourBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new OverrideEasyAdminFormTypeCompilerPass());
    }
}

Thanks a lot, you saved my day and i'm beginning to see the light with this compiler stuff.

What about put this logic to custom configurator of JavierEguiluz\Bundle\EasyAdminBundle\Form\Type\Configurator\TypeConfiguratorInterface and don't override vendor class?

@grachevko suggestion works like a charm

class EntityConfigurator implements TypeConfiguratorInterface
{
    private $repositoryFunction;
    private $repositoryArguments;

    public function configure($name, array $options, array $metadata, FormConfigInterface $parentConfig)
    {
        if (isset($metadata["repository"])) {
            $this->repositoryFunction = $metadata["repository"]["function"];
            $this->repositoryArguments = $metadata["repository"]["params"];
            $options["query_builder"] = function ($repository) {
                return call_user_func_array(
                    [
                        $repository,
                        $this->repositoryFunction,
                    ],
                    $this->repositoryArguments ? $this->repositoryArguments : []
                );
            };
        }

        return $options;
    }

    public function supports($type, array $options, array $metadata)
    {
        return 'entity' === $type && 'association' === $metadata['type'];
    }
}
//services.yml
AppBundle\Form\Type\Configurator\EntityConfigurator:
        tags: { name: 'easyadmin.form.type.configurator' }
Was this page helpful?
0 / 5 - 0 ratings