Intereting Posts
динамически вставлять данные в таблицу mysql MySQL после обновления и после запуска Триггеры сбой при вводе строки mysql_result () ожидает, что параметр 1 будет ресурсом, boolean given Как обновить раскрывающийся список без обновления страницы? Защищенные страницы с PHP / .htaccess? Войдите в файл через PHP или войдите в базу данных MySQL – что быстрее? Как сделать autocut ячеек после определенного числа и начать новую строку Перенос переменных между страницами PHP Получить URL-адрес категории в Magento при создании пользовательского меню Ответ XML содержит символы «2000» и «20a0» Как я могу заставить PHP отображать заголовки, полученные из браузера? Различные методы кэширования файлов, плюсы и минусы PHP – функция раскрывающегося списка, которая удерживает текущую страницу в фокусе Расширить класс запроса в Laravel 5 Редактирование цикла wordpress для отображения эскизов и выдержки

Symfony2: получение списка пользовательских ролей в FormBuilder

Я создаю форму для создания пользователя, и я хочу дать одну или несколько ролей пользователю, когда я его создам.

Как получить список ролей, определенных в 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, )); } 

и в User.php

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

Конечно, это решение не работает, потому что roles определяются как растровые изображения в базе данных, поэтому список choices не может быть создан.

Заранее спасибо.

Related of "Symfony2: получение списка пользовательских ролей в FormBuilder"

Параметр security.role_hierarchy.roles хранит иерархию роли как массив. Вы можете обобщить его, чтобы получить список определенных ролей.

Вы можете получить список достижимых ролей из этого метода:

 Symfony\Component\Security\Core\Role\RoleHierarchy::getReachableRoles(array $roles) 

Кажется, он возвращает все роли, доступные из ролей в параметре array $roles . Это внутренняя служба Symfony, идентификатор которой является security.role_hierarchy и не является общедоступным (вы должны явно передать его как параметры, это не доступно из Service Container).

Вы можете сделать сервис для этого и ввести параметр «security.role_hierarchy.roles».

Определение услуги:

 acme.user.roles: class: Acme\DemoBundle\Model\RolesHelper arguments: ['%security.role_hierarchy.roles%'] 

Класс обслуживания:

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

Вы можете получить роли в своем контроллере следующим образом:

 $roles = $this->get('acme.user.roles')->getRoles(); 

Для правильного представления ваших ролей вам нужна рекурсия. Роли могут распространять другие роли.

Я использую для примера следующие роли в security.yml:

 ROLE_SUPER_ADMIN: ROLE_ADMIN ROLE_ADMIN: ROLE_USER ROLE_TEST: ROLE_USER 

Вы можете получить следующие роли:

 $originalRoles = $this->getParameter('security.role_hierarchy.roles'); 

Пример с рекурсией:

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

Выход:

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

В Symfony 3.3 вы можете создать RolesType.php следующим образом:

 <?php namespace AppBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; /** * @author Echarbeto */ class RolesType extends AbstractType { private $roles = []; public function __construct(RoleHierarchyInterface $rolehierarchy) { $roles = array(); array_walk_recursive($rolehierarchy, function($val) use (&$roles) { $roles[$val] = $val; }); ksort($roles); $this->roles = array_unique($roles); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'choices' => $this->roles, 'attr' => array( 'class' => 'form-control', 'aria-hidden' => 'true', 'ref' => 'input', 'multiple' => '', 'tabindex' => '-1' ), 'required' => true, 'multiple' => true, 'empty_data' => null, 'label_attr' => array( 'class' => 'control-label' ) )); } public function getParent() { return ChoiceType::class; } } 

Затем добавьте его в форму следующим образом:

 $builder->add('roles', RolesType::class,array( 'label' => 'Roles' )); 

Важно также, чтобы каждая роль также содержалась, например: ROLE_ADMIN: [ROLE_ADMIN, ROLE_USER]

В Symfony 2.7 в контроллерах вы должны использовать $ this-> getParameters () для получения ролей:

 $roles = array(); foreach ($this->getParameter('security.role_hierarchy.roles') as $key => $value) { $roles[] = $key; foreach ($value as $value2) { $roles[] = $value2; } } $roles = array_unique($roles); 

Это не совсем то, что вы хотите, но это заставляет ваш пример работать:

 use Vendor\myBundle\Entity\User; 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, )); } 

Но в отношении получения ваших ролей от сущности, возможно, вы можете использовать материал репозитория сущности для запроса базы данных.

Вот хороший пример, чтобы получить то, что нужно, используя queryBuilder в репозитории объектов :

 public function buildForm(FormBuilder $builder, array $options) { parent::buildForm($builder, $options); // add your custom fields $user = new User(); $builder->add('regionUser'); $builder->add('roles' ,'entity' array( 'class'=>'Vendor\MyBundle\Entity\User', 'property'=>'roles', 'query_builder' => function (\Vendor\MyBundle\Entity\UserRepository $repository) { return $repository->createQueryBuilder('s') ->add('orderBy', 's.sort_order ASC'); } ) ); } 

http://inchoo.net/tools-frameworks/symfony2-entity-field-type/

Если вам нужно получить все унаследованные роли определенной роли:

 use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\RoleHierarchy; private function getRoles($role) { $hierarchy = $this->container->getParameter('security.role_hierarchy.roles'); $roleHierarchy = new RoleHierarchy($hierarchy); $roles = $roleHierarchy->getReachableRoles([new Role($role)]); return array_map(function(Role $role) { return $role->getRole(); }, $roles); } 

Затем назовите этот functon: $this->getRoles('ROLE_ADMIN');

 //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']; } 

Это пока что лучший способ найти или установить то, что я хочу, из файлов конфигурации.

Божество

Вот что я сделал:

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

В объекте:

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

Пожалуйста, предоставьте отзыв … Я использовал некоторые предложения из других ответов, но я все еще чувствую, что это не лучшее решение!