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;
30  private $role_to_orgu;
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  {
108  return ilOrgUnitUserAssignment::where(array(
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 
212  public function getOrgusWhereUserHasPermissionForOperation($operation)
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 }
getRefIdFromRoleTitle($role_title)
global $DIC
Definition: saml.php:7
if(!array_key_exists('StateId', $_REQUEST)) $id
static getCorePosition($core_identifier)
static _lookupTitle($a_id)
lookup object title
static where($where, $operator=null)
getAssignements($ref_id, ilOrgUnitPosition $ilOrgUnitPosition)
getSuperiorsOfUser($user_id, $recursive=true)
getOrgusWhereUserHasPermissionForOperationId($operation_id)
If you want to have all orgunits where the current user has the write permission: use this with the p...
getEmployees($ref_id, $recursive=false)
foreach($_POST as $key=> $value) $res
loadArrayOfStaff($title, $ref_ids)
static _lookupObjId($a_id)
getEmployeesUnderUser($user_id, $recursive=true)
getSuperiors($ref_id, $recursive=false)
$ilUser
Definition: imgupload.php:18
Class ilObjOrgUnitTree Implements a singleton pattern for caching.
static getRootOrgRefId()
getLevelXOfTreenode($orgu_ref, $level)
Specify eg.
Class ilOrgUnitPosition.
global $ilDB
dropTempTable($temporary_table_name)
buildTempTableWithUsrAssignements($temporary_table_name='orgu_usr_assignements')
Creates a temporary table with all orgu/user assignements.
getLevelXOfUser($user_id, $level)
for additional info see the other getLevelX method.
getOrgusWhereUserHasPermissionForOperation($operation)
If you want to have all orgunits where the current user has the write permission: use this with the p...
getOrgUnitOfUser($user_id, $ref_id=0)
getOrgUnitOfUser