AclList   B
last analyzed

Complexity

Total Complexity 52

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Test Coverage

Coverage 83.64%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
eloc 90
dl 0
loc 251
ccs 92
cts 110
cp 0.8364
rs 7.44
c 5
b 0
f 1
wmc 52

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getProviders() 0 2 1
A setProviders() 0 2 1
A getResourceByName() 0 2 1
A loadAcls() 0 5 2
A getRoles() 0 2 1
A getResources() 0 2 1
A loadPermissions() 0 5 2
A elementExistByName() 0 7 3
A getProviderClasses() 0 6 2
A hasCache() 0 7 3
A getAcls() 0 2 1
A getPermissionByName() 0 2 1
A getElementsNames() 0 6 2
A loadRoles() 0 5 2
A getElementByName() 0 7 3
A __construct() 0 3 1
A isAllowed() 0 12 4
A addProvider() 0 2 1
A getPermissions() 0 2 1
A getRoleByName() 0 2 1
A getAclById_() 0 7 3
A loadResources() 0 5 2
A getProvider() 0 7 3
B getRolePermissionsOn() 0 17 8
A init() 0 14 2

How to fix   Complexity   

Complex Class

Complex classes like AclList often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AclList, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Ubiquity\security\acl\models;
3
4
use Ubiquity\security\acl\persistence\AclProviderInterface;
5
use Ubiquity\exceptions\AclException;
6
use Ubiquity\security\acl\models\traits\AclListOperationsTrait;
7
use Ubiquity\security\acl\models\traits\AclListQueryTrait;
8
use Ubiquity\security\acl\persistence\AclCacheProvider;
9
10
/**
11
 * Ubiquity\security\acl\models$AclList
12
 * This class is part of Ubiquity
13
 *
14
 * @author jc
15
 * @version 1.0.1
16
 *
17
 */
18
class AclList {
19
	use AclListOperationsTrait,AclListQueryTrait;
20
21
	/**
22
	 *
23
	 * @var AclElement[]
24
	 */
25
	protected $acls;
26
27
	/**
28
	 *
29
	 * @var Role[]
30
	 */
31
	protected $roles;
32
33
	/**
34
	 *
35
	 * @var \Ubiquity\security\acl\models\Resource[]
36
	 */
37
	protected $resources;
38
39
	/**
40
	 *
41
	 * @var Permission[]
42
	 */
43
	protected $permissions;
44
45
	/**
46
	 *
47
	 * @var AclProviderInterface[]
48
	 */
49
	protected $providers = [];
50
51
	protected $elementsCache = [];
52
53 21
	protected function getElementByName(string $name, array $inArray, string $type) {
54 21
		foreach ($inArray as $elm) {
55 21
			if ($elm->getName() == $name) {
56 20
				return $elm;
57
			}
58
		}
59 7
		throw new AclException("$name does not exist in $type ACL");
60
	}
61
62 6
	protected function elementExistByName(string $name, array $inArray): bool {
63 6
		foreach ($inArray as $elm) {
64 6
			if ($elm->getName() == $name) {
65 5
				return true;
66
			}
67
		}
68 6
		return false;
69
	}
70
71 25
	public function __construct() {
72 25
		$this->providers = [];
73 25
		$this->init();
74
	}
75
76 25
	public function init() {
77 25
		$this->roles = [
78 25
			'@ALL' => new Role('@ALL')
79 25
		];
80 25
		$this->resources = [
81 25
			'*' => new Resource('*')
82 25
		];
83 25
		$this->permissions = [
84 25
			'ALL' => new Permission('ALL', 1000)
85 25
		];
86 25
		$this->elementsCache = [];
87 25
		$this->acls = [];
88 25
		foreach ($this->providers as $prov) {
89 3
			$prov->clearAll();
90
		}
91
	}
92
93 21
	public function getRoleByName(string $name) {
94 21
		return $this->elementsCache[$name] ??= $this->getElementByName($name, $this->roles, 'roles');
95
	}
96
97 13
	public function getResourceByName(string $name) {
98 13
		return $this->elementsCache[$name] ??= $this->getElementByName($name, $this->resources, 'resources');
99
	}
100
101 16
	public function getPermissionByName(string $name) {
102 16
		return $this->elementsCache[$name] ??= $this->getElementByName($name, $this->permissions, 'permissions');
103
	}
104
105 10
	public function loadAcls(): array {
106 10
		foreach ($this->providers as $provider) {
107 10
			$this->acls += $provider->loadAllAcls();
108
		}
109 10
		return $this->acls;
110
	}
111
112 10
	public function loadRoles(): array {
113 10
		foreach ($this->providers as $provider) {
114 10
			$this->roles += $provider->loadAllRoles();
115
		}
116 10
		return $this->roles;
117
	}
118
119 10
	public function loadResources(): array {
120 10
		foreach ($this->providers as $provider) {
121 10
			$this->resources += $provider->loadAllResources();
122
		}
123 10
		return $this->resources;
124
	}
125
126 10
	public function loadPermissions(): array {
127 10
		foreach ($this->providers as $provider) {
128 10
			$this->permissions+=$provider->loadAllPermissions();
129
		}
130 10
		return $this->permissions;
131
	}
132
133
	public function addProvider(AclProviderInterface $provider) {
134
		$this->providers[] = $provider;
135
	}
136
137
	/**
138
	 *
139
	 * @return AclElement[]
140
	 */
141 6
	public function getAcls() {
142 6
		return $this->acls;
143
	}
144
145
	/**
146
	 *
147
	 * @return Role[]
148
	 */
149 8
	public function getRoles() {
150 8
		return $this->roles;
151
	}
152
153
	/**
154
	 *
155
	 * @return \Ubiquity\security\acl\models\Resource[]
156
	 */
157 7
	public function getResources() {
158 7
		return $this->resources;
159
	}
160
161
	/**
162
	 *
163
	 * @return Permission[]
164
	 */
165 11
	public function getPermissions() {
166 11
		return $this->permissions;
167
	}
168
169
	/**
170
	 *
171
	 * @return AclProviderInterface[]
172
	 */
173 3
	public function getProviders() {
174 3
		return $this->providers;
175
	}
176
177
	/**
178
	 *
179
	 * @param AclProviderInterface[] $providers
180
	 */
181 11
	public function setProviders($providers) {
182 11
		$this->providers = $providers;
183
	}
184
185 20
	public function getRolePermissionsOn(string $roleName, $resourceName = '*'): array {
186 20
		$role = $this->getRoleByName($roleName);
187 19
		$parents = $role->getParentsArray();
188 19
		$result = [];
189 19
		foreach ($this->acls as $aclElement) {
190 16
			$aclRoleName = $aclElement->getRole()->getName();
191 16
			if ($aclRoleName === '@ALL' || $aclRoleName === $roleName) {
192 16
				$aclResourceName = $aclElement->getResource()->getName();
193 16
				if ($aclResourceName === '*' || $aclResourceName === $resourceName || \strpos($resourceName, $aclResourceName.'.')!==false) {
194 16
					$result[] = $aclElement;
195
				}
196
			}
197
		}
198 19
		foreach ($parents as $parentElm) {
199 4
			$result += $this->getRolePermissionsOn($parentElm, $resourceName);
200
		}
201 19
		return $result;
202
	}
203
204 20
	public function isAllowed(string $roleName, string $resourceName, string $permissionName) {
205 20
		$acls = $this->getRolePermissionsOn($roleName, $resourceName);
206 19
		if (\count($acls) > 0) {
207 16
			$permissionLevel = $this->getPermissionByName($permissionName)->getLevel();
208 15
			foreach ($acls as $aclElm) {
209 15
				$level = $aclElm->getPermission()->getLevel();
210 15
				if ($level >= $permissionLevel) {
211 15
					return true;
212
				}
213
			}
214
		}
215 15
		return false;
216
	}
217
218
	/**
219
	 *
220
	 * @param string $providerClass
221
	 * @return \Ubiquity\security\acl\persistence\AclProviderInterface|NULL
222
	 */
223 2
	public function getProvider(string $providerClass) {
224 2
		foreach ($this->providers as $prov) {
225 2
			if ($prov instanceof $providerClass) {
226 2
				return $prov;
227
			}
228
		}
229
		return null;
230
	}
231
232
	/**
233
	 *
234
	 * @param string $id_
235
	 * @return ?AclElement
236
	 */
237
	public function getAclById_(string $id_): ?AclElement {
238
		foreach ($this->acls as $acl) {
239
			if ($acl->getId_() === $id_) {
240
				return $acl;
241
			}
242
		}
243
		return null;
244
	}
245
246 1
	public function getProviderClasses() {
247 1
		$result = [];
248 1
		foreach ($this->providers as $prov) {
249 1
			$result[] = \get_class($prov);
250
		}
251 1
		return $result;
252
	}
253
254
	public function hasCache() {
255
		foreach ($this->providers as $prov) {
256
			if ($prov instanceof AclCacheProvider) {
257
				return true;
258
			}
259
		}
260
		return false;
261
	}
262
263
	public function getElementsNames($part) {
264
		$result = [];
265
		foreach ($this->$part as $elm) {
266
			$result[] = $elm->__toString();
267
		}
268
		return $result;
269
	}
270
}
271
272