Symfony2:获取FormBuilder中的用户角色列表

Gab*_*ron 17 php symfony fosuserbundle

我正在创建一个用户创建表单,我想在创建用户时为用户提供一个或多个角色.

如何获取定义的角色列表security.yml

这是我目前的表单构建器:

public function buildForm(FormBuilder $builder, array $options)
{
    parent::buildForm($builder, $options);

    // add your custom fields
    $user = new User();
    $builder->add('regionUser');
    $builder->add('roles' ,'choice' ,array('choices' => $user->getRolesNames(),
            'required'  => true,
    ));

}
Run Code Online (Sandbox Code Playgroud)

并在User.php中

public function getRolesNames(){
    return array(
        "ADMIN" => "Administrateur",
        "ANIMATOR" => "Animateur",
        "USER" => "Utilisateur",        
    );
}
Run Code Online (Sandbox Code Playgroud)

当然,此解决方案不起作用,因为roles在数据库中定义为位图,因此choices无法创建列表.

提前致谢.

Mun*_*Das 19

security.role_hierarchy.rolescontainer参数将角色层次结构保存为数组.您可以将其概括为获取定义的角色列表.

  • 对于那些没有得到它意味着什么的人,在你的控制器中使用它:$ roles = $ this-> get('security.role_hierarchy'); (16认同)
  • 不知道什么时候改变了,但在2.5中它是'security.role_hierarchy' (4认同)

Alt*_*PHP 13

您可以从此方法获取可访问角色的列表:

Symfony\Component\Security\Core\Role\RoleHierarchy::getReachableRoles(array $roles)
Run Code Online (Sandbox Code Playgroud)

它似乎返回可从数组$roles参数中的角色访问的所有角色.它是Symfony的内部服务,其ID是非security.role_hierarchy公开的(您必须明确地将其作为参数传递,它不能从Service Container中获取).


Tim*_*ius 9

为了正确表示您的角色,您需要递归.角色可以扩展其他角色.

我在security.yml中使用以下角色作为示例:

ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN:       ROLE_USER
ROLE_TEST:        ROLE_USER
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式获得此角色

$originalRoles = $this->getParameter('security.role_hierarchy.roles');
Run Code Online (Sandbox Code Playgroud)

递归的一个例子:

private function getRoles($originalRoles)
{
    $roles = array();

    /**
     * Get all unique roles
     */
    foreach ($originalRoles as $originalRole => $inheritedRoles) {
        foreach ($inheritedRoles as $inheritedRole) {
            $roles[$inheritedRole] = array();
        }

        $roles[$originalRole] = array();
    }

    /**
     * Get all inherited roles from the unique roles
     */
    foreach ($roles as $key => $role) {
        $roles[$key] = $this->getInheritedRoles($key, $originalRoles);
    }

    return $roles;
}

private function getInheritedRoles($role, $originalRoles, $roles = array())
{
    /**
     * If the role is not in the originalRoles array,
     * the role inherit no other roles.
     */
    if (!array_key_exists($role, $originalRoles)) {
        return $roles;
    }

    /**
     * Add all inherited roles to the roles array
     */
    foreach ($originalRoles[$role] as $inheritedRole) {
        $roles[$inheritedRole] = $inheritedRole;
    }

    /**
     * Check for each inhered role for other inherited roles
     */
    foreach ($originalRoles[$role] as $inheritedRole) {
        return $this->getInheritedRoles($inheritedRole, $originalRoles, $roles);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

array (
  'ROLE_USER' => array(),
  'ROLE_TEST' => array(
                        'ROLE_USER' => 'ROLE_USER',
  ),
  'ROLE_ADMIN' => array(
                        'ROLE_USER' => 'ROLE_USER',
  ),
  'ROLE_SUPER_ADMIN' => array(
                        'ROLE_ADMIN' => 'ROLE_ADMIN',
                        'ROLE_USER' => 'ROLE_USER',
  ),
)
Run Code Online (Sandbox Code Playgroud)


Mih*_*ian 8

您可以为此创建服务并注入"security.role_hierarchy.roles"参数.

服务定义:

acme.user.roles:
   class: Acme\DemoBundle\Model\RolesHelper
   arguments: ['%security.role_hierarchy.roles%']
Run Code Online (Sandbox Code Playgroud)

服务类别:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以像下面这样在控制器中获取角色:

$roles = $this->get('acme.user.roles')->getRoles();
Run Code Online (Sandbox Code Playgroud)