繁体   English   中英

在sonata admin的编辑形式中为用户设置角色

[英]set role for users in edit form of sonata admin

我正在使用Symfony 2.1进行项目。 我使用FOSUserBundle管理用户和SonataAdminBundle管理用法。

我有一些问题:

  1. 作为管理员,我想在用户编辑表单中设置用户角色。 如何访问role_hierarchy角色? 我如何将它们用作选择字段,以便管理员可以为用户设置角色?

  2. 当我在列表中显示角色时,它显示为如下字符串:

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

    我该如何改变它呢?

     ROLE_SUPER_ADMIN, ROLE_USER 

    我的意思是,只有数组的值。

根据@parisssss的答案虽然这是错误的,但这是一个有效的解决方案。 如果您保存一个角色,Sonata输入字段将显示给定角色下的所有角色。

另一方面,在数据库中将只存储最重要的角色。 但这在Sf方式中具有绝对意义。

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
        )
    );

而在另一种方法:

/**
 * Turns the role's 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;
}

看到它的实际效果:

在此输入图像描述在此输入图像描述

至于第二个问题,我在User类中添加了一个看起来像这样的方法

/**
 * @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);
 }

然后你可以在configureListFields函数中声明:

->add('rolesAsString', 'string')

我找到了第一个问题的答案!(但第二个问题尚未解答..)我在configureFormFields函数中添加如下角色:

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

如果有人回答第二个问题我会很高兴:)

Romain Bruckert的解决方案几乎是完美的,除了它不允许设置角色,这是角色层次结构的根源。 例如ROLE_SUPER_ADMIN。 这是固定方法flattenRoles,它还返回根角色:

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;
}

编辑:TrtG已在评论中发布此修复程序

只是为了夸大它,这是我的Romain Bruckert和Sash的增强版本,它给你一个这样的数组:

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))"
]

在此输入图像描述

这有助于您找到包含特定角色的所有角色 在此输入图像描述

我知道它的代码很多,它可以做得更好,但也许它可以帮助某人或者你至少可以使用这段代码。

/**
 * Turns the role's 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)));
}

第二个答案如下。 在sonata admin yml文件中添加行。

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

并在user_roles.html.twig文件中添加以下行

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}
    {% for row in value %}
        {{row}}
        {% if not loop.last %}
        ,
        {% endif %}
    {% endfor %}
{% endblock %}

然后进入你的管理控制器并在configureListFields函数中添加这一行

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

希望这能解决你的问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM