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;
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  // 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 
203  public function getOrgusWhereUserHasPermissionForOperation($operation)
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) {
533  $names[$org_unit] = ilObject::_lookupTitle(ilObject::_lookupObjId($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 }
getRefIdFromRoleTitle($role_title)
global $DIC
Definition: saml.php:7
if(!array_key_exists('StateId', $_REQUEST)) $id
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)
loadStaffRecursive($title, $ref_id)
$ilUser
Definition: imgupload.php:18
Class ilObjOrgUnitTree Implements a singleton pattern for caching.
Create styles array
The data for the language used.
static getRootOrgRefId()
loadStaff($title, $ref_id)
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