ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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
18 protected static $temporary_table_name = null;
22 private static $instance;
26 private $roles;
34 private $staff;
38 private $tree_childs;
42 private $parent;
46 private $db;
47
48
49 private function __construct()
50 {
51 global $DIC;
52 $ilDB = $DIC['ilDB'];
53 $tree = $DIC['tree'];
54 $this->db = $ilDB;
55 $this->tree = $tree;
56 $this->roles = array();
57 $this->staff = array();
58 }
59
60
64 public static function _getInstance()
65 {
66 if (self::$instance === null) {
67 self::$instance = new self();
68 }
69
70 return self::$instance;
71 }
72
73
80 public function getEmployees($ref_id, $recursive = false)
81 {
82 $arr_usr_ids = [];
83
84 switch ($recursive) {
85 case false:
87 break;
88 case true:
89 foreach ($this->getAllChildren($ref_id) as $ref_id) {
90 $arr_usr_ids = $arr_usr_ids
92 }
93 break;
94 }
95
96 return $arr_usr_ids;
97 }
98
99
106 public function getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
107 {
109 'orgu_id' => $ref_id,
110 'position_id' => $ilOrgUnitPosition->getId(),
111 ))->getArray('id', 'user_id');
112 }
113
114
121 public function getSuperiors($ref_id, $recursive = false)
122 {
123 $arr_usr_ids = [];
124
125 switch ($recursive) {
126 case false:
128 break;
129 case true:
130 foreach ($this->getAllChildren($ref_id) as $ref_id) {
131 $arr_usr_ids = $arr_usr_ids
133 }
134 break;
135 }
136
137 return $arr_usr_ids;
138 }
139
140
147 private function loadArrayOfStaff($title, $ref_ids)
148 {
149 $this->loadRoles($title);
150 $all_refs = $ref_ids;
151 //take away ref_ids that are already loaded.
152 foreach ($ref_ids as $id => $ref_id) {
153 if (isset($this->staff[$title][$ref_id])) {
154 unset($ref_ids[$id]);
155 } else {
156 $this->staff[$title][$ref_id] = array();
157 $ref_ids[$id] = $this->roles[$title][$ref_id];
158 }
159 }
160
161 //if there are still refs that need to be loaded, then do so.
162 if (count($ref_ids)) {
163 $q = "SELECT usr_id, rol_id FROM rbac_ua WHERE " . $this->db->in("rol_id", $ref_ids, false, "integer");
164 $set = $this->db->query($q);
165 while ($res = $this->db->fetchAssoc($set)) {
166 $orgu_ref = $this->role_to_orgu[$title][$res["rol_id"]];
167 $this->staff[$title][$orgu_ref][] = $res["usr_id"];
168 }
169 }
170
171 //collect * users.
172 $all_users = array();
173 foreach ($all_refs as $ref) {
174 $all_users = array_merge($all_users, $this->staff[$title][$ref]);
175 }
176
177 return $all_users;
178 }
179
180
186 public function getAllChildren($ref_id)
187 {
188 $open = array( $ref_id );
189 $closed = array();
190 while (count($open)) {
191 $ref = array_pop($open);
192 $closed[] = $ref;
193 foreach ($this->getChildren($ref) as $child) {
194 if (!in_array($child, $open) && !in_array($child, $closed)) {
195 $open[] = $child;
196 }
197 }
198 }
199
200 return $closed;
201 }
202
203
213 {
214 global $DIC;
215 $ilUser = $DIC['ilUser'];
216 /*$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
217 INNER JOIN rbac_operations ON rbac_operations.operation = ".$this->db->quote($operation, "text")."
218 INNER JOIN rbac_ua ON rbac_ua.usr_id = ".$this->db->quote($ilUser->getId(), "integer")."
219 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
220 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
221 INNER JOIN tree ON tree.child = rbac_fa.parent
222 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
223 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";*/
224
225 $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
226 INNER JOIN rbac_operations ON rbac_operations.operation = " . $this->db->quote($operation, "text") . "
227 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
228 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
229 INNER JOIN object_reference ON object_reference.ref_id = rbac_pa.ref_id
230 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
231
232 $set = $this->db->query($q);
233 $orgus = array();
234 while ($res = $this->db->fetchAssoc($set)) {
235 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
236 $perm_check = unserialize($res['ops_id']);
237 if (!in_array($res["op_id"], $perm_check)) {
238 continue;
239 }
240
241 $orgus[] = $res["ref_id"];
242 }
243
244 return $orgus;
245 }
246
247
256 public function getOrgusWhereUserHasPermissionForOperationId($operation_id)
257 {
258 global $DIC;
259 $ilUser = $DIC['ilUser'];
260 $q = "SELECT object_data.obj_id, object_data.title, object_data.type, rbac_pa.ops_id FROM object_data
261 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
262 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") . ", '%')
263 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
264 INNER JOIN tree ON tree.child = rbac_fa.parent
265 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
266 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
267
268 $set = $this->db->query($q);
269 $orgus = array();
270 while ($res = $this->db->fetchAssoc($set)) {
271 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
272 $perm_check = unserialize($res['ops_id']);
273 if (!in_array($res["ops_id"], $perm_check)) {
274 continue;
275 }
276
277 $orgus[] = $res["obj_id"];
278 }
279
280 return $orgus;
281 }
282
283
289 private function getChildren($ref_id)
290 {
291 $this->loadChildren($ref_id);
292
293 return $this->tree_childs[$ref_id];
294 }
295
296
300 private function loadChildren($ref_id)
301 {
302 if (!$this->tree_childs[$ref_id]) {
303 $children = array();
304 foreach ($this->tree->getChilds($ref_id) as $child) {
305 if ($child["type"] == "orgu") {
306 $children[] = $child["child"];
307 }
308 }
309 $this->tree_childs[$ref_id] = $children;
310 };
311 }
312
313
319 public function getAllOrgunitsOnLevelX($level)
320 {
321 $levels = array( 0 => array( ilObjOrgUnit::getRootOrgRefId() ) );
322 $current_level = 0;
323 while ($current_level < $level) {
324 $new_level = array();
325 foreach ($levels[$current_level] as $orgu_ref) {
326 $new_level = array_merge($this->getChildren($orgu_ref), $new_level);
327 }
328 $new_level = array_unique($new_level);
329 $levels[$current_level + 1] = $new_level;
330 $current_level++;
331 }
332
333 return $levels[$level];
334 }
335
336
345 public function getEmployeesUnderUser($user_id, $recursive = true)
346 {
347 //querry for all orgu where user_id is superior.
348 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
349 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
350 INNER JOIN object_data roles ON roles.title LIKE CONCAT('il_orgu_superior_',refr.ref_id)
351 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
352 WHERE orgu.type = 'orgu'";
353 $set = $this->db->query($q);
354 $orgu_ref_ids = array();
355 while ($res = $this->db->fetchAssoc($set)) {
356 $orgu_ref_ids[] = $res['ref_id'];
357 }
358 $employees = array();
359 foreach ($orgu_ref_ids as $orgu_ref_id) {
360 $employees = array_merge($employees, $this->getEmployees($orgu_ref_id, $recursive));
361 }
362
363 return $employees;
364 }
365
366
375 public function getSuperiorsOfUser($user_id, $recursive = true)
376 {
377 //querry for all orgu where user_id is superior.
378 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
379 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
380 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)
381 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
382 WHERE orgu.type = 'orgu'";
383 $set = $this->db->query($q);
384 $orgu_ref_ids = array();
385 while ($res = $this->db->fetchAssoc($set)) {
386 $orgu_ref_ids[] = $res['ref_id'];
387 }
388 $superiors = array();
389 foreach ($orgu_ref_ids as $orgu_ref_id) {
390 $superiors = array_merge($superiors, $this->getSuperiors($orgu_ref_id, $recursive));
391 }
392
393 return $superiors;
394 }
395
396
405 public function getLevelXOfUser($user_id, $level)
406 {
407 $q = "SELECT object_reference.ref_id FROM rbac_ua
408 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
409 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
410 JOIN object_data ON object_data.obj_id = object_reference.obj_id
411 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer') . " AND object_data.type = 'orgu';";
412
413 $set = $this->db->query($q);
414 $orgu_ref_ids = array();
415 while ($res = $this->db->fetchAssoc($set)) {
416 $orgu_ref_ids[] = $res['ref_id'];
417 }
418 $orgus_on_level_x = array();
419 foreach ($orgu_ref_ids as $orgu_ref_id) {
420 try {
421 $orgus_on_level_x[] = $this->getLevelXOfTreenode($orgu_ref_id, $level);
422 } catch (Exception $e) {
423 // this means the user is assigned to a orgu above the given level. just dont add it to the list.
424 }
425 }
426
427 return array_unique($orgus_on_level_x);
428 }
429
430
439 public function getOrgUnitOfUser($user_id, $ref_id = 0)
440 {
441 $q = "SELECT object_reference.ref_id FROM rbac_ua
442 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
443 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
444 JOIN object_data ON object_data.obj_id = object_reference.obj_id
445 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer') . " AND object_data.type = 'orgu'";
446
447 $set = $this->db->query($q);
448 $orgu_ref_ids = array();
449 while ($res = $this->db->fetchAssoc($set)) {
450 $orgu_ref_ids[] = $res['ref_id'];
451 }
452 $orgu_ref_ids = array_unique($orgu_ref_ids);
453 if ($ref_id) {
454 $childernOrgIds = $this->getAllChildren($ref_id);
455 foreach ($orgu_ref_ids as $k => $refId) {
456 if (!in_array($refId, $childernOrgIds)) {
457 unset($orgu_ref_ids[$k]);
458 }
459 }
460 }
461
462 return $orgu_ref_ids;
463 }
464
465
482 public function buildTempTableWithUsrAssignements($temporary_table_name = 'orgu_usr_assignements')
483 {
484 if (self::$temporary_table_name == $temporary_table_name) {
485 return true;
486 }
487 if (self::$temporary_table_name === null) {
489 self::$temporary_table_name = $temporary_table_name;
490 } elseif ($temporary_table_name != self::$temporary_table_name) {
491 throw new ilException('there is already a temporary table for org-unit assignement: ' . self::$temporary_table_name);
492 }
493
494 $q = "CREATE TEMPORARY TABLE IF NOT EXISTS " . $temporary_table_name . " AS (
495 SELECT DISTINCT object_reference.ref_id AS ref_id, il_orgu_ua.user_id AS user_id, orgu_path_storage.path AS path
496 FROM il_orgu_ua
497 JOIN object_reference ON object_reference.ref_id = il_orgu_ua.orgu_id
498 JOIN object_data ON object_data.obj_id = object_reference.obj_id
499 JOIN orgu_path_storage ON orgu_path_storage.ref_id = object_reference.ref_id
500 WHERE object_data.type = 'orgu' AND object_reference.deleted IS NULL
501 );";
502 $this->db->manipulate($q);
503
504 return true;
505 }
506
507
514 {
515 if (self::$temporary_table_name === null
516 || $temporary_table_name != self::$temporary_table_name) {
517 return false;
518 }
519 $q = "DROP TABLE IF EXISTS " . $temporary_table_name;
520 $this->db->manipulate($q);
521
522 self::$temporary_table_name = null;
523
524 return true;
525 }
526
527
533 public function getTitles($org_refs)
534 {
535 $names = array();
536 foreach ($org_refs as $org_unit) {
537 $names[$org_unit] = ilObject::_lookupTitle(ilObject::_lookupObjId($org_unit));
538 }
539
540 return $names;
541 }
542
543
547 public function getEmployeeRoles()
548 {
549 $this->loadRoles("employee");
550
551 return $this->roles["employee"];
552 }
553
554
558 public function getSuperiorRoles()
559 {
560 $this->loadRoles("superior");
561
562 return $this->roles["superior"];
563 }
564
565
569 private function loadRoles($role)
570 {
571 if ($this->roles[$role] == null) {
572 $this->loadRolesQuery($role);
573 }
574 }
575
576
577 public function flushCache()
578 {
579 $this->roles = null;
580 }
581
582
586 private function loadRolesQuery($role)
587 {
588 $this->roles[$role] = array();
589 $q = "SELECT obj_id, title FROM object_data WHERE type = 'role' AND title LIKE 'il_orgu_" . $role . "%'";
590 $set = $this->db->query($q);
591 while ($res = $this->db->fetchAssoc($set)) {
592 $orgu_ref = $this->getRefIdFromRoleTitle($res["title"]);
593 $this->roles[$role][$orgu_ref] = $res["obj_id"];
594 $this->role_to_orgu[$role][$res["obj_id"]] = $orgu_ref;
595 }
596 }
597
598
604 private function getRefIdFromRoleTitle($role_title)
605 {
606 $array = explode("_", $role_title);
607
608 return $array[count($array) - 1];
609 }
610
611
632 public function getLevelXOfTreenode($orgu_ref, $level)
633 {
634 $line = array( $orgu_ref );
635 $current_ref = $orgu_ref;
636 while ($current_ref != ilObjOrgUnit::getRootOrgRefId()) {
637 $current_ref = $this->getParent($current_ref);
638 if ($current_ref) {
639 $line[] = $current_ref;
640 } else {
641 break;
642 }
643 if (count($line) > 100) {
644 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");
645 }
646 }
647 $line = array_reverse($line);
648 if (count($line) > $level) {
649 return $line[$level];
650 } else {
651 throw new Exception("you want to fetch level " . $level . " but the line to the length of the line is only " . count($line)
652 . ". The line of the given org unit is: " . print_r($line, true));
653 }
654 }
655
656
662 public function getParent($orgu_ref)
663 {
664 if (!$this->parent[$orgu_ref]) {
665 $this->parent[$orgu_ref] = $this->tree->getParentId($orgu_ref);
666 }
667
668 return $this->parent[$orgu_ref];
669 }
670}
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...
getEmployeesUnderUser($user_id, $recursive=true)
getOrgUnitOfUser($user_id, $ref_id=0)
getOrgUnitOfUser
getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
getEmployees($ref_id, $recursive=false)
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)
if(!array_key_exists('StateId', $_REQUEST)) $id
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18