2015-07-15 2 views
1

Этот вопрос похож на Symfony2: Getting the list of user roles in FormBuilder, но ответы там привязаны к любой форме, но мой вопрос относится только к форме, созданной пользователем Bundle. Проблема заключается в том, что UserBundle контроллер создает форму, как это:Добавить список ролей в FOS Userbundle Профиль Редактировать форму

$form = $this->container->get('fos_user.profile.form'); 

Из-за этого я не знаю, как отправить роли моей формы типа.

ответ

2

Мой ответ аналогичен тому, что сказал @Mihai Aurelian на similar question.

создал сервис под названием Роль Helper:

<?php 

namespace AppBundle\Services; 

/** 
* Roles helper displays roles set in config. 
*/ 
class RolesHelper 
{ 
    private $rolesHierarchy; 

    public function __construct($rolesHierarchy) 
    { 
    $this->rolesHierarchy = $rolesHierarchy; 
    } 

    /** 
    * Return roles. 
    * 
    * @return array 
    */ 
    public function getRoles() 
    { 
    $roles = array(); 

    array_walk_recursive($this->rolesHierarchy, function($val) use (&$roles) { 
     $roles[] = $val; 
    }); 

    return array_unique($roles); 
    } 
} 

переписал Тип формы с использованием Overriding Default FOSUserBundle Forms инструкции и обновленный Constructer по умолчанию включить RolesHelper в качестве аргумента.

<?php 

namespace AppBundle\Form\Type; 

use Symfony\Component\Form\FormBuilderInterface; 
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType; 
use AppBundle\Services\RolesHelper; 

class UserType extends BaseType 
{ 
    /** 
    * @var RolesHelper 
    */ 
    private $roles; 

    /** 
    * @param string $class The User class name 
    * @param RolesHelper $roles Array or roles. 
    */ 
    public function __construct($class, RolesHelper $roles) 
    { 
    parent::__construct($class); 

    $this->roles = $roles; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
    parent::buildForm($builder, $options); 

    $builder->add('firstName') 
      ->add('lastName') 
      ->add('roles', 'choice', array(
       'choices' => $this->roles->getRoles(), 
       'required' => false, 
       'multiple'=>true 
      )); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getName() 
    { 
    return 'user_registration'; 
    } 
} 

Обновлено services.yml

app_roles_helper: 
    class: AppBundle\Services\RolesHelper 
    arguments: ['%security.role_hierarchy.roles%'] 

Добавлен второй аргумент app_user.registration.form.type в services.yml:

app_user.registration.form.type: 
    class: AppBundle\Form\Type\UserType 
    arguments: [%fos_user.model.user.class%, @app_roles_helper] 
    tags: 
    - { name: form.type, alias: user_registration } 
0

Я не могу комментировать, так что я Я сделаю свой комментарий как ответ. Как вы написали свою функцию getRoles, она вернет позицию массива как роли, что-то вроде, если у вас есть трехпозиционный массив, он будет возвращать 0,1,2 в качестве вариантов вместо имен ролей. Тогда я попытался что-то другое в этой строке, вместо:

array_walk_recursive($this->rolesHierarchy, function($val) use (&$roles) { 
    $roles[] = $val; 
}); 

Я поставил

array_walk_recursive($this->rolesHierarchy, function($val) use (&$roles) { 
    $roles[$val] = $val; 
}); 

Это решило проблему возвращения числовых позиций массива вместо имен ролей. Но возникла проблема, для иерархии, как это:

role_hierarchy: 
    ROLE_ADMIN:  ROLE_USER 
    ROLE_SUPER_ADMIN: [ ROLE_ADMIN, ROLE_TEST ] 

Было бы только вернуть ROLE_USER, ROLE_ADMIN и ROLE_TEST, но для Symfony, ROLE_ADMIN и ROLE_SUPER_ADMIN являются роли тоже. Проблема заключается в том, что array_walk_recursive не переходит к функции обратного вызова, ключ которой является значением массива. Поскольку ROLE_ADMIN является ARRAY (1) => ([0] => (строка) ROLE_USER), а ROLE_SUPER_ADMIN - ARRAY (2) => ([0] => (строка) ROLE_ADMIN [1] => (строка) ROLE_TEST), оба они будут проигнорированы.

Решение было сделать это:

public function getRoles() { 
    $roles = array(); 

    foreach (array_keys($this->rolesHierarchy) as $key){ 
     $roles[$key] = $key; 
     array_walk_recursive($this->rolesHierarchy[$key], function($val) use (&$roles){ 
      $roles[$val] = $val; 
     }); 
    } 

    return array_unique($roles); 

Ключи массива считаются, сами роли также, что причина включать $ ролей [$ ключ] = $ ключ. И, чтобы пересчитать в каждый из массивов, содержащихся в иерархии:

 array_walk_recursive($this->rolesHierarchy[$key], function($val) use (&$roles){ 
      $roles[$val] = $val; 
     }); 
Смежные вопросы