ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 // return $this->getAssignements($ref_id, new ilOrgUnitPosition(1));
83 return array_unique(($recursive ? $this->loadStaffRecursive("employee", $ref_id) : $this->loadStaff("employee", $ref_id)));
84 }
85
86
93 public function getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
94 {
95 return ilOrgUnitUserAssignment::where(array( 'orgu_id' => $ref_id,
96 'position_id' => $ilOrgUnitPosition->getId(),
97 ))->getArray('id', 'user_id');
98 }
99
100
107 public function getSuperiors($ref_id, $recursive = false)
108 {
109 return array_unique(($recursive ? $this->loadStaffRecursive("superior", $ref_id) : $this->loadStaff("superior", $ref_id)));
110 }
111
112
119 private function loadStaff($title, $ref_id)
120 {
121 return $this->loadArrayOfStaff($title, array( $ref_id ));
122 }
123
124
125 private function loadStaffRecursive($title, $ref_id)
126 {
127 return $this->loadArrayOfStaff($title, $this->getAllChildren($ref_id));
128 }
129
130
137 private function loadArrayOfStaff($title, $ref_ids)
138 {
139 $this->loadRoles($title);
140 $all_refs = $ref_ids;
141 //take away ref_ids that are already loaded.
142 foreach ($ref_ids as $id => $ref_id) {
143 if (isset($this->staff[$title][$ref_id])) {
144 unset($ref_ids[$id]);
145 } else {
146 $this->staff[$title][$ref_id] = array();
147 $ref_ids[$id] = $this->roles[$title][$ref_id];
148 }
149 }
150
151 //if there are still refs that need to be loaded, then do so.
152 if (count($ref_ids)) {
153 $q = "SELECT usr_id, rol_id FROM rbac_ua WHERE "
154 . $this->db->in("rol_id", $ref_ids, false, "integer");
155 $set = $this->db->query($q);
156 while ($res = $this->db->fetchAssoc($set)) {
157 $orgu_ref = $this->role_to_orgu[$title][$res["rol_id"]];
158 $this->staff[$title][$orgu_ref][] = $res["usr_id"];
159 }
160 }
161
162 //collect * users.
163 $all_users = array();
164 foreach ($all_refs as $ref) {
165 $all_users = array_merge($all_users, $this->staff[$title][$ref]);
166 }
167
168 return $all_users;
169 }
170
171
177 public function getAllChildren($ref_id)
178 {
179 $open = array( $ref_id );
180 $closed = array();
181 while (count($open)) {
182 $ref = array_pop($open);
183 $closed[] = $ref;
184 foreach ($this->getChildren($ref) as $child) {
185 if (!in_array($child, $open) && !in_array($child, $closed)) {
186 $open[] = $child;
187 }
188 }
189 }
190
191 return $closed;
192 }
193
194
204 {
205 global $DIC;
206 $ilUser = $DIC['ilUser'];
207 /*$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
208 INNER JOIN rbac_operations ON rbac_operations.operation = ".$this->db->quote($operation, "text")."
209 INNER JOIN rbac_ua ON rbac_ua.usr_id = ".$this->db->quote($ilUser->getId(), "integer")."
210 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
211 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
212 INNER JOIN tree ON tree.child = rbac_fa.parent
213 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
214 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";*/
215
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 = "
218 . $this->db->quote($operation, "text") . "
219 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
220 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
221 INNER JOIN object_reference ON object_reference.ref_id = rbac_pa.ref_id
222 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
223
224 $set = $this->db->query($q);
225 $orgus = array();
226 while ($res = $this->db->fetchAssoc($set)) {
227 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
228 $perm_check = unserialize($res['ops_id']);
229 if (!in_array($res["op_id"], $perm_check)) {
230 continue;
231 }
232
233 $orgus[] = $res["ref_id"];
234 }
235
236 return $orgus;
237 }
238
239
248 public function getOrgusWhereUserHasPermissionForOperationId($operation_id)
249 {
250 global $DIC;
251 $ilUser = $DIC['ilUser'];
252 $q = "SELECT object_data.obj_id, object_data.title, object_data.type, rbac_pa.ops_id FROM object_data
253 INNER JOIN rbac_ua ON rbac_ua.usr_id = " . $this->db->quote($ilUser->getId(), "integer") . "
254 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', "
255 . $this->db->quote($operation_id, "integer") . ", '%')
256 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
257 INNER JOIN tree ON tree.child = rbac_fa.parent
258 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
259 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
260
261 $set = $this->db->query($q);
262 $orgus = array();
263 while ($res = $this->db->fetchAssoc($set)) {
264 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
265 $perm_check = unserialize($res['ops_id']);
266 if (!in_array($res["ops_id"], $perm_check)) {
267 continue;
268 }
269
270 $orgus[] = $res["obj_id"];
271 }
272
273 return $orgus;
274 }
275
276
282 private function getChildren($ref_id)
283 {
284 $this->loadChildren($ref_id);
285
286 return $this->tree_childs[$ref_id];
287 }
288
289
293 private function loadChildren($ref_id)
294 {
295 if (!$this->tree_childs[$ref_id]) {
296 $children = array();
297 foreach ($this->tree->getChilds($ref_id) as $child) {
298 if ($child["type"] == "orgu") {
299 $children[] = $child["child"];
300 }
301 }
302 $this->tree_childs[$ref_id] = $children;
303 };
304 }
305
306
312 public function getAllOrgunitsOnLevelX($level)
313 {
314 $levels = array( 0 => array( ilObjOrgUnit::getRootOrgRefId() ) );
315 $current_level = 0;
316 while ($current_level < $level) {
317 $new_level = array();
318 foreach ($levels[$current_level] as $orgu_ref) {
319 $new_level = array_merge($this->getChildren($orgu_ref), $new_level);
320 }
321 $new_level = array_unique($new_level);
322 $levels[$current_level + 1] = $new_level;
323 $current_level++;
324 }
325
326 return $levels[$level];
327 }
328
329
338 public function getEmployeesUnderUser($user_id, $recursive = true)
339 {
340 //querry for all orgu where user_id is superior.
341 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
342 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
343 INNER JOIN object_data roles ON roles.title LIKE CONCAT('il_orgu_superior_',refr.ref_id)
344 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
345 WHERE orgu.type = 'orgu'";
346 $set = $this->db->query($q);
347 $orgu_ref_ids = array();
348 while ($res = $this->db->fetchAssoc($set)) {
349 $orgu_ref_ids[] = $res['ref_id'];
350 }
351 $employees = array();
352 foreach ($orgu_ref_ids as $orgu_ref_id) {
353 $employees = array_merge($employees, $this->getEmployees($orgu_ref_id, $recursive));
354 }
355
356 return $employees;
357 }
358
359
368 public function getSuperiorsOfUser($user_id, $recursive = true)
369 {
370 //querry for all orgu where user_id is superior.
371 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
372 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
373 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)
374 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
375 WHERE orgu.type = 'orgu'";
376 $set = $this->db->query($q);
377 $orgu_ref_ids = array();
378 while ($res = $this->db->fetchAssoc($set)) {
379 $orgu_ref_ids[] = $res['ref_id'];
380 }
381 $superiors = array();
382 foreach ($orgu_ref_ids as $orgu_ref_id) {
383 $superiors = array_merge($superiors, $this->getSuperiors($orgu_ref_id, $recursive));
384 }
385
386 return $superiors;
387 }
388
389
398 public function getLevelXOfUser($user_id, $level)
399 {
400 $q = "SELECT object_reference.ref_id FROM rbac_ua
401 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
402 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
403 JOIN object_data ON object_data.obj_id = object_reference.obj_id
404 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer')
405 . " AND object_data.type = 'orgu';";
406
407 $set = $this->db->query($q);
408 $orgu_ref_ids = array();
409 while ($res = $this->db->fetchAssoc($set)) {
410 $orgu_ref_ids[] = $res['ref_id'];
411 }
412 $orgus_on_level_x = array();
413 foreach ($orgu_ref_ids as $orgu_ref_id) {
414 try {
415 $orgus_on_level_x[] = $this->getLevelXOfTreenode($orgu_ref_id, $level);
416 } catch (Exception $e) {
417 // this means the user is assigned to a orgu above the given level. just dont add it to the list.
418 }
419 }
420
421 return array_unique($orgus_on_level_x);
422 }
423
424
433 public function getOrgUnitOfUser($user_id, $ref_id = 0)
434 {
435 $q = "SELECT object_reference.ref_id FROM rbac_ua
436 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
437 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
438 JOIN object_data ON object_data.obj_id = object_reference.obj_id
439 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer')
440 . " AND object_data.type = 'orgu'";
441
442 $set = $this->db->query($q);
443 $orgu_ref_ids = array();
444 while ($res = $this->db->fetchAssoc($set)) {
445 $orgu_ref_ids[] = $res['ref_id'];
446 }
447 $orgu_ref_ids = array_unique($orgu_ref_ids);
448 if ($ref_id) {
449 $childernOrgIds = $this->getAllChildren($ref_id);
450 foreach ($orgu_ref_ids as $k => $refId) {
451 if (!in_array($refId, $childernOrgIds)) {
452 unset($orgu_ref_ids[$k]);
453 }
454 }
455 }
456
457 return $orgu_ref_ids;
458 }
459
460
477 public function buildTempTableWithUsrAssignements($temporary_table_name = 'orgu_usr_assignements')
478 {
479 if (self::$temporary_table_name == $temporary_table_name) {
480 return true;
481 }
482 if (self::$temporary_table_name === null) {
484 self::$temporary_table_name = $temporary_table_name;
485 } elseif ($temporary_table_name != self::$temporary_table_name) {
486 throw new ilException('there is already a temporary table for org-unit assignement: '
487 . self::$temporary_table_name);
488 }
489
490 $q = "CREATE TEMPORARY TABLE IF NOT EXISTS " . $temporary_table_name . " AS (
491 SELECT DISTINCT object_reference.ref_id AS ref_id, il_orgu_ua.user_id AS user_id, orgu_path_storage.path AS path
492 FROM il_orgu_ua
493 JOIN object_reference ON object_reference.ref_id = il_orgu_ua.orgu_id
494 JOIN object_data ON object_data.obj_id = object_reference.obj_id
495 JOIN orgu_path_storage ON orgu_path_storage.ref_id = object_reference.ref_id
496 WHERE object_data.type = 'orgu' AND object_reference.deleted IS NULL
497 );";
498 $this->db->manipulate($q);
499
500 return true;
501 }
502
503
510 {
511 if (self::$temporary_table_name === null
512 || $temporary_table_name != self::$temporary_table_name) {
513 return false;
514 }
515 $q = "DROP TABLE IF EXISTS " . $temporary_table_name;
516 $this->db->manipulate($q);
517
518 self::$temporary_table_name = null;
519
520 return true;
521 }
522
523
529 public function getTitles($org_refs)
530 {
531 $names = array();
532 foreach ($org_refs as $org_unit) {
534 }
535
536 return $names;
537 }
538
539
543 public function getEmployeeRoles()
544 {
545 $this->loadRoles("employee");
546
547 return $this->roles["employee"];
548 }
549
550
554 public function getSuperiorRoles()
555 {
556 $this->loadRoles("superior");
557
558 return $this->roles["superior"];
559 }
560
561
565 private function loadRoles($role)
566 {
567 if ($this->roles[$role] == null) {
568 $this->loadRolesQuery($role);
569 }
570 }
571
572
573 public function flushCache()
574 {
575 $this->roles = null;
576 }
577
578
582 private function loadRolesQuery($role)
583 {
584 $this->roles[$role] = array();
585 $q = "SELECT obj_id, title FROM object_data WHERE type = 'role' AND title LIKE 'il_orgu_"
586 . $role . "%'";
587 $set = $this->db->query($q);
588 while ($res = $this->db->fetchAssoc($set)) {
589 $orgu_ref = $this->getRefIdFromRoleTitle($res["title"]);
590 $this->roles[$role][$orgu_ref] = $res["obj_id"];
591 $this->role_to_orgu[$role][$res["obj_id"]] = $orgu_ref;
592 }
593 }
594
595
601 private function getRefIdFromRoleTitle($role_title)
602 {
603 $array = explode("_", $role_title);
604
605 return $array[count($array) - 1];
606 }
607
608
629 public function getLevelXOfTreenode($orgu_ref, $level)
630 {
631 $line = array( $orgu_ref );
632 $current_ref = $orgu_ref;
633 while ($current_ref != ilObjOrgUnit::getRootOrgRefId()) {
634 $current_ref = $this->getParent($current_ref);
635 if ($current_ref) {
636 $line[] = $current_ref;
637 } else {
638 break;
639 }
640 if (count($line) > 100) {
641 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");
642 }
643 }
644 $line = array_reverse($line);
645 if (count($line) > $level) {
646 return $line[$level];
647 } else {
648 throw new Exception("you want to fetch level " . $level
649 . " but the line to the length of the line is only " . count($line)
650 . ". The line of the given org unit is: " . print_r($line, true));
651 }
652 }
653
654
660 public function getParent($orgu_ref)
661 {
662 if (!$this->parent[$orgu_ref]) {
663 $this->parent[$orgu_ref] = $this->tree->getParentId($orgu_ref);
664 }
665
666 return $this->parent[$orgu_ref];
667 }
668}
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.
loadStaff($title, $ref_id)
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...
loadStaffRecursive($title, $ref_id)
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.
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