I\'m making a form for user creation, and I want to give one or several roles to a user when I create him.
How do I get the list of roles defined in security.y
You can make a service for this and inject the "security.role_hierarchy.roles" parameter.
Service definition:
acme.user.roles:
class: Acme\DemoBundle\Model\RolesHelper
arguments: ['%security.role_hierarchy.roles%']
Service Class:
class RolesHelper
{
private $rolesHierarchy;
private $roles;
public function __construct($rolesHierarchy)
{
$this->rolesHierarchy = $rolesHierarchy;
}
public function getRoles()
{
if($this->roles) {
return $this->roles;
}
$roles = array();
array_walk_recursive($this->rolesHierarchy, function($val) use (&$roles) {
$roles[] = $val;
});
return $this->roles = array_unique($roles);
}
}
You can get the roles in your controller like this:
$roles = $this->get('acme.user.roles')->getRoles();
You can get a list of reachable roles from this method:
Symfony\Component\Security\Core\Role\RoleHierarchy::getReachableRoles(array $roles)
It seems to return all roles reachable from roles in array $roles
parameter. It's an internal service of Symfony, whose ID is security.role_hierarchy
and is not public (you must explicitely pass it as parameters, it's not acessible from Service Container).
Here's what I've done:
FormType:
use FTW\GuildBundle\Entity\User;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('enabled', null, array('required' => false))
->add('roles', 'choice', array(
'choices' => User::getRoleNames(),
'required' => false,'label'=>'Roles','multiple'=>true
))
->add('disableNotificationEmails', null, array('required' => false));
}
In the entity:
use Symfony\Component\Yaml\Parser; ...
static function getRoleNames()
{
$pathToSecurity = __DIR__ . '/../../../..' . '/app/config/security.yml';
$yaml = new Parser();
$rolesArray = $yaml->parse(file_get_contents($pathToSecurity));
$arrayKeys = array();
foreach ($rolesArray['security']['role_hierarchy'] as $key => $value)
{
//never allow assigning super admin
if ($key != 'ROLE_SUPER_ADMIN')
$arrayKeys[$key] = User::convertRoleToLabel($key);
//skip values that are arrays --- roles with multiple sub-roles
if (!is_array($value))
if ($value != 'ROLE_SUPER_ADMIN')
$arrayKeys[$value] = User::convertRoleToLabel($value);
}
//sort for display purposes
asort($arrayKeys);
return $arrayKeys;
}
static private function convertRoleToLabel($role)
{
$roleDisplay = str_replace('ROLE_', '', $role);
$roleDisplay = str_replace('_', ' ', $roleDisplay);
return ucwords(strtolower($roleDisplay));
}
Please do provide feedback... I've used some suggestions from other answers, but I still feel like this is not the best solution!
//FormType
use Symfony\Component\Yaml\Parser;
function getRolesNames(){
$pathToSecurity = /var/mydirectory/app/config/security.yml
$yaml = new Parser();
$rolesArray = $yaml->parse(file_get_contents($pathToSecurity ));
return $rolesArray['security']['role_hierarchy']['ROLE_USER'];
}
This is so far the best way i found to get or set what i want from config files.
Bon courage