ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 */
3require_once("./Modules/OrgUnit/classes/class.ilObjOrgUnit.php");
4
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 global $DIC;
51 $ilDB = $DIC['ilDB'];
52 $tree = $DIC['tree'];
53 $this->db = $ilDB;
54 $this->tree = $tree;
55 $this->roles = array();
56 $this->staff = array();
57 }
58
59
63 public static function _getInstance() {
64 if (self::$instance === null) {
65 self::$instance = new self();
66 }
67
68 return self::$instance;
69 }
70
71
77 public function getEmployees($ref_id, $recursive = false) {
78 return array_unique(($recursive ? $this->loadStaffRecursive("employee", $ref_id) : $this->loadStaff("employee", $ref_id)));
79 }
80
81
87 public function getSuperiors($ref_id, $recursive = false) {
88 return array_unique(($recursive ? $this->loadStaffRecursive("superior", $ref_id) : $this->loadStaff("superior", $ref_id)));
89 }
90
91
97 private function loadStaff($title, $ref_id) {
98 return $this->loadArrayOfStaff($title, array( $ref_id ));
99 }
100
101
102 private function loadStaffRecursive($title, $ref_id) {
103 return $this->loadArrayOfStaff($title, $this->getAllChildren($ref_id));
104 }
105
106
112 private function loadArrayOfStaff($title, $ref_ids) {
113 $this->loadRoles($title);
114 $all_refs = $ref_ids;
115 //take away ref_ids that are already loaded.
116 foreach ($ref_ids as $id => $ref_id) {
117 if (isset($this->staff[$title][$ref_id])) {
118 unset($ref_ids[$id]);
119 } else {
120 $this->staff[$title][$ref_id] = array();
121 $ref_ids[$id] = $this->roles[$title][$ref_id];
122 }
123 }
124
125 //if there are still refs that need to be loaded, then do so.
126 if (count($ref_ids)) {
127 $q = "SELECT usr_id, rol_id FROM rbac_ua WHERE " . $this->db->in("rol_id", $ref_ids, false, "integer");
128 $set = $this->db->query($q);
129 while ($res = $this->db->fetchAssoc($set)) {
130 $orgu_ref = $this->role_to_orgu[$title][$res["rol_id"]];
131 $this->staff[$title][$orgu_ref][] = $res["usr_id"];
132 }
133 }
134
135 //collect * users.
136 $all_users = array();
137 foreach ($all_refs as $ref) {
138 $all_users = array_merge($all_users, $this->staff[$title][$ref]);
139 }
140
141 return $all_users;
142 }
143
144
149 public function getAllChildren($ref_id) {
150 $open = array( $ref_id );
151 $closed = array();
152 while (count($open)) {
153 $ref = array_pop($open);
154 $closed[] = $ref;
155 foreach ($this->getChildren($ref) as $child) {
156 if (!in_array($child, $open) && !in_array($child, $closed)) {
157 $open[] = $child;
158 }
159 }
160 }
161
162 return $closed;
163 }
164
165
172 public function getOrgusWhereUserHasPermissionForOperation($operation) {
173 global $DIC;
174 $ilUser = $DIC['ilUser'];
175 /*$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
176 INNER JOIN rbac_operations ON rbac_operations.operation = ".$this->db->quote($operation, "text")."
177 INNER JOIN rbac_ua ON rbac_ua.usr_id = ".$this->db->quote($ilUser->getId(), "integer")."
178 INNER JOIN rbac_pa ON rbac_pa.rol_id = rbac_ua.rol_id AND rbac_pa.ops_id LIKE CONCAT('%', rbac_operations.ops_id, '%')
179 INNER JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
180 INNER JOIN tree ON tree.child = rbac_fa.parent
181 INNER JOIN object_reference ON object_reference.ref_id = tree.parent
182 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";*/
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 object_reference ON object_reference.ref_id = rbac_pa.ref_id
189 WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'orgu'";
190
191 $set = $this->db->query($q);
192 $orgus = array();
193 while ($res = $this->db->fetchAssoc($set)) {
194 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
195 $perm_check = unserialize($res['ops_id']);
196 if (!in_array($res["op_id"], $perm_check)) {
197 continue;
198 }
199
200 $orgus[] = $res["ref_id"];
201 }
202
203 return $orgus;
204 }
205
206
214 public function getOrgusWhereUserHasPermissionForOperationId($operation_id) {
215 global $DIC;
216 $ilUser = $DIC['ilUser'];
217 $q = "SELECT object_data.obj_id, object_data.title, object_data.type, rbac_pa.ops_id FROM object_data
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('%', " . $this->db->quote($operation_id, "integer") . ", '%')
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 $set = $this->db->query($q);
226 $orgus = array();
227 while ($res = $this->db->fetchAssoc($set)) {
228 //this is needed as the table rbac_operations is not in the first normal form, thus this needs some additional checkings.
229 $perm_check = unserialize($res['ops_id']);
230 if (!in_array($res["ops_id"], $perm_check)) {
231 continue;
232 }
233
234 $orgus[] = $res["obj_id"];
235 }
236
237 return $orgus;
238 }
239
240
245 private function getChildren($ref_id) {
246 $this->loadChildren($ref_id);
247
248 return $this->tree_childs[$ref_id];
249 }
250
251
255 private function loadChildren($ref_id) {
256 if (!$this->tree_childs[$ref_id]) {
257 $children = array();
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
272 public function getAllOrgunitsOnLevelX($level) {
273 $levels = array( 0 => array( ilObjOrgUnit::getRootOrgRefId() ) );
274 $current_level = 0;
275 while ($current_level < $level) {
276 $new_level = array();
277 foreach ($levels[$current_level] as $orgu_ref) {
278 $new_level = array_merge($this->getChildren($orgu_ref), $new_level);
279 }
280 $new_level = array_unique($new_level);
281 $levels[$current_level + 1] = $new_level;
282 $current_level ++;
283 }
284
285 return $levels[$level];
286 }
287
288
294 public function getEmployeesUnderUser($user_id, $recursive = true) {
295 //querry for all orgu where user_id is superior.
296 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
297 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
298 INNER JOIN object_data roles ON roles.title LIKE CONCAT('il_orgu_superior_',refr.ref_id)
299 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
300 WHERE orgu.type = 'orgu'";
301 $set = $this->db->query($q);
302 $orgu_ref_ids = array();
303 while ($res = $this->db->fetchAssoc($set)) {
304 $orgu_ref_ids[] = $res['ref_id'];
305 }
306 $employees = array();
307 foreach ($orgu_ref_ids as $orgu_ref_id) {
308 $employees = array_merge($employees, $this->getEmployees($orgu_ref_id, $recursive));
309 }
310
311 return $employees;
312 }
313
314
320 public function getSuperiorsOfUser($user_id, $recursive = true) {
321 //querry for all orgu where user_id is superior.
322 $q = "SELECT orgu.obj_id, refr.ref_id FROM object_data orgu
323 INNER JOIN object_reference refr ON refr.obj_id = orgu.obj_id
324 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)
325 INNER JOIN rbac_ua rbac ON rbac.usr_id = " . $this->db->quote($user_id, "integer") . " AND roles.obj_id = rbac.rol_id
326 WHERE orgu.type = 'orgu'";
327 $set = $this->db->query($q);
328 $orgu_ref_ids = array();
329 while ($res = $this->db->fetchAssoc($set)) {
330 $orgu_ref_ids[] = $res['ref_id'];
331 }
332 $superiors = array();
333 foreach ($orgu_ref_ids as $orgu_ref_id) {
334 $superiors = array_merge($superiors, $this->getSuperiors($orgu_ref_id, $recursive));
335 }
336
337 return $superiors;
338 }
339
340
349 public function getLevelXOfUser($user_id, $level) {
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
373
381 public function getOrgUnitOfUser($user_id, $ref_id = 0) {
382 $q = "SELECT object_reference.ref_id FROM rbac_ua
383 JOIN rbac_fa ON rbac_fa.rol_id = rbac_ua.rol_id
384 JOIN object_reference ON rbac_fa.parent = object_reference.ref_id
385 JOIN object_data ON object_data.obj_id = object_reference.obj_id
386 WHERE rbac_ua.usr_id = " . $this->db->quote($user_id, 'integer') . " AND object_data.type = 'orgu'";
387
388 $set = $this->db->query($q);
389 $orgu_ref_ids = array();
390 while ($res = $this->db->fetchAssoc($set)) {
391 $orgu_ref_ids[] = $res['ref_id'];
392 }
393 $orgu_ref_ids = array_unique($orgu_ref_ids);
394 if ($ref_id) {
395 $childernOrgIds = $this->getAllChildren($ref_id);
396 foreach ($orgu_ref_ids as $k => $refId) {
397 if (!in_array($refId, $childernOrgIds)) {
398 unset($orgu_ref_ids[$k]);
399 }
400 }
401 }
402
403 return $orgu_ref_ids;
404 }
405
406
422 public function buildTempTableWithUsrAssignements($temporary_table_name = 'orgu_usr_assignements') {
423 if (self::$temporary_table_name == $temporary_table_name) {
424 return true;
425 }
426 if (self::$temporary_table_name === null) {
428 self::$temporary_table_name = $temporary_table_name;
429 } elseif ($temporary_table_name != self::$temporary_table_name) {
430 throw new ilException('there is already a temporary table for org-unit assignement: ' . self::$temporary_table_name);
431 }
432
433 $q = "CREATE TEMPORARY TABLE IF NOT EXISTS " . $temporary_table_name . " AS (
434 SELECT DISTINCT object_reference.ref_id AS ref_id, rbac_ua.usr_id AS user_id, orgu_path_storage.path AS path
435 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 JOIN orgu_path_storage ON orgu_path_storage.ref_id = object_reference.ref_id
440 WHERE object_data.type = 'orgu' AND object_reference.deleted IS NULL
441 );";
442 $this->db->manipulate($q);
443 return true;
444 }
445
446
452 if (self::$temporary_table_name === null || $temporary_table_name != self::$temporary_table_name) {
453 return false;
454 }
455 $q = "DROP TABLE IF EXISTS " . $temporary_table_name;
456 $this->db->manipulate($q);
457
458 self::$temporary_table_name = null;
459
460 return true;
461 }
462
463
468 public function getTitles($org_refs) {
469 $names = array();
470 foreach ($org_refs as $org_unit) {
472 }
473
474 return $names;
475 }
476
477
481 public function getEmployeeRoles() {
482 $this->loadRoles("employee");
483
484 return $this->roles["employee"];
485 }
486
487
491 public function getSuperiorRoles() {
492 $this->loadRoles("superior");
493
494 return $this->roles["superior"];
495 }
496
497
501 private function loadRoles($role) {
502 if ($this->roles[$role] == null) {
503 $this->loadRolesQuery($role);
504 }
505 }
506
507
508 public function flushCache() {
509 $this->roles = null;
510 }
511
512
516 private function loadRolesQuery($role) {
517 $this->roles[$role] = array();
518 $q = "SELECT obj_id, title FROM object_data WHERE type = 'role' AND title LIKE 'il_orgu_" . $role . "%'";
519 $set = $this->db->query($q);
520 while ($res = $this->db->fetchAssoc($set)) {
521 $orgu_ref = $this->getRefIdFromRoleTitle($res["title"]);
522 $this->roles[$role][$orgu_ref] = $res["obj_id"];
523 $this->role_to_orgu[$role][$res["obj_id"]] = $orgu_ref;
524 }
525 }
526
527
532 private function getRefIdFromRoleTitle($role_title) {
533 $array = explode("_", $role_title);
534
535 return $array[count($array) - 1];
536 }
537
538
557 public function getLevelXOfTreenode($orgu_ref, $level) {
558 $line = array( $orgu_ref );
559 $current_ref = $orgu_ref;
560 while ($current_ref != ilObjOrgUnit::getRootOrgRefId()) {
561 $current_ref = $this->getParent($current_ref);
562 if ($current_ref) {
563 $line[] = $current_ref;
564 } else {
565 break;
566 }
567 if (count($line) > 100) {
568 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");
569 }
570 }
571 $line = array_reverse($line);
572 if (count($line) > $level) {
573 return $line[$level];
574 } else {
575 throw new Exception("you want to fetch level " . $level . " but the line to the length of the line is only " . count($line)
576 . ". The line of the given org unit is: " . print_r($line, true));
577 }
578 }
579
580
585 public function getParent($orgu_ref) {
586 if (!$this->parent[$orgu_ref]) {
587 $this->parent[$orgu_ref] = $this->tree->getParentId($orgu_ref);
588 }
589
590 return $this->parent[$orgu_ref];
591 }
592}
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
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
$ref_id
Definition: sahs_server.php:39
global $ilDB
global $DIC
$ilUser
Definition: imgupload.php:18