ILIAS  release_8 Revision v8.24
class.ilObjOrgUnitTree.php
Go to the documentation of this file.
1<?php
2
26{
27 protected static ?string $temporary_table_name_getOrgUnitOfUser = null;
28 protected static ?string $temporary_table_name = null;
29 protected static ?ilObjOrgUnitTree $instance = null;
31 private array $roles;
33 private array $role_to_orgu;
35 private $staff;
37 private array $tree_childs = [];
39 private array $parent = [];
42 private \ilTree $tree;
43
44 private function __construct()
45 {
46 global $DIC;
47 $this->db = $DIC->database();
48 $this->tree = $DIC->repositoryTree();
49 $this->roles = array();
50 $this->staff = array();
51 $this->ilUser = $DIC->user();
52 }
53
54 public static function _getInstance(): \ilObjOrgUnitTree
55 {
56 if (static::$instance === null) {
57 static::$instance = new self();
58 }
59
60 return static::$instance;
61 }
62
67 public function getEmployees(int $ref_id, bool $recursive = false): array
68 {
69 $arr_usr_ids = [];
70
71 switch ($recursive) {
72 case false:
73 $arr_usr_ids = $this->getAssignements(
74 $ref_id,
76 );
77 break;
78 case true:
80 $arr_usr_ids = $assignment_query->getUserIdsOfOrgUnitsInPosition(
81 $this->getAllChildren($ref_id),
83 );
84 break;
85 }
86
87 return $arr_usr_ids;
88 }
89
90 public function getAssignements(int $ref_id, ilOrgUnitPosition $ilOrgUnitPosition): array
91 {
93 'orgu_id' => $ref_id,
94 'position_id' => $ilOrgUnitPosition->getId(),
95 ))->getArray('id', 'user_id');
96 }
97
103 public function getSuperiors(int $ref_id, bool $recursive = false): array
104 {
105 if ($recursive === false) {
106 return $this->getAssignements(
107 $ref_id,
109 );
110 }
111
112 $arr_usr_ids = [];
113 foreach ($this->getAllChildren($ref_id) as $ref_id_child) {
114 $arr_usr_ids += $this->getAssignements(
115 $ref_id_child,
117 );
118 }
119 return $arr_usr_ids;
120 }
121
127 private function loadArrayOfStaff(string $title, array $ref_ids): array
128 {
129 $this->loadRoles($title);
130 $all_refs = $ref_ids;
131 //take away ref_ids that are already loaded.
132 foreach ($ref_ids as $id => $ref_id) {
133 if (isset($this->staff[$title][$ref_id])) {
134 unset($ref_ids[$id]);
135 } else {
136 $this->staff[$title][$ref_id] = array();
137 $ref_ids[$id] = $this->roles[$title][$ref_id];
138 }
139 }
140
141 //if there are still refs that need to be loaded, then do so.
142 if (count($ref_ids)) {
143 $q = "SELECT usr_id, rol_id FROM rbac_ua WHERE " . $this->db->in("rol_id", $ref_ids, false, "integer");
144 $set = $this->db->query($q);
145 while ($res = $this->db->fetchAssoc($set)) {
146 $orgu_ref = $this->role_to_orgu[$title][$res["rol_id"]];
147 $this->staff[$title][$orgu_ref][] = $res["usr_id"];
148 }
149 }
150
151 //collect * users.
152 $all_users = [];
153 foreach ($all_refs as $ref) {
154 $all_users = array_merge($all_users, $this->staff[$title][$ref]);
155 }
156 return $all_users;
157 }
158
159 public function getAllChildren(int $ref_id): array
160 {
161 $open = array($ref_id);
162 $closed = array();
163 while (count($open)) {
164 $ref = array_pop($open);
165 $closed[] = $ref;
166 foreach ($this->getChildren($ref) as $child) {
167 if (in_array($child, $open, true) === false && in_array($child, $closed, true) === false) {
168 $open[] = $child;
169 }
170 }
171 }
172
173 return $closed;
174 }
175
181 public function getOrgusWhereUserHasPermissionForOperation($operation): array
182 {
183
184 /*$q = "SELECT object_data.obj_id, object_reference.ref_id, object_data.title, object_data.type, rbac_pa.ops_id, rbac_operations.ops_id as op_id FROM object_data
185 INNER JOIN rbac_operations ON rbac_operations.operation = ".$this->db->quote($operation, "text")."
186 INNER JOIN rbac_ua ON rbac_ua.usr_id = ".$this->db->quote($ilUser->getId(), "integer")."
187 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
188 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
189 INNER JOIN tree ON tree.child = rbac_fa.parent
190 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
191 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";*/
192
193 $q = "SELECT object_data.obj_id, object_reference.ref_id, object_data.title, object_data.type, rbac_pa.ops_id, rbac_operations.ops_id as op_id FROM object_data
194 INNER JOIN rbac_operations ON rbac_operations.operation = " . $this->db->quote($operation, "text") . "
195 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($this->ilUser->getId(), "integer") . "
196 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
197 INNER JOIN object_reference ON object_reference.ref_id = rbac_pa.ref_id
198 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
199
200 $set = $this->db->query($q);
201 $orgus = [];
202 while ($res = $this->db->fetchAssoc($set)) {
203 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
204 $perm_check = unserialize($res['ops_id'], ['allowed_classes' => true]);
205 if (in_array($res["op_id"], $perm_check, true) === false) {
206 continue;
207 }
208
209 $orgus[] = $res["ref_id"];
210 }
211
212 return $orgus;
213 }
214
220 public function getOrgusWhereUserHasPermissionForOperationId(string $operation_id): array
221 {
222 $q = "SELECT object_data.obj_id, object_data.title, object_data.type, rbac_pa.ops_id FROM object_data
223 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($this->ilUser->getId(), "integer") . "
224 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', " . $this->db->quote(
225 $operation_id,
226 "integer"
227 ) . ", '%')
228 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
229 INNER JOIN tree ON tree.child = rbac_fa.parent
230 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
231 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
232
233 $set = $this->db->query($q);
234 $orgus = array();
235 while ($res = $this->db->fetchAssoc($set)) {
236 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
237 $perm_check = unserialize($res['ops_id'], ['allowed_classes' => true]);
238 if (in_array($res["ops_id"], $perm_check, true) === false) {
239 continue;
240 }
241
242 $orgus[] = $res["obj_id"];
243 }
244
245 return $orgus;
246 }
247
248 private function getChildren(int $ref_id): array
249 {
250 $this->loadChildren($ref_id);
251 return $this->tree_childs[$ref_id];
252 }
253
254 private function loadChildren(int $ref_id): void
255 {
256 if (!array_key_exists($ref_id, $this->tree_childs)) {
257 $children = [];
258 foreach ($this->tree->getChilds($ref_id) as $child) {
259 if ($child["type"] == "orgu") {
260 $children[] = $child["child"];
261 }
262 }
263 $this->tree_childs[$ref_id] = $children;
264 }
265 }
266
267 public function getAllOrgunitsOnLevelX(int $level): array
268 {
269 $levels = array(0 => array(ilObjOrgUnit::getRootOrgRefId()));
270 $current_level = 0;
271 while ($current_level < $level) {
272 $new_level = array();
273 foreach ($levels[$current_level] as $orgu_ref) {
274 $new_level = array_merge($this->getChildren($orgu_ref), $new_level);
275 }
276 $new_level = array_unique($new_level);
277 $levels[$current_level + 1] = $new_level;
278 $current_level++;
279 }
280
281 return $levels[$level];
282 }
283
290 public function getEmployeesUnderUser(int $user_id, bool $recursive = true): array
291 {
293 $orgu_ref_ids = $assignment_query->getOrgUnitIdsOfUsersPosition(
295 $user_id
296 );
297
298 switch ($recursive) {
299 case true:
300 $orgu_ref_id_with_children = [];
301 foreach ($orgu_ref_ids as $orgu_ref_id) {
302 $orgu_ref_id_with_children = array_merge($orgu_ref_ids, $this->getAllChildren($orgu_ref_id));
303 }
304 return $assignment_query->getUserIdsOfOrgUnitsInPosition(
305 $orgu_ref_id_with_children,
307 );
308 default:
309 return $assignment_query->getUserIdsOfOrgUnitsInPosition(
310 $orgu_ref_ids,
312 );
313 }
314 }
315
322 public function getSuperiorsOfUser(int $user_id, bool $recursive = true): array
323 {
324 //querry for all orgu where user_id is superior.
325 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
326 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
327 INNER JOIN object_data roles ON roles.title LIKE CONCAT('il_orgu_employee_',refr.ref_id) OR roles.title LIKE CONCAT('il_orgu_superior_',refr.ref_id)
328 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
329 WHERE orgu.type = 'orgu'";
330 $set = $this->db->query($q);
331 $orgu_ref_ids = array();
332 while ($res = $this->db->fetchAssoc($set)) {
333 $orgu_ref_ids[] = $res['ref_id'];
334 }
335 $superiors = array();
336 foreach ($orgu_ref_ids as $orgu_ref_id) {
337 $superiors = array_merge($superiors, $this->getSuperiors($orgu_ref_id, $recursive));
338 }
339
340 return $superiors;
341 }
342
348 public function getLevelXOfUser(int $user_id, int $level): array
349 {
350 $q = "SELECT object_reference.ref_id FROM rbac_ua
351 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
352 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
353 JOIN object_data ON object_data.obj_id = object_reference.obj_id
354 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer') . " AND object_data.type = 'orgu';";
355
356 $set = $this->db->query($q);
357 $orgu_ref_ids = array();
358 while ($res = $this->db->fetchAssoc($set)) {
359 $orgu_ref_ids[] = $res['ref_id'];
360 }
361 $orgus_on_level_x = array();
362 foreach ($orgu_ref_ids as $orgu_ref_id) {
363 try {
364 $orgus_on_level_x[] = $this->getLevelXOfTreenode($orgu_ref_id, $level);
365 } catch (Exception $e) {
366 // this means the user is assigned to a orgu above the given level. just dont add it to the list.
367 }
368 }
369
370 return array_unique($orgus_on_level_x);
371 }
372
377 public function getOrgUnitOfUser(int $user_id): array
378 {
379 $orgu_ref_ids = [];
381
382 $orgus = $orgu_query->getAssignmentsOfUserId($user_id);
383 foreach ($orgus as $orgu) {
384 $orgu_ref_ids[] = $orgu->getOrguId();
385 }
386 return $orgu_ref_ids;
387 }
388
401 public function buildTempTableWithUsrAssignements(string $temporary_table_name = 'orgu_usr_assignements'): bool
402 {
403 if (self::$temporary_table_name == $temporary_table_name) {
404 return true;
405 }
406 if (self::$temporary_table_name === null) {
407 $this->dropTempTable($temporary_table_name);
408 self::$temporary_table_name = $temporary_table_name;
409 } elseif ($temporary_table_name != self::$temporary_table_name) {
410 throw new ilException('there is already a temporary table for org-unit assignement: ' . self::$temporary_table_name);
411 }
412
413 $q = "CREATE TEMPORARY TABLE IF NOT EXISTS " . $temporary_table_name . " AS (
414 SELECT DISTINCT object_reference.ref_id AS ref_id, il_orgu_ua.user_id AS user_id, orgu_path_storage.path AS path
415 FROM il_orgu_ua
416 JOIN object_reference ON object_reference.ref_id = il_orgu_ua.orgu_id
417 JOIN object_data ON object_data.obj_id = object_reference.obj_id
418 JOIN orgu_path_storage ON orgu_path_storage.ref_id = object_reference.ref_id
419 WHERE object_data.type = 'orgu' AND object_reference.deleted IS NULL
420 );";
421 $this->db->manipulate($q);
422
423 return true;
424 }
425
426 public function dropTempTable(string $temporary_table_name): bool
427 {
428 if (self::$temporary_table_name === null
429 || $temporary_table_name !== self::$temporary_table_name
430 ) {
431 return false;
432 }
433 $q = "DROP TABLE IF EXISTS " . $temporary_table_name;
434 $this->db->manipulate($q);
435
436 self::$temporary_table_name = null;
437
438 return true;
439 }
440
441 public function getTitles(array $org_refs): array
442 {
443 $names = array();
444 foreach ($org_refs as $org_unit) {
445 $names[$org_unit] = ilObject::_lookupTitle(ilObject::_lookupObjId($org_unit));
446 }
447
448 return $names;
449 }
450
454 public function getEmployeeRoles(): array
455 {
456 $this->loadRoles("employee");
457 return $this->roles["employee"];
458 }
459
463 public function getSuperiorRoles(): array
464 {
465 $this->loadRoles("superior");
466
467 return $this->roles["superior"];
468 }
469
470 private function loadRoles(string $role)
471 {
472 if ($this->roles[$role] == null) {
473 $this->loadRolesQuery($role);
474 }
475 }
476
477 public function flushCache(): void
478 {
479 $this->roles = null;
480 }
481
482 private function loadRolesQuery(string $role): void
483 {
484 $this->roles[$role] = array();
485 $q = "SELECT obj_id, title FROM object_data WHERE type = 'role' AND title LIKE 'il_orgu_" . $role . "%'";
486 $set = $this->db->query($q);
487 while ($res = $this->db->fetchAssoc($set)) {
488 $orgu_ref = $this->getRefIdFromRoleTitle($res["title"]);
489 $this->roles[$role][$orgu_ref] = $res["obj_id"];
490 $this->role_to_orgu[$role][$res["obj_id"]] = $orgu_ref;
491 }
492 }
493
494 private function getRefIdFromRoleTitle(string $role_title): int
495 {
496 $array = explode("_", $role_title);
497
498 return $array[count($array) - 1];
499 }
500
517 public function getLevelXOfTreenode(int $orgu_ref, int $level)
518 {
519 $line = array($orgu_ref);
520 $current_ref = $orgu_ref;
521 while ($current_ref != ilObjOrgUnit::getRootOrgRefId()) {
522 $current_ref = $this->getParent($current_ref);
523 if ($current_ref) {
524 $line[] = $current_ref;
525 } else {
526 break;
527 }
528 if (count($line) > 100) {
529 throw new Exception("There's either a non valid call of the getLevelXOfTreenode in ilObjOrgUnitTree or your nesting of orgunits is higher than 100 units, which isn't encouraged");
530 }
531 }
532 $line = array_reverse($line);
533 if (count($line) > $level) {
534 return $line[$level];
535 } else {
536 throw new Exception("you want to fetch level " . $level . " but the line to the length of the line is only " . count($line)
537 . ". The line of the given org unit is: " . print_r($line, true));
538 }
539 }
540
541 public function getParent(int $orgu_ref): int
542 {
543 if (array_key_exists($orgu_ref, $this->parent) === false) {
544 $this->parent[$orgu_ref] = $this->tree->getParentId($orgu_ref);
545 }
546
547 return $this->parent[$orgu_ref];
548 }
549}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static where($where, $operator=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static ilObjOrgUnitTree $instance
getTitles(array $org_refs)
getRefIdFromRoleTitle(string $role_title)
static string $temporary_table_name
getEmployees(int $ref_id, bool $recursive=false)
getAllOrgunitsOnLevelX(int $level)
getOrgusWhereUserHasPermissionForOperation($operation)
If you want to have all orgunits where the current user has the write permission: use this with the p...
loadArrayOfStaff(string $title, array $ref_ids)
getLevelXOfTreenode(int $orgu_ref, int $level)
Specify eg.
getLevelXOfUser(int $user_id, int $level)
for additional info see the other getLevelX method.
buildTempTableWithUsrAssignements(string $temporary_table_name='orgu_usr_assignements')
Creates a temporary table with all orgu/user assignements.
getSuperiorsOfUser(int $user_id, bool $recursive=true)
dropTempTable(string $temporary_table_name)
getOrgusWhereUserHasPermissionForOperationId(string $operation_id)
If you want to have all orgunits where the current user has the write permission: use this with the p...
getAssignements(int $ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
static string $temporary_table_name_getOrgUnitOfUser
getOrgUnitOfUser(int $user_id)
getSuperiors(int $ref_id, bool $recursive=false)
getEmployeesUnderUser(int $user_id, bool $recursive=true)
static getRootOrgRefId()
User class.
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getCorePosition(int $core_identifier)
global $DIC
Definition: feed.php:28
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:67
$res
Definition: ltiservices.php:69