How to change role hierarchy storage in Symfony2?

前端 未结 6 1228
醉话见心
醉话见心 2020-12-22 21:32

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

6条回答
  •  -上瘾入骨i
    2020-12-22 21:45

    My solution was inspired by the solution provided by zls. His solution worked perfectly for me, but the one-to-many relation between the roles meant having one huge role tree, which would become hard to maintain. Also, a problem might occur if two different roles wanted to inherit one same role (as there could only be one parent). That's why I decided to create a many-to-many solution. Instead of having only the parent in the role class, I have first put this in the role class:

    /**
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="role_permission",
     *      joinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
     *      )
     */
    protected $children;
    

    After that I rewrote the buildRolesTree function like so:

    private function buildRolesTree()
    {
        $hierarchy = array();
        $roles = $this->em->createQuery('select r, p from AltGrBaseBundle:Role r JOIN r.children p')->execute();
    
        foreach ($roles as $role)
        {
            /* @var $role Role */
            if (count($role->getChildren()) > 0)
            {
                $roleChildren = array();
    
                foreach ($role->getChildren() as $child)
                {
                    /* @var $child Role */
                    $roleChildren[] = $child->getRole();
                }
    
                $hierarchy[$role->getRole()] = $roleChildren;
            }
        }
    
        return $hierarchy;
    }
    

    The result is the ability to create several easily maintained trees. For instance, you can have a tree of roles defining the ROLE_SUPERADMIN role and entirely separate tree defining a ROLE_ADMIN role with several roles shared between them. Although circular connections should be avoided (roles should be laid out as trees, without any circular connections between them), there should be no problems if it actually happens. I haven't tested this, but going through the buildRoleMap code, it is obvious it dumps any duplicates. This should also mean it won't get stuck in endless loops if the circular connection occurs, but this definitely needs more testing.

    I hope this proves helpful to someone.

提交回复
热议问题