ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilRbacReview.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
21 {
22  const FILTER_ALL = 1;
23  const FILTER_ALL_GLOBAL = 2;
24  const FILTER_ALL_LOCAL = 3;
25  const FILTER_INTERNAL = 4;
27  const FILTER_TEMPLATES = 6;
28 
29  protected $assigned_roles = array();
30  var $log = null;
31 
32  // Cache operation ids
33  private static $_opsCache = null;
34 
39  function ilRbacReview()
40  {
41  global $ilDB,$ilErr,$ilias,$ilLog;
42 
43  $this->log =& $ilLog;
44 
45  // set db & error handler
46  (isset($ilDB)) ? $this->ilDB =& $ilDB : $this->ilDB =& $ilias->db;
47 
48  if (!isset($ilErr))
49  {
50  $ilErr = new ilErrorHandling();
51  $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK,array($ilErr,'errorHandler'));
52  }
53  else
54  {
55  $this->ilErr =& $ilErr;
56  }
57  }
58 
105  function searchRolesByMailboxAddressList($a_address_list)
106  {
107  global $ilDB;
108 
109  $role_ids = array();
110 
111  include_once "Services/Mail/classes/class.ilMail.php";
112  if(ilMail::_usePearMail())
113  {
114  require_once './Services/PEAR/lib/Mail/RFC822.php';
115  $parser = new Mail_RFC822();
116  $parsedList = $parser->parseAddressList($a_address_list, "ilias", false, true);
117  foreach ($parsedList as $address)
118  {
119  $local_part = $address->mailbox;
120  if (strpos($local_part,'#') !== 0 &&
121  !($local_part{0} == '"' && $local_part{1} == "#"))
122  {
123  // A local-part which doesn't start with a '#' doesn't denote a role.
124  // Therefore we can skip it.
125  continue;
126  }
127 
128  $local_part = substr($local_part, 1);
129 
130  /* If role contains spaces, eg. 'foo role', double quotes are added which have to be
131  removed here.*/
132  if( $local_part{0} == '#' && $local_part{strlen($local_part) - 1} == '"' )
133  {
134  $local_part = substr($local_part, 1);
135  $local_part = substr($local_part, 0, strlen($local_part) - 1);
136  }
137 
138  if (substr($local_part,0,8) == 'il_role_')
139  {
140  $role_id = substr($local_part,8);
141  $query = "SELECT t.tree ".
142  "FROM rbac_fa fa ".
143  "JOIN tree t ON t.child = fa.parent ".
144  "WHERE fa.rol_id = ".$this->ilDB->quote($role_id,'integer')." ".
145  "AND fa.assign = 'y' ".
146  "AND t.tree = 1";
147  $r = $ilDB->query($query);
148  if ($r->numRows() > 0)
149  {
150  $role_ids[] = $role_id;
151  }
152  continue;
153  }
154 
155 
156  $domain = $address->host;
157  if (strpos($domain,'[') == 0 && strrpos($domain,']'))
158  {
159  $domain = substr($domain,1,strlen($domain) - 2);
160  }
161  if (strlen($local_part) == 0)
162  {
163  $local_part = $domain;
164  $address->host = 'ilias';
165  $domain = 'ilias';
166  }
167 
168  if (strtolower($address->host) == 'ilias')
169  {
170  // Search for roles = local-part in the whole repository
171  $query = "SELECT dat.obj_id ".
172  "FROM object_data dat ".
173  "JOIN rbac_fa fa ON fa.rol_id = dat.obj_id ".
174  "JOIN tree t ON t.child = fa.parent ".
175  "WHERE dat.title =".$this->ilDB->quote($local_part,'text')." ".
176  "AND dat.type = 'role' ".
177  "AND fa.assign = 'y' ".
178  "AND t.tree = 1";
179  }
180  else
181  {
182  // Search for roles like local-part in objects = host
183  $query = "SELECT rdat.obj_id ".
184  "FROM object_data odat ".
185  "JOIN object_reference oref ON oref.obj_id = odat.obj_id ".
186  "JOIN tree otree ON otree.child = oref.ref_id ".
187  "JOIN tree rtree ON rtree.parent = otree.child ".
188  "JOIN rbac_fa rfa ON rfa.parent = rtree.child ".
189  "JOIN object_data rdat ON rdat.obj_id = rfa.rol_id ".
190  "WHERE odat.title = ".$this->ilDB->quote($domain,'text')." ".
191  "AND otree.tree = 1 AND rtree.tree = 1 ".
192  "AND rfa.assign = 'y' ".
193  "AND rdat.title LIKE ".
194  $this->ilDB->quote('%'.preg_replace('/([_%])/','\\\\$1',$local_part).'%','text');
195  }
196  $r = $ilDB->query($query);
197 
198  $count = 0;
199  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
200  {
201  $role_ids[] = $row->obj_id;
202  $count++;
203  }
204 
205  // Nothing found?
206  // In this case, we search for roles = host.
207  if ($count == 0 && strtolower($address->host) == 'ilias')
208  {
209  $q = "SELECT dat.obj_id ".
210  "FROM object_data dat ".
211  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
212  "JOIN tree t ON t.child = ref.ref_id ".
213  "WHERE dat.title = ".$this->ilDB->quote($domain ,'text')." ".
214  "AND dat.type = 'role' ".
215  "AND t.tree = 1 ";
216  $r = $this->ilDB->query($q);
217 
218  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
219  {
220  $role_ids[] = $row->obj_id;
221  }
222  }
223  //echo '<br>ids='.var_export($role_ids,true);
224  }
225  }
226  else
227  {
228  // the following code is executed, when Pear Mail is
229  // not installed
230 
231  $titles = explode(',', $a_address_list);
232 
233  $titleList = '';
234  foreach ($titles as $title)
235  {
236  if (strlen($inList) > 0)
237  {
238  $titleList .= ',';
239  }
240  $title = trim($title);
241  if (strpos($title,'#') == 0)
242  {
243  $titleList .= $this->ilDB->quote(substr($title, 1));
244  }
245  }
246  if (strlen($titleList) > 0)
247  {
248  $q = "SELECT obj_id ".
249  "FROM object_data ".
250  "WHERE title IN (".$titleList.") ".
251  "AND type='role'";
252  $r = $this->ilDB->query($q);
253  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
254  {
255  $role_ids[] = $row->obj_id;
256  }
257  }
258  }
259 
260  return $role_ids;
261  }
262 
326  function getRoleMailboxAddress($a_role_id, $is_localize = true)
327  {
328  global $log, $lng,$ilDB;
329 
330  include_once "Services/Mail/classes/class.ilMail.php";
331  if (ilMail::_usePearMail())
332  {
333  // Retrieve the role title and the object title.
334  $query = "SELECT rdat.title role_title,odat.title object_title, ".
335  " oref.ref_id object_ref ".
336  "FROM object_data rdat ".
337  "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id ".
338  "JOIN tree rtree ON rtree.child = fa.parent ".
339  "JOIN object_reference oref ON oref.ref_id = rtree.parent ".
340  "JOIN object_data odat ON odat.obj_id = oref.obj_id ".
341  "WHERE rdat.obj_id = ".$this->ilDB->quote($a_role_id,'integer')." ".
342  "AND fa.assign = 'y' ";
343  $r = $ilDB->query($query);
344  if (!$row = $ilDB->fetchObject($r))
345  {
346  //$log->write('class.ilRbacReview->getMailboxAddress('.$a_role_id.'): error role does not exist');
347  return null; // role does not exist
348  }
349  $object_title = $row->object_title;
350  $object_ref = $row->object_ref;
351  $role_title = $row->role_title;
352 
353 
354  // In a perfect world, we could use the object_title in the
355  // domain part of the mailbox address, and the role title
356  // with prefix '#' in the local part of the mailbox address.
357  $domain = $object_title;
358  $local_part = $role_title;
359 
360 
361  // Determine if the object title is unique
362  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
363  "FROM object_data dat ".
364  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
365  "JOIN tree ON tree.child = ref.ref_id ".
366  "WHERE title = ".$this->ilDB->quote($object_title,'text')." ".
367  "AND tree.tree = 1 ";
368  $r = $this->ilDB->query($q);
369  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
370 
371  // If the object title is not unique, we get rid of the domain.
372  if ($row->count > 1)
373  {
374  $domain = null;
375  }
376 
377  // If the domain contains illegal characters, we get rid of it.
378  //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
379  // Fix for Mantis Bug: 7429 sending mail fails because of brakets
380  // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
381  if ($domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/',$domain))
382  {
383  $domain = null;
384  }
385 
386  // If the domain contains special characters, we put square
387  // brackets around it.
388  if ($domain != null &&
389  (preg_match('/[()<>@,;:\\".\[\]]/',$domain) ||
390  preg_match('/[^\x21-\x8f]/',$domain))
391  )
392  {
393  $domain = '['.$domain.']';
394  }
395 
396  // If the role title is one of the ILIAS reserved role titles,
397  // we can use a shorthand version of it for the local part
398  // of the mailbox address.
399  if (strpos($role_title, 'il_') === 0 && $domain != null)
400  {
401  $unambiguous_role_title = $role_title;
402 
403  $pos = strpos($role_title, '_', 3) + 1;
404  $local_part = substr(
405  $role_title,
406  $pos,
407  strrpos($role_title, '_') - $pos
408  );
409  }
410  else
411  {
412  $unambiguous_role_title = 'il_role_'.$a_role_id;
413  }
414 
415  // Determine if the local part is unique. If we don't have a
416  // domain, the local part must be unique within the whole repositry.
417  // If we do have a domain, the local part must be unique for that
418  // domain.
419  if ($domain == null)
420  {
421  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
422  "FROM object_data dat ".
423  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
424  "JOIN tree ON tree.child = ref.ref_id ".
425  "WHERE title = ".$this->ilDB->quote($local_part,'text')." ".
426  "AND tree.tree = 1 ";
427  }
428  else
429  {
430  $q = "SELECT COUNT(rd.obj_id) count ".
431  "FROM object_data rd ".
432  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
433  "JOIN tree t ON t.child = fa.parent ".
434  "WHERE fa.assign = 'y' ".
435  "AND t.parent = ".$this->ilDB->quote($object_ref,'integer')." ".
436  "AND rd.title LIKE ".$this->ilDB->quote(
437  '%'.preg_replace('/([_%])/','\\\\$1', $local_part).'%','text')." ";
438  }
439 
440  $r = $this->ilDB->query($q);
441  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
442 
443  // if the local_part is not unique, we use the unambiguous role title
444  // instead for the local part of the mailbox address
445  if ($row->count > 1)
446  {
447  $local_part = $unambiguous_role_title;
448  }
449 
450  $use_phrase = true;
451 
452  // If the local part contains illegal characters, we use
453  // the unambiguous role title instead.
454  if (preg_match('/[\\"\x00-\x1f]/',$local_part))
455  {
456  $local_part = $unambiguous_role_title;
457  }
458  else if(!preg_match('/^[\\x00-\\x7E]+$/i', $local_part))
459  {
460  // 2013-12-05: According to #12283, we do not accept umlauts in the local part
461  $local_part = $unambiguous_role_title;
462  $use_phrase = false;
463  }
464 
465  // Add a "#" prefix to the local part
466  $local_part = '#'.$local_part;
467 
468  // Put quotes around the role title, if needed
469  if (preg_match('/[()<>@,;:.\[\]\x20]/',$local_part))
470  {
471  $local_part = '"'.$local_part.'"';
472  }
473 
474  $mailbox = ($domain == null) ?
475  $local_part :
476  $local_part.'@'.$domain;
477 
478  if ($is_localize)
479  {
480  if (substr($role_title,0,3) == 'il_')
481  {
482  $phrase = $lng->txt(substr($role_title, 0, strrpos($role_title,'_')));
483  }
484  else
485  {
486  $phrase = $role_title;
487  }
488 
489  if($use_phrase)
490  {
491  // make phrase RFC 822 conformant:
492  // - strip excessive whitespace
493  // - strip special characters
494  $phrase = preg_replace('/\s\s+/', ' ', $phrase);
495  $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
496 
497  $mailbox = $phrase.' <'.$mailbox.'>';
498  }
499  }
500 
501  return $mailbox;
502  }
503  else
504  {
505  $q = "SELECT title ".
506  "FROM object_data ".
507  "WHERE obj_id = ".$this->ilDB->quote($a_role_id ,'integer');
508  $r = $this->ilDB->query($q);
509 
510  if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
511  {
512  return '#'.$row->title;
513  }
514  else
515  {
516  return null;
517  }
518  }
519  }
520 
521 
529  function roleExists($a_title,$a_id = 0)
530  {
531  global $ilDB;
532 
533  if (empty($a_title))
534  {
535  $message = get_class($this)."::roleExists(): No title given!";
536  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
537  }
538 
539  $clause = ($a_id) ? " AND obj_id != ".$ilDB->quote($a_id)." " : "";
540 
541  $q = "SELECT DISTINCT(obj_id) obj_id FROM object_data ".
542  "WHERE title =".$ilDB->quote($a_title)." ".
543  "AND type IN('role','rolt')".
544  $clause." ";
545  $r = $this->ilDB->query($q);
546 
547  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
548  {
549  return $row->obj_id;
550  }
551  return false;
552  }
553 
566  function __getParentRoles($a_path,$a_templates,$a_keep_protected)
567  {
568  global $log,$ilDB;
569 
570  if (!isset($a_path) or !is_array($a_path))
571  {
572  $message = get_class($this)."::getParentRoles(): No path given or wrong datatype!";
573  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
574  }
575 
576  $parent_roles = array();
577  $role_hierarchy = array();
578 
579  // Select all role folders on a path using a single SQL-statement.
580  // CREATE IN() STATEMENT
581  $in = $ilDB->in('t.parent',$a_path,false,'integer');
582 
583  $q = "SELECT t.child,t.depth FROM tree t ".
584  "JOIN object_reference r ON r.ref_id = t.child ".
585  "JOIN object_data o ON o.obj_id = r.obj_id ".
586  "WHERE ".$in." ".
587  "AND o.type= ".$ilDB->quote('rolf','text')." ".
588  "ORDER BY t.depth ASC";
589 
590  $r = $this->ilDB->query($q);
591 
592 
593  // Sort by path (Administration -> Rolefolder is first element)
594  $role_rows = array();
595  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
596  {
597 
598  $depth = ($row->child == ROLE_FOLDER_ID ? 0 : $row->depth);
599  $role_rows[$depth]['child'] = $row->child;
600  }
601  ksort($role_rows,SORT_NUMERIC);
602 
603  foreach($role_rows as $row)
604  {
605  $roles = $this->getRoleListByObject($row['child'],$a_templates);
606  foreach ($roles as $role)
607  {
608  $id = $role["obj_id"];
609  $role["parent"] = $row['child'];
610  $parent_roles[$id] = $role;
611 
612  if (!array_key_exists($role['obj_id'],$role_hierarchy))
613  {
614  $role_hierarchy[$id] = $row['child'];
615  }
616  }
617  }
618  if (!$a_keep_protected)
619  {
620  return $this->__setProtectedStatus($parent_roles,$role_hierarchy,reset($a_path));
621  }
622  return $parent_roles;
623  }
624 
633  function getParentRoleIds($a_endnode_id,$a_templates = false,$a_keep_protected = false)
634  {
635  global $tree,$log,$ilDB;
636 
637  if (!isset($a_endnode_id))
638  {
639  $GLOBALS['ilLog']->logStack();
640  $message = get_class($this)."::getParentRoleIds(): No node_id (ref_id) given!";
641  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
642  }
643 
644  //var_dump($a_endnode_id);exit;
645  //$log->write("ilRBACreview::getParentRoleIds(), 0");
646  $pathIds = $tree->getPathId($a_endnode_id);
647 
648  // add system folder since it may not in the path
649  $pathIds[0] = SYSTEM_FOLDER_ID;
650  //$log->write("ilRBACreview::getParentRoleIds(), 1");
651  #return $this->getParentRoles($a_endnode_id,$a_templates,$a_keep_protected);
652  return $this->__getParentRoles($pathIds,$a_templates,$a_keep_protected);
653  }
654 
662  function getRoleListByObject($a_ref_id,$a_templates = false)
663  {
664  global $ilDB;
665 
666  if (!isset($a_ref_id) or !isset($a_templates))
667  {
668  $message = get_class($this)."::getRoleListByObject(): Missing parameter!".
669  "ref_id: ".$a_ref_id.
670  "tpl_flag: ".$a_templates;
671  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
672  }
673 
674  $role_list = array();
675 
676  $where = $this->__setTemplateFilter($a_templates);
677 
678  $query = "SELECT * FROM object_data ".
679  "JOIN rbac_fa ON obj_id = rol_id ".
680  $where.
681  "AND object_data.obj_id = rbac_fa.rol_id ".
682  "AND rbac_fa.parent = ".$ilDB->quote($a_ref_id,'integer')." ";
683 
684  $res = $ilDB->query($query);
685  while ($row = $ilDB->fetchAssoc($res))
686  {
687  $row["desc"] = $row["description"];
688  $row["user_id"] = $row["owner"];
689  $role_list[] = $row;
690  }
691 
692  $role_list = $this->__setRoleType($role_list);
693 
694  return $role_list;
695  }
696 
703  function getAssignableRoles($a_templates = false,$a_internal_roles = false, $title_filter = '')
704  {
705  global $ilDB;
706 
707  $role_list = array();
708 
709  $where = $this->__setTemplateFilter($a_templates);
710 
711  $query = "SELECT * FROM object_data ".
712  "JOIN rbac_fa ON obj_id = rol_id ".
713  $where.
714  "AND rbac_fa.assign = 'y' ";
715 
716  if(strlen($title_filter))
717  {
718  $query .= (' AND '.$ilDB->like(
719  'title',
720  'text',
721  $title_filter.'%'
722  ));
723  }
724  $res = $ilDB->query($query);
725 
726  while ($row = $ilDB->fetchAssoc($res))
727  {
728  $row["desc"] = $row["description"];
729  $row["user_id"] = $row["owner"];
730  $role_list[] = $row;
731  }
732 
733  $role_list = $this->__setRoleType($role_list);
734 
735  return $role_list;
736  }
737 
745  {
746  global $ilDB;
747 
748  $role_list = array();
749  $where = $this->__setTemplateFilter(false);
750 
751  $query = "SELECT fa.*, dat.* ".
752  "FROM tree root ".
753  "JOIN tree node ON node.tree = root.tree ".
754  "AND node.lft > root.lft AND node.rgt < root.rgt ".
755  "JOIN object_reference ref ON ref.ref_id = node.child ".
756  "JOIN rbac_fa fa ON fa.parent = ref.ref_id ".
757  "JOIN object_data dat ON dat.obj_id = fa.rol_id ".
758  "WHERE root.child = ".$this->ilDB->quote($ref_id,'integer')." ".
759  "AND root.tree = 1 ".
760  "AND fa.assign = 'y' ".
761  "ORDER BY dat.title";
762  $res = $ilDB->query($query);
763 
764  while($row = $ilDB->fetchAssoc($res))
765  {
766  $role_list[] = $row;
767  }
768 
769  $role_list = $this->__setRoleType($role_list);
770  return $role_list;
771  }
772 
779  function getAssignableChildRoles($a_ref_id)
780  {
781  global $ilDB;
782  global $tree;
783 
784  $query = "SELECT fa.*, rd.* ".
785  "FROM object_data rd ".
786  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
787  "JOIN tree t ON t.child = fa.parent ".
788  "WHERE fa.assign = 'y' ".
789  "AND t.parent = ".$this->ilDB->quote($a_ref_id,'integer')." "
790  ;
791  $res = $ilDB->query($query);
792  while($row = $ilDB->fetchAssoc($res))
793  {
794  $roles_data[] = $row;
795  }
796  return $roles_data ? $roles_data : array();
797  }
798 
805  function __setTemplateFilter($a_templates)
806  {
807  global $ilDB;
808 
809  if ($a_templates === true)
810  {
811  $where = "WHERE ".$ilDB->in('object_data.type',array('role','rolt'),false,'text')." ";
812  }
813  else
814  {
815  $where = "WHERE ".$ilDB->in('object_data.type',array('role'),false,'text')." ";
816  }
817 
818  return $where;
819  }
820 
832  function __setRoleType($a_role_list)
833  {
834  foreach ($a_role_list as $key => $val)
835  {
836  // determine role type
837  if ($val["type"] == "rolt")
838  {
839  $a_role_list[$key]["role_type"] = "template";
840  }
841  else
842  {
843  if ($val["assign"] == "y")
844  {
845  if ($val["parent"] == ROLE_FOLDER_ID)
846  {
847  $a_role_list[$key]["role_type"] = "global";
848  }
849  else
850  {
851  $a_role_list[$key]["role_type"] = "local";
852  }
853  }
854  else
855  {
856  $a_role_list[$key]["role_type"] = "linked";
857  }
858  }
859 
860  if ($val["protected"] == "y")
861  {
862  $a_role_list[$key]["protected"] = true;
863  }
864  else
865  {
866  $a_role_list[$key]["protected"] = false;
867  }
868  }
869 
870  return $a_role_list;
871  }
872 
879  public function getNumberOfAssignedUsers(Array $a_roles)
880  {
881  global $ilDB;
882 
883  $query = 'SELECT COUNT(DISTINCT(usr_id)) as num FROM rbac_ua '.
884  'WHERE '.$ilDB->in('rol_id', $a_roles, false, 'integer').' ';
885 
886  $res = $ilDB->query($query);
887  $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
888  return $row->num ? $row->num : 0;
889  }
890 
898  function assignedUsers($a_rol_id, $a_fields = NULL)
899  {
900  global $ilBench,$ilDB;
901 
902  $ilBench->start("RBAC", "review_assignedUsers");
903 
904  if (!isset($a_rol_id))
905  {
906  $message = get_class($this)."::assignedUsers(): No role_id given!";
907  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
908  }
909 
910  $result_arr = array();
911 
912  if ($a_fields !== NULL and is_array($a_fields))
913  {
914  if (count($a_fields) == 0)
915  {
916  $select = "*";
917  }
918  else
919  {
920  if (($usr_id_field = array_search("usr_id",$a_fields)) !== false)
921  unset($a_fields[$usr_id_field]);
922 
923  $select = implode(",",$a_fields).",usr_data.usr_id";
924  $select = addslashes($select);
925  }
926 
927  $ilDB->enableResultBuffering(false);
928  $query = "SELECT ".$select." FROM usr_data ".
929  "LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id ".
930  "WHERE rbac_ua.rol_id =".$ilDB->quote($a_rol_id,'integer');
931  $res = $ilDB->query($query);
932  while($row = $ilDB->fetchAssoc($res))
933  {
934  $result_arr[] = $row;
935  }
936  $ilDB->enableResultBuffering(true);
937  }
938  else
939  {
940  $ilDB->enableResultBuffering(false);
941  $query = "SELECT usr_id FROM rbac_ua WHERE rol_id= ".$ilDB->quote($a_rol_id,'integer');
942 
943  $res = $ilDB->query($query);
944  while($row = $ilDB->fetchAssoc($res))
945  {
946  array_push($result_arr,$row["usr_id"]);
947  }
948  $ilDB->enableResultBuffering(true);
949  }
950 
951  $ilBench->stop("RBAC", "review_assignedUsers");
952 
953  return $result_arr;
954  }
955 
963  function isAssigned($a_usr_id,$a_role_id)
964  {
965  // Quickly determine if user is assigned to a role
966  global $ilDB;
967 
968  $ilDB->setLimit(1,0);
969  $query = "SELECT usr_id FROM rbac_ua WHERE ".
970  "rol_id= ".$ilDB->quote($a_role_id,'integer')." ".
971  "AND usr_id= ".$ilDB->quote($a_usr_id);
972  $res = $ilDB->query($query);
973 
974  return $res->numRows() == 1;
975  }
976 
988  function isAssignedToAtLeastOneGivenRole($a_usr_id,$a_role_ids)
989  {
990  global $ilDB;
991 
992  $ilDB->setLimit(1,0);
993  $query = "SELECT usr_id FROM rbac_ua WHERE ".
994  $ilDB->in('rol_id',$a_role_ids,false,'integer').
995  " AND usr_id= ".$ilDB->quote($a_usr_id);
996  $res = $ilDB->query($query);
997 
998  return $ilDB->numRows($res) == 1;
999  }
1000 
1007  function assignedRoles($a_usr_id)
1008  {
1009  global $ilDB;
1010 
1011  $role_arr = array();
1012 
1013  $query = "SELECT rol_id FROM rbac_ua WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer');
1014 
1015  $res = $ilDB->query($query);
1016  while($row = $ilDB->fetchObject($res))
1017  {
1018  $role_arr[] = $row->rol_id;
1019  }
1020  return $role_arr ? $role_arr : array();
1021  }
1022 
1027  public function assignedGlobalRoles($a_usr_id)
1028  {
1029  global $ilDB;
1030 
1031  $query = "SELECT ua.rol_id FROM rbac_ua ua ".
1032  "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id ".
1033  "WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer').' '.
1034  "AND parent = ".$ilDB->quote(ROLE_FOLDER_ID)." ".
1035  "AND assign = 'y' ";
1036 
1037  $res = $ilDB->query($query);
1038  while($row = $ilDB->fetchObject($res))
1039  {
1040  $role_arr[] = $row->rol_id;
1041  }
1042  return $role_arr ? $role_arr : array();
1043  }
1044 
1052  function isAssignable($a_rol_id, $a_ref_id)
1053  {
1054  global $ilBench,$ilDB;
1055 
1056  $ilBench->start("RBAC", "review_isAssignable");
1057 
1058  // exclude system role from rbac
1059  if ($a_rol_id == SYSTEM_ROLE_ID)
1060  {
1061  $ilBench->stop("RBAC", "review_isAssignable");
1062  return true;
1063  }
1064 
1065  if (!isset($a_rol_id) or !isset($a_ref_id))
1066  {
1067  $message = get_class($this)."::isAssignable(): Missing parameter!".
1068  " role_id: ".$a_rol_id." ,ref_id: ".$a_ref_id;
1069  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1070  }
1071  $query = "SELECT * FROM rbac_fa ".
1072  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1073  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1074  $res = $ilDB->query($query);
1075  $row = $ilDB->fetchObject($res);
1076 
1077  $ilBench->stop("RBAC", "review_isAssignable");
1078  return $row->assign == 'y' ? true : false;
1079  }
1080 
1084  public function hasMultipleAssignments($a_role_id)
1085  {
1086  global $ilDB;
1087 
1088  $query = "SELECT * FROM rbac_fa WHERE rol_id = ".$ilDB->quote($a_role_id,'integer').' '.
1089  "AND assign = ".$ilDB->quote('y','text');
1090  $res = $ilDB->query($query);
1091  return $res->numRows() > 1;
1092  }
1093 
1104  function getFoldersAssignedToRole($a_rol_id, $a_assignable = false)
1105  {
1106  global $ilDB;
1107 
1108  if (!isset($a_rol_id))
1109  {
1110  $message = get_class($this)."::getFoldersAssignedToRole(): No role_id given!";
1111  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1112  }
1113 
1114  if ($a_assignable)
1115  {
1116  $where = " AND assign ='y'";
1117  }
1118 
1119  $query = "SELECT DISTINCT parent FROM rbac_fa ".
1120  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".$where." ";
1121 
1122  $res = $ilDB->query($query);
1123  while($row = $ilDB->fetchObject($res))
1124  {
1125  $folders[] = $row->parent;
1126  }
1127  return $folders ? $folders : array();
1128  }
1129 
1138  function getRolesOfRoleFolder($a_ref_id,$a_nonassignable = true)
1139  {
1140  global $ilBench,$ilDB,$ilLog;
1141 
1142  $ilBench->start("RBAC", "review_getRolesOfRoleFolder");
1143 
1144  if (!isset($a_ref_id))
1145  {
1146  $message = get_class($this)."::getRolesOfRoleFolder(): No ref_id given!";
1147  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1148 
1149  }
1150 
1151  if ($a_nonassignable === false)
1152  {
1153  $and = " AND assign='y'";
1154  }
1155 
1156  $query = "SELECT rol_id FROM rbac_fa ".
1157  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1158  $and;
1159 
1160  $res = $ilDB->query($query);
1161  while($row = $ilDB->fetchObject($res))
1162  {
1163  $rol_id[] = $row->rol_id;
1164  }
1165 
1166  $ilBench->stop("RBAC", "review_getRolesOfRoleFolder");
1167 
1168  return $rol_id ? $rol_id : array();
1169  }
1170 
1176  function getGlobalRoles()
1177  {
1178  return $this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false);
1179  }
1180 
1185  public function getLocalRoles($a_ref_id)
1186  {
1187  global $ilDB;
1188 
1189  // @todo: all this in one query
1190  $rolf = $this->getRoleFolderIdOfObject($a_ref_id);
1191  if(!$rolf)
1192  {
1193  return array();
1194  }
1195  $lroles = array();
1196  foreach($this->getRolesOfRoleFolder($rolf) as $role_id)
1197  {
1198  if($this->isAssignable($role_id, $rolf))
1199  {
1200  $lroles[] = $role_id;
1201  }
1202  }
1203  return $lroles;
1204  }
1205 
1212  {
1213  foreach($this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false) as $role_id)
1214  {
1215  $ga[] = array('obj_id' => $role_id,
1216  'role_type' => 'global');
1217  }
1218  return $ga ? $ga : array();
1219  }
1220 
1227  {
1228  include_once './Services/AccessControl/classes/class.ilObjRole.php';
1229 
1230  foreach($this->getGlobalRoles() as $role_id)
1231  {
1232  if(ilObjRole::_getAssignUsersStatus($role_id))
1233  {
1234  $ga[] = array('obj_id' => $role_id,
1235  'role_type' => 'global');
1236  }
1237  }
1238  return $ga ? $ga : array();
1239  }
1240 
1247  {
1248  global $ilDB;
1249 
1250  $query = "SELECT DISTINCT parent FROM rbac_fa";
1251  $res = $ilDB->query($query);
1252 
1253  $parent = array();
1254  while($row = $ilDB->fetchObject($res))
1255  {
1256  $parent[] = $row->parent;
1257  }
1258  return $parent;
1259  }
1260 
1267  function getRoleFolderOfObject($a_ref_id)
1268  {
1269  global $tree,$ilBench;
1270 
1271  $ilBench->start("RBAC", "review_getRoleFolderOfObject");
1272 
1273  if (!isset($a_ref_id))
1274  {
1275  $GLOBALS['ilLog']->logStack();
1276  $message = get_class($this)."::getRoleFolderOfObject(): No ref_id given!";
1277  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1278  }
1279  $childs = $tree->getChildsByType($a_ref_id,"rolf");
1280 
1281  $ilBench->stop("RBAC", "review_getRoleFolderOfObject");
1282 
1283  return $childs[0] ? $childs[0] : array();
1284  }
1285 
1286  function getRoleFolderIdOfObject($a_ref_id)
1287  {
1288  $rolf = $this->getRoleFolderOfObject($a_ref_id);
1289 
1290  if (!$rolf)
1291  {
1292  return false;
1293  }
1294 
1295  return $rolf['ref_id'];
1296  }
1297 
1301  public function isRoleAssignedToFolder($a_role_id, $a_parent_id)
1302  {
1303  global $rbacreview, $ilDB;
1304 
1305  $query = 'SELECT * FROM rbac_fa '.
1306  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
1307  'AND parent = '.$ilDB->quote($a_parent_id,'integer');
1308  $res = $ilDB->query($query);
1309  return $res->numRows() ? true : false;
1310  }
1311 
1317  function getOperations()
1318  {
1319  global $ilDB;
1320 
1321  $query = 'SELECT * FROM rbac_operations ORDER BY ops_id ';
1322  $res = $this->ilDB->query($query);
1323  while($row = $ilDB->fetchObject($res))
1324  {
1325  $ops[] = array('ops_id' => $row->ops_id,
1326  'operation' => $row->operation,
1327  'description' => $row->description);
1328  }
1329 
1330  return $ops ? $ops : array();
1331  }
1332 
1338  function getOperation($ops_id)
1339  {
1340  global $ilDB;
1341 
1342  $query = 'SELECT * FROM rbac_operations WHERE ops_id = '.$ilDB->quote($ops_id,'integer');
1343  $res = $this->ilDB->query($query);
1344  while($row = $ilDB->fetchObject($res))
1345  {
1346  $ops = array('ops_id' => $row->ops_id,
1347  'operation' => $row->operation,
1348  'description' => $row->description);
1349  }
1350 
1351  return $ops ? $ops : array();
1352  }
1353 
1362  public function getAllOperationsOfRole($a_rol_id, $a_parent = 0)
1363  {
1364  global $ilDB;
1365 
1366  if(!$a_parent)
1367  {
1368  $a_parent = ROLE_FOLDER_ID;
1369  }
1370 
1371  $query = "SELECT ops_id,type FROM rbac_templates ".
1372  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1373  "AND parent = ".$ilDB->quote($a_parent,'integer');
1374  $res = $ilDB->query($query);
1375 
1376  while ($row = $ilDB->fetchObject($res))
1377  {
1378  $ops_arr[$row->type][] = $row->ops_id;
1379  }
1380  return (array) $ops_arr;
1381  }
1382 
1389  public function getActiveOperationsOfRole($a_ref_id, $a_role_id)
1390  {
1391  global $ilDB;
1392 
1393  $query = 'SELECT * FROM rbac_pa '.
1394  'WHERE ref_id = '.$ilDB->quote($a_ref_id,'integer').' '.
1395  'AND rol_id = '.$ilDB->quote($a_role_id,'integer').' ';
1396 
1397  $res = $ilDB->query($query);
1398  while($row = $res->fetchRow(DB_FETCHMODE_ASSOC))
1399  {
1400  return unserialize($row['ops_id']);
1401  }
1402  return array();
1403  }
1404 
1405 
1415  function getOperationsOfRole($a_rol_id,$a_type,$a_parent = 0)
1416  {
1417  global $ilDB,$ilLog;
1418 
1419  if (!isset($a_rol_id) or !isset($a_type))
1420  {
1421  $message = get_class($this)."::getOperationsOfRole(): Missing Parameter!".
1422  "role_id: ".$a_rol_id.
1423  "type: ".$a_type.
1424  "parent_id: ".$a_parent;
1425  $ilLog->logStack("Missing parameter! ");
1426  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1427  }
1428 
1429  $ops_arr = array();
1430 
1431  // if no rolefolder id is given, assume global role folder as target
1432  if ($a_parent == 0)
1433  {
1434  $a_parent = ROLE_FOLDER_ID;
1435  }
1436 
1437  $query = "SELECT ops_id FROM rbac_templates ".
1438  "WHERE type =".$ilDB->quote($a_type,'text')." ".
1439  "AND rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1440  "AND parent = ".$ilDB->quote($a_parent,'integer');
1441  $res = $ilDB->query($query);
1442  while ($row = $ilDB->fetchObject($res))
1443  {
1444  $ops_arr[] = $row->ops_id;
1445  }
1446 
1447  return $ops_arr;
1448  }
1449 
1450  function getRoleOperationsOnObject($a_role_id,$a_ref_id)
1451  {
1452  global $ilDB;
1453 
1454  $query = "SELECT * FROM rbac_pa ".
1455  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1456  "AND ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
1457 
1458  $res = $ilDB->query($query);
1459  while($row = $ilDB->fetchObject($res))
1460  {
1461  $ops = unserialize($row->ops_id);
1462  }
1463 
1464  return $ops ? $ops : array();
1465  }
1466 
1473  function getOperationsOnType($a_typ_id)
1474  {
1475  global $ilDB;
1476 
1477  if (!isset($a_typ_id))
1478  {
1479  $message = get_class($this)."::getOperationsOnType(): No type_id given!";
1480  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1481  }
1482 
1483  #$query = "SELECT * FROM rbac_ta WHERE typ_id = ".$ilDB->quote($a_typ_id,'integer');
1484 
1485  $query = 'SELECT * FROM rbac_ta ta JOIN rbac_operations o ON ta.ops_id = o.ops_id '.
1486  'WHERE typ_id = '.$ilDB->quote($a_typ_id,'integer').' '.
1487  'ORDER BY op_order';
1488 
1489  $res = $ilDB->query($query);
1490 
1491  while($row = $ilDB->fetchObject($res))
1492  {
1493  $ops_id[] = $row->ops_id;
1494  }
1495 
1496  return $ops_id ? $ops_id : array();
1497  }
1498 
1505  function getOperationsOnTypeString($a_type)
1506  {
1507  global $ilDB;
1508 
1509  $query = "SELECT * FROM object_data WHERE type = 'typ' AND title = ".$ilDB->quote($a_type ,'text')." ";
1510 
1511 
1512  $res = $this->ilDB->query($query);
1513  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1514  {
1515  return $this->getOperationsOnType($row->obj_id);
1516  }
1517  return false;
1518  }
1519 
1526  public function getOperationsByTypeAndClass($a_type,$a_class)
1527  {
1528  global $ilDB;
1529 
1530  if($a_class != 'create')
1531  {
1532  $condition = "AND class != ".$ilDB->quote('create','text');
1533  }
1534  else
1535  {
1536  $condition = "AND class = ".$ilDB->quote('create','text');
1537  }
1538 
1539  $query = "SELECT ro.ops_id FROM rbac_operations ro ".
1540  "JOIN rbac_ta rt ON ro.ops_id = rt.ops_id ".
1541  "JOIN object_data od ON rt.typ_id = od.obj_id ".
1542  "WHERE type = ".$ilDB->quote('typ','text')." ".
1543  "AND title = ".$ilDB->quote($a_type,'text')." ".
1544  $condition." ".
1545  "ORDER BY op_order ";
1546 
1547  $res = $ilDB->query($query);
1548 
1549  $ops = array();
1550  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1551  {
1552  $ops[] = $row->ops_id;
1553  }
1554  return $ops;
1555  }
1556 
1557 
1566  function getObjectsWithStopedInheritance($a_rol_id,$a_filter = array())
1567  {
1568  global $ilDB;
1569 
1570  $query = 'SELECT t.parent p FROM tree t JOIN rbac_fa fa ON fa.parent = child '.
1571  'WHERE assign = '.$ilDB->quote('n','text').' '.
1572  'AND rol_id = '.$ilDB->quote($a_rol_id,'integer').' ';
1573 
1574  if($a_filter)
1575  {
1576  $query .= ('AND '.$ilDB->in('t.parent',(array) $a_filter,false,'integer'));
1577  }
1578 
1579  $res = $ilDB->query($query);
1580  $parent = array();
1581  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1582  {
1583  $parent[] = $row->p;
1584  }
1585  return $parent;
1586  }
1587 
1594  function isDeleted($a_node_id)
1595  {
1596  global $ilDB;
1597 
1598  $q = "SELECT tree FROM tree WHERE child =".$ilDB->quote($a_node_id)." ";
1599  $r = $this->ilDB->query($q);
1600 
1601  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1602 
1603  if (!$row)
1604  {
1605  $message = sprintf('%s::isDeleted(): Role folder with ref_id %s not found!',
1606  get_class($this),
1607  $a_node_id);
1608  $this->log->write($message,$this->log->FATAL);
1609 
1610  return true;
1611  }
1612 
1613  // rolefolder is deleted
1614  if ($row->tree < 0)
1615  {
1616  return true;
1617  }
1618 
1619  return false;
1620  }
1621 
1627  public function isGlobalRole($a_role_id)
1628  {
1629  return in_array($a_role_id,$this->getGlobalRoles());
1630  }
1631 
1632  function getRolesByFilter($a_filter = 0,$a_user_id = 0, $title_filter = '')
1633  {
1634  global $ilDB;
1635 
1636  $assign = "y";
1637 
1638  switch($a_filter)
1639  {
1640  // all (assignable) roles
1641  case self::FILTER_ALL:
1642  return $this->getAssignableRoles(true,true,$title_filter);
1643  break;
1644 
1645  // all (assignable) global roles
1646  case self::FILTER_ALL_GLOBAL:
1647  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),false,'integer').' ';
1648  break;
1649 
1650  // all (assignable) local roles
1651  case self::FILTER_ALL_LOCAL:
1652  case self::FILTER_INTERNAL:
1653  case self::FILTER_NOT_INTERNAL:
1654  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),true,'integer');
1655  break;
1656 
1657  // all role templates
1658  case self::FILTER_TEMPLATES:
1659  $where = "WHERE object_data.type = 'rolt'";
1660  $assign = "n";
1661  break;
1662 
1663  // only assigned roles, handled by ilObjUserGUI::roleassignmentObject()
1664  case 0:
1665  default:
1666  if(!$a_user_id)
1667  return array();
1668 
1669  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->assignedRoles($a_user_id),false,'integer').' ';
1670  break;
1671  }
1672 
1673  $roles = array();
1674 
1675  $query = "SELECT * FROM object_data ".
1676  "JOIN rbac_fa ON obj_id = rol_id ".
1677  $where.
1678  "AND rbac_fa.assign = ".$ilDB->quote($assign,'text')." ";
1679 
1680  if(strlen($title_filter))
1681  {
1682  $query .= (' AND '.$ilDB->like(
1683  'title',
1684  'text',
1685  '%'.$title_filter.'%'
1686  ));
1687  }
1688 
1689  $res = $ilDB->query($query);
1690  while($row = $ilDB->fetchAssoc($res))
1691  {
1692  $prefix = (substr($row["title"],0,3) == "il_") ? true : false;
1693 
1694  // all (assignable) internal local roles only
1695  if ($a_filter == 4 and !$prefix)
1696  {
1697  continue;
1698  }
1699 
1700  // all (assignable) non internal local roles only
1701  if ($a_filter == 5 and $prefix)
1702  {
1703  continue;
1704  }
1705 
1706  $row["desc"] = $row["description"];
1707  $row["user_id"] = $row["owner"];
1708  $roles[] = $row;
1709  }
1710 
1711  $roles = $this->__setRoleType($roles);
1712 
1713  return $roles ? $roles : array();
1714  }
1715 
1716  // get id of a given object type (string)
1717  function getTypeId($a_type)
1718  {
1719  global $ilDB;
1720 
1721  $q = "SELECT obj_id FROM object_data ".
1722  "WHERE title=".$ilDB->quote($a_type ,'text')." AND type='typ'";
1723  $r = $ilDB->query($q);
1724 
1725  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1726  return $row->obj_id;
1727  }
1728 
1738  public static function _getOperationIdsByName($operations)
1739  {
1740  global $ilDB;
1741 
1742  if(!count($operations))
1743  {
1744  return array();
1745  }
1746 
1747  $query = 'SELECT ops_id FROM rbac_operations '.
1748  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1749 
1750  $res = $ilDB->query($query);
1751  while($row = $ilDB->fetchObject($res))
1752  {
1753  $ops_ids[] = $row->ops_id;
1754  }
1755  return $ops_ids ? $ops_ids : array();
1756  }
1757 
1765  public static function _getOperationIdByName($a_operation)
1766  {
1767  global $ilDB,$ilErr;
1768 
1769  if (!isset($a_operation))
1770  {
1771  $message = "perm::getOperationId(): No operation given!";
1772  $ilErr->raiseError($message,$ilErr->WARNING);
1773  }
1774 
1775  // Cache operation ids
1776  if (! is_array(self::$_opsCache)) {
1777  self::$_opsCache = array();
1778 
1779  $q = "SELECT ops_id, operation FROM rbac_operations";
1780  $r = $ilDB->query($q);
1781  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
1782  {
1783  self::$_opsCache[$row->operation] = $row->ops_id;
1784  }
1785  }
1786 
1787  // Get operation ID by name from cache
1788  if (array_key_exists($a_operation, self::$_opsCache)) {
1789  return self::$_opsCache[$a_operation];
1790  }
1791  return null;
1792  }
1793 
1799  public static function lookupCreateOperationIds($a_type_arr)
1800  {
1801  global $ilDB;
1802 
1803  $operations = array();
1804  foreach($a_type_arr as $type)
1805  {
1806  $operations[] = ('create_'.$type);
1807  }
1808 
1809  if(!count($operations))
1810  {
1811  return array();
1812  }
1813 
1814  $query = 'SELECT ops_id, operation FROM rbac_operations '.
1815  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1816 
1817  $res = $ilDB->query($query);
1818 
1819  $ops_ids = array();
1820  while($row = $ilDB->fetchObject($res))
1821  {
1822  $type_arr = explode('_', $row->operation);
1823  $type = $type_arr[1];
1824 
1825  $ops_ids[$type] = $row->ops_id;
1826  }
1827  return $ops_ids;
1828  }
1829 
1830 
1839  function getLinkedRolesOfRoleFolder($a_ref_id)
1840  {
1841  global $ilDB;
1842 
1843  if (!isset($a_ref_id))
1844  {
1845  $message = get_class($this)."::getLinkedRolesOfRoleFolder(): No ref_id given!";
1846  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1847  }
1848 
1849  $and = " AND assign='n'";
1850 
1851  $query = "SELECT rol_id FROM rbac_fa ".
1852  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1853  $and;
1854  $res = $this->ilDB->query($query);
1855  while($row = $ilDB->fetchObject($res))
1856  {
1857  $rol_id[] = $row->rol_id;
1858  }
1859 
1860  return $rol_id ? $rol_id : array();
1861  }
1862 
1863  // checks if default permission settings of role under current parent (rolefolder) are protected from changes
1864  function isProtected($a_ref_id,$a_role_id)
1865  {
1866  global $ilDB;
1867 
1868  $query = "SELECT protected FROM rbac_fa ".
1869  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1870  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1871  $res = $ilDB->query($query);
1872  $row = $ilDB->fetchAssoc($res);
1873 
1874  return ilUtil::yn2tf($row['protected']);
1875  }
1876 
1877  // this method alters the protected status of role regarding the current user's role assignment
1878  // and current postion in the hierarchy.
1879  function __setProtectedStatus($a_parent_roles,$a_role_hierarchy,$a_ref_id)
1880  {
1881  //vd('refId',$a_ref_id,'parent roles',$a_parent_roles,'role-hierarchy',$a_role_hierarchy);
1882 
1883  global $rbacsystem,$ilUser,$log;
1884 
1885  if (in_array(SYSTEM_ROLE_ID,$this->assignedRoles($ilUser->getId())))
1886  {
1887  $leveladmin = true;
1888  }
1889  else
1890  {
1891  $leveladmin = false;
1892  }
1893  #vd("RoleHierarchy",$a_role_hierarchy);
1894  foreach ($a_role_hierarchy as $role_id => $rolf_id)
1895  {
1896  //$log->write("ilRBACreview::__setProtectedStatus(), 0");
1897  #echo "<br/>ROLF: ".$rolf_id." ROLE_ID: ".$role_id." (".$a_parent_roles[$role_id]['title'].") ";
1898  //var_dump($leveladmin,$a_parent_roles[$role_id]['protected']);
1899 
1900  if ($leveladmin == true)
1901  {
1902  $a_parent_roles[$role_id]['protected'] = false;
1903  continue;
1904  }
1905 
1906  if ($a_parent_roles[$role_id]['protected'] == true)
1907  {
1908  $arr_lvl_roles_user = array_intersect($this->assignedRoles($ilUser->getId()),array_keys($a_role_hierarchy,$rolf_id));
1909 
1910  #vd("intersection",$arr_lvl_roles_user);
1911 
1912  foreach ($arr_lvl_roles_user as $lvl_role_id)
1913  {
1914  #echo "<br/>level_role: ".$lvl_role_id;
1915  #echo "<br/>a_ref_id: ".$a_ref_id;
1916 
1917  //$log->write("ilRBACreview::__setProtectedStatus(), 1");
1918  // check if role grants 'edit_permission' to parent
1919  $rolf = $a_parent_roles[$role_id]['parent'];
1920  $parent_obj = $GLOBALS['tree']->getParentId($rolf);
1921  if ($rbacsystem->checkPermission($parent_obj,$lvl_role_id,'edit_permission'))
1922  {
1923  #echo "<br />Permission granted";
1924  //$log->write("ilRBACreview::__setProtectedStatus(), 2");
1925  // user may change permissions of that higher-ranked role
1926  $a_parent_roles[$role_id]['protected'] = false;
1927 
1928  // remember successful check
1929  //$leveladmin = true;
1930  }
1931  }
1932  }
1933  }
1934 
1935  return $a_parent_roles;
1936  }
1937 
1948  public static function _getOperationList($a_type = null)
1949  {
1950  global $ilDB;
1951 
1952  $arr = array();
1953 
1954  if ($a_type)
1955  {
1956  $query = sprintf('SELECT * FROM rbac_operations '.
1957  'JOIN rbac_ta ON rbac_operations.ops_id = rbac_ta.ops_id '.
1958  'JOIN object_data ON rbac_ta.typ_id = object_data.obj_id '.
1959  'WHERE object_data.title = %s '.
1960  'AND object_data.type = %s '.
1961  'ORDER BY op_order ASC',
1962  $ilDB->quote($a_type,'text'),
1963  $ilDB->quote('typ','text'));
1964  }
1965  else
1966  {
1967  $query = 'SELECT * FROM rbac_operations ORDER BY op_order ASC';
1968  }
1969  $res = $ilDB->query($query);
1970  while ($row = $ilDB->fetchAssoc($res))
1971  {
1972  $arr[] = array(
1973  "ops_id" => $row['ops_id'],
1974  "operation" => $row['operation'],
1975  "desc" => $row['description'],
1976  "class" => $row['class'],
1977  "order" => $row['op_order']
1978  );
1979  }
1980  return $arr;
1981  }
1982 
1983  public static function _groupOperationsByClass($a_ops_arr)
1984  {
1985  $arr = array();
1986 
1987  foreach ($a_ops_arr as $ops)
1988  {
1989  $arr[$ops['class']][] = array ('ops_id' => $ops['ops_id'],
1990  'name' => $ops['operation']
1991  );
1992  }
1993  return $arr;
1994  }
1995 
2003  public function getObjectOfRole($a_role_id)
2004  {
2005  // internal cache
2006  static $obj_cache = array();
2007 
2008  global $ilDB;
2009 
2010 
2011  if(isset($obj_cache[$a_role_id]) and $obj_cache[$a_role_id])
2012  {
2013  return $obj_cache[$a_role_id];
2014  }
2015 
2016  $query = "SELECT obr.obj_id FROM rbac_fa rfa ".
2017  "JOIN tree ON rfa.parent = tree.child ".
2018  "JOIN object_reference obr ON tree.parent = obr.ref_id ".
2019  "WHERE tree.tree = 1 ".
2020  "AND assign = 'y' ".
2021  "AND rol_id = ".$ilDB->quote($a_role_id,'integer')." ";
2022  $res = $ilDB->query($query);
2023 
2024  $obj_cache[$a_role_id] = 0;
2025  while($row = $ilDB->fetchObject($res))
2026  {
2027  $obj_cache[$a_role_id] = $row->obj_id;
2028  }
2029  return $obj_cache[$a_role_id];
2030  }
2031 
2037  public function getObjectReferenceOfRole($a_role_id)
2038  {
2039  global $ilDB;
2040 
2041  $query = "SELECT tree.parent ref FROM rbac_fa fa ".
2042  "JOIN tree ON fa.parent = tree.child ".
2043  "WHERE tree.tree = 1 ".
2044  "AND assign = ".$ilDB->quote('y','text').' '.
2045  "AND rol_id = ".$ilDB->quote($a_role_id,'integer');
2046 
2047  $res = $ilDB->query($query);
2048  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2049  {
2050  return $row->ref;
2051  }
2052  return 0;
2053  }
2054 
2061  public function isRoleDeleted ($a_role_id){
2062  $rolf_list = $this->getFoldersAssignedToRole($a_role_id, false);
2063  $deleted = true;
2064  if (count($rolf_list))
2065  {
2066  foreach ($rolf_list as $rolf) {
2067  // only list roles that are not set to status "deleted"
2068  if (!$this->isDeleted($rolf))
2069  {
2070  $deleted = false;
2071  break;
2072  }
2073  }
2074  }
2075  return $deleted;
2076  }
2077 
2078 
2079  function getRolesForIDs($role_ids, $use_templates)
2080  {
2081  global $ilDB;
2082 
2083  $role_list = array();
2084 
2085  $where = $this->__setTemplateFilter($use_templates);
2086 
2087  $query = "SELECT * FROM object_data ".
2088  "JOIN rbac_fa ON object_data.obj_id = rbac_fa.rol_id ".
2089  $where.
2090  "AND rbac_fa.assign = 'y' " .
2091  'AND '.$ilDB->in('object_data.obj_id',$role_ids,false,'integer');
2092 
2093  $res = $ilDB->query($query);
2094  while($row = $ilDB->fetchAssoc($res))
2095  {
2096  $row["desc"] = $row["description"];
2097  $row["user_id"] = $row["owner"];
2098  $role_list[] = $row;
2099  }
2100 
2101  $role_list = $this->__setRoleType($role_list);
2102  return $role_list;
2103  }
2104 
2109  public function getOperationAssignment()
2110  {
2111  global $ilDB;
2112 
2113  $query = 'SELECT ta.typ_id, obj.title, ops.ops_id, ops.operation FROM rbac_ta ta '.
2114  'JOIN object_data obj ON obj.obj_id = ta.typ_id '.
2115  'JOIN rbac_operations ops ON ops.ops_id = ta.ops_id ';
2116  $res = $ilDB->query($query);
2117 
2118  $counter = 0;
2119  while($row = $ilDB->fetchObject($res))
2120  {
2121  $info[$counter]['typ_id'] = $row->typ_id;
2122  $info[$counter]['type'] = $row->title;
2123  $info[$counter]['ops_id'] = $row->ops_id;
2124  $info[$counter]['operation'] = $row->operation;
2125  $counter++;
2126  }
2127  return $info ? $info : array();
2128 
2129  }
2130 
2139  public function filterEmptyRoleFolders($a_rolf_candidates)
2140  {
2141  global $ilDB;
2142 
2143  $query = 'SELECT DISTINCT(parent) parent FROM rbac_fa '.
2144  'WHERE '.$ilDB->in('parent',$a_rolf_candidates,false,'integer');
2145  $res = $ilDB->query($query);
2146  while($row = $ilDB->fetchObject($res))
2147  {
2148  $non_empty[] = $row->parent;
2149  }
2150  return $non_empty ? $non_empty : array();
2151  }
2152 
2159  public function isDeleteable($a_role_id, $a_rolf_id)
2160  {
2161  if(!$this->isAssignable($a_role_id, $a_rolf_id))
2162  {
2163  return false;
2164  }
2165  if($a_role_id == SYSTEM_ROLE_ID or $a_role_id == ANONYMOUS_ROLE_ID)
2166  {
2167  return false;
2168  }
2169  if(substr(ilObject::_lookupTitle($a_role_id),0,3) == 'il_')
2170  {
2171  return false;
2172  }
2173  return true;
2174  }
2175 
2181  public function isSystemGeneratedRole($a_role_id)
2182  {
2183  $title = ilObject::_lookupTitle($a_role_id);
2184  return substr($title,0,3) == 'il_' ? true : false;
2185  }
2186 
2187 
2194  public function getRoleFolderOfRole($a_role_id)
2195  {
2196  global $ilDB;
2197 
2198  if(ilObject::_lookupType($a_role_id) == 'role')
2199  {
2200  $and = ('AND assign = '.$ilDB->quote('y','text'));
2201  }
2202  else
2203  {
2204  $and = '';
2205  }
2206 
2207  $query = 'SELECT * FROM rbac_fa '.
2208  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
2209  $and;
2210  $res = $ilDB->query($query);
2211  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2212  {
2213  return $row->parent;
2214  }
2215  return 0;
2216  }
2217 
2224  function getUserPermissionsOnObject($a_user_id, $a_ref_id)
2225  {
2226  global $ilDB;
2227 
2228  $query = "SELECT ops_id FROM rbac_pa JOIN rbac_ua ".
2229  "ON (rbac_pa.rol_id = rbac_ua.rol_id) ".
2230  "WHERE rbac_ua.usr_id = ".$ilDB->quote($a_user_id,'integer')." ".
2231  "AND rbac_pa.ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
2232 
2233  $res = $ilDB->query($query);
2234  $all_ops = array();
2235  while ($row = $ilDB->fetchObject($res))
2236  {
2237  $ops = unserialize($row->ops_id);
2238  $all_ops = array_merge($all_ops, $ops);
2239  }
2240  $all_ops = array_unique($all_ops);
2241 
2242  $set = $ilDB->query("SELECT operation FROM rbac_operations ".
2243  " WHERE ".$ilDB->in("ops_id", $all_ops, false, "integer"));
2244  $perms = array();
2245  while ($rec = $ilDB->fetchAssoc($set))
2246  {
2247  $perms[] = $rec["operation"];
2248  }
2249 
2250  return $perms;
2251  }
2252 
2253 } // END class.ilRbacReview
2254 ?>