Define a role for users in the sonata admin edit form

I am using Symfony 2.1 for a project. I use FOSUserBundle for user management and SonataAdminBundle for admin use.

I have some questions about this:

  • As an administrator, I want to establish user roles in the user editing form. How can I access roles in role_hierarchy ? And how can I use them as selection fields so that the administrator can set roles for users?

  • When I show the roles in the list, it displays as a string:

     [0 => ROLE_SUPER_ADMIN] [1 => ROLE_USER] 

    How can I change it to this?

     ROLE_SUPER_ADMIN, ROLE_USER 

    I mean, having only an array value.

+4
source share
6 answers

I found the answer to my first question! (but the second in the answer has not yet answered). I am adding roles, as shown below, in the configureFormFields function:

  protected function configureFormFields(FormMapper $formMapper) { //.. $formMapper ->add('roles','choice',array('choices'=>$this->getConfigurationPool()->getContainer()->getParameter('security.role_hierarchy.roles'),'multiple'=>true )); } 

I would be very happy if someone answers the second question :)

+2
source

Based on @parisssss answer, although it was wrong, here is a working solution. In the Sonata input field, all roles that are under this role will be shown if you save one role.

On the other hand, only the most important role will be stored in the database. But that makes absolute sense in the Sf method.

 protected function configureFormFields(FormMapper $formMapper) { // .. $container = $this->getConfigurationPool()->getContainer(); $roles = $container->getParameter('security.role_hierarchy.roles'); $rolesChoices = self::flattenRoles($roles); $formMapper //... ->add('roles', 'choice', array( 'choices' => $rolesChoices, 'multiple' => true ) ); 

And in another method:

 /** * Turns the role array keys into string <ROLES_NAME> keys. * @todo Move to convenience or make it recursive ? ;-) */ protected static function flattenRoles($rolesHierarchy) { $flatRoles = array(); foreach($rolesHierarchy as $roles) { if(empty($roles)) { continue; } foreach($roles as $role) { if(!isset($flatRoles[$role])) { $flatRoles[$role] = $role; } } } return $flatRoles; } 

See in action:

enter image description hereenter image description here

+12
source

Regarding the second question, I added a method to the User class that looks like

 /** * @return string */ public function getRolesAsString() { $roles = array(); foreach ($this->getRoles() as $role) { $role = explode('_', $role); array_shift($role); $roles[] = ucfirst(strtolower(implode(' ', $role))); } return implode(', ', $roles); } 

And then you can declare in your function configureListFields :

 ->add('rolesAsString', 'string') 
+9
source

Roman Brookter's solution is almost perfect, except that it does not allow you to define roles that are the roots of the role of hierarchies. For example, ROLE_SUPER_ADMIN. Here's a fixed flattenRoles method that also returns root roles:

 protected static function flattenRoles($rolesHierarchy) { $flatRoles = []; foreach ($rolesHierarchy as $key => $roles) { $flatRoles[$key] = $key; if (empty($roles)) { continue; } foreach($roles as $role) { if(!isset($flatRoles[$role])) { $flatRoles[$role] = $role; } } } return $flatRoles; } 

Edit: TrtG has already posted this fix in the comments

+2
source

To replay it a bit, here is my extended version of Romain Bruckert and Sash, which gives you such an array:

 array:4 [β–Ό "ROLE_USER" => "User" "ROLE_ALLOWED_TO_SWITCH" => "Allowed To Switch" "ROLE_ADMIN" => "Admin (User, Allowed To Switch)" "ROLE_SUPER_ADMIN" => "Super Admin (Admin (User, Allowed To Switch))" ] 

enter image description here

This will help you find all roles that include a specific role : enter image description here

I know a lot of code, it can be done much better, but maybe it helps someone, or you can at least use snippets of this code.

 /** * Turns the role array keys into string <ROLES_NAME> keys. * @param array $rolesHierarchy * @param bool $niceName * @param bool $withChildren * @param bool $withGrandChildren * @return array */ protected static function flattenRoles($rolesHierarchy, $niceName = false, $withChildren = false, $withGrandChildren = false) { $flatRoles = []; foreach ($rolesHierarchy as $key => $roles) { if(!empty($roles)) { foreach($roles as $role) { if(!isset($flatRoles[$role])) { $flatRoles[$role] = $niceName ? self::niceRoleName($role) : $role; } } } $flatRoles[$key] = $niceName ? self::niceRoleName($key) : $key; if ($withChildren && !empty($roles)) { if (!$recursive) { if ($niceName) { array_walk($roles, function(&$item) { $item = self::niceRoleName($item);}); } $flatRoles[$key] .= ' (' . join(', ', $roles) . ')'; } else { $childRoles = []; foreach($roles as $role) { $childRoles[$role] = $niceName ? self::niceRoleName($role) : $role; if (!empty($rolesHierarchy[$role])) { if ($niceName) { array_walk($rolesHierarchy[$role], function(&$item) { $item = self::niceRoleName($item);}); } $childRoles[$role] .= ' (' . join(', ', $rolesHierarchy[$role]) . ')'; } } $flatRoles[$key] .= ' (' . join(', ', $childRoles) . ')'; } } } return $flatRoles; } /** * Remove underscors, ROLE_ prefix and uppercase words * @param string $role * @return string */ protected static function niceRoleName($role) { return ucwords(strtolower(preg_replace(['/\AROLE_/', '/_/'], ['', ' '], $role))); } 
+2
source

The second answer is below. Add the lines to the yam admin admin file.

 sonata_doctrine_orm_admin: templates: types: list: user_roles: AcmeDemoBundle:Default:user_roles.html.twig 

and in user_roles.html.twig files add the lines below

 {% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %} {% block field %} {% for row in value %} {{row}} {% if not loop.last %} , {% endif %} {% endfor %} {% endblock %} 

then in your admin controller and in the configureListFields function add this line

 ->add('roles', 'user_roles') 

Hope this solves your problem.

+1
source

All Articles