Passed
Push — main ( c291e2...a2634b )
by Jean-Christophe
02:27
created

AclDAOProvider::loadAllRoles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 3
b 0
f 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
namespace Ubiquity\security\acl\persistence;
3
4
use Ubiquity\cache\CacheManager;
5
use Ubiquity\cache\ClassUtils;
6
use Ubiquity\controllers\Startup;
7
use Ubiquity\db\reverse\DbGenerator;
8
use Ubiquity\exceptions\AclException;
9
use Ubiquity\orm\DAO;
10
use Ubiquity\orm\reverse\DatabaseReversor;
11
use Ubiquity\scaffolding\creators\ClassCreator;
12
use Ubiquity\security\acl\models\AbstractAclPart;
13
use Ubiquity\security\acl\models\AclElement;
14
use Ubiquity\security\acl\models\Permission;
15
use Ubiquity\security\acl\models\Resource;
16
use Ubiquity\security\acl\models\Role;
17
18
/**
19
 * Load and save Acls with a database using DAO.
20
 * Ubiquity\security\acl\persistence$AclDAOProvider
21
 * This class is part of Ubiquity
22
 *
23
 * @author jc
24
 * @version 1.0.2
25
 *
26
 */
27
class AclDAOProvider implements AclProviderInterface {
28
29
	protected string $aclClass;
30
31
	protected string $roleClass;
32
33
	protected string $permissionClass;
34
35
	protected string $resourceClass;
36
37
	/**
38
	 * @param array $config The $config array
39
	 * @param array $classes
40
	 *        	associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
41
	 */
42 4
	public function __construct(array &$config,$classes = []) {
43 4
		Startup::$config=$config;
44 4
		$this->aclClass = $classes['acl'] ?? AclElement::class;
45 4
		$this->roleClass = $classes['role'] ?? Role::class;
46 4
		$this->resourceClass = $classes['resource'] ?? Resource::class;
47 4
		$this->permissionClass = $classes['permission'] ?? Permission::class;
48
	}
49
50
	/**
51
	 * Initialize the cache for the ACL models.
52
	 * @param $config
53
	 */
54
	public function initModelsCache(&$config) {
55
		CacheManager::start($config);
56
		CacheManager::createOrmModelCache($this->aclClass);
57
		CacheManager::createOrmModelCache($this->roleClass);
58
		CacheManager::createOrmModelCache($this->resourceClass);
59
		CacheManager::createOrmModelCache($this->permissionClass);
60
	}
61
62
	/**
63
	 * Defines the database offset used for ACL.
64
	 * @param string $dbOffset
65
	 * @param  bool $persist
66
	 */
67
	public function setDbOffset(string $dbOffset = 'default',bool $persist=true):void {
68
		DAO::setModelDatabase($this->aclClass, $dbOffset);
69
		DAO::setModelDatabase($this->resourceClass, $dbOffset);
70
		DAO::setModelDatabase($this->roleClass, $dbOffset);
71
		DAO::setModelDatabase($this->permissionClass, $dbOffset);
72
		if($persist){
73
			CacheManager::storeModelsDatabases(DAO::getModelsDatabase ());
74
		}
75
	}
76
77
	/**
78
	 * Generates the models.
79
	 * @param ?array $classes associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
80
	 */
81
	public function createModels(?array $classes=null):void{
82
		$classes??=[
83
			'acl'=>'models\\AclElement','role'=>'models\\Role','resource'=>'models\\Resource','permission'=>'models\\Permission'
84
		];
85
		$this->createModel($classes['acl'] ?? $this->aclClass,AclElement::class);
86
		$this->createModel($classes['role'] ?? $this->roleClass,Role::class);
87
		$this->createModel($classes['resource'] ?? $this->resourceClass,Resource::class);
88
		$this->createModel($classes['permission'] ?? $this->permissionClass,Permission::class);
89
	}
90
91
	public function createModel($modelName,$refName):void{
92
		if($modelName!==$refName){
93
			$className=ClassUtils::getClassSimpleName($modelName);
94
			$ns=ClassUtils::getNamespaceFromCompleteClassname($modelName);
95
			$cCreator=new ClassCreator($className,'',$ns,' extends \\'.$refName);
96
			$cCreator->generate();
97
		}
98
	}
99
100
	/**
101
	 * Generates the tables for ACL model classes.
102
	 * @param string $dbOffset
103
	 * @param bool $createDb
104
	 * @throws AclException
105
	 */
106
	public function generateDbTables(string $dbOffset='default',bool $createDb=false):void{
107
		$this->setDbOffset($dbOffset);
108
		$generator = new DatabaseReversor(new DbGenerator(), $dbOffset);
109
		$activeOffsetValue=DAO::getDbOffset(Startup::$config,$dbOffset);
110
		if(($dbName=$activeOffsetValue['dbName']??'')!='') {
111
			$generator->setModels([$this->aclClass,$this->roleClass,$this->resourceClass,$this->permissionClass]);
112
			$generator->createDatabase($dbName, $createDb);
113
			$db=DAO::getDatabase($dbOffset);
114
			$db->beginTransaction();
115
			$db->execute($generator->__toString());
116
			$db->commit();
117
		}else{
118
			throw new AclException('dbName key is not present or his value is empty!');
119
		}
120
	}
121
122
	/**
123
	 *
124
	 * {@inheritdoc}
125
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllAcls()
126
	 */
127 4
	public function loadAllAcls(): array {
128 4
		return DAO::getAll($this->aclClass);
129
	}
130
131
	/**
132
	 *
133
	 * {@inheritdoc}
134
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::saveAcl()
135
	 */
136 1
	public function saveAcl(AclElement $aclElement) {
137 1
		if(!$this->existPart($aclElement->getResource())){
138
			$this->savePart($aclElement->getResource());
139
		}
140 1
		if(!$this->existPart($aclElement->getPermission())){
141
			$this->savePart($aclElement->getPermission());
142
		}
143 1
		if(!$this->existPart($aclElement->getRole())){
144
			$this->savePart($aclElement->getRole());
145
		}
146 1
		$object = $this->castElement($aclElement);
147 1
		$res = DAO::save($object);
148 1
		if ($res) {
149 1
			$aclElement->setId($object->getId());
150
		}
151 1
		return $res;
152
	}
153
154
	/**
155
	 *
156
	 * {@inheritdoc}
157
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::removeAcl()
158
	 */
159 1
	public function removeAcl(AclElement $aclElement) {
160 1
		return DAO::remove($aclElement);
161
	}
162
163 4
	protected function loadElements(string $className): array {
164 4
		$elements = DAO::getAll($className);
165 4
		$result = [];
166 4
		foreach ($elements as $elm) {
167 4
			$result[$elm->getName()] = $elm;
168
		}
169 4
		return $result;
170
	}
171
172 3
	protected function castElement($part) {
173 3
		$class = $this->getModelClasses()[get_class($part)] ?? get_class($part);
174 3
		return $part->castAs($class);
175
	}
176
177
	/**
178
	 *
179
	 * {@inheritdoc}
180
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllPermissions()
181
	 */
182 4
	public function loadAllPermissions(): array {
183 4
		return $this->loadElements($this->permissionClass);
184
	}
185
186
	/**
187
	 *
188
	 * {@inheritdoc}
189
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllResources()
190
	 */
191 4
	public function loadAllResources(): array {
192 4
		return $this->loadElements($this->resourceClass);
193
	}
194
195
	/**
196
	 *
197
	 * {@inheritdoc}
198
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllRoles()
199
	 */
200 4
	public function loadAllRoles(): array {
201 4
		return $this->loadElements($this->roleClass);
202
	}
203
204
	/**
205
	 *
206
	 * {@inheritdoc}
207
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::savePart()
208
	 */
209 2
	public function savePart(\Ubiquity\security\acl\models\AbstractAclPart $part) {
210 2
		$object = $this->castElement($part);
211 2
		$res = DAO::insert($object);
212 2
		if ($res) {
213 2
			$part->setName($object->getName());
214
		}
215 2
		return $res;
216
	}
217
218
	/**
219
	 *
220
	 * {@inheritdoc}
221
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::updatePart()
222
	 */
223 1
	public function updatePart(\Ubiquity\security\acl\models\AbstractAclPart $part) {
224 1
		return DAO::update($this->castElement($part));
225
	}
226
227
	/**
228
	 *
229
	 * {@inheritdoc}
230
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::removePart()
231
	 */
232 2
	public function removePart(\Ubiquity\security\acl\models\AbstractAclPart $part) {
233 2
		return DAO::remove($this->castElement($part));
234
	}
235
236 1
	public function isAutosave(): bool {
237 1
		return true;
238
	}
239
240
	public function saveAll(): void {}
241
242 1
	public function existPart(AbstractAclPart $part): bool {
243 1
		$elm = $this->castElement($part);
244 1
		return DAO::exists(\get_class($elm), 'name= ?', [
245 1
			$elm->getName()
246 1
		]);
247
	}
248
249 1
	public function existAcl(AclElement $aclElement): bool {
250 1
		$elm = $this->castElement($aclElement);
251 1
		return DAO::exists(\get_class($aclElement), 'id= ?', [
252 1
			$elm->getId()
253 1
		]);
254
	}
255
256
	public function getDetails(): array {
257
		return [
258
			'user' => $this->roleClass,
259
			'archive' => $this->resourceClass,
260
			'unlock alternate' => $this->permissionClass,
261
			'lock' => $this->aclClass
262
		];
263
	}
264
265
	public function getModelClassesSwap(): array {
266
		$swap = $this->getModelClasses();
267
		$classes = \array_values($swap);
268
		$result = [];
269
		foreach ($classes as $class) {
270
			$result[$class] = $swap;
271
		}
272
		return $result;
273
	}
274
275 3
	public function getModelClasses(): array {
276 3
		return [
277 3
			AclElement::class => $this->aclClass,
278 3
			Role::class => $this->roleClass,
279 3
			Resource::class => $this->resourceClass,
280 3
			Permission::class => $this->permissionClass
281 3
		];
282
	}
283
284
	public function clearAll(): void {}
285
286
	/**
287
	 * Initializes AclDAOProvider and creates ACL tables in the specified dbOffset.
288
	 * Do not use in production
289
	 *
290
	 * @param array $config
291
	 * @param string $dbOffset
292
	 * @param array $classes
293
	 *        	associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
294
	 * @return AclDAOProvider
295
	 * @throws AclException
296
	 */
297
	public static function initializeProvider(array $config,string $dbOffset='default',array $classes = []): AclDAOProvider {
298
		$dbProvider=new AclDAOProvider($config,$classes);
299
		$dbProvider->initModelsCache($config);
300
		$dbProvider->setDbOffset($dbOffset);
301
		$dbProvider->generateDbTables($dbOffset);
302
		return $dbProvider;
303
	}
304
}
305