ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilObjOrgUnitTree.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
13{
14
22 protected static $temporary_table_name;
26 private static $instance;
30 private $roles;
38 private $staff;
42 private $tree_childs;
46 private $parent;
50 private $db;
51
52
53 private function __construct()
54 {
55 global $DIC;
56 $ilDB = $DIC['ilDB'];
57 $tree = $DIC['tree'];
58 $this->db = $ilDB;
59 $this->tree = $tree;
60 $this->roles = array();
61 $this->staff = array();
62 }
63
64
68 public static function _getInstance()
69 {
70 if (self::$instance === null) {
71 self::$instance = new self();
72 }
73
74 return self::$instance;
75 }
76
77
84 public function getEmployees($ref_id, $recursive = false)
85 {
86 $arr_usr_ids = [];
87
88 switch ($recursive) {
89 case false:
91 break;
92 case true:
94 $arr_usr_ids = $assignment_query->getUserIdsOfOrgUnitsInPosition($this->getAllChildren($ref_id),ilOrgUnitPosition::CORE_POSITION_EMPLOYEE);
95 break;
96 }
97
98 return $arr_usr_ids;
99 }
100
101
108 public function getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
109 {
111 'orgu_id' => $ref_id,
112 'position_id' => $ilOrgUnitPosition->getId(),
113 ))->getArray('id', 'user_id');
114 }
115
116
123 public function getSuperiors($ref_id, $recursive = false)
124 {
125 $arr_usr_ids = [];
126
127 switch ($recursive) {
128 case false:
130 break;
131 case true:
132 foreach ($this->getAllChildren($ref_id) as $ref_id) {
133 $arr_usr_ids = $arr_usr_ids
135 }
136 break;
137 }
138
139 return $arr_usr_ids;
140 }
141
142
149 private function loadArrayOfStaff($title, $ref_ids)
150 {
151 $this->loadRoles($title);
152 $all_refs = $ref_ids;
153 //take away ref_ids that are already loaded.
154 foreach ($ref_ids as $id => $ref_id) {
155 if (isset($this->staff[$title][$ref_id])) {
156 unset($ref_ids[$id]);
157 } else {
158 $this->staff[$title][$ref_id] = array();
159 $ref_ids[$id] = $this->roles[$title][$ref_id];
160 }
161 }
162
163 //if there are still refs that need to be loaded, then do so.
164 if (count($ref_ids)) {
165 $q = "SELECT usr_id, rol_id FROM rbac_ua WHERE " . $this->db->in("rol_id", $ref_ids, false, "integer");
166 $set = $this->db->query($q);
167 while ($res = $this->db->fetchAssoc($set)) {
168 $orgu_ref = $this->role_to_orgu[$title][$res["rol_id"]];
169 $this->staff[$title][$orgu_ref][] = $res["usr_id"];
170 }
171 }
172
173 //collect * users.
174 $all_users = array();
175 foreach ($all_refs as $ref) {
176 $all_users = array_merge($all_users, $this->staff[$title][$ref]);
177 }
178
179 return $all_users;
180 }
181
182
188 public function getAllChildren($ref_id)
189 {
190 $open = array($ref_id);
191 $closed = array();
192 while (count($open)) {
193 $ref = array_pop($open);
194 $closed[] = $ref;
195 foreach ($this->getChildren($ref) as $child) {
196 if (!in_array($child, $open) && !in_array($child, $closed)) {
197 $open[] = $child;
198 }
199 }
200 }
201
202 return $closed;
203 }
204
205
215 {
216 global $DIC;
217 $ilUser = $DIC['ilUser'];
218 /*$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
219 INNER JOIN rbac_operations ON rbac_operations.operation = ".$this->db->quote($operation, "text")."
220 INNER JOIN rbac_ua ON rbac_ua.usr_id = ".$this->db->quote($ilUser->getId(), "integer")."
221 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
222 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
223 INNER JOIN tree ON tree.child = rbac_fa.parent
224 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
225 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";*/
226
227 $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
228 INNER JOIN rbac_operations ON rbac_operations.operation = " . $this->db->quote($operation, "text") . "
229 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
230 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
231 INNER JOIN object_reference ON object_reference.ref_id = rbac_pa.ref_id
232 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
233
234 $set = $this->db->query($q);
235 $orgus = array();
236 while ($res = $this->db->fetchAssoc($set)) {
237 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
238 $perm_check = unserialize($res['ops_id']);
239 if (!in_array($res["op_id"], $perm_check)) {
240 continue;
241 }
242
243 $orgus[] = $res["ref_id"];
244 }
245
246 return $orgus;
247 }
248
249
258 public function getOrgusWhereUserHasPermissionForOperationId($operation_id)
259 {
260 global $DIC;
261 $ilUser = $DIC['ilUser'];
262 $q = "SELECT object_data.obj_id, object_data.title, object_data.type, rbac_pa.ops_id FROM object_data
263 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
264 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', " . $this->db->quote($operation_id, "integer") . ", '%')
265 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
266 INNER JOIN tree ON tree.child = rbac_fa.parent
267 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
268 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
269
270 $set = $this->db->query($q);
271 $orgus = array();
272 while ($res = $this->db->fetchAssoc($set)) {
273 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
274 $perm_check = unserialize($res['ops_id']);
275 if (!in_array($res["ops_id"], $perm_check)) {
276 continue;
277 }
278
279 $orgus[] = $res["obj_id"];
280 }
281
282 return $orgus;
283 }
284
285
291 private function getChildren($ref_id)
292 {
293 $this->loadChildren($ref_id);
294
295 return $this->tree_childs[$ref_id];
296 }
297
298
302 private function loadChildren($ref_id)
303 {
304 if (!$this->tree_childs[$ref_id]) {
305 $children = array();
306 foreach ($this->tree->getChilds($ref_id) as $child) {
307 if ($child["type"] == "orgu") {
308 $children[] = $child["child"];
309 }
310 }
311 $this->tree_childs[$ref_id] = $children;
312 };
313 }
314
315
321 public function getAllOrgunitsOnLevelX($level)
322 {
323 $levels = array(0 => array(ilObjOrgUnit::getRootOrgRefId()));
324 $current_level = 0;
325 while ($current_level < $level) {
326 $new_level = array();
327 foreach ($levels[$current_level] as $orgu_ref) {
328 $new_level = array_merge($this->getChildren($orgu_ref), $new_level);
329 }
330 $new_level = array_unique($new_level);
331 $levels[$current_level + 1] = $new_level;
332 $current_level++;
333 }
334
335 return $levels[$level];
336 }
337
338
347 public function getEmployeesUnderUser($user_id, $recursive = true)
348 {
349 $employees = [];
351
352 $orgu_ref_ids = $assignment_query->getOrgUnitIdsOfUsersPosition(
354 $user_id);
355
356 switch($recursive) {
357 case true:
358 $orgu_ref_id_with_children = [];
359 foreach($orgu_ref_ids as $orgu_ref_id ) {
360 $orgu_ref_id_with_children = array_merge($orgu_ref_ids, $this->getAllChildren($orgu_ref_id));
361 }
362
363 return $assignment_query->getUserIdsOfOrgUnitsInPosition($orgu_ref_id_with_children,ilOrgUnitPosition::CORE_POSITION_EMPLOYEE);
364 break;
365 default:
366 return $assignment_query->getUserIdsOfOrgUnitsInPosition($orgu_ref_ids,ilOrgUnitPosition::CORE_POSITION_EMPLOYEE);
367 break;
368 }
369
370 return [];
371 }
372
373
382 public function getSuperiorsOfUser($user_id, $recursive = true)
383 {
384 //querry for all orgu where user_id is superior.
385 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
386 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
387 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)
388 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
389 WHERE orgu.type = 'orgu'";
390 $set = $this->db->query($q);
391 $orgu_ref_ids = array();
392 while ($res = $this->db->fetchAssoc($set)) {
393 $orgu_ref_ids[] = $res['ref_id'];
394 }
395 $superiors = array();
396 foreach ($orgu_ref_ids as $orgu_ref_id) {
397 $superiors = array_merge($superiors, $this->getSuperiors($orgu_ref_id, $recursive));
398 }
399
400 return $superiors;
401 }
402
403
412 public function getLevelXOfUser($user_id, $level)
413 {
414 $q = "SELECT object_reference.ref_id FROM rbac_ua
415 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
416 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
417 JOIN object_data ON object_data.obj_id = object_reference.obj_id
418 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer') . " AND object_data.type = 'orgu';";
419
420 $set = $this->db->query($q);
421 $orgu_ref_ids = array();
422 while ($res = $this->db->fetchAssoc($set)) {
423 $orgu_ref_ids[] = $res['ref_id'];
424 }
425 $orgus_on_level_x = array();
426 foreach ($orgu_ref_ids as $orgu_ref_id) {
427 try {
428 $orgus_on_level_x[] = $this->getLevelXOfTreenode($orgu_ref_id, $level);
429 } catch (Exception $e) {
430 // this means the user is assigned to a orgu above the given level. just dont add it to the list.
431 }
432 }
433
434 return array_unique($orgus_on_level_x);
435 }
436
437
446 public function getOrgUnitOfUser($user_id)
447 {
448 $orgu_ref_ids = [];
450
451 $orgus = $orgu_query->getAssignmentsOfUserId($user_id);
452 foreach($orgus as $orgu) {
453 $orgu_ref_ids[] = $orgu->getOrguId();
454 }
455 return $orgu_ref_ids;
456 }
457
458
475 public function buildTempTableWithUsrAssignements($temporary_table_name = 'orgu_usr_assignements')
476 {
477 if (self::$temporary_table_name == $temporary_table_name) {
478 return true;
479 }
480 if (self::$temporary_table_name === null) {
482 self::$temporary_table_name = $temporary_table_name;
483 } elseif ($temporary_table_name != self::$temporary_table_name) {
484 throw new ilException('there is already a temporary table for org-unit assignement: ' . self::$temporary_table_name);
485 }
486
487 $q = "CREATE TEMPORARY TABLE IF NOT EXISTS " . $temporary_table_name . " AS (
488 SELECT DISTINCT object_reference.ref_id AS ref_id, il_orgu_ua.user_id AS user_id, orgu_path_storage.path AS path
489 FROM il_orgu_ua
490 JOIN object_reference ON object_reference.ref_id = il_orgu_ua.orgu_id
491 JOIN object_data ON object_data.obj_id = object_reference.obj_id
492 JOIN orgu_path_storage ON orgu_path_storage.ref_id = object_reference.ref_id
493 WHERE object_data.type = 'orgu' AND object_reference.deleted IS NULL
494 );";
495 $this->db->manipulate($q);
496
497 return true;
498 }
499
500
507 {
508 if (self::$temporary_table_name === null
509 || $temporary_table_name != self::$temporary_table_name
510 ) {
511 return false;
512 }
513 $q = "DROP TABLE IF EXISTS " . $temporary_table_name;
514 $this->db->manipulate($q);
515
516 self::$temporary_table_name = null;
517
518 return true;
519 }
520
521
527 public function getTitles($org_refs)
528 {
529 $names = array();
530 foreach ($org_refs as $org_unit) {
531 $names[$org_unit] = ilObject::_lookupTitle(ilObject::_lookupObjId($org_unit));
532 }
533
534 return $names;
535 }
536
537
541 public function getEmployeeRoles()
542 {
543 $this->loadRoles("employee");
544
545 return $this->roles["employee"];
546 }
547
548
552 public function getSuperiorRoles()
553 {
554 $this->loadRoles("superior");
555
556 return $this->roles["superior"];
557 }
558
559
563 private function loadRoles($role)
564 {
565 if ($this->roles[$role] == null) {
566 $this->loadRolesQuery($role);
567 }
568 }
569
570
571 public function flushCache()
572 {
573 $this->roles = null;
574 }
575
576
580 private function loadRolesQuery($role)
581 {
582 $this->roles[$role] = array();
583 $q = "SELECT obj_id, title FROM object_data WHERE type = 'role' AND title LIKE 'il_orgu_" . $role . "%'";
584 $set = $this->db->query($q);
585 while ($res = $this->db->fetchAssoc($set)) {
586 $orgu_ref = $this->getRefIdFromRoleTitle($res["title"]);
587 $this->roles[$role][$orgu_ref] = $res["obj_id"];
588 $this->role_to_orgu[$role][$res["obj_id"]] = $orgu_ref;
589 }
590 }
591
592
598 private function getRefIdFromRoleTitle($role_title)
599 {
600 $array = explode("_", $role_title);
601
602 return $array[count($array) - 1];
603 }
604
605
626 public function getLevelXOfTreenode($orgu_ref, $level)
627 {
628 $line = array($orgu_ref);
629 $current_ref = $orgu_ref;
630 while ($current_ref != ilObjOrgUnit::getRootOrgRefId()) {
631 $current_ref = $this->getParent($current_ref);
632 if ($current_ref) {
633 $line[] = $current_ref;
634 } else {
635 break;
636 }
637 if (count($line) > 100) {
638 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");
639 }
640 }
641 $line = array_reverse($line);
642 if (count($line) > $level) {
643 return $line[$level];
644 } else {
645 throw new Exception("you want to fetch level " . $level . " but the line to the length of the line is only " . count($line)
646 . ". The line of the given org unit is: " . print_r($line, true));
647 }
648 }
649
650
656 public function getParent($orgu_ref)
657 {
658 if (!$this->parent[$orgu_ref]) {
659 $this->parent[$orgu_ref] = $this->tree->getParentId($orgu_ref);
660 }
661
662 return $this->parent[$orgu_ref];
663 }
664}
static where($where, $operator=null)
An exception for terminatinating execution or to throw for unit testing.
Base class for ILIAS Exception handling.
Class ilObjOrgUnitTree Implements a singleton pattern for caching.
buildTempTableWithUsrAssignements($temporary_table_name='orgu_usr_assignements')
Creates a temporary table with all orgu/user assignements.
getOrgusWhereUserHasPermissionForOperation($operation)
If you want to have all orgunits where the current user has the write permission: use this with the p...
getOrgusWhereUserHasPermissionForOperationId($operation_id)
If you want to have all orgunits where the current user has the write permission: use this with the p...
getOrgUnitOfUser($user_id)
getOrgUnitOfUser
getEmployeesUnderUser($user_id, $recursive=true)
getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
getEmployees($ref_id, $recursive=false)
static $temporary_table_namgetOrgUnitOfUsere
loadArrayOfStaff($title, $ref_ids)
getRefIdFromRoleTitle($role_title)
getSuperiors($ref_id, $recursive=false)
getLevelXOfTreenode($orgu_ref, $level)
Specify eg.
getLevelXOfUser($user_id, $level)
for additional info see the other getLevelX method.
dropTempTable($temporary_table_name)
getSuperiorsOfUser($user_id, $recursive=true)
static getRootOrgRefId()
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
Class ilOrgUnitPosition.
static getCorePosition($core_identifier)
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46