diff options
Diffstat (limited to 'Core/Role/RoleHierarchy.php')
-rw-r--r-- | Core/Role/RoleHierarchy.php | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/Core/Role/RoleHierarchy.php b/Core/Role/RoleHierarchy.php new file mode 100644 index 0000000..9556801 --- /dev/null +++ b/Core/Role/RoleHierarchy.php @@ -0,0 +1,77 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien.potencier@symfony-project.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Core\Role; + +/** + * RoleHierarchy defines a role hierarchy. + * + * @author Fabien Potencier <fabien.potencier@symfony-project.com> + */ +class RoleHierarchy implements RoleHierarchyInterface +{ + protected $hierarchy; + protected $map; + + /** + * Constructor. + * + * @param array $hierarchy An array defining the hierarchy + */ + public function __construct(array $hierarchy) + { + $this->hierarchy = $hierarchy; + + $this->buildRoleMap(); + } + + /** + * Returns an array of all roles reachable by the given ones. + * + * @param RoleInterface[] $roles An array of RoleInterface instances + * + * @return RoleInterface[] An array of RoleInterface instances + */ + public function getReachableRoles(array $roles) + { + $reachableRoles = $roles; + foreach ($roles as $role) { + if (!isset($this->map[$role->getRole()])) { + continue; + } + + foreach ($this->map[$role->getRole()] as $r) { + $reachableRoles[] = new Role($r); + } + } + + return $reachableRoles; + } + + protected function buildRoleMap() + { + $this->map = array(); + foreach ($this->hierarchy as $main => $roles) { + $this->map[$main] = $roles; + $visited = array(); + $additionalRoles = $roles; + while ($role = array_shift($additionalRoles)) { + if (!isset($this->hierarchy[$role])) { + continue; + } + + $visited[] = $role; + $this->map[$main] = array_unique(array_merge($this->map[$main], $this->hierarchy[$role])); + $additionalRoles = array_merge($additionalRoles, array_diff($this->hierarchy[$role], $visited)); + } + } + } +} |