4

プロジェクトに Symfony 2.1 を使用しています。ユーザーの管理には FOSUserBundle を使用し、管理の使用には SonataAdminBundle を使用します。

それについていくつか質問があります:

  1. 管理者として、ユーザー編集フォームでユーザーからロールを設定したいと考えています。のロールにアクセスするにはどうすればよいrole_hierarchyですか? また、管理者がユーザーにロールを設定できるように、それらを選択フィールドとして使用するにはどうすればよいですか?

  2. リストにロールを表示すると、次のような文字列として表示されます。

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

    どうすればこれに変更できますか?

    ROLE_SUPER_ADMIN, ROLE_USER 
    

    つまり、配列の値だけを持っています。

4

6 に答える 6

12

@parisssssの回答に基づいていますが、間違っていましたが、これが実用的な解決策です。Sonata の入力フィールドには、ロールを 1 つ保存すると、そのロールの下にあるすべてのロールが表示されます。

一方、データベースには最も重要なロールのみが格納されます。しかし、それは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;
}

実際に見てみましょう:

ここに画像の説明を入力 ここに画像の説明を入力

于 2015-05-07T15:14:32.910 に答える
10

2番目の質問については、次のような 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')
于 2014-06-18T08:20:17.690 に答える
2

Romain Bruckert のソリューションは、ロール階層のルートであるロールを設定できないことを除けば、ほぼ完璧です。たとえば、ROLE_SUPER_ADMIN です。root ロールも返す固定メソッド 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はすでにこの修正をコメントに投稿しています

于 2016-08-12T11:21:41.907 に答える
2

私は最初の質問に対する答えを見つけました!(しかし、2番目の質問はまだ答えられていません..)configureFormFields関数に以下のような役割を追加します:

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

誰かが2番目の質問に答えてくれたらとても嬉しいです:)

于 2013-02-24T19:49:51.687 に答える
2

少し大げさに言うと、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)));
}
于 2016-11-01T01:20:51.300 に答える
1

2番目の答えは以下です。sonata admin yml file に行を追加します。

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

これがあなたの問題を解決することを願っています

于 2014-09-29T10:39:10.417 に答える