How to change role hierarchy storage in Symfony2?

前端 未结 6 1236
醉话见心
醉话见心 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条回答
  •  悲&欢浪女
    2020-12-22 21:48

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

    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:

    
        
            %security.role_hierarchy.roles%
            
        
    
    

    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.

提交回复
热议问题