Reputation: 55
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 !
Upvotes: 2
Views: 884
Reputation: 133
You should simply precise it in your query (and avoid as far as you can using raw strings in your code) :
//somewhere in your project
class User
{
const ROLE_MANAGER = 'ROLE_MANAGER'; //or in your config, parameters etc
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$role = User::ROLE_MANAGER;
// OR something like this if you think you gonna
// need to reuse this formtype with other roles restructions :
// $role = $options["role"];
//...
->andWhere(':role IN u.roles')
->setParameter('role', $role)
Another cool thing in DQL is that it adds some sugar on standard SQL operations. For example, in a use case that is close to this one, you could need to use "MEMBER OF" keywords that allows you to search for a particular entity in a collection :
->andWhere(':manager MEMBER OF u.managedBy')
->setParameter('manager', $user)
Hope it helped !
Upvotes: 0
Reputation: 4701
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.
Upvotes: 2