ILIAS  Release_4_2_x_branch Revision 61807
 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 'Mail/RFC822.php';
115  $parser = &new Mail_RFC822();
116  $parsedList = $parser->parseAddressList($a_address_list, "ilias", false, true);
117  //echo '<br>ilRBACReview '.var_export($parsedList,false);
118  foreach ($parsedList as $address)
119  {
120  $local_part = $address->mailbox;
121  if (strpos($local_part,'#') !== 0 &&
122  !($local_part{0} == '"' && $local_part{1} == "#"))
123  {
124  // A local-part which doesn't start with a '#' doesn't denote a role.
125  // Therefore we can skip it.
126  continue;
127  }
128 
129  $local_part = substr($local_part, 1);
130 
131  /* If role contains spaces, eg. 'foo role', double quotes are added which have to be
132  removed here.*/
133  if( $local_part{0} == '#' && $local_part{strlen($local_part) - 1} == '"' )
134  {
135  $local_part = substr($local_part, 1);
136  $local_part = substr($local_part, 0, strlen($local_part) - 1);
137  }
138 
139  if (substr($local_part,0,8) == 'il_role_')
140  {
141  $role_id = substr($local_part,8);
142  $query = "SELECT t.tree ".
143  "FROM rbac_fa fa ".
144  "JOIN tree t ON t.child = fa.parent ".
145  "WHERE fa.rol_id = ".$this->ilDB->quote($role_id,'integer')." ".
146  "AND fa.assign = 'y' ".
147  "AND t.tree = 1";
148  $r = $ilDB->query($query);
149  if ($r->numRows() > 0)
150  {
151  $role_ids[] = $role_id;
152  }
153  continue;
154  }
155 
156 
157  $domain = $address->host;
158  if (strpos($domain,'[') == 0 && strrpos($domain,']'))
159  {
160  $domain = substr($domain,1,strlen($domain) - 2);
161  }
162  if (strlen($local_part) == 0)
163  {
164  $local_part = $domain;
165  $address->host = 'ilias';
166  $domain = 'ilias';
167  }
168 
169  if (strtolower($address->host) == 'ilias')
170  {
171  // Search for roles = local-part in the whole repository
172  $query = "SELECT dat.obj_id ".
173  "FROM object_data dat ".
174  "JOIN rbac_fa fa ON fa.rol_id = dat.obj_id ".
175  "JOIN tree t ON t.child = fa.parent ".
176  "WHERE dat.title =".$this->ilDB->quote($local_part,'text')." ".
177  "AND dat.type = 'role' ".
178  "AND fa.assign = 'y' ".
179  "AND t.tree = 1";
180  }
181  else
182  {
183  // Search for roles like local-part in objects = host
184  $query = "SELECT rdat.obj_id ".
185  "FROM object_data odat ".
186  "JOIN object_reference oref ON oref.obj_id = odat.obj_id ".
187  "JOIN tree otree ON otree.child = oref.ref_id ".
188  "JOIN tree rtree ON rtree.parent = otree.child ".
189  "JOIN rbac_fa rfa ON rfa.parent = rtree.child ".
190  "JOIN object_data rdat ON rdat.obj_id = rfa.rol_id ".
191  "WHERE odat.title = ".$this->ilDB->quote($domain,'text')." ".
192  "AND otree.tree = 1 AND rtree.tree = 1 ".
193  "AND rfa.assign = 'y' ".
194  "AND rdat.title LIKE ".
195  $this->ilDB->quote('%'.preg_replace('/([_%])/','\\\\$1',$local_part).'%','text');
196  }
197  $r = $ilDB->query($query);
198 
199  $count = 0;
200  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
201  {
202  $role_ids[] = $row->obj_id;
203  $count++;
204  }
205 
206  // Nothing found?
207  // In this case, we search for roles = host.
208  if ($count == 0 && strtolower($address->host) == 'ilias')
209  {
210  $q = "SELECT dat.obj_id ".
211  "FROM object_data dat ".
212  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
213  "JOIN tree t ON t.child = ref.ref_id ".
214  "WHERE dat.title = ".$this->ilDB->quote($domain ,'text')." ".
215  "AND dat.type = 'role' ".
216  "AND t.tree = 1 ";
217  $r = $this->ilDB->query($q);
218 
219  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
220  {
221  $role_ids[] = $row->obj_id;
222  }
223  }
224  //echo '<br>ids='.var_export($role_ids,true);
225  }
226  }
227  else
228  {
229  // the following code is executed, when Pear Mail is
230  // not installed
231 
232  $titles = explode(',', $a_address_list);
233 
234  $titleList = '';
235  foreach ($titles as $title)
236  {
237  if (strlen($inList) > 0)
238  {
239  $titleList .= ',';
240  }
241  $title = trim($title);
242  if (strpos($title,'#') == 0)
243  {
244  $titleList .= $this->ilDB->quote(substr($title, 1));
245  }
246  }
247  if (strlen($titleList) > 0)
248  {
249  $q = "SELECT obj_id ".
250  "FROM object_data ".
251  "WHERE title IN (".$titleList.") ".
252  "AND type='role'";
253  $r = $this->ilDB->query($q);
254  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
255  {
256  $role_ids[] = $row->obj_id;
257  }
258  }
259  }
260 
261  return $role_ids;
262  }
263 
327  function getRoleMailboxAddress($a_role_id, $is_localize = true)
328  {
329  global $log, $lng,$ilDB;
330 
331  include_once "Services/Mail/classes/class.ilMail.php";
332  if (ilMail::_usePearMail())
333  {
334  // Retrieve the role title and the object title.
335  $query = "SELECT rdat.title role_title,odat.title object_title, ".
336  " oref.ref_id object_ref ".
337  "FROM object_data rdat ".
338  "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id ".
339  "JOIN tree rtree ON rtree.child = fa.parent ".
340  "JOIN object_reference oref ON oref.ref_id = rtree.parent ".
341  "JOIN object_data odat ON odat.obj_id = oref.obj_id ".
342  "WHERE rdat.obj_id = ".$this->ilDB->quote($a_role_id,'integer')." ".
343  "AND fa.assign = 'y' ";
344  $r = $ilDB->query($query);
345  if (!$row = $ilDB->fetchObject($r))
346  {
347  //$log->write('class.ilRbacReview->getMailboxAddress('.$a_role_id.'): error role does not exist');
348  return null; // role does not exist
349  }
350  $object_title = $row->object_title;
351  $object_ref = $row->object_ref;
352  $role_title = $row->role_title;
353 
354 
355  // In a perfect world, we could use the object_title in the
356  // domain part of the mailbox address, and the role title
357  // with prefix '#' in the local part of the mailbox address.
358  $domain = $object_title;
359  $local_part = $role_title;
360 
361 
362  // Determine if the object title is unique
363  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
364  "FROM object_data dat ".
365  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
366  "JOIN tree ON tree.child = ref.ref_id ".
367  "WHERE title = ".$this->ilDB->quote($object_title,'text')." ".
368  "AND tree.tree = 1 ";
369  $r = $this->ilDB->query($q);
370  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
371 
372  // If the object title is not unique, we get rid of the domain.
373  if ($row->count > 1)
374  {
375  $domain = null;
376  }
377 
378  // If the domain contains illegal characters, we get rid of it.
379  //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
380  // Fix for Mantis Bug: 7429 sending mail fails because of brakets
381  // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
382  if ($domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/',$domain))
383  {
384  $domain = null;
385  }
386 
387  // If the domain contains special characters, we put square
388  // brackets around it.
389  if ($domain != null &&
390  (preg_match('/[()<>@,;:\\".\[\]]/',$domain) ||
391  preg_match('/[^\x21-\x8f]/',$domain))
392  )
393  {
394  $domain = '['.$domain.']';
395  }
396 
397  // If the role title is one of the ILIAS reserved role titles,
398  // we can use a shorthand version of it for the local part
399  // of the mailbox address.
400  if (strpos($role_title, 'il_') === 0 && $domain != null)
401  {
402  $unambiguous_role_title = $role_title;
403 
404  $pos = strpos($role_title, '_', 3) + 1;
405  $local_part = substr(
406  $role_title,
407  $pos,
408  strrpos($role_title, '_') - $pos
409  );
410  }
411  else
412  {
413  $unambiguous_role_title = 'il_role_'.$a_role_id;
414  }
415 
416  // Determine if the local part is unique. If we don't have a
417  // domain, the local part must be unique within the whole repositry.
418  // If we do have a domain, the local part must be unique for that
419  // domain.
420  if ($domain == null)
421  {
422  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
423  "FROM object_data dat ".
424  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
425  "JOIN tree ON tree.child = ref.ref_id ".
426  "WHERE title = ".$this->ilDB->quote($local_part,'text')." ".
427  "AND tree.tree = 1 ";
428  }
429  else
430  {
431  $q = "SELECT COUNT(rd.obj_id) count ".
432  "FROM object_data rd ".
433  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
434  "JOIN tree t ON t.child = fa.parent ".
435  "WHERE fa.assign = 'y' ".
436  "AND t.parent = ".$this->ilDB->quote($object_ref,'integer')." ".
437  "AND rd.title LIKE ".$this->ilDB->quote(
438  '%'.preg_replace('/([_%])/','\\\\$1', $local_part).'%','text')." ";
439  }
440 
441  $r = $this->ilDB->query($q);
442  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
443 
444  // if the local_part is not unique, we use the unambiguous role title
445  // instead for the local part of the mailbox address
446  if ($row->count > 1)
447  {
448  $local_part = $unambiguous_role_title;
449  }
450 
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 
457 
458  $local_part = $unambiguous_role_title;
459  }
460 
461 
462  // Add a "#" prefix to the local part
463  $local_part = '#'.$local_part;
464 
465  // Put quotes around the role title, if needed
466  if (preg_match('/[()<>@,;:.\[\]\x20]/',$local_part))
467  {
468  $local_part = '"'.$local_part.'"';
469  }
470 
471  $mailbox = ($domain == null) ?
472  $local_part :
473  $local_part.'@'.$domain;
474 
475  if ($is_localize)
476  {
477  if (substr($role_title,0,3) == 'il_')
478  {
479  $phrase = $lng->txt(substr($role_title, 0, strrpos($role_title,'_')));
480  }
481  else
482  {
483  $phrase = $role_title;
484  }
485 
486  // make phrase RFC 822 conformant:
487  // - strip excessive whitespace
488  // - strip special characters
489  $phrase = preg_replace('/\s\s+/', ' ', $phrase);
490  $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
491 
492  $mailbox = $phrase.' <'.$mailbox.'>';
493  }
494 
495  return $mailbox;
496  }
497  else
498  {
499  $q = "SELECT title ".
500  "FROM object_data ".
501  "WHERE obj_id = ".$this->ilDB->quote($a_role_id ,'integer');
502  $r = $this->ilDB->query($q);
503 
504  if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
505  {
506  return '#'.$row->title;
507  }
508  else
509  {
510  return null;
511  }
512  }
513  }
514 
515 
523  function roleExists($a_title,$a_id = 0)
524  {
525  global $ilDB;
526 
527  if (empty($a_title))
528  {
529  $message = get_class($this)."::roleExists(): No title given!";
530  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
531  }
532 
533  $clause = ($a_id) ? " AND obj_id != ".$ilDB->quote($a_id)." " : "";
534 
535  $q = "SELECT DISTINCT(obj_id) obj_id FROM object_data ".
536  "WHERE title =".$ilDB->quote($a_title)." ".
537  "AND type IN('role','rolt')".
538  $clause." ";
539  $r = $this->ilDB->query($q);
540 
541  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
542  {
543  return $row->obj_id;
544  }
545  return false;
546  }
547 
560  function __getParentRoles($a_path,$a_templates,$a_keep_protected)
561  {
562  global $log,$ilDB;
563 
564  if (!isset($a_path) or !is_array($a_path))
565  {
566  $message = get_class($this)."::getParentRoles(): No path given or wrong datatype!";
567  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
568  }
569 
570  $parent_roles = array();
571  $role_hierarchy = array();
572 
573  // Select all role folders on a path using a single SQL-statement.
574  // CREATE IN() STATEMENT
575  $in = $ilDB->in('t.parent',$a_path,false,'integer');
576 
577  $q = "SELECT t.child,t.depth FROM tree t ".
578  "JOIN object_reference r ON r.ref_id = t.child ".
579  "JOIN object_data o ON o.obj_id = r.obj_id ".
580  "WHERE ".$in." ".
581  "AND o.type= ".$ilDB->quote('rolf','text')." ".
582  "ORDER BY t.depth ASC";
583 
584  $r = $this->ilDB->query($q);
585 
586 
587  // Sort by path (Administration -> Rolefolder is first element)
588  $role_rows = array();
589  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
590  {
591 
592  $depth = ($row->child == ROLE_FOLDER_ID ? 0 : $row->depth);
593  $role_rows[$depth]['child'] = $row->child;
594  }
595  ksort($role_rows,SORT_NUMERIC);
596 
597  foreach($role_rows as $row)
598  {
599  $roles = $this->getRoleListByObject($row['child'],$a_templates);
600  foreach ($roles as $role)
601  {
602  $id = $role["obj_id"];
603  $role["parent"] = $row['child'];
604  $parent_roles[$id] = $role;
605 
606  if (!array_key_exists($role['obj_id'],$role_hierarchy))
607  {
608  $role_hierarchy[$id] = $row['child'];
609  }
610  }
611  }
612  if (!$a_keep_protected)
613  {
614  return $this->__setProtectedStatus($parent_roles,$role_hierarchy,reset($a_path));
615  }
616  return $parent_roles;
617  }
618 
627  function getParentRoleIds($a_endnode_id,$a_templates = false,$a_keep_protected = false)
628  {
629  global $tree,$log,$ilDB;
630 
631  if (!isset($a_endnode_id))
632  {
633  $GLOBALS['ilLog']->logStack();
634  $message = get_class($this)."::getParentRoleIds(): No node_id (ref_id) given!";
635  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
636  }
637 
638  //var_dump($a_endnode_id);exit;
639  //$log->write("ilRBACreview::getParentRoleIds(), 0");
640  $pathIds = $tree->getPathId($a_endnode_id);
641 
642  // add system folder since it may not in the path
643  $pathIds[0] = SYSTEM_FOLDER_ID;
644  //$log->write("ilRBACreview::getParentRoleIds(), 1");
645  #return $this->getParentRoles($a_endnode_id,$a_templates,$a_keep_protected);
646  return $this->__getParentRoles($pathIds,$a_templates,$a_keep_protected);
647  }
648 
656  function getRoleListByObject($a_ref_id,$a_templates = false)
657  {
658  global $ilDB;
659 
660  if (!isset($a_ref_id) or !isset($a_templates))
661  {
662  $message = get_class($this)."::getRoleListByObject(): Missing parameter!".
663  "ref_id: ".$a_ref_id.
664  "tpl_flag: ".$a_templates;
665  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
666  }
667 
668  $role_list = array();
669 
670  $where = $this->__setTemplateFilter($a_templates);
671 
672  $query = "SELECT * FROM object_data ".
673  "JOIN rbac_fa ON obj_id = rol_id ".
674  $where.
675  "AND object_data.obj_id = rbac_fa.rol_id ".
676  "AND rbac_fa.parent = ".$ilDB->quote($a_ref_id,'integer')." ";
677 
678  $res = $ilDB->query($query);
679  while ($row = $ilDB->fetchAssoc($res))
680  {
681  $row["desc"] = $row["description"];
682  $row["user_id"] = $row["owner"];
683  $role_list[] = $row;
684  }
685 
686  $role_list = $this->__setRoleType($role_list);
687 
688  return $role_list;
689  }
690 
697  function getAssignableRoles($a_templates = false,$a_internal_roles = false, $title_filter = '')
698  {
699  global $ilDB;
700 
701  $role_list = array();
702 
703  $where = $this->__setTemplateFilter($a_templates);
704 
705  $query = "SELECT * FROM object_data ".
706  "JOIN rbac_fa ON obj_id = rol_id ".
707  $where.
708  "AND rbac_fa.assign = 'y' ";
709 
710  if(strlen($title_filter))
711  {
712  $query .= (' AND '.$ilDB->like(
713  'title',
714  'text',
715  $title_filter.'%'
716  ));
717  }
718  $res = $ilDB->query($query);
719 
720  while ($row = $ilDB->fetchAssoc($res))
721  {
722  $row["desc"] = $row["description"];
723  $row["user_id"] = $row["owner"];
724  $role_list[] = $row;
725  }
726 
727  $role_list = $this->__setRoleType($role_list);
728 
729  return $role_list;
730  }
731 
739  {
740  global $ilDB;
741 
742  $role_list = array();
743  $where = $this->__setTemplateFilter(false);
744 
745  $query = "SELECT fa.*, dat.* ".
746  "FROM tree root ".
747  "JOIN tree node ON node.tree = root.tree ".
748  "AND node.lft > root.lft AND node.rgt < root.rgt ".
749  "JOIN object_reference ref ON ref.ref_id = node.child ".
750  "JOIN rbac_fa fa ON fa.parent = ref.ref_id ".
751  "JOIN object_data dat ON dat.obj_id = fa.rol_id ".
752  "WHERE root.child = ".$this->ilDB->quote($ref_id,'integer')." ".
753  "AND root.tree = 1 ".
754  "AND fa.assign = 'y' ".
755  "ORDER BY dat.title";
756  $res = $ilDB->query($query);
757 
758  while($row = $ilDB->fetchAssoc($res))
759  {
760  $role_list[] = $row;
761  }
762 
763  $role_list = $this->__setRoleType($role_list);
764  return $role_list;
765  }
766 
773  function getAssignableChildRoles($a_ref_id)
774  {
775  global $ilDB;
776  global $tree;
777 
778  $query = "SELECT fa.*, rd.* ".
779  "FROM object_data rd ".
780  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
781  "JOIN tree t ON t.child = fa.parent ".
782  "WHERE fa.assign = 'y' ".
783  "AND t.parent = ".$this->ilDB->quote($a_ref_id,'integer')." "
784  ;
785  $res = $ilDB->query($query);
786  while($row = $ilDB->fetchAssoc($res))
787  {
788  $roles_data[] = $row;
789  }
790  return $roles_data ? $roles_data : array();
791  }
792 
799  function __setTemplateFilter($a_templates)
800  {
801  global $ilDB;
802 
803  if ($a_templates === true)
804  {
805  $where = "WHERE ".$ilDB->in('object_data.type',array('role','rolt'),false,'text')." ";
806  }
807  else
808  {
809  $where = "WHERE ".$ilDB->in('object_data.type',array('role'),false,'text')." ";
810  }
811 
812  return $where;
813  }
814 
826  function __setRoleType($a_role_list)
827  {
828  foreach ($a_role_list as $key => $val)
829  {
830  // determine role type
831  if ($val["type"] == "rolt")
832  {
833  $a_role_list[$key]["role_type"] = "template";
834  }
835  else
836  {
837  if ($val["assign"] == "y")
838  {
839  if ($val["parent"] == ROLE_FOLDER_ID)
840  {
841  $a_role_list[$key]["role_type"] = "global";
842  }
843  else
844  {
845  $a_role_list[$key]["role_type"] = "local";
846  }
847  }
848  else
849  {
850  $a_role_list[$key]["role_type"] = "linked";
851  }
852  }
853 
854  if ($val["protected"] == "y")
855  {
856  $a_role_list[$key]["protected"] = true;
857  }
858  else
859  {
860  $a_role_list[$key]["protected"] = false;
861  }
862  }
863 
864  return $a_role_list;
865  }
866 
873  public function getNumberOfAssignedUsers(Array $a_roles)
874  {
875  global $ilDB;
876 
877  $query = 'SELECT COUNT(DISTINCT(usr_id)) as num FROM rbac_ua '.
878  'WHERE '.$ilDB->in('rol_id', $a_roles, false, 'integer').' ';
879 
880  $res = $ilDB->query($query);
881  $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
882  return $row->num ? $row->num : 0;
883  }
884 
892  function assignedUsers($a_rol_id, $a_fields = NULL)
893  {
894  global $ilBench,$ilDB;
895 
896  $ilBench->start("RBAC", "review_assignedUsers");
897 
898  if (!isset($a_rol_id))
899  {
900  $message = get_class($this)."::assignedUsers(): No role_id given!";
901  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
902  }
903 
904  $result_arr = array();
905 
906  if ($a_fields !== NULL and is_array($a_fields))
907  {
908  if (count($a_fields) == 0)
909  {
910  $select = "*";
911  }
912  else
913  {
914  if (($usr_id_field = array_search("usr_id",$a_fields)) !== false)
915  unset($a_fields[$usr_id_field]);
916 
917  $select = implode(",",$a_fields).",usr_data.usr_id";
918  $select = addslashes($select);
919  }
920 
921  $ilDB->enableResultBuffering(false);
922  $query = "SELECT ".$select." FROM usr_data ".
923  "LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id ".
924  "WHERE rbac_ua.rol_id =".$ilDB->quote($a_rol_id,'integer');
925  $res = $ilDB->query($query);
926  while($row = $ilDB->fetchAssoc($res))
927  {
928  $result_arr[] = $row;
929  }
930  $ilDB->enableResultBuffering(true);
931  }
932  else
933  {
934  $ilDB->enableResultBuffering(false);
935  $query = "SELECT usr_id FROM rbac_ua WHERE rol_id= ".$ilDB->quote($a_rol_id,'integer');
936 
937  $res = $ilDB->query($query);
938  while($row = $ilDB->fetchAssoc($res))
939  {
940  array_push($result_arr,$row["usr_id"]);
941  }
942  $ilDB->enableResultBuffering(true);
943  }
944 
945  $ilBench->stop("RBAC", "review_assignedUsers");
946 
947  return $result_arr;
948  }
949 
957  function isAssigned($a_usr_id,$a_role_id)
958  {
959  // Quickly determine if user is assigned to a role
960  global $ilDB;
961 
962  $ilDB->setLimit(1,0);
963  $query = "SELECT usr_id FROM rbac_ua WHERE ".
964  "rol_id= ".$ilDB->quote($a_role_id,'integer')." ".
965  "AND usr_id= ".$ilDB->quote($a_usr_id);
966  $res = $ilDB->query($query);
967 
968  return $res->numRows() == 1;
969  }
970 
982  function isAssignedToAtLeastOneGivenRole($a_usr_id,$a_role_ids)
983  {
984  global $ilDB;
985 
986  $ilDB->setLimit(1,0);
987  $query = "SELECT usr_id FROM rbac_ua WHERE ".
988  $ilDB->in('rol_id',$a_role_ids,false,'integer').
989  " AND usr_id= ".$ilDB->quote($a_usr_id);
990  $res = $ilDB->query($query);
991 
992  return $ilDB->numRows($res) == 1;
993  }
994 
1001  function assignedRoles($a_usr_id)
1002  {
1003  global $ilDB;
1004 
1005  $role_arr = array();
1006 
1007  $query = "SELECT rol_id FROM rbac_ua WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer');
1008 
1009  $res = $ilDB->query($query);
1010  while($row = $ilDB->fetchObject($res))
1011  {
1012  $role_arr[] = $row->rol_id;
1013  }
1014  return $role_arr ? $role_arr : array();
1015  }
1016 
1021  public function assignedGlobalRoles($a_usr_id)
1022  {
1023  global $ilDB;
1024 
1025  $query = "SELECT ua.rol_id FROM rbac_ua ua ".
1026  "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id ".
1027  "WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer').' '.
1028  "AND parent = ".$ilDB->quote(ROLE_FOLDER_ID)." ".
1029  "AND assign = 'y' ";
1030 
1031  $res = $ilDB->query($query);
1032  while($row = $ilDB->fetchObject($res))
1033  {
1034  $role_arr[] = $row->rol_id;
1035  }
1036  return $role_arr ? $role_arr : array();
1037  }
1038 
1046  function isAssignable($a_rol_id, $a_ref_id)
1047  {
1048  global $ilBench,$ilDB;
1049 
1050  $ilBench->start("RBAC", "review_isAssignable");
1051 
1052  // exclude system role from rbac
1053  if ($a_rol_id == SYSTEM_ROLE_ID)
1054  {
1055  $ilBench->stop("RBAC", "review_isAssignable");
1056  return true;
1057  }
1058 
1059  if (!isset($a_rol_id) or !isset($a_ref_id))
1060  {
1061  $message = get_class($this)."::isAssignable(): Missing parameter!".
1062  " role_id: ".$a_rol_id." ,ref_id: ".$a_ref_id;
1063  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1064  }
1065  $query = "SELECT * FROM rbac_fa ".
1066  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1067  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1068  $res = $ilDB->query($query);
1069  $row = $ilDB->fetchObject($res);
1070 
1071  $ilBench->stop("RBAC", "review_isAssignable");
1072  return $row->assign == 'y' ? true : false;
1073  }
1074 
1078  public function hasMultipleAssignments($a_role_id)
1079  {
1080  global $ilDB;
1081 
1082  $query = "SELECT * FROM rbac_fa WHERE rol_id = ".$ilDB->quote($a_role_id,'integer').' '.
1083  "AND assign = ".$ilDB->quote('y','text');
1084  $res = $ilDB->query($query);
1085  return $res->numRows() > 1;
1086  }
1087 
1098  function getFoldersAssignedToRole($a_rol_id, $a_assignable = false)
1099  {
1100  global $ilDB;
1101 
1102  if (!isset($a_rol_id))
1103  {
1104  $message = get_class($this)."::getFoldersAssignedToRole(): No role_id given!";
1105  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1106  }
1107 
1108  if ($a_assignable)
1109  {
1110  $where = " AND assign ='y'";
1111  }
1112 
1113  $query = "SELECT DISTINCT parent FROM rbac_fa ".
1114  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".$where." ";
1115 
1116  $res = $ilDB->query($query);
1117  while($row = $ilDB->fetchObject($res))
1118  {
1119  $folders[] = $row->parent;
1120  }
1121  return $folders ? $folders : array();
1122  }
1123 
1132  function getRolesOfRoleFolder($a_ref_id,$a_nonassignable = true)
1133  {
1134  global $ilBench,$ilDB,$ilLog;
1135 
1136  $ilBench->start("RBAC", "review_getRolesOfRoleFolder");
1137 
1138  if (!isset($a_ref_id))
1139  {
1140  $message = get_class($this)."::getRolesOfRoleFolder(): No ref_id given!";
1141  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1142 
1143  }
1144 
1145  if ($a_nonassignable === false)
1146  {
1147  $and = " AND assign='y'";
1148  }
1149 
1150  $query = "SELECT rol_id FROM rbac_fa ".
1151  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1152  $and;
1153 
1154  $res = $ilDB->query($query);
1155  while($row = $ilDB->fetchObject($res))
1156  {
1157  $rol_id[] = $row->rol_id;
1158  }
1159 
1160  $ilBench->stop("RBAC", "review_getRolesOfRoleFolder");
1161 
1162  return $rol_id ? $rol_id : array();
1163  }
1164 
1170  function getGlobalRoles()
1171  {
1172  return $this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false);
1173  }
1174 
1179  public function getLocalRoles($a_ref_id)
1180  {
1181  global $ilDB;
1182 
1183  // @todo: all this in one query
1184  $rolf = $this->getRoleFolderIdOfObject($a_ref_id);
1185  if(!$rolf)
1186  {
1187  return array();
1188  }
1189  $lroles = array();
1190  foreach($this->getRolesOfRoleFolder($rolf) as $role_id)
1191  {
1192  if($this->isAssignable($role_id, $rolf))
1193  {
1194  $lroles[] = $role_id;
1195  }
1196  }
1197  return $lroles;
1198  }
1199 
1206  {
1207  foreach($this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false) as $role_id)
1208  {
1209  $ga[] = array('obj_id' => $role_id,
1210  'role_type' => 'global');
1211  }
1212  return $ga ? $ga : array();
1213  }
1214 
1221  {
1222  include_once './Services/AccessControl/classes/class.ilObjRole.php';
1223 
1224  foreach($this->getGlobalRoles() as $role_id)
1225  {
1226  if(ilObjRole::_getAssignUsersStatus($role_id))
1227  {
1228  $ga[] = array('obj_id' => $role_id,
1229  'role_type' => 'global');
1230  }
1231  }
1232  return $ga ? $ga : array();
1233  }
1234 
1241  {
1242  global $ilDB;
1243 
1244  $query = "SELECT DISTINCT parent FROM rbac_fa";
1245  $res = $ilDB->query($query);
1246 
1247  $parent = array();
1248  while($row = $ilDB->fetchObject($res))
1249  {
1250  $parent[] = $row->parent;
1251  }
1252  return $parent;
1253  }
1254 
1261  function getRoleFolderOfObject($a_ref_id)
1262  {
1263  global $tree,$ilBench;
1264 
1265  $ilBench->start("RBAC", "review_getRoleFolderOfObject");
1266 
1267  if (!isset($a_ref_id))
1268  {
1269  $GLOBALS['ilLog']->logStack();
1270  $message = get_class($this)."::getRoleFolderOfObject(): No ref_id given!";
1271  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1272  }
1273  $childs = $tree->getChildsByType($a_ref_id,"rolf");
1274 
1275  $ilBench->stop("RBAC", "review_getRoleFolderOfObject");
1276 
1277  return $childs[0] ? $childs[0] : array();
1278  }
1279 
1280  function getRoleFolderIdOfObject($a_ref_id)
1281  {
1282  $rolf = $this->getRoleFolderOfObject($a_ref_id);
1283 
1284  if (!$rolf)
1285  {
1286  return false;
1287  }
1288 
1289  return $rolf['ref_id'];
1290  }
1291 
1295  public function isRoleAssignedToFolder($a_role_id, $a_parent_id)
1296  {
1297  global $rbacreview, $ilDB;
1298 
1299  $query = 'SELECT * FROM rbac_fa '.
1300  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
1301  'AND parent = '.$ilDB->quote($a_parent_id,'integer');
1302  $res = $ilDB->query($query);
1303  return $res->numRows() ? true : false;
1304  }
1305 
1311  function getOperations()
1312  {
1313  global $ilDB;
1314 
1315  $query = 'SELECT * FROM rbac_operations ORDER BY ops_id ';
1316  $res = $this->ilDB->query($query);
1317  while($row = $ilDB->fetchObject($res))
1318  {
1319  $ops[] = array('ops_id' => $row->ops_id,
1320  'operation' => $row->operation,
1321  'description' => $row->description);
1322  }
1323 
1324  return $ops ? $ops : array();
1325  }
1326 
1332  function getOperation($ops_id)
1333  {
1334  global $ilDB;
1335 
1336  $query = 'SELECT * FROM rbac_operations WHERE ops_id = '.$ilDB->quote($ops_id,'integer');
1337  $res = $this->ilDB->query($query);
1338  while($row = $ilDB->fetchObject($res))
1339  {
1340  $ops = array('ops_id' => $row->ops_id,
1341  'operation' => $row->operation,
1342  'description' => $row->description);
1343  }
1344 
1345  return $ops ? $ops : array();
1346  }
1347 
1356  public function getAllOperationsOfRole($a_rol_id, $a_parent = 0)
1357  {
1358  global $ilDB;
1359 
1360  if(!$a_parent)
1361  {
1362  $a_parent = ROLE_FOLDER_ID;
1363  }
1364 
1365  $query = "SELECT ops_id,type FROM rbac_templates ".
1366  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1367  "AND parent = ".$ilDB->quote($a_parent,'integer');
1368  $res = $ilDB->query($query);
1369 
1370  while ($row = $ilDB->fetchObject($res))
1371  {
1372  $ops_arr[$row->type][] = $row->ops_id;
1373  }
1374  return (array) $ops_arr;
1375  }
1376 
1383  public function getActiveOperationsOfRole($a_ref_id, $a_role_id)
1384  {
1385  global $ilDB;
1386 
1387  $query = 'SELECT * FROM rbac_pa '.
1388  'WHERE ref_id = '.$ilDB->quote($a_ref_id,'integer').' '.
1389  'AND rol_id = '.$ilDB->quote($a_role_id,'integer').' ';
1390 
1391  $res = $ilDB->query($query);
1392  while($row = $res->fetchRow(DB_FETCHMODE_ASSOC))
1393  {
1394  return unserialize($row['ops_id']);
1395  }
1396  return array();
1397  }
1398 
1399 
1409  function getOperationsOfRole($a_rol_id,$a_type,$a_parent = 0)
1410  {
1411  global $ilDB,$ilLog;
1412 
1413  if (!isset($a_rol_id) or !isset($a_type))
1414  {
1415  $message = get_class($this)."::getOperationsOfRole(): Missing Parameter!".
1416  "role_id: ".$a_rol_id.
1417  "type: ".$a_type.
1418  "parent_id: ".$a_parent;
1419  $ilLog->logStack("Missing parameter! ");
1420  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1421  }
1422 
1423  $ops_arr = array();
1424 
1425  // if no rolefolder id is given, assume global role folder as target
1426  if ($a_parent == 0)
1427  {
1428  $a_parent = ROLE_FOLDER_ID;
1429  }
1430 
1431  $query = "SELECT ops_id FROM rbac_templates ".
1432  "WHERE type =".$ilDB->quote($a_type,'text')." ".
1433  "AND rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1434  "AND parent = ".$ilDB->quote($a_parent,'integer');
1435  $res = $ilDB->query($query);
1436  while ($row = $ilDB->fetchObject($res))
1437  {
1438  $ops_arr[] = $row->ops_id;
1439  }
1440 
1441  return $ops_arr;
1442  }
1443 
1444  function getRoleOperationsOnObject($a_role_id,$a_ref_id)
1445  {
1446  global $ilDB;
1447 
1448  $query = "SELECT * FROM rbac_pa ".
1449  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1450  "AND ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
1451 
1452  $res = $ilDB->query($query);
1453  while($row = $ilDB->fetchObject($res))
1454  {
1455  $ops = unserialize($row->ops_id);
1456  }
1457 
1458  return $ops ? $ops : array();
1459  }
1460 
1467  function getOperationsOnType($a_typ_id)
1468  {
1469  global $ilDB;
1470 
1471  if (!isset($a_typ_id))
1472  {
1473  $message = get_class($this)."::getOperationsOnType(): No type_id given!";
1474  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1475  }
1476 
1477  #$query = "SELECT * FROM rbac_ta WHERE typ_id = ".$ilDB->quote($a_typ_id,'integer');
1478 
1479  $query = 'SELECT * FROM rbac_ta ta JOIN rbac_operations o ON ta.ops_id = o.ops_id '.
1480  'WHERE typ_id = '.$ilDB->quote($a_typ_id,'integer').' '.
1481  'ORDER BY op_order';
1482 
1483  $res = $ilDB->query($query);
1484 
1485  while($row = $ilDB->fetchObject($res))
1486  {
1487  $ops_id[] = $row->ops_id;
1488  }
1489 
1490  return $ops_id ? $ops_id : array();
1491  }
1492 
1499  function getOperationsOnTypeString($a_type)
1500  {
1501  global $ilDB;
1502 
1503  $query = "SELECT * FROM object_data WHERE type = 'typ' AND title = ".$ilDB->quote($a_type ,'text')." ";
1504 
1505 
1506  $res = $this->ilDB->query($query);
1507  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1508  {
1509  return $this->getOperationsOnType($row->obj_id);
1510  }
1511  return false;
1512  }
1513 
1520  public function getOperationsByTypeAndClass($a_type,$a_class)
1521  {
1522  global $ilDB;
1523 
1524  if($a_class != 'create')
1525  {
1526  $condition = "AND class != ".$ilDB->quote('create','text');
1527  }
1528  else
1529  {
1530  $condition = "AND class = ".$ilDB->quote('create','text');
1531  }
1532 
1533  $query = "SELECT ro.ops_id FROM rbac_operations ro ".
1534  "JOIN rbac_ta rt ON ro.ops_id = rt.ops_id ".
1535  "JOIN object_data od ON rt.typ_id = od.obj_id ".
1536  "WHERE type = ".$ilDB->quote('typ','text')." ".
1537  "AND title = ".$ilDB->quote($a_type,'text')." ".
1538  $condition." ".
1539  "ORDER BY op_order ";
1540 
1541  $res = $ilDB->query($query);
1542 
1543  $ops = array();
1544  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1545  {
1546  $ops[] = $row->ops_id;
1547  }
1548  return $ops;
1549  }
1550 
1551 
1560  function getObjectsWithStopedInheritance($a_rol_id,$a_filter = array())
1561  {
1562  global $ilDB;
1563 
1564  $query = 'SELECT t.parent p FROM tree t JOIN rbac_fa fa ON fa.parent = child '.
1565  'WHERE assign = '.$ilDB->quote('n','text').' '.
1566  'AND rol_id = '.$ilDB->quote($a_rol_id,'integer').' ';
1567 
1568  if($a_filter)
1569  {
1570  $query .= ('AND '.$ilDB->in('t.parent',(array) $a_filter,false,'integer'));
1571  }
1572 
1573  $res = $ilDB->query($query);
1574  $parent = array();
1575  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1576  {
1577  $parent[] = $row->p;
1578  }
1579  return $parent;
1580  }
1581 
1588  function isDeleted($a_node_id)
1589  {
1590  global $ilDB;
1591 
1592  $q = "SELECT tree FROM tree WHERE child =".$ilDB->quote($a_node_id)." ";
1593  $r = $this->ilDB->query($q);
1594 
1595  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1596 
1597  if (!$row)
1598  {
1599  $message = sprintf('%s::isDeleted(): Role folder with ref_id %s not found!',
1600  get_class($this),
1601  $a_node_id);
1602  $this->log->write($message,$this->log->FATAL);
1603 
1604  return true;
1605  }
1606 
1607  // rolefolder is deleted
1608  if ($row->tree < 0)
1609  {
1610  return true;
1611  }
1612 
1613  return false;
1614  }
1615 
1616  public function isGlobalRole($a_role_id)
1617  {
1618  return in_array($a_role_id,$this->getGlobalRoles());
1619  }
1620 
1621  /*
1622  * Check if role is local role of a role folder
1623  */
1624  public function isLocalRole($a_role_id, $a_role_folder_id)
1625  {
1626  global $ilDB;
1627 
1628  $query = 'SELECT assign FROM rbac_fa '.
1629  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
1630  'AND parent = '.$ilDB->quote($a_role_folder_id,'integer');
1631  $res = $ilDB->query($query);
1632  $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
1633 
1634  return $row->assign == 'y' ? true : false;
1635  }
1636 
1637  function getRolesByFilter($a_filter = 0,$a_user_id = 0, $title_filter = '')
1638  {
1639  global $ilDB;
1640 
1641  $assign = "y";
1642 
1643  switch($a_filter)
1644  {
1645  // all (assignable) roles
1646  case self::FILTER_ALL:
1647  return $this->getAssignableRoles($title_filter);
1648  break;
1649 
1650  // all (assignable) global roles
1651  case self::FILTER_ALL_GLOBAL:
1652  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),false,'integer').' ';
1653  break;
1654 
1655  // all (assignable) local roles
1656  case self::FILTER_ALL_LOCAL:
1657  case self::FILTER_INTERNAL:
1658  case self::FILTER_NOT_INTERNAL:
1659  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),true,'integer');
1660  break;
1661 
1662  // all role templates
1663  case self::FILTER_TEMPLATES:
1664  $where = "WHERE object_data.type = 'rolt'";
1665  $assign = "n";
1666  break;
1667 
1668  // only assigned roles, handled by ilObjUserGUI::roleassignmentObject()
1669  case 0:
1670  default:
1671  if(!$a_user_id)
1672  return array();
1673 
1674  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->assignedRoles($a_user_id),false,'integer').' ';
1675  break;
1676  }
1677 
1678  $roles = array();
1679 
1680  $query = "SELECT * FROM object_data ".
1681  "JOIN rbac_fa ON obj_id = rol_id ".
1682  $where.
1683  "AND rbac_fa.assign = ".$ilDB->quote($assign,'text')." ";
1684 
1685  if(strlen($title_filter))
1686  {
1687  $query .= (' AND '.$ilDB->like(
1688  'title',
1689  'text',
1690  '%'.$title_filter.'%'
1691  ));
1692  }
1693 
1694  $res = $ilDB->query($query);
1695  while($row = $ilDB->fetchAssoc($res))
1696  {
1697  $prefix = (substr($row["title"],0,3) == "il_") ? true : false;
1698 
1699  // all (assignable) internal local roles only
1700  if ($a_filter == 4 and !$prefix)
1701  {
1702  continue;
1703  }
1704 
1705  // all (assignable) non internal local roles only
1706  if ($a_filter == 5 and $prefix)
1707  {
1708  continue;
1709  }
1710 
1711  $row["desc"] = $row["description"];
1712  $row["user_id"] = $row["owner"];
1713  $roles[] = $row;
1714  }
1715 
1716  $roles = $this->__setRoleType($roles);
1717 
1718  return $roles ? $roles : array();
1719  }
1720 
1721  // get id of a given object type (string)
1722  function getTypeId($a_type)
1723  {
1724  global $ilDB;
1725 
1726  $q = "SELECT obj_id FROM object_data ".
1727  "WHERE title=".$ilDB->quote($a_type ,'text')." AND type='typ'";
1728  $r = $ilDB->query($q);
1729 
1730  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1731  return $row->obj_id;
1732  }
1733 
1743  public static function _getOperationIdsByName($operations)
1744  {
1745  global $ilDB;
1746 
1747  if(!count($operations))
1748  {
1749  return array();
1750  }
1751 
1752  $query = 'SELECT ops_id FROM rbac_operations '.
1753  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1754 
1755  $res = $ilDB->query($query);
1756  while($row = $ilDB->fetchObject($res))
1757  {
1758  $ops_ids[] = $row->ops_id;
1759  }
1760  return $ops_ids ? $ops_ids : array();
1761  }
1762 
1770  public static function _getOperationIdByName($a_operation)
1771  {
1772  global $ilDB,$ilErr;
1773 
1774  if (!isset($a_operation))
1775  {
1776  $message = "perm::getOperationId(): No operation given!";
1777  $ilErr->raiseError($message,$ilErr->WARNING);
1778  }
1779 
1780  // Cache operation ids
1781  if (! is_array(self::$_opsCache)) {
1782  self::$_opsCache = array();
1783 
1784  $q = "SELECT ops_id, operation FROM rbac_operations";
1785  $r = $ilDB->query($q);
1786  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
1787  {
1788  self::$_opsCache[$row->operation] = $row->ops_id;
1789  }
1790  }
1791 
1792  // Get operation ID by name from cache
1793  if (array_key_exists($a_operation, self::$_opsCache)) {
1794  return self::$_opsCache[$a_operation];
1795  }
1796  return null;
1797  }
1798 
1804  public static function lookupCreateOperationIds($a_type_arr)
1805  {
1806  global $ilDB;
1807 
1808  $operations = array();
1809  foreach($a_type_arr as $type)
1810  {
1811  $operations[] = ('create_'.$type);
1812  }
1813 
1814  if(!count($operations))
1815  {
1816  return array();
1817  }
1818 
1819  $query = 'SELECT ops_id, operation FROM rbac_operations '.
1820  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1821 
1822  $res = $ilDB->query($query);
1823 
1824  $ops_ids = array();
1825  while($row = $ilDB->fetchObject($res))
1826  {
1827  $type_arr = explode('_', $row->operation);
1828  $type = $type_arr[1];
1829 
1830  $ops_ids[$type] = $row->ops_id;
1831  }
1832  return $ops_ids;
1833  }
1834 
1835 
1844  function getLinkedRolesOfRoleFolder($a_ref_id)
1845  {
1846  global $ilDB;
1847 
1848  if (!isset($a_ref_id))
1849  {
1850  $message = get_class($this)."::getLinkedRolesOfRoleFolder(): No ref_id given!";
1851  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1852  }
1853 
1854  $and = " AND assign='n'";
1855 
1856  $query = "SELECT rol_id FROM rbac_fa ".
1857  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1858  $and;
1859  $res = $this->ilDB->query($query);
1860  while($row = $ilDB->fetchObject($res))
1861  {
1862  $rol_id[] = $row->rol_id;
1863  }
1864 
1865  return $rol_id ? $rol_id : array();
1866  }
1867 
1868  // checks if default permission settings of role under current parent (rolefolder) are protected from changes
1869  function isProtected($a_ref_id,$a_role_id)
1870  {
1871  global $ilDB;
1872 
1873  $query = "SELECT protected FROM rbac_fa ".
1874  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1875  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1876  $res = $ilDB->query($query);
1877  $row = $ilDB->fetchAssoc($res);
1878 
1879  return ilUtil::yn2tf($row['protected']);
1880  }
1881 
1882  // this method alters the protected status of role regarding the current user's role assignment
1883  // and current postion in the hierarchy.
1884  function __setProtectedStatus($a_parent_roles,$a_role_hierarchy,$a_ref_id)
1885  {
1886  #vd('refId',$a_ref_id,'parent roles',$a_parent_roles,'role-hierarchy',$a_role_hierarchy);
1887 
1888  global $rbacsystem,$ilUser,$log;
1889 
1890  if (in_array(SYSTEM_ROLE_ID,$this->assignedRoles($ilUser->getId())))
1891  {
1892  $leveladmin = true;
1893  }
1894  else
1895  {
1896  $leveladmin = false;
1897  }
1898  #vd("RoleHierarchy",$a_role_hierarchy);
1899  foreach ($a_role_hierarchy as $role_id => $rolf_id)
1900  {
1901  //$log->write("ilRBACreview::__setProtectedStatus(), 0");
1902  #echo "<br/>ROLF: ".$rolf_id." ROLE_ID: ".$role_id." (".$a_parent_roles[$role_id]['title'].") ";
1903  //var_dump($leveladmin,$a_parent_roles[$role_id]['protected']);
1904 
1905  if ($leveladmin == true)
1906  {
1907  $a_parent_roles[$role_id]['protected'] = false;
1908  continue;
1909  }
1910 
1911  if ($a_parent_roles[$role_id]['protected'] == true)
1912  {
1913  $arr_lvl_roles_user = array_intersect($this->assignedRoles($ilUser->getId()),array_keys($a_role_hierarchy,$rolf_id));
1914 
1915  #vd("intersection",$arr_lvl_roles_user);
1916 
1917  foreach ($arr_lvl_roles_user as $lvl_role_id)
1918  {
1919  #echo "<br/>level_role: ".$lvl_role_id;
1920  #echo "<br/>a_ref_id: ".$a_ref_id;
1921 
1922  //$log->write("ilRBACreview::__setProtectedStatus(), 1");
1923  // check if role grants 'edit_permission' to parent
1924 
1925  if ($rbacsystem->checkPermission($a_ref_id,$lvl_role_id,'edit_permission'))
1926  {
1927  #echo "<br />Permission granted";
1928  //$log->write("ilRBACreview::__setProtectedStatus(), 2");
1929  // user may change permissions of that higher-ranked role
1930  $a_parent_roles[$role_id]['protected'] = false;
1931 
1932  // remember successful check
1933  $leveladmin = true;
1934  }
1935  }
1936  }
1937  }
1938 
1939  return $a_parent_roles;
1940  }
1941 
1952  public static function _getOperationList($a_type = null)
1953  {
1954  global $ilDB;
1955 
1956  $arr = array();
1957 
1958  if ($a_type)
1959  {
1960  $query = sprintf('SELECT * FROM rbac_operations '.
1961  'JOIN rbac_ta ON rbac_operations.ops_id = rbac_ta.ops_id '.
1962  'JOIN object_data ON rbac_ta.typ_id = object_data.obj_id '.
1963  'WHERE object_data.title = %s '.
1964  'AND object_data.type = %s '.
1965  'ORDER BY op_order ASC',
1966  $ilDB->quote($a_type,'text'),
1967  $ilDB->quote('typ','text'));
1968  }
1969  else
1970  {
1971  $query = 'SELECT * FROM rbac_operations ORDER BY op_order ASC';
1972  }
1973  $res = $ilDB->query($query);
1974  while ($row = $ilDB->fetchAssoc($res))
1975  {
1976  $arr[] = array(
1977  "ops_id" => $row['ops_id'],
1978  "operation" => $row['operation'],
1979  "desc" => $row['description'],
1980  "class" => $row['class'],
1981  "order" => $row['op_order']
1982  );
1983  }
1984  return $arr;
1985  }
1986 
1987  public static function _groupOperationsByClass($a_ops_arr)
1988  {
1989  $arr = array();
1990 
1991  foreach ($a_ops_arr as $ops)
1992  {
1993  $arr[$ops['class']][] = array ('ops_id' => $ops['ops_id'],
1994  'name' => $ops['operation']
1995  );
1996  }
1997  return $arr;
1998  }
1999 
2007  public function getObjectOfRole($a_role_id)
2008  {
2009  global $ilDB;
2010 
2011  $query = "SELECT obr.obj_id FROM rbac_fa rfa ".
2012  "JOIN tree ON rfa.parent = tree.child ".
2013  "JOIN object_reference obr ON tree.parent = obr.ref_id ".
2014  "WHERE tree.tree = 1 ".
2015  "AND assign = 'y' ".
2016  "AND rol_id = ".$ilDB->quote($a_role_id,'integer')." ";
2017  $res = $ilDB->query($query);
2018  while($row = $ilDB->fetchObject($res))
2019  {
2020  $obj_id = $row->obj_id;
2021  }
2022 
2023  return $obj_id ? $obj_id : 0;
2024  }
2025 
2031  public function getObjectReferenceOfRole($a_role_id)
2032  {
2033  global $ilDB;
2034 
2035  $query = "SELECT tree.parent ref FROM rbac_fa fa ".
2036  "JOIN tree ON fa.parent = tree.child ".
2037  "WHERE tree.tree = 1 ".
2038  "AND assign = ".$ilDB->quote('y','text').' '.
2039  "AND rol_id = ".$ilDB->quote($a_role_id,'integer');
2040 
2041  $res = $ilDB->query($query);
2042  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2043  {
2044  return $row->ref;
2045  }
2046  return 0;
2047  }
2048 
2055  public function isRoleDeleted ($a_role_id){
2056  $rolf_list = $this->getFoldersAssignedToRole($a_role_id, false);
2057  $deleted = true;
2058  if (count($rolf_list))
2059  {
2060  foreach ($rolf_list as $rolf) {
2061  // only list roles that are not set to status "deleted"
2062  if (!$this->isDeleted($rolf))
2063  {
2064  $deleted = false;
2065  break;
2066  }
2067  }
2068  }
2069  return $deleted;
2070  }
2071 
2072 
2073  function getRolesForIDs($role_ids, $use_templates)
2074  {
2075  global $ilDB;
2076 
2077  $role_list = array();
2078 
2079  $where = $this->__setTemplateFilter($use_templates);
2080 
2081  $query = "SELECT * FROM object_data ".
2082  "JOIN rbac_fa ON object_data.obj_id = rbac_fa.rol_id ".
2083  $where.
2084  "AND rbac_fa.assign = 'y' " .
2085  'AND '.$ilDB->in('object_data.obj_id',$role_ids,false,'integer');
2086 
2087  $res = $ilDB->query($query);
2088  while($row = $ilDB->fetchAssoc($res))
2089  {
2090  $row["desc"] = $row["description"];
2091  $row["user_id"] = $row["owner"];
2092  $role_list[] = $row;
2093  }
2094 
2095  $role_list = $this->__setRoleType($role_list);
2096  return $role_list;
2097  }
2098 
2103  public function getOperationAssignment()
2104  {
2105  global $ilDB;
2106 
2107  $query = 'SELECT ta.typ_id, obj.title, ops.ops_id, ops.operation FROM rbac_ta ta '.
2108  'JOIN object_data obj ON obj.obj_id = ta.typ_id '.
2109  'JOIN rbac_operations ops ON ops.ops_id = ta.ops_id ';
2110  $res = $ilDB->query($query);
2111 
2112  $counter = 0;
2113  while($row = $ilDB->fetchObject($res))
2114  {
2115  $info[$counter]['typ_id'] = $row->typ_id;
2116  $info[$counter]['type'] = $row->title;
2117  $info[$counter]['ops_id'] = $row->ops_id;
2118  $info[$counter]['operation'] = $row->operation;
2119  $counter++;
2120  }
2121  return $info ? $info : array();
2122 
2123  }
2124 
2133  public function filterEmptyRoleFolders($a_rolf_candidates)
2134  {
2135  global $ilDB;
2136 
2137  $query = 'SELECT DISTINCT(parent) parent FROM rbac_fa '.
2138  'WHERE '.$ilDB->in('parent',$a_rolf_candidates,false,'integer');
2139  $res = $ilDB->query($query);
2140  while($row = $ilDB->fetchObject($res))
2141  {
2142  $non_empty[] = $row->parent;
2143  }
2144  return $non_empty ? $non_empty : array();
2145  }
2146 
2153  public function isDeleteable($a_role_id, $a_rolf_id)
2154  {
2155  if(!$this->isAssignable($a_role_id, $a_rolf_id))
2156  {
2157  return false;
2158  }
2159  if($a_role_id == SYSTEM_ROLE_ID or $a_role_id == ANONYMOUS_ROLE_ID)
2160  {
2161  return false;
2162  }
2163  if(substr(ilObject::_lookupTitle($a_role_id),0,3) == 'il_')
2164  {
2165  return false;
2166  }
2167  return true;
2168  }
2169 
2175  public function isSystemGeneratedRole($a_role_id)
2176  {
2177  $title = ilObject::_lookupTitle($a_role_id);
2178  return substr($title,0,3) == 'il_' ? true : false;
2179  }
2180 
2181 
2188  public function getRoleFolderOfRole($a_role_id)
2189  {
2190  global $ilDB;
2191 
2192  if(ilObject::_lookupType($a_role_id) == 'role')
2193  {
2194  $and = ('AND assign = '.$ilDB->quote('y','text'));
2195  }
2196  else
2197  {
2198  $and = '';
2199  }
2200 
2201  $query = 'SELECT * FROM rbac_fa '.
2202  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
2203  $and;
2204  $res = $ilDB->query($query);
2205  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2206  {
2207  return $row->parent;
2208  }
2209  return 0;
2210  }
2211 } // END class.ilRbacReview
2212 ?>