RoleHierarchy.php 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Core\Role;
  11. /**
  12. * RoleHierarchy defines a role hierarchy.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. */
  16. class RoleHierarchy implements RoleHierarchyInterface
  17. {
  18. private $hierarchy;
  19. protected $map;
  20. /**
  21. * @param array $hierarchy An array defining the hierarchy
  22. */
  23. public function __construct(array $hierarchy)
  24. {
  25. $this->hierarchy = $hierarchy;
  26. $this->buildRoleMap();
  27. }
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function getReachableRoleNames(array $roles): array
  32. {
  33. $reachableRoles = $roles;
  34. foreach ($roles as $role) {
  35. if (!isset($this->map[$role])) {
  36. continue;
  37. }
  38. foreach ($this->map[$role] as $r) {
  39. $reachableRoles[] = $r;
  40. }
  41. }
  42. return $reachableRoles;
  43. }
  44. protected function buildRoleMap()
  45. {
  46. $this->map = [];
  47. foreach ($this->hierarchy as $main => $roles) {
  48. $this->map[$main] = $roles;
  49. $visited = [];
  50. $additionalRoles = $roles;
  51. while ($role = array_shift($additionalRoles)) {
  52. if (!isset($this->hierarchy[$role])) {
  53. continue;
  54. }
  55. $visited[] = $role;
  56. foreach ($this->hierarchy[$role] as $roleToAdd) {
  57. $this->map[$main][] = $roleToAdd;
  58. }
  59. foreach (array_diff($this->hierarchy[$role], $visited) as $additionalRole) {
  60. $additionalRoles[] = $additionalRole;
  61. }
  62. }
  63. $this->map[$main] = array_unique($this->map[$main]);
  64. }
  65. }
  66. }