add zend acl implementation
[GitHub/Stricted/Domain-Control-Panel.git] / vendor / Zend / Permissions / Acl / Role / Registry.php
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10 namespace Zend\Permissions\Acl\Role;
11
12 use Traversable;
13 use Zend\Permissions\Acl\Exception;
14
15 class Registry
16 {
17 /**
18 * Internal Role registry data storage
19 *
20 * @var array
21 */
22 protected $roles = [];
23
24 /**
25 * Adds a Role having an identifier unique to the registry
26 *
27 * The $parents parameter may be a reference to, or the string identifier for,
28 * a Role existing in the registry, or $parents may be passed as an array of
29 * these - mixing string identifiers and objects is ok - to indicate the Roles
30 * from which the newly added Role will directly inherit.
31 *
32 * In order to resolve potential ambiguities with conflicting rules inherited
33 * from different parents, the most recently added parent takes precedence over
34 * parents that were previously added. In other words, the first parent added
35 * will have the least priority, and the last parent added will have the
36 * highest priority.
37 *
38 * @param RoleInterface $role
39 * @param RoleInterface|string|array|Traversable $parents
40 * @throws Exception\InvalidArgumentException
41 * @return Registry Provides a fluent interface
42 */
43 public function add(RoleInterface $role, $parents = null)
44 {
45 $roleId = $role->getRoleId();
46
47 if ($this->has($roleId)) {
48 throw new Exception\InvalidArgumentException(sprintf(
49 'Role id "%s" already exists in the registry',
50 $roleId
51 ));
52 }
53
54 $roleParents = [];
55
56 if (null !== $parents) {
57 if (!is_array($parents) && !$parents instanceof Traversable) {
58 $parents = [$parents];
59 }
60 foreach ($parents as $parent) {
61 try {
62 if ($parent instanceof RoleInterface) {
63 $roleParentId = $parent->getRoleId();
64 } else {
65 $roleParentId = $parent;
66 }
67 $roleParent = $this->get($roleParentId);
68 } catch (\Exception $e) {
69 throw new Exception\InvalidArgumentException(sprintf(
70 'Parent Role id "%s" does not exist',
71 $roleParentId
72 ), 0, $e);
73 }
74 $roleParents[$roleParentId] = $roleParent;
75 $this->roles[$roleParentId]['children'][$roleId] = $role;
76 }
77 }
78
79 $this->roles[$roleId] = [
80 'instance' => $role,
81 'parents' => $roleParents,
82 'children' => [],
83 ];
84
85 return $this;
86 }
87
88 /**
89 * Returns the identified Role
90 *
91 * The $role parameter can either be a Role or a Role identifier.
92 *
93 * @param RoleInterface|string $role
94 * @throws Exception\InvalidArgumentException
95 * @return RoleInterface
96 */
97 public function get($role)
98 {
99 if ($role instanceof RoleInterface) {
100 $roleId = $role->getRoleId();
101 } else {
102 $roleId = (string) $role;
103 }
104
105 if (!$this->has($role)) {
106 throw new Exception\InvalidArgumentException("Role '$roleId' not found");
107 }
108
109 return $this->roles[$roleId]['instance'];
110 }
111
112 /**
113 * Returns true if and only if the Role exists in the registry
114 *
115 * The $role parameter can either be a Role or a Role identifier.
116 *
117 * @param RoleInterface|string $role
118 * @return bool
119 */
120 public function has($role)
121 {
122 if ($role instanceof RoleInterface) {
123 $roleId = $role->getRoleId();
124 } else {
125 $roleId = (string) $role;
126 }
127
128 return isset($this->roles[$roleId]);
129 }
130
131 /**
132 * Returns an array of an existing Role's parents
133 *
134 * The array keys are the identifiers of the parent Roles, and the values are
135 * the parent Role instances. The parent Roles are ordered in this array by
136 * ascending priority. The highest priority parent Role, last in the array,
137 * corresponds with the parent Role most recently added.
138 *
139 * If the Role does not have any parents, then an empty array is returned.
140 *
141 * @param RoleInterface|string $role
142 * @return array
143 */
144 public function getParents($role)
145 {
146 $roleId = $this->get($role)->getRoleId();
147
148 return $this->roles[$roleId]['parents'];
149 }
150
151 /**
152 * Returns true if and only if $role inherits from $inherit
153 *
154 * Both parameters may be either a Role or a Role identifier. If
155 * $onlyParents is true, then $role must inherit directly from
156 * $inherit in order to return true. By default, this method looks
157 * through the entire inheritance DAG to determine whether $role
158 * inherits from $inherit through its ancestor Roles.
159 *
160 * @param RoleInterface|string $role
161 * @param RoleInterface|string $inherit
162 * @param bool $onlyParents
163 * @throws Exception\InvalidArgumentException
164 * @return bool
165 */
166 public function inherits($role, $inherit, $onlyParents = false)
167 {
168 try {
169 $roleId = $this->get($role)->getRoleId();
170 $inheritId = $this->get($inherit)->getRoleId();
171 } catch (Exception\ExceptionInterface $e) {
172 throw new Exception\InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
173 }
174
175 $inherits = isset($this->roles[$roleId]['parents'][$inheritId]);
176
177 if ($inherits || $onlyParents) {
178 return $inherits;
179 }
180
181 foreach ($this->roles[$roleId]['parents'] as $parentId => $parent) {
182 if ($this->inherits($parentId, $inheritId)) {
183 return true;
184 }
185 }
186
187 return false;
188 }
189
190 /**
191 * Removes the Role from the registry
192 *
193 * The $role parameter can either be a Role or a Role identifier.
194 *
195 * @param RoleInterface|string $role
196 * @throws Exception\InvalidArgumentException
197 * @return Registry Provides a fluent interface
198 */
199 public function remove($role)
200 {
201 try {
202 $roleId = $this->get($role)->getRoleId();
203 } catch (Exception\ExceptionInterface $e) {
204 throw new Exception\InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
205 }
206
207 foreach ($this->roles[$roleId]['children'] as $childId => $child) {
208 unset($this->roles[$childId]['parents'][$roleId]);
209 }
210 foreach ($this->roles[$roleId]['parents'] as $parentId => $parent) {
211 unset($this->roles[$parentId]['children'][$roleId]);
212 }
213
214 unset($this->roles[$roleId]);
215
216 return $this;
217 }
218
219 /**
220 * Removes all Roles from the registry
221 *
222 * @return Registry Provides a fluent interface
223 */
224 public function removeAll()
225 {
226 $this->roles = [];
227
228 return $this;
229 }
230
231 /**
232 * Get all roles in the registry
233 *
234 * @return array
235 */
236 public function getRoles()
237 {
238 return $this->roles;
239 }
240 }