如何在Symfony2中更改角色层次结构存储? [英] How to change role hierarchy storage in Symfony2?

查看:71
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆