ILIAS  Release_4_1_x_branch Revision 61804
 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  protected $assigned_roles = array();
23  var $log = null;
24 
25  // Cache operation ids
26  private static $_opsCache = null;
27 
32  function ilRbacReview()
33  {
34  global $ilDB,$ilErr,$ilias,$ilLog;
35 
36  $this->log =& $ilLog;
37 
38  // set db & error handler
39  (isset($ilDB)) ? $this->ilDB =& $ilDB : $this->ilDB =& $ilias->db;
40 
41  if (!isset($ilErr))
42  {
43  $ilErr = new ilErrorHandling();
44  $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK,array($ilErr,'errorHandler'));
45  }
46  else
47  {
48  $this->ilErr =& $ilErr;
49  }
50  }
51 
98  function searchRolesByMailboxAddressList($a_address_list)
99  {
100  global $ilDB;
101 
102  $role_ids = array();
103 
104  include_once "Services/Mail/classes/class.ilMail.php";
105  if (ilMail::_usePearMail())
106  {
107  require_once 'Mail/RFC822.php';
108  $parser = &new Mail_RFC822();
109  $parsedList = $parser->parseAddressList($a_address_list, "ilias", false, true);
110  //echo '<br>ilRBACReview '.var_export($parsedList,false);
111  foreach ($parsedList as $address)
112  {
113  $local_part = $address->mailbox;
114  if (strpos($local_part,'#') !== 0 &&
115  !($local_part{0} == '"' && $local_part{1} == "#"))
116  {
117  // A local-part which doesn't start with a '#' doesn't denote a role.
118  // Therefore we can skip it.
119  continue;
120  }
121 
122  $local_part = substr($local_part, 1);
123 
124  /* If role contains spaces, eg. 'foo role', double quotes are added which have to be
125  removed here.*/
126  if( $local_part{0} == '#' && $local_part{strlen($local_part) - 1} == '"' )
127  {
128  $local_part = substr($local_part, 1);
129  $local_part = substr($local_part, 0, strlen($local_part) - 1);
130  }
131 
132  if (substr($local_part,0,8) == 'il_role_')
133  {
134  $role_id = substr($local_part,8);
135  $query = "SELECT t.tree ".
136  "FROM rbac_fa fa ".
137  "JOIN tree t ON t.child = fa.parent ".
138  "WHERE fa.rol_id = ".$this->ilDB->quote($role_id,'integer')." ".
139  "AND fa.assign = 'y' ".
140  "AND t.tree = 1";
141  $r = $ilDB->query($query);
142  if ($r->numRows() > 0)
143  {
144  $role_ids[] = $role_id;
145  }
146  continue;
147  }
148 
149 
150  $domain = $address->host;
151  if (strpos($domain,'[') == 0 && strrpos($domain,']'))
152  {
153  $domain = substr($domain,1,strlen($domain) - 2);
154  }
155  if (strlen($local_part) == 0)
156  {
157  $local_part = $domain;
158  $address->host = 'ilias';
159  $domain = 'ilias';
160  }
161 
162  if (strtolower($address->host) == 'ilias')
163  {
164  // Search for roles = local-part in the whole repository
165  $query = "SELECT dat.obj_id ".
166  "FROM object_data dat ".
167  "JOIN rbac_fa fa ON fa.rol_id = dat.obj_id ".
168  "JOIN tree t ON t.child = fa.parent ".
169  "WHERE dat.title =".$this->ilDB->quote($local_part,'text')." ".
170  "AND dat.type = 'role' ".
171  "AND fa.assign = 'y' ".
172  "AND t.tree = 1";
173  }
174  else
175  {
176  // Search for roles like local-part in objects = host
177  $query = "SELECT rdat.obj_id ".
178  "FROM object_data odat ".
179  "JOIN object_reference oref ON oref.obj_id = odat.obj_id ".
180  "JOIN tree otree ON otree.child = oref.ref_id ".
181  "JOIN tree rtree ON rtree.parent = otree.child ".
182  "JOIN rbac_fa rfa ON rfa.parent = rtree.child ".
183  "JOIN object_data rdat ON rdat.obj_id = rfa.rol_id ".
184  "WHERE odat.title = ".$this->ilDB->quote($domain,'text')." ".
185  "AND otree.tree = 1 AND rtree.tree = 1 ".
186  "AND rfa.assign = 'y' ".
187  "AND rdat.title LIKE ".
188  $this->ilDB->quote('%'.preg_replace('/([_%])/','\\\\$1',$local_part).'%','text');
189  }
190  $r = $ilDB->query($query);
191 
192  $count = 0;
193  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
194  {
195  $role_ids[] = $row->obj_id;
196  $count++;
197  }
198 
199  // Nothing found?
200  // In this case, we search for roles = host.
201  if ($count == 0 && strtolower($address->host) == 'ilias')
202  {
203  $q = "SELECT dat.obj_id ".
204  "FROM object_data dat ".
205  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
206  "JOIN tree t ON t.child = ref.ref_id ".
207  "WHERE dat.title = ".$this->ilDB->quote($domain ,'text')." ".
208  "AND dat.type = 'role' ".
209  "AND t.tree = 1 ";
210  $r = $this->ilDB->query($q);
211 
212  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
213  {
214  $role_ids[] = $row->obj_id;
215  }
216  }
217  //echo '<br>ids='.var_export($role_ids,true);
218  }
219  }
220  else
221  {
222  // the following code is executed, when Pear Mail is
223  // not installed
224 
225  $titles = explode(',', $a_address_list);
226 
227  $titleList = '';
228  foreach ($titles as $title)
229  {
230  if (strlen($inList) > 0)
231  {
232  $titleList .= ',';
233  }
234  $title = trim($title);
235  if (strpos($title,'#') == 0)
236  {
237  $titleList .= $this->ilDB->quote(substr($title, 1));
238  }
239  }
240  if (strlen($titleList) > 0)
241  {
242  $q = "SELECT obj_id ".
243  "FROM object_data ".
244  "WHERE title IN (".$titleList.") ".
245  "AND type='role'";
246  $r = $this->ilDB->query($q);
247  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
248  {
249  $role_ids[] = $row->obj_id;
250  }
251  }
252  }
253 
254  return $role_ids;
255  }
256 
320  function getRoleMailboxAddress($a_role_id, $is_localize = true)
321  {
322  global $log, $lng,$ilDB;
323 
324  include_once "Services/Mail/classes/class.ilMail.php";
325  if (ilMail::_usePearMail())
326  {
327  // Retrieve the role title and the object title.
328  $query = "SELECT rdat.title role_title,odat.title object_title, ".
329  " oref.ref_id object_ref ".
330  "FROM object_data rdat ".
331  "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id ".
332  "JOIN tree rtree ON rtree.child = fa.parent ".
333  "JOIN object_reference oref ON oref.ref_id = rtree.parent ".
334  "JOIN object_data odat ON odat.obj_id = oref.obj_id ".
335  "WHERE rdat.obj_id = ".$this->ilDB->quote($a_role_id,'integer')." ".
336  "AND fa.assign = 'y' ";
337  $r = $ilDB->query($query);
338  if (!$row = $ilDB->fetchObject($r))
339  {
340  //$log->write('class.ilRbacReview->getMailboxAddress('.$a_role_id.'): error role does not exist');
341  return null; // role does not exist
342  }
343  $object_title = $row->object_title;
344  $object_ref = $row->object_ref;
345  $role_title = $row->role_title;
346 
347 
348  // In a perfect world, we could use the object_title in the
349  // domain part of the mailbox address, and the role title
350  // with prefix '#' in the local part of the mailbox address.
351  $domain = $object_title;
352  $local_part = $role_title;
353 
354 
355  // Determine if the object title is unique
356  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
357  "FROM object_data dat ".
358  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
359  "JOIN tree ON tree.child = ref.ref_id ".
360  "WHERE title = ".$this->ilDB->quote($object_title,'text')." ".
361  "AND tree.tree = 1 ";
362  $r = $this->ilDB->query($q);
363  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
364 
365  // If the object title is not unique, we get rid of the domain.
366  if ($row->count > 1)
367  {
368  $domain = null;
369  }
370 
371  // If the domain contains illegal characters, we get rid of it.
372  //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
373  // Fix for Mantis Bug: 7429 sending mail fails because of brakets
374  if ($domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]/',$domain))
375  {
376  $domain = null;
377  }
378 
379  // If the domain contains special characters, we put square
380  // brackets around it.
381  if ($domain != null &&
382  (preg_match('/[()<>@,;:\\".\[\]]/',$domain) ||
383  preg_match('/[^\x21-\x8f]/',$domain))
384  )
385  {
386  $domain = '['.$domain.']';
387  }
388 
389  // If the role title is one of the ILIAS reserved role titles,
390  // we can use a shorthand version of it for the local part
391  // of the mailbox address.
392  if (strpos($role_title, 'il_') === 0 && $domain != null)
393  {
394  $unambiguous_role_title = $role_title;
395 
396  $pos = strpos($role_title, '_', 3) + 1;
397  $local_part = substr(
398  $role_title,
399  $pos,
400  strrpos($role_title, '_') - $pos
401  );
402  }
403  else
404  {
405  $unambiguous_role_title = 'il_role_'.$a_role_id;
406  }
407 
408  // Determine if the local part is unique. If we don't have a
409  // domain, the local part must be unique within the whole repositry.
410  // If we do have a domain, the local part must be unique for that
411  // domain.
412  if ($domain == null)
413  {
414  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
415  "FROM object_data dat ".
416  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
417  "JOIN tree ON tree.child = ref.ref_id ".
418  "WHERE title = ".$this->ilDB->quote($local_part,'text')." ".
419  "AND tree.tree = 1 ";
420  }
421  else
422  {
423  $q = "SELECT COUNT(rd.obj_id) count ".
424  "FROM object_data rd ".
425  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
426  "JOIN tree t ON t.child = fa.parent ".
427  "WHERE fa.assign = 'y' ".
428  "AND t.parent = ".$this->ilDB->quote($object_ref,'integer')." ".
429  "AND rd.title LIKE ".$this->ilDB->quote(
430  '%'.preg_replace('/([_%])/','\\\\$1', $local_part).'%','text')." ";
431  }
432 
433  $r = $this->ilDB->query($q);
434  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
435 
436  // if the local_part is not unique, we use the unambiguous role title
437  // instead for the local part of the mailbox address
438  if ($row->count > 1)
439  {
440  $local_part = $unambiguous_role_title;
441  }
442 
443 
444  // If the local part contains illegal characters, we use
445  // the unambiguous role title instead.
446  if (preg_match('/[\\"\x00-\x1f]/',$local_part))
447  {
448  $local_part = $unambiguous_role_title;
449  }
450 
451 
452  // Add a "#" prefix to the local part
453  $local_part = '#'.$local_part;
454 
455  // Put quotes around the role title, if needed
456  if (preg_match('/[()<>@,;:.\[\]\x20]/',$local_part))
457  {
458  $local_part = '"'.$local_part.'"';
459  }
460 
461  $mailbox = ($domain == null) ?
462  $local_part :
463  $local_part.'@'.$domain;
464 
465  if ($is_localize)
466  {
467  if (substr($role_title,0,3) == 'il_')
468  {
469  $phrase = $lng->txt(substr($role_title, 0, strrpos($role_title,'_')));
470  }
471  else
472  {
473  $phrase = $role_title;
474  }
475 
476  // make phrase RFC 822 conformant:
477  // - strip excessive whitespace
478  // - strip special characters
479  $phrase = preg_replace('/\s\s+/', ' ', $phrase);
480  $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
481 
482  $mailbox = $phrase.' <'.$mailbox.'>';
483  }
484 
485  return $mailbox;
486  }
487  else
488  {
489  $q = "SELECT title ".
490  "FROM object_data ".
491  "WHERE obj_id = ".$this->ilDB->quote($a_role_id ,'integer');
492  $r = $this->ilDB->query($q);
493 
494  if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
495  {
496  return '#'.$row->title;
497  }
498  else
499  {
500  return null;
501  }
502  }
503  }
504 
505 
513  function roleExists($a_title,$a_id = 0)
514  {
515  global $ilDB;
516 
517  if (empty($a_title))
518  {
519  $message = get_class($this)."::roleExists(): No title given!";
520  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
521  }
522 
523  $clause = ($a_id) ? " AND obj_id != ".$ilDB->quote($a_id)." " : "";
524 
525  $q = "SELECT DISTINCT(obj_id) obj_id FROM object_data ".
526  "WHERE title =".$ilDB->quote($a_title)." ".
527  "AND type IN('role','rolt')".
528  $clause." ";
529  $r = $this->ilDB->query($q);
530 
531  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
532  {
533  return $row->obj_id;
534  }
535  return false;
536  }
537 
550  function __getParentRoles($a_path,$a_templates,$a_keep_protected)
551  {
552  global $log,$ilDB;
553 
554  if (!isset($a_path) or !is_array($a_path))
555  {
556  $message = get_class($this)."::getParentRoles(): No path given or wrong datatype!";
557  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
558  }
559 
560  $parent_roles = array();
561  $role_hierarchy = array();
562 
563  // Select all role folders on a path using a single SQL-statement.
564  // CREATE IN() STATEMENT
565  $in = $ilDB->in('t.parent',$a_path,false,'integer');
566 
567  $q = "SELECT t.child,t.depth FROM tree t ".
568  "JOIN object_reference r ON r.ref_id = t.child ".
569  "JOIN object_data o ON o.obj_id = r.obj_id ".
570  "WHERE ".$in." ".
571  "AND o.type= ".$ilDB->quote('rolf','text')." ".
572  "ORDER BY t.depth ASC";
573 
574  $r = $this->ilDB->query($q);
575 
576 
577  // Sort by path (Administration -> Rolefolder is first element)
578  $role_rows = array();
579  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
580  {
581 
582  $depth = ($row->child == ROLE_FOLDER_ID ? 0 : $row->depth);
583  $role_rows[$depth]['child'] = $row->child;
584  }
585  ksort($role_rows,SORT_NUMERIC);
586 
587  foreach($role_rows as $row)
588  {
589  $roles = $this->getRoleListByObject($row['child'],$a_templates);
590  foreach ($roles as $role)
591  {
592  $id = $role["obj_id"];
593  $role["parent"] = $row['child'];
594  $parent_roles[$id] = $role;
595 
596  if (!array_key_exists($role['obj_id'],$role_hierarchy))
597  {
598  $role_hierarchy[$id] = $row['child'];
599  }
600  }
601  }
602  if (!$a_keep_protected)
603  {
604  return $this->__setProtectedStatus($parent_roles,$role_hierarchy,reset($a_path));
605  }
606  return $parent_roles;
607  }
608 
617  function getParentRoleIds($a_endnode_id,$a_templates = false,$a_keep_protected = false)
618  {
619  global $tree,$log,$ilDB;
620 
621  if (!isset($a_endnode_id))
622  {
623  $GLOBALS['ilLog']->logStack();
624  $message = get_class($this)."::getParentRoleIds(): No node_id (ref_id) given!";
625  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
626  }
627 
628  //var_dump($a_endnode_id);exit;
629  //$log->write("ilRBACreview::getParentRoleIds(), 0");
630  $pathIds = $tree->getPathId($a_endnode_id);
631 
632  // add system folder since it may not in the path
633  $pathIds[0] = SYSTEM_FOLDER_ID;
634  //$log->write("ilRBACreview::getParentRoleIds(), 1");
635  #return $this->getParentRoles($a_endnode_id,$a_templates,$a_keep_protected);
636  return $this->__getParentRoles($pathIds,$a_templates,$a_keep_protected);
637  }
638 
646  function getRoleListByObject($a_ref_id,$a_templates = false)
647  {
648  global $ilDB;
649 
650  if (!isset($a_ref_id) or !isset($a_templates))
651  {
652  $message = get_class($this)."::getRoleListByObject(): Missing parameter!".
653  "ref_id: ".$a_ref_id.
654  "tpl_flag: ".$a_templates;
655  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
656  }
657 
658  $role_list = array();
659 
660  $where = $this->__setTemplateFilter($a_templates);
661 
662  $query = "SELECT * FROM object_data ".
663  "JOIN rbac_fa ON obj_id = rol_id ".
664  $where.
665  "AND object_data.obj_id = rbac_fa.rol_id ".
666  "AND rbac_fa.parent = ".$ilDB->quote($a_ref_id,'integer')." ";
667 
668  $res = $ilDB->query($query);
669  while ($row = $ilDB->fetchAssoc($res))
670  {
671  $row["desc"] = $row["description"];
672  $row["user_id"] = $row["owner"];
673  $role_list[] = $row;
674  }
675 
676  $role_list = $this->__setRoleType($role_list);
677 
678  return $role_list;
679  }
680 
687  function getAssignableRoles($a_templates = false,$a_internal_roles = false)
688  {
689  global $ilDB;
690 
691  $role_list = array();
692 
693  $where = $this->__setTemplateFilter($a_templates);
694 
695  $query = "SELECT * FROM object_data ".
696  "JOIN rbac_fa ON obj_id = rol_id ".
697  $where.
698  "AND rbac_fa.assign = 'y' ";
699  $res = $ilDB->query($query);
700 
701  while ($row = $ilDB->fetchAssoc($res))
702  {
703  $row["desc"] = $row["description"];
704  $row["user_id"] = $row["owner"];
705  $role_list[] = $row;
706  }
707 
708  $role_list = $this->__setRoleType($role_list);
709 
710  return $role_list;
711  }
712 
720  {
721  global $ilDB;
722 
723  $role_list = array();
724  $where = $this->__setTemplateFilter(false);
725 
726  $query = "SELECT fa.*, dat.* ".
727  "FROM tree root ".
728  "JOIN tree node ON node.tree = root.tree ".
729  "AND node.lft > root.lft AND node.rgt < root.rgt ".
730  "JOIN object_reference ref ON ref.ref_id = node.child ".
731  "JOIN rbac_fa fa ON fa.parent = ref.ref_id ".
732  "JOIN object_data dat ON dat.obj_id = fa.rol_id ".
733  "WHERE root.child = ".$this->ilDB->quote($ref_id,'integer')." ".
734  "AND root.tree = 1 ".
735  "AND fa.assign = 'y' ".
736  "ORDER BY dat.title";
737  $res = $ilDB->query($query);
738 
739  while($row = $ilDB->fetchAssoc($res))
740  {
741  $role_list[] = $row;
742  }
743 
744  $role_list = $this->__setRoleType($role_list);
745  return $role_list;
746  }
747 
754  function getAssignableChildRoles($a_ref_id)
755  {
756  global $ilDB;
757  global $tree;
758 
759  $query = "SELECT fa.*, rd.* ".
760  "FROM object_data rd ".
761  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
762  "JOIN tree t ON t.child = fa.parent ".
763  "WHERE fa.assign = 'y' ".
764  "AND t.parent = ".$this->ilDB->quote($a_ref_id,'integer')." "
765  ;
766  $res = $ilDB->query($query);
767  while($row = $ilDB->fetchAssoc($res))
768  {
769  $roles_data[] = $row;
770  }
771  return $roles_data ? $roles_data : array();
772  }
773 
780  function __setTemplateFilter($a_templates)
781  {
782  global $ilDB;
783 
784  if ($a_templates === true)
785  {
786  $where = "WHERE ".$ilDB->in('object_data.type',array('role','rolt'),false,'text')." ";
787  }
788  else
789  {
790  $where = "WHERE ".$ilDB->in('object_data.type',array('role'),false,'text')." ";
791  }
792 
793  return $where;
794  }
795 
807  function __setRoleType($a_role_list)
808  {
809  foreach ($a_role_list as $key => $val)
810  {
811  // determine role type
812  if ($val["type"] == "rolt")
813  {
814  $a_role_list[$key]["role_type"] = "template";
815  }
816  else
817  {
818  if ($val["assign"] == "y")
819  {
820  if ($val["parent"] == ROLE_FOLDER_ID)
821  {
822  $a_role_list[$key]["role_type"] = "global";
823  }
824  else
825  {
826  $a_role_list[$key]["role_type"] = "local";
827  }
828  }
829  else
830  {
831  $a_role_list[$key]["role_type"] = "linked";
832  }
833  }
834 
835  if ($val["protected"] == "y")
836  {
837  $a_role_list[$key]["protected"] = true;
838  }
839  else
840  {
841  $a_role_list[$key]["protected"] = false;
842  }
843  }
844 
845  return $a_role_list;
846  }
847 
855  function assignedUsers($a_rol_id, $a_fields = NULL)
856  {
857  global $ilBench,$ilDB;
858 
859  $ilBench->start("RBAC", "review_assignedUsers");
860 
861  if (!isset($a_rol_id))
862  {
863  $message = get_class($this)."::assignedUsers(): No role_id given!";
864  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
865  }
866 
867  $result_arr = array();
868 
869  if ($a_fields !== NULL and is_array($a_fields))
870  {
871  if (count($a_fields) == 0)
872  {
873  $select = "*";
874  }
875  else
876  {
877  if (($usr_id_field = array_search("usr_id",$a_fields)) !== false)
878  unset($a_fields[$usr_id_field]);
879 
880  $select = implode(",",$a_fields).",usr_data.usr_id";
881  $select = addslashes($select);
882  }
883 
884  $query = "SELECT ".$select." FROM usr_data ".
885  "LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id ".
886  "WHERE rbac_ua.rol_id =".$ilDB->quote($a_rol_id,'integer');
887  $res = $ilDB->query($query);
888  while($row = $ilDB->fetchAssoc($res))
889  {
890  $result_arr[] = $row;
891  }
892  }
893  else
894  {
895  $query = "SELECT usr_id FROM rbac_ua WHERE rol_id= ".$ilDB->quote($a_rol_id,'integer');
896 
897  $res = $ilDB->query($query);
898  while($row = $ilDB->fetchAssoc($res))
899  {
900  array_push($result_arr,$row["usr_id"]);
901  }
902  }
903 
904  $ilBench->stop("RBAC", "review_assignedUsers");
905 
906  return $result_arr;
907  }
908 
916  function isAssigned($a_usr_id,$a_role_id)
917  {
918  // Quickly determine if user is assigned to a role
919  global $ilDB;
920 
921  $ilDB->setLimit(1,0);
922  $query = "SELECT usr_id FROM rbac_ua WHERE ".
923  "rol_id= ".$ilDB->quote($a_role_id,'integer')." ".
924  "AND usr_id= ".$ilDB->quote($a_usr_id);
925  $res = $ilDB->query($query);
926 
927  return $res->numRows() == 1;
928  }
929 
941  function isAssignedToAtLeastOneGivenRole($a_usr_id,$a_role_ids)
942  {
943  global $ilDB;
944 
945  $ilDB->setLimit(1,0);
946  $query = "SELECT usr_id FROM rbac_ua WHERE ".
947  $ilDB->in('rol_id',$a_role_ids,false,'integer').
948  " AND usr_id= ".$ilDB->quote($a_usr_id);
949  $res = $ilDB->query($query);
950 
951  return $ilDB->numRows($res) == 1;
952  }
953 
960  function assignedRoles($a_usr_id)
961  {
962  global $ilDB;
963 
964  $role_arr = array();
965 
966  $query = "SELECT rol_id FROM rbac_ua WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer');
967 
968  $res = $ilDB->query($query);
969  while($row = $ilDB->fetchObject($res))
970  {
971  $role_arr[] = $row->rol_id;
972  }
973  return $role_arr ? $role_arr : array();
974  }
975 
980  public function assignedGlobalRoles($a_usr_id)
981  {
982  global $ilDB;
983 
984  $query = "SELECT ua.rol_id FROM rbac_ua ua ".
985  "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id ".
986  "WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer').' '.
987  "AND parent = ".$ilDB->quote(ROLE_FOLDER_ID)." ".
988  "AND assign = 'y' ";
989 
990  $res = $ilDB->query($query);
991  while($row = $ilDB->fetchObject($res))
992  {
993  $role_arr[] = $row->rol_id;
994  }
995  return $role_arr ? $role_arr : array();
996  }
997 
1005  function isAssignable($a_rol_id, $a_ref_id)
1006  {
1007  global $ilBench,$ilDB;
1008 
1009  $ilBench->start("RBAC", "review_isAssignable");
1010 
1011  // exclude system role from rbac
1012  if ($a_rol_id == SYSTEM_ROLE_ID)
1013  {
1014  $ilBench->stop("RBAC", "review_isAssignable");
1015  return true;
1016  }
1017 
1018  if (!isset($a_rol_id) or !isset($a_ref_id))
1019  {
1020  $message = get_class($this)."::isAssignable(): Missing parameter!".
1021  " role_id: ".$a_rol_id." ,ref_id: ".$a_ref_id;
1022  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1023  }
1024  $query = "SELECT * FROM rbac_fa ".
1025  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1026  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1027  $res = $ilDB->query($query);
1028  $row = $ilDB->fetchObject($res);
1029 
1030  $ilBench->stop("RBAC", "review_isAssignable");
1031  return $row->assign == 'y' ? true : false;
1032  }
1033 
1037  public function hasMultipleAssignments($a_role_id)
1038  {
1039  global $ilDB;
1040 
1041  $query = "SELECT * FROM rbac_fa WHERE rol_id = ".$ilDB->quote($a_role_id,'integer').' '.
1042  "AND assign = ".$ilDB->quote('y','text');
1043  $res = $ilDB->query($query);
1044  return $res->numRows() > 1;
1045  }
1046 
1057  function getFoldersAssignedToRole($a_rol_id, $a_assignable = false)
1058  {
1059  global $ilDB;
1060 
1061  if (!isset($a_rol_id))
1062  {
1063  $message = get_class($this)."::getFoldersAssignedToRole(): No role_id given!";
1064  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1065  }
1066 
1067  if ($a_assignable)
1068  {
1069  $where = " AND assign ='y'";
1070  }
1071 
1072  $query = "SELECT DISTINCT parent FROM rbac_fa ".
1073  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".$where." ";
1074 
1075  $res = $ilDB->query($query);
1076  while($row = $ilDB->fetchObject($res))
1077  {
1078  $folders[] = $row->parent;
1079  }
1080  return $folders ? $folders : array();
1081  }
1082 
1091  function getRolesOfRoleFolder($a_ref_id,$a_nonassignable = true)
1092  {
1093  global $ilBench,$ilDB,$ilLog;
1094 
1095  $ilBench->start("RBAC", "review_getRolesOfRoleFolder");
1096 
1097  if (!isset($a_ref_id))
1098  {
1099  $message = get_class($this)."::getRolesOfRoleFolder(): No ref_id given!";
1100  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1101 
1102  }
1103 
1104  if ($a_nonassignable === false)
1105  {
1106  $and = " AND assign='y'";
1107  }
1108 
1109  $query = "SELECT rol_id FROM rbac_fa ".
1110  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1111  $and;
1112 
1113  $res = $ilDB->query($query);
1114  while($row = $ilDB->fetchObject($res))
1115  {
1116  $rol_id[] = $row->rol_id;
1117  }
1118 
1119  $ilBench->stop("RBAC", "review_getRolesOfRoleFolder");
1120 
1121  return $rol_id ? $rol_id : array();
1122  }
1123 
1129  function getGlobalRoles()
1130  {
1131  return $this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false);
1132  }
1133 
1140  {
1141  foreach($this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false) as $role_id)
1142  {
1143  $ga[] = array('obj_id' => $role_id,
1144  'role_type' => 'global');
1145  }
1146  return $ga ? $ga : array();
1147  }
1148 
1155  {
1156  include_once './Services/AccessControl/classes/class.ilObjRole.php';
1157 
1158  foreach($this->getGlobalRoles() as $role_id)
1159  {
1160  if(ilObjRole::_getAssignUsersStatus($role_id))
1161  {
1162  $ga[] = array('obj_id' => $role_id,
1163  'role_type' => 'global');
1164  }
1165  }
1166  return $ga ? $ga : array();
1167  }
1168 
1175  {
1176  global $ilDB;
1177 
1178  $query = "SELECT DISTINCT parent FROM rbac_fa";
1179  $res = $ilDB->query($query);
1180 
1181  $parent = array();
1182  while($row = $ilDB->fetchObject($res))
1183  {
1184  $parent[] = $row->parent;
1185  }
1186  return $parent;
1187  }
1188 
1195  function getRoleFolderOfObject($a_ref_id)
1196  {
1197  global $tree,$ilBench;
1198 
1199  $ilBench->start("RBAC", "review_getRoleFolderOfObject");
1200 
1201  if (!isset($a_ref_id))
1202  {
1203  $GLOBALS['ilLog']->logStack();
1204  $message = get_class($this)."::getRoleFolderOfObject(): No ref_id given!";
1205  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1206  }
1207  $childs = $tree->getChildsByType($a_ref_id,"rolf");
1208 
1209  $ilBench->stop("RBAC", "review_getRoleFolderOfObject");
1210 
1211  return $childs[0] ? $childs[0] : array();
1212  }
1213 
1214  function getRoleFolderIdOfObject($a_ref_id)
1215  {
1216  $rolf = $this->getRoleFolderOfObject($a_ref_id);
1217 
1218  if (!$rolf)
1219  {
1220  return false;
1221  }
1222 
1223  return $rolf['ref_id'];
1224  }
1225 
1231  function getOperations()
1232  {
1233  global $ilDB;
1234 
1235  $query = 'SELECT * FROM rbac_operations ORDER BY ops_id ';
1236  $res = $this->ilDB->query($query);
1237  while($row = $ilDB->fetchObject($res))
1238  {
1239  $ops[] = array('ops_id' => $row->ops_id,
1240  'operation' => $row->operation,
1241  'description' => $row->description);
1242  }
1243 
1244  return $ops ? $ops : array();
1245  }
1246 
1252  function getOperation($ops_id)
1253  {
1254  global $ilDB;
1255 
1256  $query = 'SELECT * FROM rbac_operations WHERE ops_id = '.$ilDB->quote($ops_id,'integer');
1257  $res = $this->ilDB->query($query);
1258  while($row = $ilDB->fetchObject($res))
1259  {
1260  $ops = array('ops_id' => $row->ops_id,
1261  'operation' => $row->operation,
1262  'description' => $row->description);
1263  }
1264 
1265  return $ops ? $ops : array();
1266  }
1267 
1276  public function getAllOperationsOfRole($a_rol_id, $a_parent = 0)
1277  {
1278  global $ilDB;
1279 
1280  if(!$a_parent)
1281  {
1282  $a_parent = ROLE_FOLDER_ID;
1283  }
1284 
1285  $query = "SELECT ops_id,type FROM rbac_templates ".
1286  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1287  "AND parent = ".$ilDB->quote($a_parent,'integer');
1288  $res = $ilDB->query($query);
1289 
1290  while ($row = $ilDB->fetchObject($res))
1291  {
1292  $ops_arr[$row->type][] = $row->ops_id;
1293  }
1294  return (array) $ops_arr;
1295  }
1296 
1303  public function getActiveOperationsOfRole($a_ref_id, $a_role_id)
1304  {
1305  global $ilDB;
1306 
1307  $query = 'SELECT * FROM rbac_pa '.
1308  'WHERE ref_id = '.$ilDB->quote($a_ref_id,'integer').' '.
1309  'AND rol_id = '.$ilDB->quote($a_role_id,'integer').' ';
1310 
1311  $res = $ilDB->query($query);
1312  while($row = $res->fetchRow(DB_FETCHMODE_ASSOC))
1313  {
1314  return unserialize($row['ops_id']);
1315  }
1316  return array();
1317  }
1318 
1319 
1329  function getOperationsOfRole($a_rol_id,$a_type,$a_parent = 0)
1330  {
1331  global $ilDB,$ilLog;
1332 
1333  if (!isset($a_rol_id) or !isset($a_type))
1334  {
1335  $message = get_class($this)."::getOperationsOfRole(): Missing Parameter!".
1336  "role_id: ".$a_rol_id.
1337  "type: ".$a_type.
1338  "parent_id: ".$a_parent;
1339  $ilLog->logStack("Missing parameter! ");
1340  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1341  }
1342 
1343  $ops_arr = array();
1344 
1345  // if no rolefolder id is given, assume global role folder as target
1346  if ($a_parent == 0)
1347  {
1348  $a_parent = ROLE_FOLDER_ID;
1349  }
1350 
1351  $query = "SELECT ops_id FROM rbac_templates ".
1352  "WHERE type =".$ilDB->quote($a_type,'text')." ".
1353  "AND rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1354  "AND parent = ".$ilDB->quote($a_parent,'integer');
1355  $res = $ilDB->query($query);
1356  while ($row = $ilDB->fetchObject($res))
1357  {
1358  $ops_arr[] = $row->ops_id;
1359  }
1360 
1361  return $ops_arr;
1362  }
1363 
1364  function getRoleOperationsOnObject($a_role_id,$a_ref_id)
1365  {
1366  global $ilDB;
1367 
1368  $query = "SELECT * FROM rbac_pa ".
1369  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1370  "AND ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
1371 
1372  $res = $ilDB->query($query);
1373  while($row = $ilDB->fetchObject($res))
1374  {
1375  $ops = unserialize($row->ops_id);
1376  }
1377 
1378  return $ops ? $ops : array();
1379  }
1380 
1387  function getOperationsOnType($a_typ_id)
1388  {
1389  global $ilDB;
1390 
1391  if (!isset($a_typ_id))
1392  {
1393  $message = get_class($this)."::getOperationsOnType(): No type_id given!";
1394  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1395  }
1396 
1397  #$query = "SELECT * FROM rbac_ta WHERE typ_id = ".$ilDB->quote($a_typ_id,'integer');
1398 
1399  $query = 'SELECT * FROM rbac_ta ta JOIN rbac_operations o ON ta.ops_id = o.ops_id '.
1400  'WHERE typ_id = '.$ilDB->quote($a_typ_id,'integer').' '.
1401  'ORDER BY op_order';
1402 
1403  $res = $ilDB->query($query);
1404 
1405  while($row = $ilDB->fetchObject($res))
1406  {
1407  $ops_id[] = $row->ops_id;
1408  }
1409 
1410  return $ops_id ? $ops_id : array();
1411  }
1412 
1419  function getOperationsOnTypeString($a_type)
1420  {
1421  global $ilDB;
1422 
1423  $query = "SELECT * FROM object_data WHERE type = 'typ' AND title = ".$ilDB->quote($a_type ,'text')." ";
1424 
1425 
1426  $res = $this->ilDB->query($query);
1427  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1428  {
1429  return $this->getOperationsOnType($row->obj_id);
1430  }
1431  return false;
1432  }
1433 
1440  public function getOperationsByTypeAndClass($a_type,$a_class)
1441  {
1442  global $ilDB;
1443 
1444  if($a_class != 'create')
1445  {
1446  $condition = "AND class != ".$ilDB->quote('create','text');
1447  }
1448  else
1449  {
1450  $condition = "AND class = ".$ilDB->quote('create','text');
1451  }
1452 
1453  $query = "SELECT ro.ops_id FROM rbac_operations ro ".
1454  "JOIN rbac_ta rt ON ro.ops_id = rt.ops_id ".
1455  "JOIN object_data od ON rt.typ_id = od.obj_id ".
1456  "WHERE type = ".$ilDB->quote('typ','text')." ".
1457  "AND title = ".$ilDB->quote($a_type,'text')." ".
1458  $condition." ".
1459  "ORDER BY op_order ";
1460 
1461  $res = $ilDB->query($query);
1462 
1463  $ops = array();
1464  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1465  {
1466  $ops[] = $row->ops_id;
1467  }
1468  return $ops;
1469  }
1470 
1471 
1480  function getObjectsWithStopedInheritance($a_rol_id,$a_filter = array())
1481  {
1482  global $ilDB;
1483 
1484  $query = 'SELECT t.parent p FROM tree t JOIN rbac_fa fa ON fa.parent = child '.
1485  'WHERE assign = '.$ilDB->quote('n','text').' '.
1486  'AND rol_id = '.$ilDB->quote($a_rol_id,'integer').' ';
1487 
1488  if($a_filter)
1489  {
1490  $query .= ('AND '.$ilDB->in('t.parent',(array) $a_filter,false,'integer'));
1491  }
1492 
1493  $res = $ilDB->query($query);
1494  $parent = array();
1495  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1496  {
1497  $parent[] = $row->p;
1498  }
1499  return $parent;
1500  }
1501 
1508  function isDeleted($a_node_id)
1509  {
1510  global $ilDB;
1511 
1512  $q = "SELECT tree FROM tree WHERE child =".$ilDB->quote($a_node_id)." ";
1513  $r = $this->ilDB->query($q);
1514 
1515  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1516 
1517  if (!$row)
1518  {
1519  $message = sprintf('%s::isDeleted(): Role folder with ref_id %s not found!',
1520  get_class($this),
1521  $a_node_id);
1522  $this->log->write($message,$this->log->FATAL);
1523 
1524  return true;
1525  }
1526 
1527  // rolefolder is deleted
1528  if ($row->tree < 0)
1529  {
1530  return true;
1531  }
1532 
1533  return false;
1534  }
1535 
1536  public function isGlobalRole($a_role_id)
1537  {
1538  return in_array($a_role_id,$this->getGlobalRoles());
1539  }
1540 
1541  function getRolesByFilter($a_filter = 0,$a_user_id = 0)
1542  {
1543  global $ilDB;
1544 
1545  $assign = "y";
1546 
1547  switch($a_filter)
1548  {
1549  // all (assignable) roles
1550  case 1:
1551  return $this->getAssignableRoles();
1552  break;
1553 
1554  // all (assignable) global roles
1555  case 2:
1556  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),false,'integer').' ';
1557  break;
1558 
1559  // all (assignable) local roles
1560  case 3:
1561  case 4:
1562  case 5:
1563  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),true,'integer');
1564  break;
1565 
1566  // all role templates
1567  case 6:
1568  $where = "WHERE object_data.type = 'rolt'";
1569  $assign = "n";
1570  break;
1571 
1572  // only assigned roles, handled by ilObjUserGUI::roleassignmentObject()
1573  case 0:
1574  default:
1575  if(!$a_user_id)
1576  return array();
1577 
1578  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->assignedRoles($a_user_id),false,'integer').' ';
1579  break;
1580  }
1581 
1582  $roles = array();
1583 
1584  $query = "SELECT * FROM object_data ".
1585  "JOIN rbac_fa ON obj_id = rol_id ".
1586  $where.
1587  "AND rbac_fa.assign = ".$ilDB->quote($assign,'text')." ";
1588 
1589  $res = $ilDB->query($query);
1590  while($row = $ilDB->fetchAssoc($res))
1591  {
1592  $prefix = (substr($row["title"],0,3) == "il_") ? true : false;
1593 
1594  // all (assignable) internal local roles only
1595  if ($a_filter == 4 and !$prefix)
1596  {
1597  continue;
1598  }
1599 
1600  // all (assignable) non internal local roles only
1601  if ($a_filter == 5 and $prefix)
1602  {
1603  continue;
1604  }
1605 
1606  $row["desc"] = $row["description"];
1607  $row["user_id"] = $row["owner"];
1608  $roles[] = $row;
1609  }
1610 
1611  $roles = $this->__setRoleType($roles);
1612 
1613  return $roles ? $roles : array();
1614  }
1615 
1616  // get id of a given object type (string)
1617  function getTypeId($a_type)
1618  {
1619  global $ilDB;
1620 
1621  $q = "SELECT obj_id FROM object_data ".
1622  "WHERE title=".$ilDB->quote($a_type ,'text')." AND type='typ'";
1623  $r = $ilDB->query($q);
1624 
1625  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1626  return $row->obj_id;
1627  }
1628 
1638  public static function _getOperationIdsByName($operations)
1639  {
1640  global $ilDB;
1641 
1642  if(!count($operations))
1643  {
1644  return array();
1645  }
1646 
1647  $query = 'SELECT ops_id FROM rbac_operations '.
1648  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1649 
1650  $res = $ilDB->query($query);
1651  while($row = $ilDB->fetchObject($res))
1652  {
1653  $ops_ids[] = $row->ops_id;
1654  }
1655  return $ops_ids ? $ops_ids : array();
1656  }
1657 
1665  public static function _getOperationIdByName($a_operation)
1666  {
1667  global $ilDB,$ilErr;
1668 
1669  if (!isset($a_operation))
1670  {
1671  $message = "perm::getOperationId(): No operation given!";
1672  $ilErr->raiseError($message,$ilErr->WARNING);
1673  }
1674 
1675  // Cache operation ids
1676  if (! is_array(self::$_opsCache)) {
1677  self::$_opsCache = array();
1678 
1679  $q = "SELECT ops_id, operation FROM rbac_operations";
1680  $r = $ilDB->query($q);
1681  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
1682  {
1683  self::$_opsCache[$row->operation] = $row->ops_id;
1684  }
1685  }
1686 
1687  // Get operation ID by name from cache
1688  if (array_key_exists($a_operation, self::$_opsCache)) {
1689  return self::$_opsCache[$a_operation];
1690  }
1691  return null;
1692  }
1693 
1699  public static function lookupCreateOperationIds($a_type_arr)
1700  {
1701  global $ilDB;
1702 
1703  $operations = array();
1704  foreach($a_type_arr as $type)
1705  {
1706  $operations[] = ('create_'.$type);
1707  }
1708 
1709  if(!count($operations))
1710  {
1711  return array();
1712  }
1713 
1714  $query = 'SELECT ops_id, operation FROM rbac_operations '.
1715  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1716 
1717  $res = $ilDB->query($query);
1718 
1719  $ops_ids = array();
1720  while($row = $ilDB->fetchObject($res))
1721  {
1722  $type_arr = explode('_', $row->operation);
1723  $type = $type_arr[1];
1724 
1725  $ops_ids[$type] = $row->ops_id;
1726  }
1727  return $ops_ids;
1728  }
1729 
1730 
1739  function getLinkedRolesOfRoleFolder($a_ref_id)
1740  {
1741  global $ilDB;
1742 
1743  if (!isset($a_ref_id))
1744  {
1745  $message = get_class($this)."::getLinkedRolesOfRoleFolder(): No ref_id given!";
1746  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1747  }
1748 
1749  $and = " AND assign='n'";
1750 
1751  $query = "SELECT rol_id FROM rbac_fa ".
1752  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1753  $and;
1754  $res = $this->ilDB->query($query);
1755  while($row = $ilDB->fetchObject($res))
1756  {
1757  $rol_id[] = $row->rol_id;
1758  }
1759 
1760  return $rol_id ? $rol_id : array();
1761  }
1762 
1763  // checks if default permission settings of role under current parent (rolefolder) are protected from changes
1764  function isProtected($a_ref_id,$a_role_id)
1765  {
1766  global $ilDB;
1767 
1768  $query = "SELECT protected FROM rbac_fa ".
1769  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1770  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1771  $res = $ilDB->query($query);
1772  $row = $ilDB->fetchAssoc($res);
1773 
1774  return ilUtil::yn2tf($row['protected']);
1775  }
1776 
1777  // this method alters the protected status of role regarding the current user's role assignment
1778  // and current postion in the hierarchy.
1779  function __setProtectedStatus($a_parent_roles,$a_role_hierarchy,$a_ref_id)
1780  {
1781  #vd('refId',$a_ref_id,'parent roles',$a_parent_roles,'role-hierarchy',$a_role_hierarchy);
1782 
1783  global $rbacsystem,$ilUser,$log;
1784 
1785  if (in_array(SYSTEM_ROLE_ID,$this->assignedRoles($ilUser->getId())))
1786  {
1787  $leveladmin = true;
1788  }
1789  else
1790  {
1791  $leveladmin = false;
1792  }
1793  #vd("RoleHierarchy",$a_role_hierarchy);
1794  foreach ($a_role_hierarchy as $role_id => $rolf_id)
1795  {
1796  //$log->write("ilRBACreview::__setProtectedStatus(), 0");
1797  #echo "<br/>ROLF: ".$rolf_id." ROLE_ID: ".$role_id." (".$a_parent_roles[$role_id]['title'].") ";
1798  //var_dump($leveladmin,$a_parent_roles[$role_id]['protected']);
1799 
1800  if ($leveladmin == true)
1801  {
1802  $a_parent_roles[$role_id]['protected'] = false;
1803  continue;
1804  }
1805 
1806  if ($a_parent_roles[$role_id]['protected'] == true)
1807  {
1808  $arr_lvl_roles_user = array_intersect($this->assignedRoles($ilUser->getId()),array_keys($a_role_hierarchy,$rolf_id));
1809 
1810  #vd("intersection",$arr_lvl_roles_user);
1811 
1812  foreach ($arr_lvl_roles_user as $lvl_role_id)
1813  {
1814  #echo "<br/>level_role: ".$lvl_role_id;
1815  #echo "<br/>a_ref_id: ".$a_ref_id;
1816 
1817  //$log->write("ilRBACreview::__setProtectedStatus(), 1");
1818  // check if role grants 'edit_permission' to parent
1819 
1820  if ($rbacsystem->checkPermission($a_ref_id,$lvl_role_id,'edit_permission'))
1821  {
1822  #echo "<br />Permission granted";
1823  //$log->write("ilRBACreview::__setProtectedStatus(), 2");
1824  // user may change permissions of that higher-ranked role
1825  $a_parent_roles[$role_id]['protected'] = false;
1826 
1827  // remember successful check
1828  $leveladmin = true;
1829  }
1830  }
1831  }
1832  }
1833 
1834  return $a_parent_roles;
1835  }
1836 
1847  public static function _getOperationList($a_type = null)
1848  {
1849  global $ilDB;
1850 
1851  $arr = array();
1852 
1853  if ($a_type)
1854  {
1855  $query = sprintf('SELECT * FROM rbac_operations '.
1856  'JOIN rbac_ta ON rbac_operations.ops_id = rbac_ta.ops_id '.
1857  'JOIN object_data ON rbac_ta.typ_id = object_data.obj_id '.
1858  'WHERE object_data.title = %s '.
1859  'AND object_data.type = %s '.
1860  'ORDER BY op_order ASC',
1861  $ilDB->quote($a_type,'text'),
1862  $ilDB->quote('typ','text'));
1863  }
1864  else
1865  {
1866  $query = 'SELECT * FROM rbac_operations ORDER BY op_order ASC';
1867  }
1868  $res = $ilDB->query($query);
1869  while ($row = $ilDB->fetchAssoc($res))
1870  {
1871  $arr[] = array(
1872  "ops_id" => $row['ops_id'],
1873  "operation" => $row['operation'],
1874  "desc" => $row['description'],
1875  "class" => $row['class'],
1876  "order" => $row['op_order']
1877  );
1878  }
1879  return $arr;
1880  }
1881 
1882  public static function _groupOperationsByClass($a_ops_arr)
1883  {
1884  $arr = array();
1885 
1886  foreach ($a_ops_arr as $ops)
1887  {
1888  $arr[$ops['class']][] = array ('ops_id' => $ops['ops_id'],
1889  'name' => $ops['operation']
1890  );
1891  }
1892  return $arr;
1893  }
1894 
1902  public function getObjectOfRole($a_role_id)
1903  {
1904  global $ilDB;
1905 
1906  $query = "SELECT obr.obj_id FROM rbac_fa rfa ".
1907  "JOIN tree ON rfa.parent = tree.child ".
1908  "JOIN object_reference obr ON tree.parent = obr.ref_id ".
1909  "WHERE tree.tree = 1 ".
1910  "AND assign = 'y' ".
1911  "AND rol_id = ".$ilDB->quote($a_role_id,'integer')." ";
1912  $res = $ilDB->query($query);
1913  while($row = $ilDB->fetchObject($res))
1914  {
1915  $obj_id = $row->obj_id;
1916  }
1917 
1918  return $obj_id ? $obj_id : 0;
1919  }
1920 
1926  public function getObjectReferenceOfRole($a_role_id)
1927  {
1928  global $ilDB;
1929 
1930  $query = "SELECT tree.parent ref FROM rbac_fa fa ".
1931  "JOIN tree ON fa.parent = tree.child ".
1932  "WHERE tree.tree = 1 ".
1933  "AND assign = ".$ilDB->quote('y','text').' '.
1934  "AND rol_id = ".$ilDB->quote($a_role_id,'integer');
1935 
1936  $res = $ilDB->query($query);
1937  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1938  {
1939  return $row->ref;
1940  }
1941  return 0;
1942  }
1943 
1950  public function isRoleDeleted ($a_role_id){
1951  $rolf_list = $this->getFoldersAssignedToRole($a_role_id, false);
1952  $deleted = true;
1953  if (count($rolf_list))
1954  {
1955  foreach ($rolf_list as $rolf) {
1956  // only list roles that are not set to status "deleted"
1957  if (!$this->isDeleted($rolf))
1958  {
1959  $deleted = false;
1960  break;
1961  }
1962  }
1963  }
1964  return $deleted;
1965  }
1966 
1967 
1968  function getRolesForIDs($role_ids, $use_templates)
1969  {
1970  global $ilDB;
1971 
1972  $role_list = array();
1973 
1974  $where = $this->__setTemplateFilter($use_templates);
1975 
1976  $query = "SELECT * FROM object_data ".
1977  "JOIN rbac_fa ON object_data.obj_id = rbac_fa.rol_id ".
1978  $where.
1979  "AND rbac_fa.assign = 'y' " .
1980  'AND '.$ilDB->in('object_data.obj_id',$role_ids,false,'integer');
1981 
1982  $res = $ilDB->query($query);
1983  while($row = $ilDB->fetchAssoc($res))
1984  {
1985  $row["desc"] = $row["description"];
1986  $row["user_id"] = $row["owner"];
1987  $role_list[] = $row;
1988  }
1989 
1990  $role_list = $this->__setRoleType($role_list);
1991  return $role_list;
1992  }
1993 
1998  public function getOperationAssignment()
1999  {
2000  global $ilDB;
2001 
2002  $query = 'SELECT ta.typ_id, obj.title, ops.ops_id, ops.operation FROM rbac_ta ta '.
2003  'JOIN object_data obj ON obj.obj_id = ta.typ_id '.
2004  'JOIN rbac_operations ops ON ops.ops_id = ta.ops_id ';
2005  $res = $ilDB->query($query);
2006 
2007  $counter = 0;
2008  while($row = $ilDB->fetchObject($res))
2009  {
2010  $info[$counter]['typ_id'] = $row->typ_id;
2011  $info[$counter]['type'] = $row->title;
2012  $info[$counter]['ops_id'] = $row->ops_id;
2013  $info[$counter]['operation'] = $row->operation;
2014  $counter++;
2015  }
2016  return $info ? $info : array();
2017 
2018  }
2019 
2028  public function filterEmptyRoleFolders($a_rolf_candidates)
2029  {
2030  global $ilDB;
2031 
2032  $query = 'SELECT DISTINCT(parent) parent FROM rbac_fa '.
2033  'WHERE '.$ilDB->in('parent',$a_rolf_candidates,false,'integer');
2034  $res = $ilDB->query($query);
2035  while($row = $ilDB->fetchObject($res))
2036  {
2037  $non_empty[] = $row->parent;
2038  }
2039  return $non_empty ? $non_empty : array();
2040  }
2041 
2048  public function isDeleteable($a_role_id, $a_rolf_id)
2049  {
2050  if(!$this->isAssignable($a_role_id, $a_rolf_id))
2051  {
2052  return false;
2053  }
2054  if($a_role_id == SYSTEM_ROLE_ID or $a_role_id == ANONYMOUS_ROLE_ID)
2055  {
2056  return false;
2057  }
2058  if(substr(ilObject::_lookupTitle($a_role_id),0,3) == 'il_')
2059  {
2060  return false;
2061  }
2062  return true;
2063  }
2064 } // END class.ilRbacReview
2065 ?>