如何在Symfony2中更改角色层次结构存储? [英] How to change role hierarchy storage in Symfony2?
问题描述
在我的项目中,我需要将角色层次结构存储在数据库中并动态创建新角色.
在Symfony2中,角色层次结构默认情况下存储在security.yml
中.
我发现了什么:
In my project I need to store role hierarchy in database and create new roles dynamically.
In Symfony2 role hierarchy is stored in security.yml
by default.
What have I found:
有一项服务security.role_hierarchy
(Symfony\Component\Security\Core\Role\RoleHierarchy
);
该服务在构造函数中接收一个角色数组:
There is a service security.role_hierarchy
(Symfony\Component\Security\Core\Role\RoleHierarchy
);
This service receives a roles array in constructor:
public function __construct(array $hierarchy)
{
$this->hierarchy = $hierarchy;
$this->buildRoleMap();
}
,$hierarchy
属性是私有的.
此参数来自\Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension::createRoleHierarchy()
的构造函数
据我所知,它使用了config中的角色:
This argument comes in constructor from \Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension::createRoleHierarchy()
which uses roles from config, as I understood:
$container->setParameter('security.role_hierarchy.roles', $config['role_hierarchy']);
在我看来,最好的方法是从数据库编译一组角色并将其设置为服务的参数.但是我还不知道该怎么做.
It seems me that the best way is to compile an array of roles from database and set it as an argument for the service. But I haven't yet understood how to do it.
我看到的第二种方法是定义从基类继承的我自己的RoleHierarchy
类.但是由于在RoleHierarchy
基类中,$hierarchy
属性被定义为私有属性,所以我将不得不从RoleHierarchy
基类中重新定义所有功能.但是我认为这不是一个好的OOP和Symfony方式...
The second way I see is to define my own RoleHierarchy
class inherited from the base one. But since in the base RoleHierarchy
class the $hierarchy
property is defined as private, than I would have to redefine all the functions from the base RoleHierarchy
class. But I don't think it is a good OOP and Symfony way...
推荐答案
解决方案很简单. 首先,我创建了一个Role实体.
The solution was simple. First I created a Role entity.
class Role
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="Role")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;
...
}
之后,创建了一个RoleHierarchy服务,该服务是从Symfony本机服务扩展而来的.我继承了构造函数,并在其中添加了EntityManager,并为原始构造函数提供了一个新的Roles数组,而不是旧的Roles数组:
after that created a RoleHierarchy service, extended from the Symfony native one. I inherited the constructor, added an EntityManager there and provided an original constructor with a new roles array instead of the old one:
class RoleHierarchy extends Symfony\Component\Security\Core\Role\RoleHierarchy
{
private $em;
/**
* @param array $hierarchy
*/
public function __construct(array $hierarchy, EntityManager $em)
{
$this->em = $em;
parent::__construct($this->buildRolesTree());
}
/**
* Here we build an array with roles. It looks like a two-levelled tree - just
* like original Symfony roles are stored in security.yml
* @return array
*/
private function buildRolesTree()
{
$hierarchy = array();
$roles = $this->em->createQuery('select r from UserBundle:Role r')->execute();
foreach ($roles as $role) {
/** @var $role Role */
if ($role->getParent()) {
if (!isset($hierarchy[$role->getParent()->getName()])) {
$hierarchy[$role->getParent()->getName()] = array();
}
$hierarchy[$role->getParent()->getName()][] = $role->getName();
} else {
if (!isset($hierarchy[$role->getName()])) {
$hierarchy[$role->getName()] = array();
}
}
}
return $hierarchy;
}
}
...并将其重新定义为服务:
... and redefined it as a service:
<services>
<service id="security.role_hierarchy" class="Acme\UserBundle\Security\Role\RoleHierarchy" public="false">
<argument>%security.role_hierarchy.roles%</argument>
<argument type="service" id="doctrine.orm.default_entity_manager"/>
</service>
</services>
仅此而已. 也许,我的代码中有不必要的东西.也许有可能写得更好.但是我认为,这个主要想法现在很明显.
That's all. Maybe, there is something unnecessary in my code. Maybe it is possible to write better. But I think, that main idea is evident now.
这篇关于如何在Symfony2中更改角色层次结构存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!