AclDAOProvider::setDbOffset()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 3
Bugs 1 Features 2
Metric Value
cc 2
eloc 6
c 3
b 1
f 2
nc 2
nop 2
dl 0
loc 7
ccs 0
cts 7
cp 0
crap 6
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.3
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, array $classes = []) {
43 4
		Startup::$config=$config;
44 4
		$this->setClasses($classes);
45
	}
46
47 4
	private function setClasses(array $classes): void {
48 4
		$this->aclClass = $classes['acl'] ?? AclElement::class;
49 4
		$this->roleClass = $classes['role'] ?? Role::class;
50 4
		$this->resourceClass = $classes['resource'] ?? Resource::class;
51 4
		$this->permissionClass = $classes['permission'] ?? Permission::class;
52
	}
53
54
	/**
55
	 * Initialize the cache for the ACL models.
56
	 * @param $config
57
	 */
58
	public function initModelsCache(&$config) {
59
		CacheManager::start($config);
60
		CacheManager::createOrmModelCache($this->aclClass);
61
		CacheManager::createOrmModelCache($this->roleClass);
62
		CacheManager::createOrmModelCache($this->resourceClass);
63
		CacheManager::createOrmModelCache($this->permissionClass);
64
	}
65
66
	/**
67
	 * Defines the database offset used for ACL.
68
	 * @param string $dbOffset
69
	 * @param  bool $persist
70
	 */
71
	public function setDbOffset(string $dbOffset = 'default', bool $persist=true): void {
72
		DAO::setModelDatabase($this->aclClass, $dbOffset);
73
		DAO::setModelDatabase($this->resourceClass, $dbOffset);
74
		DAO::setModelDatabase($this->roleClass, $dbOffset);
75
		DAO::setModelDatabase($this->permissionClass, $dbOffset);
76
		if ($persist) {
77
			CacheManager::storeModelsDatabases(DAO::getModelsDatabase ());
78
		}
79
	}
80
81
	/**
82
	 * Generates the models.
83
	 * @param string $dbOffset default
84
	 * @param ?array $classes associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
85
	 */
86
	public function createModels(string $dbOffset='default', ?array $classes=null): void {
87
		$classes??=[
88
			'acl'=>'models\\AclElement','role'=>'models\\Role','resource'=>'models\\Resource','permission'=>'models\\Permission'
89
		];
90
		$this->setClasses($classes);
91
		$this->createModel($classes['acl'] ?? $this->aclClass,AclElement::class, $dbOffset);
92
		$this->createModel($classes['role'] ?? $this->roleClass,Role::class, $dbOffset);
93
		$this->createModel($classes['resource'] ?? $this->resourceClass,Resource::class, $dbOffset);
94
		$this->createModel($classes['permission'] ?? $this->permissionClass,Permission::class, $dbOffset);
95
	}
96
97
	public function createModel(string $modelName, string $refName, string $dbOffset='default'): void {
98
		if ($modelName!==$refName) {
99
			$className=ClassUtils::getClassSimpleName($modelName);
100
			$ns=ClassUtils::getNamespaceFromCompleteClassname($modelName);
101
			$cCreator=new ClassCreator($className, $ns, ' extends \\'.$refName);
102
			if ($dbOffset!=='default') {
103
				$annot=CacheManager::getAnnotationsEngineInstance()->getAnnotation($cCreator, 'database', ['name'=>$dbOffset]);
104
				$cCreator->addClassAttribute($annot);
0 ignored issues
show
Bug introduced by
The method addClassAttribute() does not exist on Ubiquity\scaffolding\creators\ClassCreator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

104
				$cCreator->/** @scrutinizer ignore-call */ 
105
               addClassAttribute($annot);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
105
			}
106
			$cCreator->generate();
107
		}
108
	}
109
110
	/**
111
	 * Generates the tables for ACL model classes.
112
	 * @param string $dbOffset
113
	 * @param bool $createDb
114
	 * @throws AclException
115
	 */
116
	public function generateDbTables(string $dbOffset='default',bool $createDb=false):void{
117
		$this->setDbOffset($dbOffset);
118
		$generator = new DatabaseReversor(new DbGenerator(), $dbOffset);
119
		$activeOffsetValue=DAO::getDbOffset(Startup::$config, $dbOffset);
120
		if (($dbName=$activeOffsetValue['dbName']??'')!='') {
121
			$generator->setModels([$this->aclClass,$this->roleClass,$this->resourceClass,$this->permissionClass]);
122
			$generator->createDatabase($dbName, $createDb);
123
			$db=DAO::getDatabase($dbOffset);
124
			$db->beginTransaction();
125
			$db->execute($generator->__toString());
126
			$db->commit();
127
		} else {
128
			throw new AclException('dbName key is not present or his value is empty!');
129
		}
130
	}
131
132
	/**
133
	 *
134
	 * {@inheritdoc}
135
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllAcls()
136
	 */
137 4
	public function loadAllAcls(): array {
138 4
		$result= DAO::getAll($this->aclClass);
139 4
		foreach ($result as $elm) {
140 4
			$elm->setType(AclDAOProvider::class);
141
		}
142 4
		return $result;
143
	}
144
145
	/**
146
	 *
147
	 * {@inheritdoc}
148
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::saveAcl()
149
	 */
150 1
	public function saveAcl(AclElement $aclElement) {
151 1
		$aclElement->_rest=[];
152 1
		if (!$this->existPart($aclElement->getResource())) {
153
			$this->savePart($aclElement->getResource());
154
		}
155 1
		if (!$this->existPart($aclElement->getPermission())) {
156
			$this->savePart($aclElement->getPermission());
157
		}
158 1
		if (!$this->existPart($aclElement->getRole())) {
159
			$this->savePart($aclElement->getRole());
160
		}
161 1
		$object = $this->castElement($aclElement);
162 1
		if ($this->existAcl($aclElement)) {
163
			$res=DAO::update($object);
164
		} else {
165 1
			$res = DAO::insert($object);
166
		}
167 1
		if ($res) {
168 1
			$aclElement->setId($object->getId());
169
		}
170 1
		return $res;
171
	}
172
173
	/**
174
	 *
175
	 * {@inheritdoc}
176
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::removeAcl()
177
	 */
178 1
	public function removeAcl(AclElement $aclElement) {
179 1
		return DAO::remove($aclElement);
180
	}
181
182 4
	protected function loadElements(string $className): array {
183 4
		$elements = DAO::getAll($className);
184 4
		$result = [];
185 4
		foreach ($elements as $elm) {
186 4
			$elm->setType(AclDAOProvider::class);
187 4
			$result[$elm->getName()] = $elm;
188
		}
189 4
		return $result;
190
	}
191
192 3
	protected function castElement($part) {
193 3
		$class = $this->getModelClasses()[get_class($part)] ?? get_class($part);
194 3
		return $part->castAs($class);
195
	}
196
197
	/**
198
	 *
199
	 * {@inheritdoc}
200
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllPermissions()
201
	 */
202 4
	public function loadAllPermissions(): array {
203 4
		return $this->loadElements($this->permissionClass);
204
	}
205
206
	/**
207
	 *
208
	 * {@inheritdoc}
209
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllResources()
210
	 */
211 4
	public function loadAllResources(): array {
212 4
		return $this->loadElements($this->resourceClass);
213
	}
214
215
	/**
216
	 *
217
	 * {@inheritdoc}
218
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::loadAllRoles()
219
	 */
220 4
	public function loadAllRoles(): array {
221 4
		return $this->loadElements($this->roleClass);
222
	}
223
224
	/**
225
	 *
226
	 * {@inheritdoc}
227
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::savePart()
228
	 */
229 2
	public function savePart(\Ubiquity\security\acl\models\AbstractAclPart $part) {
230 2
		$object = $this->castElement($part);
231 2
		if ($this->existPart($part)) {
232
			$object->_rest=[];
233
			$res = DAO::update($object);
234
		} else {
235 2
			$res=DAO::insert($object);
236
		}
237 2
		if ($res) {
238 2
			$part->setName($object->getName());
239
		}
240 2
		return $res;
241
	}
242
243
	/**
244
	 *
245
	 * {@inheritdoc}
246
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::updatePart()
247
	 */
248 1
	public function updatePart(string $id, \Ubiquity\security\acl\models\AbstractAclPart $part) {
249 1
		$object=$this->castElement($part);
250 1
		$object->_rest=[];
251 1
		$object->_pkv['___name']=$id;
252 1
		return DAO::update($object);
253
	}
254
255
	/**
256
	 *
257
	 * {@inheritdoc}
258
	 * @see \Ubiquity\security\acl\persistence\AclProviderInterface::removePart()
259
	 */
260 2
	public function removePart(\Ubiquity\security\acl\models\AbstractAclPart $part) {
261 2
		return DAO::remove($this->castElement($part));
262
	}
263
264 1
	public function isAutosave(): bool {
265 1
		return true;
266
	}
267
268
	public function saveAll(): void {}
269
270 3
	public function existPart(AbstractAclPart $part): bool {
271 3
		$elm = $this->castElement($part);
272 3
		return DAO::exists(\get_class($elm), 'name= ?', [
273 3
			$elm->getName()
274 3
		]);
275
	}
276
277 1
	public function existAcl(AclElement $aclElement): bool {
278 1
		$elm = $this->castElement($aclElement);
279 1
		return DAO::exists(\get_class($elm), 'id= ?', [
280 1
			$elm->getId()
281 1
		]);
282
	}
283
284
	public function getDetails(): array {
285
		return [
286
			'user' => $this->roleClass,
287
			'archive' => $this->resourceClass,
288
			'unlock alternate' => $this->permissionClass,
289
			'lock' => $this->aclClass
290
		];
291
	}
292
293
	public function getModelClassesSwap(): array {
294
		$swap = $this->getModelClasses();
295
		$classes = \array_values($swap);
296
		$result = [];
297
		foreach ($classes as $class) {
298
			$result[$class] = $swap;
299
		}
300
		return $result;
301
	}
302
303 3
	public function getModelClasses(): array {
304 3
		return [
305 3
			AclElement::class => $this->aclClass,
306 3
			Role::class => $this->roleClass,
307 3
			Resource::class => $this->resourceClass,
308 3
			Permission::class => $this->permissionClass
309 3
		];
310
	}
311
312
	public function clearAll(): void {}
313
314
	/**
315
	 * Initializes AclDAOProvider and creates ACL tables in the specified dbOffset.
316
	 * Do not use in production
317
	 *
318
	 * @param array $config
319
	 * @param string $dbOffset
320
	 * @param array $classes
321
	 *        	associative array['acl'=>'','role'=>'','resource'=>'','permission'=>'']
322
	 * @return AclDAOProvider
323
	 * @throws AclException
324
	 */
325
	public static function initializeProvider(array $config,string $dbOffset='default',array $classes = []): AclDAOProvider {
326
		$dbProvider=new AclDAOProvider($config,$classes);
327
		$dbProvider->initModelsCache($config);
328
		$dbProvider->setDbOffset($dbOffset);
329
		$dbProvider->generateDbTables($dbOffset);
330
		return $dbProvider;
331
	}
332
	
333
	public function cacheUpdated(): bool {
334
		return false;
335
	}
336
}
337