Search code examples
symfony4

How can I filter an EntityType in my form with roles?


I'd like to show in a Synfomy formType a select input which only proposes users with a particular role.

I'm currently writing an app which involves some basic users and some super-users that are in charge of the basic users.

So whenever I sign-up a new user, I want to be able to assign him to a designated "super-user" to be managed by.

But when I try to make an entityType field in my registrationType to select the super-user to be assigned, I don't know how to display only users with the ROLE_MANAGER in the choice. I only understand how to display all users.

All users are in the same table. I make a distinction between them using Symfony roles system only.

I've tried to look at a query_builder solution, but I didn't understant how to look in arrays with the "where" parameter or apply role hierarchy in that query.

My formType is as follow. I'm trying to display only users with ROLE_MANAGER and higher in their roles in the "manager" entityType select input.

Roles are stored in arrays like this : ["ROLE_USER", "ROLE_MANAGER","ROLE_ADMIN"]... so user.roles returns this kind of array.


class RegistrationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('email')
            ->add('username')
            ->add('manager', EntityType::class,[
                'class' => User::class,
                'choice_label' => 'username',
                'query_builder' => function (EntityRepository $er){
                    return $er->createQueryBuilder('u')
                        ->orderBy('u.username', 'ASC');
                }])
            ->add('password',PasswordType::class)
            ->add('confirm_password',PasswordType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'validation_groups' => ['Default', 'registration'],
        ]);
    }
}

Could anyone point me toward the right direction ?

Many Thanks !


Solution

  • I believe user roles are stored in a stringified array, which makes it harder to query with something like ==. What you can do however is to use the LIKE operator. This will look for a pattern. In your case if you only want to show users with ROLE_MANAGER you can use:

     ->andWhere('u.roles LIKE \'%ROLE_MANAGER%\' ')
    

    Put this in your line above ->orderBy('u.username', 'ASC');.

    Be aware: if you have other roles containing ROLE_MANAGER these will also be returned with when using LIKE with %...%. You can read more about the sql LIKE operator here.

    ps. You might be wondering why I would use andWhere() instead of where(). This is done habitually because where() could remove previous WHERE statements in the actual SQL query if there were any, so I try to avoid it. and use andWhere() instead.