ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilRbacReview.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
20 {
21  const FILTER_ALL = 1;
22  const FILTER_ALL_GLOBAL = 2;
23  const FILTER_ALL_LOCAL = 3;
24  const FILTER_INTERNAL = 4;
26  const FILTER_TEMPLATES = 6;
27 
28  protected $assigned_roles = array();
29  var $log = null;
30 
31  // Cache operation ids
32  private static $_opsCache = null;
33 
37  protected static $assigned_users_cache = array();
38 
42  protected static $is_assigned_cache = array();
43 
48  public function __construct()
49  {
50  global $ilDB,$ilErr,$ilias,$ilLog;
51 
52  $this->log =& $ilLog;
53 
54  // set db & error handler
55  (isset($ilDB)) ? $this->ilDB =& $ilDB : $this->ilDB =& $ilias->db;
56 
57  if (!isset($ilErr))
58  {
59  $ilErr = new ilErrorHandling();
60  $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK,array($ilErr,'errorHandler'));
61  }
62  else
63  {
64  $this->ilErr =& $ilErr;
65  }
66  }
67 
115  function searchRolesByMailboxAddressList($a_address_list)
116  {
117  global $ilDB;
118 
119  $role_ids = array();
120 
121  include_once "Services/Mail/classes/class.ilMail.php";
122  if(ilMail::_usePearMail())
123  {
124  require_once './Services/PEAR/lib/Mail/RFC822.php';
125  $parser = new Mail_RFC822();
126  $parsedList = $parser->parseAddressList($a_address_list, ilMail::ILIAS_HOST, false, true);
127  foreach ($parsedList as $address)
128  {
129  $local_part = $address->mailbox;
130  if (strpos($local_part,'#') !== 0 &&
131  !($local_part{0} == '"' && $local_part{1} == "#"))
132  {
133  // A local-part which doesn't start with a '#' doesn't denote a role.
134  // Therefore we can skip it.
135  continue;
136  }
137 
138  $local_part = substr($local_part, 1);
139 
140  /* If role contains spaces, eg. 'foo role', double quotes are added which have to be
141  removed here.*/
142  if( $local_part{0} == '#' && $local_part{strlen($local_part) - 1} == '"' )
143  {
144  $local_part = substr($local_part, 1);
145  $local_part = substr($local_part, 0, strlen($local_part) - 1);
146  }
147 
148  if (substr($local_part,0,8) == 'il_role_')
149  {
150  $role_id = substr($local_part,8);
151  $query = "SELECT t.tree ".
152  "FROM rbac_fa fa ".
153  "JOIN tree t ON t.child = fa.parent ".
154  "WHERE fa.rol_id = ".$this->ilDB->quote($role_id,'integer')." ".
155  "AND fa.assign = 'y' ".
156  "AND t.tree = 1";
157  $r = $ilDB->query($query);
158  if ($r->numRows() > 0)
159  {
160  $role_ids[] = $role_id;
161  }
162  continue;
163  }
164 
165 
166  $domain = $address->host;
167  if (strpos($domain,'[') == 0 && strrpos($domain,']'))
168  {
169  $domain = substr($domain,1,strlen($domain) - 2);
170  }
171  if (strlen($local_part) == 0)
172  {
173  $local_part = $domain;
174  $address->host = ilMail::ILIAS_HOST;
175  $domain = ilMail::ILIAS_HOST;
176  }
177 
178  if (strtolower($address->host) == ilMail::ILIAS_HOST)
179  {
180  // Search for roles = local-part in the whole repository
181  $query = "SELECT dat.obj_id ".
182  "FROM object_data dat ".
183  "JOIN rbac_fa fa ON fa.rol_id = dat.obj_id ".
184  "JOIN tree t ON t.child = fa.parent ".
185  "WHERE dat.title =".$this->ilDB->quote($local_part,'text')." ".
186  "AND dat.type = 'role' ".
187  "AND fa.assign = 'y' ".
188  "AND t.tree = 1";
189  }
190  else
191  {
192  // Search for roles like local-part in objects = host
193  $query = "SELECT rdat.obj_id ".
194  "FROM object_data odat ".
195  "JOIN object_reference oref ON oref.obj_id = odat.obj_id ".
196  "JOIN tree otree ON otree.child = oref.ref_id ".
197  "JOIN rbac_fa rfa ON rfa.parent = otree.child ".
198  "JOIN object_data rdat ON rdat.obj_id = rfa.rol_id ".
199  "WHERE odat.title = ".$this->ilDB->quote($domain,'text')." ".
200  "AND otree.tree = 1 ".
201  "AND rfa.assign = 'y' ".
202  "AND rdat.title LIKE ".
203  $this->ilDB->quote('%'.preg_replace('/([_%])/','\\\\$1',$local_part).'%','text');
204  }
205  $r = $ilDB->query($query);
206 
207  $count = 0;
208  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
209  {
210  $role_ids[] = $row->obj_id;
211  $count++;
212  }
213 
214  // Nothing found?
215  // In this case, we search for roles = host.
216  if ($count == 0 && strtolower($address->host) == ilMail::ILIAS_HOST)
217  {
218  $q = "SELECT dat.obj_id ".
219  "FROM object_data dat ".
220  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
221  "JOIN tree t ON t.child = ref.ref_id ".
222  "WHERE dat.title = ".$this->ilDB->quote($domain ,'text')." ".
223  "AND dat.type = 'role' ".
224  "AND t.tree = 1 ";
225  $r = $this->ilDB->query($q);
226 
227  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
228  {
229  $role_ids[] = $row->obj_id;
230  }
231  }
232  //echo '<br>ids='.var_export($role_ids,true);
233  }
234  }
235  else
236  {
237  // the following code is executed, when Pear Mail is
238  // not installed
239 
240  $titles = explode(',', $a_address_list);
241 
242  $titleList = '';
243  foreach ($titles as $title)
244  {
245  if (strlen($inList) > 0)
246  {
247  $titleList .= ',';
248  }
249  $title = trim($title);
250  if (strpos($title,'#') == 0)
251  {
252  $titleList .= $this->ilDB->quote(substr($title, 1));
253  }
254  }
255  if (strlen($titleList) > 0)
256  {
257  $q = "SELECT obj_id ".
258  "FROM object_data ".
259  "WHERE title IN (".$titleList.") ".
260  "AND type='role'";
261  $r = $this->ilDB->query($q);
262  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
263  {
264  $role_ids[] = $row->obj_id;
265  }
266  }
267  }
268 
269  return $role_ids;
270  }
271 
336  function getRoleMailboxAddress($a_role_id, $is_localize = true)
337  {
338  global $log, $lng,$ilDB;
339 
340  include_once "Services/Mail/classes/class.ilMail.php";
341  if (ilMail::_usePearMail())
342  {
343  // Retrieve the role title and the object title.
344  $query = "SELECT rdat.title role_title,odat.title object_title, ".
345  " oref.ref_id object_ref ".
346  "FROM object_data rdat ".
347  "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id ".
348  "JOIN tree rtree ON rtree.child = fa.parent ".
349  "JOIN object_reference oref ON oref.ref_id = rtree.child ".
350  "JOIN object_data odat ON odat.obj_id = oref.obj_id ".
351  "WHERE rdat.obj_id = ".$this->ilDB->quote($a_role_id,'integer')." ".
352  "AND fa.assign = 'y' ";
353  $r = $ilDB->query($query);
354  if (!$row = $ilDB->fetchObject($r))
355  {
356  //$log->write('class.ilRbacReview->getMailboxAddress('.$a_role_id.'): error role does not exist');
357  return null; // role does not exist
358  }
359  $object_title = $row->object_title;
360  $object_ref = $row->object_ref;
361  $role_title = $row->role_title;
362 
363 
364  // In a perfect world, we could use the object_title in the
365  // domain part of the mailbox address, and the role title
366  // with prefix '#' in the local part of the mailbox address.
367  $domain = $object_title;
368  $local_part = $role_title;
369 
370 
371  // Determine if the object title is unique
372  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
373  "FROM object_data dat ".
374  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
375  "JOIN tree ON tree.child = ref.ref_id ".
376  "WHERE title = ".$this->ilDB->quote($object_title,'text')." ".
377  "AND tree.tree = 1 ";
378  $r = $this->ilDB->query($q);
379  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
380 
381  // If the object title is not unique, we get rid of the domain.
382  if ($row->count > 1)
383  {
384  $domain = null;
385  }
386 
387  // If the domain contains illegal characters, we get rid of it.
388  //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain))
389  // Fix for Mantis Bug: 7429 sending mail fails because of brakets
390  // Fix for Mantis Bug: 9978 sending mail fails because of semicolon
391  if ($domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]|[\x28-\x29]|[;]/',$domain))
392  {
393  $domain = null;
394  }
395 
396  // If the domain contains special characters, we put square
397  // brackets around it.
398  if ($domain != null &&
399  (preg_match('/[()<>@,;:\\".\[\]]/',$domain) ||
400  preg_match('/[^\x21-\x8f]/',$domain))
401  )
402  {
403  $domain = '['.$domain.']';
404  }
405 
406  // If the role title is one of the ILIAS reserved role titles,
407  // we can use a shorthand version of it for the local part
408  // of the mailbox address.
409  if (strpos($role_title, 'il_') === 0 && $domain != null)
410  {
411  $unambiguous_role_title = $role_title;
412 
413  $pos = strpos($role_title, '_', 3) + 1;
414  $local_part = substr(
415  $role_title,
416  $pos,
417  strrpos($role_title, '_') - $pos
418  );
419  }
420  else
421  {
422  $unambiguous_role_title = 'il_role_'.$a_role_id;
423  }
424 
425  // Determine if the local part is unique. If we don't have a
426  // domain, the local part must be unique within the whole repositry.
427  // If we do have a domain, the local part must be unique for that
428  // domain.
429  if ($domain == null)
430  {
431  $q = "SELECT COUNT(DISTINCT dat.obj_id) count ".
432  "FROM object_data dat ".
433  "JOIN object_reference ref ON ref.obj_id = dat.obj_id ".
434  "JOIN tree ON tree.child = ref.ref_id ".
435  "WHERE title = ".$this->ilDB->quote($local_part,'text')." ".
436  "AND tree.tree = 1 ";
437  }
438  else
439  {
440  $q = "SELECT COUNT(rd.obj_id) count ".
441  "FROM object_data rd ".
442  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
443  "JOIN tree t ON t.child = fa.parent ".
444  "WHERE fa.assign = 'y' ".
445  "AND t.child = ".$this->ilDB->quote($object_ref,'integer')." ".
446  "AND rd.title LIKE ".$this->ilDB->quote(
447  '%'.preg_replace('/([_%])/','\\\\$1', $local_part).'%','text')." ";
448  }
449 
450  $r = $this->ilDB->query($q);
451  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
452 
453  // if the local_part is not unique, we use the unambiguous role title
454  // instead for the local part of the mailbox address
455  if ($row->count > 1)
456  {
457  $local_part = $unambiguous_role_title;
458  }
459 
460  $use_phrase = true;
461 
462  // If the local part contains illegal characters, we use
463  // the unambiguous role title instead.
464  if (preg_match('/[\\"\x00-\x1f]/',$local_part))
465  {
466  $local_part = $unambiguous_role_title;
467  }
468  else if(!preg_match('/^[\\x00-\\x7E]+$/i', $local_part))
469  {
470  // 2013-12-05: According to #12283, we do not accept umlauts in the local part
471  $local_part = $unambiguous_role_title;
472  $use_phrase = false;
473  }
474 
475  // Add a "#" prefix to the local part
476  $local_part = '#'.$local_part;
477 
478  // Put quotes around the role title, if needed
479  if (preg_match('/[()<>@,;:.\[\]\x20]/',$local_part))
480  {
481  $local_part = '"'.$local_part.'"';
482  }
483 
484  $mailbox = ($domain == null) ?
485  $local_part :
486  $local_part.'@'.$domain;
487 
488  if ($is_localize)
489  {
490  if (substr($role_title,0,3) == 'il_')
491  {
492  $phrase = $lng->txt(substr($role_title, 0, strrpos($role_title,'_')));
493  }
494  else
495  {
496  $phrase = $role_title;
497  }
498 
499  if($use_phrase)
500  {
501  // make phrase RFC 822 conformant:
502  // - strip excessive whitespace
503  // - strip special characters
504  $phrase = preg_replace('/\s\s+/', ' ', $phrase);
505  $phrase = preg_replace('/[()<>@,;:\\".\[\]]/', '', $phrase);
506 
507  $mailbox = $phrase.' <'.$mailbox.'>';
508  }
509  }
510 
511  require_once './Services/PEAR/lib/Mail/RFC822.php';
512  $obj = new Mail_RFC822($mailbox, ilMail::ILIAS_HOST);
513  if(@$obj->parseAddressList() instanceof PEAR_Error)
514  {
515  $q = "SELECT title ".
516  "FROM object_data ".
517  "WHERE obj_id = ".$this->ilDB->quote($a_role_id ,'integer');
518  $r = $this->ilDB->query($q);
519 
520  if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
521  {
522  return '#'.$row->title;
523  }
524  else
525  {
526  return null;
527  }
528  }
529 
530  return $mailbox;
531  }
532  else
533  {
534  $q = "SELECT title ".
535  "FROM object_data ".
536  "WHERE obj_id = ".$this->ilDB->quote($a_role_id ,'integer');
537  $r = $this->ilDB->query($q);
538 
539  if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
540  {
541  return '#'.$row->title;
542  }
543  else
544  {
545  return null;
546  }
547  }
548  }
549 
550 
559  public function roleExists($a_title,$a_id = 0)
560  {
561  global $ilDB;
562 
563  if (empty($a_title))
564  {
565  $message = get_class($this)."::roleExists(): No title given!";
566  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
567  }
568 
569  $clause = ($a_id) ? " AND obj_id != ".$ilDB->quote($a_id)." " : "";
570 
571  $q = "SELECT DISTINCT(obj_id) obj_id FROM object_data ".
572  "WHERE title =".$ilDB->quote($a_title)." ".
573  "AND type IN('role','rolt')".
574  $clause." ";
575  $r = $this->ilDB->query($q);
576 
577  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
578  {
579  return $row->obj_id;
580  }
581  return false;
582  }
583 
597  protected function __getParentRoles($a_path,$a_templates)
598  {
599  if (!isset($a_path) or !is_array($a_path))
600  {
601  $message = get_class($this)."::getParentRoles(): No path given or wrong datatype!";
602  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
603  }
604 
605  $parent_roles = array();
606  $role_hierarchy = array();
607 
608  foreach($a_path as $ref_id)
609  {
610  $roles = $this->getRoleListByObject($ref_id,$a_templates);
611  foreach($roles as $role)
612  {
613  $id = $role["obj_id"];
614  $role["parent"] = $ref_id;
615  $parent_roles[$id] = $role;
616 
617  if (!array_key_exists($role['obj_id'],$role_hierarchy))
618  {
619  $role_hierarchy[$id] = $ref_id;
620  }
621  }
622  }
623  return $this->__setProtectedStatus($parent_roles,$role_hierarchy,reset($a_path));
624  }
625 
635  public function getParentRoleIds($a_endnode_id,$a_templates = false)
636  {
637  global $tree;
638 
639  if (!isset($a_endnode_id))
640  {
641  $GLOBALS['ilLog']->logStack();
642  $message = get_class($this)."::getParentRoleIds(): No node_id (ref_id) given!";
643  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
644  }
645 
646  //var_dump($a_endnode_id);exit;
647  //$log->write("ilRBACreview::getParentRoleIds(), 0");
648  $pathIds = $tree->getPathId($a_endnode_id);
649 
650  // add system folder since it may not in the path
651  //$pathIds[0] = SYSTEM_FOLDER_ID;
652  $pathIds[0] = ROLE_FOLDER_ID;
653  //$log->write("ilRBACreview::getParentRoleIds(), 1");
654  #return $this->getParentRoles($a_endnode_id,$a_templates,$a_keep_protected);
655  return $this->__getParentRoles($pathIds,$a_templates);
656  }
657 
666  public function getRoleListByObject($a_ref_id,$a_templates = false)
667  {
668  global $ilDB;
669 
670  if (!isset($a_ref_id) or !isset($a_templates))
671  {
672  $message = get_class($this)."::getRoleListByObject(): Missing parameter!".
673  "ref_id: ".$a_ref_id.
674  "tpl_flag: ".$a_templates;
675  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
676  }
677 
678  $role_list = array();
679 
680  $where = $this->__setTemplateFilter($a_templates);
681 
682  $query = "SELECT * FROM object_data ".
683  "JOIN rbac_fa ON obj_id = rol_id ".
684  $where.
685  "AND object_data.obj_id = rbac_fa.rol_id ".
686  "AND rbac_fa.parent = ".$ilDB->quote($a_ref_id,'integer')." ";
687 
688  $res = $ilDB->query($query);
689  while ($row = $ilDB->fetchAssoc($res))
690  {
691  $row["desc"] = $row["description"];
692  $row["user_id"] = $row["owner"];
693  $role_list[] = $row;
694  }
695 
696  $role_list = $this->__setRoleType($role_list);
697 
698  return $role_list;
699  }
700 
708  function getAssignableRoles($a_templates = false,$a_internal_roles = false, $title_filter = '')
709  {
710  global $ilDB;
711 
712  $role_list = array();
713 
714  $where = $this->__setTemplateFilter($a_templates);
715 
716  $query = "SELECT * FROM object_data ".
717  "JOIN rbac_fa ON obj_id = rol_id ".
718  $where.
719  "AND rbac_fa.assign = 'y' ";
720 
721  if(strlen($title_filter))
722  {
723  $query .= (' AND '.$ilDB->like(
724  'title',
725  'text',
726  $title_filter.'%'
727  ));
728  }
729  $res = $ilDB->query($query);
730 
731  while ($row = $ilDB->fetchAssoc($res))
732  {
733  $row["desc"] = $row["description"];
734  $row["user_id"] = $row["owner"];
735  $role_list[] = $row;
736  }
737 
738  $role_list = $this->__setRoleType($role_list);
739 
740  return $role_list;
741  }
742 
751  {
752  global $ilDB;
753 
754  $query = 'SELECT rol_id FROM rbac_fa fa '.
755  'JOIN tree t1 ON t1.child = fa.parent '.
756  'JOIN object_data obd ON fa.rol_id = obd.obj_id ' .
757  'WHERE assign = '.$ilDB->quote('y','text').' '.
758  'AND obd.type = '.$ilDB->quote('role','text').' '.
759  'AND t1.child IN ('.
760  $GLOBALS['tree']->getSubTreeQuery($ref_id,array('child')).' '.
761  ') ';
762 
763 
764  $res = $ilDB->query($query);
765 
766  $role_list = array();
767  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
768  {
769  $role_list[] = $row->rol_id;
770  }
771  return $role_list;
772  }
773 
781  public function getAssignableChildRoles($a_ref_id)
782  {
783  global $ilDB;
784 
785  $query = "SELECT fa.*, rd.* ".
786  "FROM object_data rd ".
787  "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id ".
788  "WHERE fa.assign = 'y' ".
789  "AND fa.parent = ".$this->ilDB->quote($a_ref_id,'integer')." "
790  ;
791 
792  $res = $ilDB->query($query);
793  while($row = $ilDB->fetchAssoc($res))
794  {
795  $roles_data[] = $row;
796  }
797  return $roles_data ? $roles_data : array();
798  }
799 
807  protected function __setTemplateFilter($a_templates)
808  {
809  global $ilDB;
810 
811  if ($a_templates === true)
812  {
813  $where = "WHERE ".$ilDB->in('object_data.type',array('role','rolt'),false,'text')." ";
814  }
815  else
816  {
817  $where = "WHERE ".$ilDB->in('object_data.type',array('role'),false,'text')." ";
818  }
819 
820  return $where;
821  }
822 
835  protected function __setRoleType($a_role_list)
836  {
837  foreach ($a_role_list as $key => $val)
838  {
839  // determine role type
840  if ($val["type"] == "rolt")
841  {
842  $a_role_list[$key]["role_type"] = "template";
843  }
844  else
845  {
846  if ($val["assign"] == "y")
847  {
848  if ($val["parent"] == ROLE_FOLDER_ID)
849  {
850  $a_role_list[$key]["role_type"] = "global";
851  }
852  else
853  {
854  $a_role_list[$key]["role_type"] = "local";
855  }
856  }
857  else
858  {
859  $a_role_list[$key]["role_type"] = "linked";
860  }
861  }
862 
863  if ($val["protected"] == "y")
864  {
865  $a_role_list[$key]["protected"] = true;
866  }
867  else
868  {
869  $a_role_list[$key]["protected"] = false;
870  }
871  }
872 
873  return $a_role_list;
874  }
875 
883  public function getNumberOfAssignedUsers(Array $a_roles)
884  {
885  global $ilDB;
886 
887  $query = 'SELECT COUNT(DISTINCT(usr_id)) as num FROM rbac_ua '.
888  'WHERE '.$ilDB->in('rol_id', $a_roles, false, 'integer').' ';
889 
890  $res = $ilDB->query($query);
891  $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
892  return $row->num ? $row->num : 0;
893  }
894 
895 
904  public function assignedUsers($a_rol_id, $a_fields = NULL)
905  {
906  global $ilBench,$ilDB;
907 
908  $ilBench->start("RBAC", "review_assignedUsers");
909 
910  if (!isset($a_rol_id))
911  {
912  $message = get_class($this)."::assignedUsers(): No role_id given!";
913  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
914  }
915  if (! $a_fields AND isset(self::$assigned_users_cache[$a_rol_id])) {
916  return self::$assigned_users_cache[$a_rol_id];
917  }
918 
919  $result_arr = array();
920 
921  if ($a_fields !== NULL and is_array($a_fields))
922  {
923  if (count($a_fields) == 0)
924  {
925  $select = "*";
926  }
927  else
928  {
929  if (($usr_id_field = array_search("usr_id",$a_fields)) !== false)
930  unset($a_fields[$usr_id_field]);
931 
932  $select = implode(",",$a_fields).",usr_data.usr_id";
933  $select = addslashes($select);
934  }
935 
936  $ilDB->enableResultBuffering(false);
937  $query = "SELECT ".$select." FROM usr_data ".
938  "LEFT JOIN rbac_ua ON usr_data.usr_id = rbac_ua.usr_id ".
939  "WHERE rbac_ua.rol_id =".$ilDB->quote($a_rol_id,'integer');
940  $res = $ilDB->query($query);
941  while($row = $ilDB->fetchAssoc($res))
942  {
943  $result_arr[] = $row;
944  }
945  $ilDB->enableResultBuffering(true);
946  }
947  else
948  {
949  $ilDB->enableResultBuffering(false);
950  $query = "SELECT usr_id FROM rbac_ua WHERE rol_id= ".$ilDB->quote($a_rol_id,'integer');
951 
952  $res = $ilDB->query($query);
953  while($row = $ilDB->fetchAssoc($res))
954  {
955  array_push($result_arr,$row["usr_id"]);
956  }
957  $ilDB->enableResultBuffering(true);
958  }
959 
960  $ilBench->stop("RBAC", "review_assignedUsers");
961 
962  if (! $a_fields) {
963  self::$assigned_users_cache[$a_rol_id] = $result_arr;
964  }
965 
966  return $result_arr;
967  }
968 
969 
978  public function isAssigned($a_usr_id,$a_role_id)
979  {
980  if(isset(self::$is_assigned_cache[$a_role_id][$a_usr_id])) {
981  return self::$is_assigned_cache[$a_role_id][$a_usr_id];
982  }
983  // Quickly determine if user is assigned to a role
984  global $ilDB;
985 
986  $ilDB->setLimit(1,0);
987  $query = "SELECT usr_id FROM rbac_ua WHERE ".
988  "rol_id= ".$ilDB->quote($a_role_id,'integer')." ".
989  "AND usr_id= ".$ilDB->quote($a_usr_id);
990  $res = $ilDB->query($query);
991 
992  $is_assigned = $res->numRows() == 1;
993  self::$is_assigned_cache[$a_role_id][$a_usr_id] = $is_assigned;
994 
995  return $is_assigned;
996  }
997 
1010  public function isAssignedToAtLeastOneGivenRole($a_usr_id,$a_role_ids)
1011  {
1012  global $ilDB;
1013 
1014  $ilDB->setLimit(1,0);
1015  $query = "SELECT usr_id FROM rbac_ua WHERE ".
1016  $ilDB->in('rol_id',$a_role_ids,false,'integer').
1017  " AND usr_id= ".$ilDB->quote($a_usr_id);
1018  $res = $ilDB->query($query);
1019 
1020  return $ilDB->numRows($res) == 1;
1021  }
1022 
1030  public function assignedRoles($a_usr_id)
1031  {
1032  global $ilDB;
1033 
1034  $role_arr = array();
1035 
1036  $query = "SELECT rol_id FROM rbac_ua WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer');
1037 
1038  $res = $ilDB->query($query);
1039  while($row = $ilDB->fetchObject($res))
1040  {
1041  $role_arr[] = $row->rol_id;
1042  }
1043  return $role_arr ? $role_arr : array();
1044  }
1045 
1051  public function assignedGlobalRoles($a_usr_id)
1052  {
1053  global $ilDB;
1054 
1055  $query = "SELECT ua.rol_id FROM rbac_ua ua ".
1056  "JOIN rbac_fa fa ON ua.rol_id = fa.rol_id ".
1057  "WHERE usr_id = ".$ilDB->quote($a_usr_id,'integer').' '.
1058  "AND parent = ".$ilDB->quote(ROLE_FOLDER_ID)." ".
1059  "AND assign = 'y' ";
1060 
1061  $res = $ilDB->query($query);
1062  while($row = $ilDB->fetchObject($res))
1063  {
1064  $role_arr[] = $row->rol_id;
1065  }
1066  return $role_arr ? $role_arr : array();
1067  }
1068 
1077  public function isAssignable($a_rol_id, $a_ref_id)
1078  {
1079  global $ilBench,$ilDB;
1080 
1081  $ilBench->start("RBAC", "review_isAssignable");
1082 
1083  // exclude system role from rbac
1084  if ($a_rol_id == SYSTEM_ROLE_ID)
1085  {
1086  $ilBench->stop("RBAC", "review_isAssignable");
1087  return true;
1088  }
1089 
1090  if (!isset($a_rol_id) or !isset($a_ref_id))
1091  {
1092  $message = get_class($this)."::isAssignable(): Missing parameter!".
1093  " role_id: ".$a_rol_id." ,ref_id: ".$a_ref_id;
1094  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1095  }
1096  $query = "SELECT * FROM rbac_fa ".
1097  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1098  "AND parent = ".$ilDB->quote($a_ref_id,'integer')." ";
1099  $res = $ilDB->query($query);
1100  $row = $ilDB->fetchObject($res);
1101 
1102  $ilBench->stop("RBAC", "review_isAssignable");
1103  return $row->assign == 'y' ? true : false;
1104  }
1105 
1111  public function hasMultipleAssignments($a_role_id)
1112  {
1113  global $ilDB;
1114 
1115  $query = "SELECT * FROM rbac_fa WHERE rol_id = ".$ilDB->quote($a_role_id,'integer').' '.
1116  "AND assign = ".$ilDB->quote('y','text');
1117  $res = $ilDB->query($query);
1118  return $res->numRows() > 1;
1119  }
1120 
1132  public function getFoldersAssignedToRole($a_rol_id, $a_assignable = false)
1133  {
1134  global $ilDB;
1135 
1136  if (!isset($a_rol_id))
1137  {
1138  $message = get_class($this)."::getFoldersAssignedToRole(): No role_id given!";
1139  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1140  }
1141 
1142  if ($a_assignable)
1143  {
1144  $where = " AND assign ='y'";
1145  }
1146 
1147  $query = "SELECT DISTINCT parent FROM rbac_fa ".
1148  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".$where." ";
1149 
1150  $res = $ilDB->query($query);
1151  while($row = $ilDB->fetchObject($res))
1152  {
1153  $folders[] = $row->parent;
1154  }
1155  return $folders ? $folders : array();
1156  }
1157 
1165  public function getRolesOfObject($a_ref_id, $a_assignable_only = FALSE)
1166  {
1167  global $ilDB;
1168 
1169  if(!isset($a_ref_id))
1170  {
1171  $GLOBALS['ilLog']->logStack();
1172  throw new InvalidArgumentException(__METHOD__.': No ref_id given!');
1173  }
1174  if($a_assignable_only === TRUE)
1175  {
1176  $and = 'AND assign = '.$ilDB->quote('y','text');
1177  }
1178  $query = "SELECT rol_id FROM rbac_fa ".
1179  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1180  $and;
1181 
1182  $res = $ilDB->query($query);
1183 
1184  $role_ids = array();
1185  while($row = $ilDB->fetchObject($res))
1186  {
1187  $role_ids[] = $row->rol_id;
1188  }
1189  return $role_ids;
1190  }
1191 
1192 
1193 
1194 
1205  public function getRolesOfRoleFolder($a_ref_id,$a_nonassignable = true)
1206  {
1207  global $ilBench,$ilDB,$ilLog;
1208 
1209  $ilBench->start("RBAC", "review_getRolesOfRoleFolder");
1210 
1211  if (!isset($a_ref_id))
1212  {
1213  $message = get_class($this)."::getRolesOfRoleFolder(): No ref_id given!";
1214  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1215 
1216  }
1217 
1218  if ($a_nonassignable === false)
1219  {
1220  $and = " AND assign='y'";
1221  }
1222 
1223  $query = "SELECT rol_id FROM rbac_fa ".
1224  "WHERE parent = ".$ilDB->quote($a_ref_id,'integer')." ".
1225  $and;
1226 
1227  $res = $ilDB->query($query);
1228  while($row = $ilDB->fetchObject($res))
1229  {
1230  $rol_id[] = $row->rol_id;
1231  }
1232 
1233  $ilBench->stop("RBAC", "review_getRolesOfRoleFolder");
1234 
1235  return $rol_id ? $rol_id : array();
1236  }
1237 
1244  public function getGlobalRoles()
1245  {
1246  return $this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false);
1247  }
1248 
1254  public function getLocalRoles($a_ref_id)
1255  {
1256  global $ilDB;
1257 
1258  $lroles = array();
1259  foreach($this->getRolesOfRoleFolder($a_ref_id) as $role_id)
1260  {
1261  if($this->isAssignable($role_id, $a_ref_id))
1262  {
1263  $lroles[] = $role_id;
1264  }
1265  }
1266  return $lroles;
1267  }
1268 
1274  public function getLocalPolicies($a_ref_id)
1275  {
1276  $lroles = array();
1277  foreach($this->getRolesOfRoleFolder($a_ref_id) as $role_id)
1278  {
1279  $lroles[] = $role_id;
1280  }
1281  return $lroles;
1282  }
1283 
1290  public function getGlobalRolesArray()
1291  {
1292  foreach($this->getRolesOfRoleFolder(ROLE_FOLDER_ID,false) as $role_id)
1293  {
1294  $ga[] = array('obj_id' => $role_id,
1295  'role_type' => 'global');
1296  }
1297  return $ga ? $ga : array();
1298  }
1299 
1306  public function getGlobalAssignableRoles()
1307  {
1308  include_once './Services/AccessControl/classes/class.ilObjRole.php';
1309 
1310  foreach($this->getGlobalRoles() as $role_id)
1311  {
1312  if(ilObjRole::_getAssignUsersStatus($role_id))
1313  {
1314  $ga[] = array('obj_id' => $role_id,
1315  'role_type' => 'global');
1316  }
1317  }
1318  return $ga ? $ga : array();
1319  }
1320 
1321 
1326  public function isRoleAssignedToObject($a_role_id, $a_parent_id)
1327  {
1328  global $rbacreview, $ilDB;
1329 
1330  $query = 'SELECT * FROM rbac_fa '.
1331  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
1332  'AND parent = '.$ilDB->quote($a_parent_id,'integer');
1333  $res = $ilDB->query($query);
1334  return $res->numRows() ? true : false;
1335  }
1336 
1343  public function getOperations()
1344  {
1345  global $ilDB;
1346 
1347  $query = 'SELECT * FROM rbac_operations ORDER BY ops_id ';
1348  $res = $this->ilDB->query($query);
1349  while($row = $ilDB->fetchObject($res))
1350  {
1351  $ops[] = array('ops_id' => $row->ops_id,
1352  'operation' => $row->operation,
1353  'description' => $row->description);
1354  }
1355 
1356  return $ops ? $ops : array();
1357  }
1358 
1365  public function getOperation($ops_id)
1366  {
1367  global $ilDB;
1368 
1369  $query = 'SELECT * FROM rbac_operations WHERE ops_id = '.$ilDB->quote($ops_id,'integer');
1370  $res = $this->ilDB->query($query);
1371  while($row = $ilDB->fetchObject($res))
1372  {
1373  $ops = array('ops_id' => $row->ops_id,
1374  'operation' => $row->operation,
1375  'description' => $row->description);
1376  }
1377 
1378  return $ops ? $ops : array();
1379  }
1380 
1390  public function getAllOperationsOfRole($a_rol_id, $a_parent = 0)
1391  {
1392  global $ilDB;
1393 
1394  if(!$a_parent)
1395  {
1396  $a_parent = ROLE_FOLDER_ID;
1397  }
1398 
1399  $query = "SELECT ops_id,type FROM rbac_templates ".
1400  "WHERE rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1401  "AND parent = ".$ilDB->quote($a_parent,'integer');
1402  $res = $ilDB->query($query);
1403 
1404  $ops_arr = array();
1405  while ($row = $ilDB->fetchObject($res))
1406  {
1407  $ops_arr[$row->type][] = $row->ops_id;
1408  }
1409  return (array) $ops_arr;
1410  }
1411 
1419  public function getActiveOperationsOfRole($a_ref_id, $a_role_id)
1420  {
1421  global $ilDB;
1422 
1423  $query = 'SELECT * FROM rbac_pa '.
1424  'WHERE ref_id = '.$ilDB->quote($a_ref_id,'integer').' '.
1425  'AND rol_id = '.$ilDB->quote($a_role_id,'integer').' ';
1426 
1427  $res = $ilDB->query($query);
1428  while($row = $res->fetchRow(DB_FETCHMODE_ASSOC))
1429  {
1430  return unserialize($row['ops_id']);
1431  }
1432  return array();
1433  }
1434 
1435 
1446  public function getOperationsOfRole($a_rol_id, $a_type, $a_parent = 0)
1447  {
1448  global $ilDB,$ilLog;
1449 
1450  if (!isset($a_rol_id) or !isset($a_type))
1451  {
1452  $message = get_class($this)."::getOperationsOfRole(): Missing Parameter!".
1453  "role_id: ".$a_rol_id.
1454  "type: ".$a_type.
1455  "parent_id: ".$a_parent;
1456  $ilLog->logStack("Missing parameter! ");
1457  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1458  }
1459 
1460  $ops_arr = array();
1461 
1462  // if no rolefolder id is given, assume global role folder as target
1463  if ($a_parent == 0)
1464  {
1465  $a_parent = ROLE_FOLDER_ID;
1466  }
1467 
1468  $query = "SELECT ops_id FROM rbac_templates ".
1469  "WHERE type =".$ilDB->quote($a_type,'text')." ".
1470  "AND rol_id = ".$ilDB->quote($a_rol_id,'integer')." ".
1471  "AND parent = ".$ilDB->quote($a_parent,'integer');
1472  $res = $ilDB->query($query);
1473  while ($row = $ilDB->fetchObject($res))
1474  {
1475  $ops_arr[] = $row->ops_id;
1476  }
1477 
1478  return $ops_arr;
1479  }
1480 
1488  public function getRoleOperationsOnObject($a_role_id,$a_ref_id)
1489  {
1490  global $ilDB;
1491 
1492  $query = "SELECT * FROM rbac_pa ".
1493  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ".
1494  "AND ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
1495 
1496  $res = $ilDB->query($query);
1497  while($row = $ilDB->fetchObject($res))
1498  {
1499  $ops = unserialize($row->ops_id);
1500  }
1501 
1502  return $ops ? $ops : array();
1503  }
1504 
1512  public function getOperationsOnType($a_typ_id)
1513  {
1514  global $ilDB;
1515 
1516  if (!isset($a_typ_id))
1517  {
1518  $message = get_class($this)."::getOperationsOnType(): No type_id given!";
1519  $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1520  }
1521 
1522  #$query = "SELECT * FROM rbac_ta WHERE typ_id = ".$ilDB->quote($a_typ_id,'integer');
1523 
1524  $query = 'SELECT * FROM rbac_ta ta JOIN rbac_operations o ON ta.ops_id = o.ops_id '.
1525  'WHERE typ_id = '.$ilDB->quote($a_typ_id,'integer').' '.
1526  'ORDER BY op_order';
1527 
1528  $res = $ilDB->query($query);
1529 
1530  while($row = $ilDB->fetchObject($res))
1531  {
1532  $ops_id[] = $row->ops_id;
1533  }
1534 
1535  return $ops_id ? $ops_id : array();
1536  }
1537 
1546  public function getOperationsOnTypeString($a_type)
1547  {
1548  global $ilDB;
1549 
1550  $query = "SELECT * FROM object_data WHERE type = 'typ' AND title = ".$ilDB->quote($a_type ,'text')." ";
1551 
1552 
1553  $res = $this->ilDB->query($query);
1554  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1555  {
1556  return $this->getOperationsOnType($row->obj_id);
1557  }
1558  return false;
1559  }
1560 
1568  public function getOperationsByTypeAndClass($a_type,$a_class)
1569  {
1570  global $ilDB;
1571 
1572  if($a_class != 'create')
1573  {
1574  $condition = "AND class != ".$ilDB->quote('create','text');
1575  }
1576  else
1577  {
1578  $condition = "AND class = ".$ilDB->quote('create','text');
1579  }
1580 
1581  $query = "SELECT ro.ops_id FROM rbac_operations ro ".
1582  "JOIN rbac_ta rt ON ro.ops_id = rt.ops_id ".
1583  "JOIN object_data od ON rt.typ_id = od.obj_id ".
1584  "WHERE type = ".$ilDB->quote('typ','text')." ".
1585  "AND title = ".$ilDB->quote($a_type,'text')." ".
1586  $condition." ".
1587  "ORDER BY op_order ";
1588 
1589  $res = $ilDB->query($query);
1590 
1591  $ops = array();
1592  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1593  {
1594  $ops[] = $row->ops_id;
1595  }
1596  return $ops;
1597  }
1598 
1599 
1609  public function getObjectsWithStopedInheritance($a_rol_id,$a_filter = array())
1610  {
1611  global $ilDB;
1612 
1613  #$query = 'SELECT t.parent p FROM tree t JOIN rbac_fa fa ON fa.parent = child '.
1614  # 'WHERE assign = '.$ilDB->quote('n','text').' '.
1615  # 'AND rol_id = '.$ilDB->quote($a_rol_id,'integer').' ';
1616 
1617  $query = 'SELECT parent p FROM rbac_fa '.
1618  'WHERE assign = '.$ilDB->quote('n','text').' '.
1619  'AND rol_id = '.$ilDB->quote($a_rol_id,'integer').' ';
1620 
1621  if($a_filter)
1622  {
1623  $query .= ('AND '.$ilDB->in('parent',(array) $a_filter,false,'integer'));
1624  }
1625 
1626  $res = $ilDB->query($query);
1627  $parent = array();
1628  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1629  {
1630  $parent[] = $row->p;
1631  }
1632  return $parent;
1633  }
1634 
1642  public function isDeleted($a_node_id)
1643  {
1644  global $ilDB;
1645 
1646  $q = "SELECT tree FROM tree WHERE child =".$ilDB->quote($a_node_id)." ";
1647  $r = $this->ilDB->query($q);
1648 
1649  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1650 
1651  if (!$row)
1652  {
1653  $message = sprintf('%s::isDeleted(): Role folder with ref_id %s not found!',
1654  get_class($this),
1655  $a_node_id);
1656  $this->log->write($message,$this->log->FATAL);
1657 
1658  return true;
1659  }
1660 
1661  // rolefolder is deleted
1662  if ($row->tree < 0)
1663  {
1664  return true;
1665  }
1666 
1667  return false;
1668  }
1669 
1676  public function isGlobalRole($a_role_id)
1677  {
1678  return in_array($a_role_id,$this->getGlobalRoles());
1679  }
1680 
1690  public function getRolesByFilter($a_filter = 0,$a_user_id = 0, $title_filter = '')
1691  {
1692  global $ilDB;
1693 
1694  $assign = "y";
1695 
1696  switch($a_filter)
1697  {
1698  // all (assignable) roles
1699  case self::FILTER_ALL:
1700  return $this->getAssignableRoles(true,true,$title_filter);
1701  break;
1702 
1703  // all (assignable) global roles
1704  case self::FILTER_ALL_GLOBAL:
1705  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),false,'integer').' ';
1706  break;
1707 
1708  // all (assignable) local roles
1709  case self::FILTER_ALL_LOCAL:
1710  case self::FILTER_INTERNAL:
1711  case self::FILTER_NOT_INTERNAL:
1712  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->getGlobalRoles(),true,'integer');
1713  break;
1714 
1715  // all role templates
1716  case self::FILTER_TEMPLATES:
1717  $where = "WHERE object_data.type = 'rolt'";
1718  $assign = "n";
1719  break;
1720 
1721  // only assigned roles, handled by ilObjUserGUI::roleassignmentObject()
1722  case 0:
1723  default:
1724  if(!$a_user_id)
1725  return array();
1726 
1727  $where = 'WHERE '.$ilDB->in('rbac_fa.rol_id',$this->assignedRoles($a_user_id),false,'integer').' ';
1728  break;
1729  }
1730 
1731  $roles = array();
1732 
1733  $query = "SELECT * FROM object_data ".
1734  "JOIN rbac_fa ON obj_id = rol_id ".
1735  $where.
1736  "AND rbac_fa.assign = ".$ilDB->quote($assign,'text')." ";
1737 
1738  if(strlen($title_filter))
1739  {
1740  $query .= (' AND '.$ilDB->like(
1741  'title',
1742  'text',
1743  '%'.$title_filter.'%'
1744  ));
1745  }
1746 
1747  $res = $ilDB->query($query);
1748  while($row = $ilDB->fetchAssoc($res))
1749  {
1750  $prefix = (substr($row["title"],0,3) == "il_") ? true : false;
1751 
1752  // all (assignable) internal local roles only
1753  if ($a_filter == 4 and !$prefix)
1754  {
1755  continue;
1756  }
1757 
1758  // all (assignable) non internal local roles only
1759  if ($a_filter == 5 and $prefix)
1760  {
1761  continue;
1762  }
1763 
1764  $row["desc"] = $row["description"];
1765  $row["user_id"] = $row["owner"];
1766  $roles[] = $row;
1767  }
1768 
1769  $roles = $this->__setRoleType($roles);
1770 
1771  return $roles ? $roles : array();
1772  }
1773 
1781  public function getTypeId($a_type)
1782  {
1783  global $ilDB;
1784 
1785  $q = "SELECT obj_id FROM object_data ".
1786  "WHERE title=".$ilDB->quote($a_type ,'text')." AND type='typ'";
1787  $r = $ilDB->query($q);
1788 
1789  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
1790  return $row->obj_id;
1791  }
1792 
1803  public static function _getOperationIdsByName($operations)
1804  {
1805  global $ilDB;
1806 
1807  if(!count($operations))
1808  {
1809  return array();
1810  }
1811 
1812  $query = 'SELECT ops_id FROM rbac_operations '.
1813  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1814 
1815  $res = $ilDB->query($query);
1816  while($row = $ilDB->fetchObject($res))
1817  {
1818  $ops_ids[] = $row->ops_id;
1819  }
1820  return $ops_ids ? $ops_ids : array();
1821  }
1822 
1831  public static function _getOperationIdByName($a_operation)
1832  {
1833  global $ilDB,$ilErr;
1834 
1835  if (!isset($a_operation))
1836  {
1837  $message = "perm::getOperationId(): No operation given!";
1838  $ilErr->raiseError($message,$ilErr->WARNING);
1839  }
1840 
1841  // Cache operation ids
1842  if (! is_array(self::$_opsCache)) {
1843  self::$_opsCache = array();
1844 
1845  $q = "SELECT ops_id, operation FROM rbac_operations";
1846  $r = $ilDB->query($q);
1847  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
1848  {
1849  self::$_opsCache[$row->operation] = $row->ops_id;
1850  }
1851  }
1852 
1853  // Get operation ID by name from cache
1854  if (array_key_exists($a_operation, self::$_opsCache)) {
1855  return self::$_opsCache[$a_operation];
1856  }
1857  return null;
1858  }
1859 
1866  public static function lookupCreateOperationIds($a_type_arr)
1867  {
1868  global $ilDB;
1869 
1870  $operations = array();
1871  foreach($a_type_arr as $type)
1872  {
1873  $operations[] = ('create_'.$type);
1874  }
1875 
1876  if(!count($operations))
1877  {
1878  return array();
1879  }
1880 
1881  $query = 'SELECT ops_id, operation FROM rbac_operations '.
1882  'WHERE '.$ilDB->in('operation',$operations,false,'text');
1883 
1884  $res = $ilDB->query($query);
1885 
1886  $ops_ids = array();
1887  while($row = $ilDB->fetchObject($res))
1888  {
1889  $type_arr = explode('_', $row->operation);
1890  $type = $type_arr[1];
1891 
1892  $ops_ids[$type] = $row->ops_id;
1893  }
1894  return $ops_ids;
1895  }
1896 
1897 
1898 
1907  public function isProtected($a_ref_id,$a_role_id)
1908  {
1909  global $ilDB;
1910 
1911  // ref_id not used yet. protected permission acts 'global' for each role,
1912  $query = "SELECT protected FROM rbac_fa ".
1913  "WHERE rol_id = ".$ilDB->quote($a_role_id,'integer')." ";
1914  $res = $ilDB->query($query);
1915  $row = $ilDB->fetchAssoc($res);
1916 
1917  return ilUtil::yn2tf($row['protected']);
1918  }
1919 
1920  // this method alters the protected status of role regarding the current user's role assignment
1921  // and current postion in the hierarchy.
1922 
1934  protected function __setProtectedStatus($a_parent_roles,$a_role_hierarchy,$a_ref_id)
1935  {
1936  //vd('refId',$a_ref_id,'parent roles',$a_parent_roles,'role-hierarchy',$a_role_hierarchy);
1937 
1938  global $rbacsystem,$ilUser,$log;
1939 
1940  if (in_array(SYSTEM_ROLE_ID,$this->assignedRoles($ilUser->getId())))
1941  {
1942  $leveladmin = true;
1943  }
1944  else
1945  {
1946  $leveladmin = false;
1947  }
1948  #vd("RoleHierarchy",$a_role_hierarchy);
1949  foreach ($a_role_hierarchy as $role_id => $rolf_id)
1950  {
1951  //$log->write("ilRBACreview::__setProtectedStatus(), 0");
1952  #echo "<br/>ROLF: ".$rolf_id." ROLE_ID: ".$role_id." (".$a_parent_roles[$role_id]['title'].") ";
1953  //var_dump($leveladmin,$a_parent_roles[$role_id]['protected']);
1954 
1955  if ($leveladmin == true)
1956  {
1957  $a_parent_roles[$role_id]['protected'] = false;
1958  continue;
1959  }
1960 
1961  if ($a_parent_roles[$role_id]['protected'] == true)
1962  {
1963  $arr_lvl_roles_user = array_intersect($this->assignedRoles($ilUser->getId()),array_keys($a_role_hierarchy,$rolf_id));
1964 
1965  #vd("intersection",$arr_lvl_roles_user);
1966 
1967  foreach ($arr_lvl_roles_user as $lvl_role_id)
1968  {
1969  #echo "<br/>level_role: ".$lvl_role_id;
1970  #echo "<br/>a_ref_id: ".$a_ref_id;
1971 
1972  //$log->write("ilRBACreview::__setProtectedStatus(), 1");
1973  // check if role grants 'edit_permission' to parent
1974  $rolf = $a_parent_roles[$role_id]['parent'];
1975  #$parent_obj = $GLOBALS['tree']->getParentId($rolf);
1976  if ($rbacsystem->checkPermission($rolf,$lvl_role_id,'edit_permission'))
1977  {
1978  #echo "<br />Permission granted";
1979  //$log->write("ilRBACreview::__setProtectedStatus(), 2");
1980  // user may change permissions of that higher-ranked role
1981  $a_parent_roles[$role_id]['protected'] = false;
1982 
1983  // remember successful check
1984  //$leveladmin = true;
1985  }
1986  }
1987  }
1988  }
1989  return $a_parent_roles;
1990  }
1991 
2002  public static function _getOperationList($a_type = null)
2003  {
2004  global $ilDB;
2005 
2006  $arr = array();
2007 
2008  if ($a_type)
2009  {
2010  $query = sprintf('SELECT * FROM rbac_operations '.
2011  'JOIN rbac_ta ON rbac_operations.ops_id = rbac_ta.ops_id '.
2012  'JOIN object_data ON rbac_ta.typ_id = object_data.obj_id '.
2013  'WHERE object_data.title = %s '.
2014  'AND object_data.type = %s '.
2015  'ORDER BY op_order ASC',
2016  $ilDB->quote($a_type,'text'),
2017  $ilDB->quote('typ','text'));
2018  }
2019  else
2020  {
2021  $query = 'SELECT * FROM rbac_operations ORDER BY op_order ASC';
2022  }
2023  $res = $ilDB->query($query);
2024  while ($row = $ilDB->fetchAssoc($res))
2025  {
2026  $arr[] = array(
2027  "ops_id" => $row['ops_id'],
2028  "operation" => $row['operation'],
2029  "desc" => $row['description'],
2030  "class" => $row['class'],
2031  "order" => $row['op_order']
2032  );
2033  }
2034  return $arr;
2035  }
2036 
2043  public static function _groupOperationsByClass($a_ops_arr)
2044  {
2045  $arr = array();
2046 
2047  foreach ($a_ops_arr as $ops)
2048  {
2049  $arr[$ops['class']][] = array ('ops_id' => $ops['ops_id'],
2050  'name' => $ops['operation']
2051  );
2052  }
2053  return $arr;
2054  }
2055 
2065  public function getObjectOfRole($a_role_id)
2066  {
2067  // internal cache
2068  static $obj_cache = array();
2069 
2070  global $ilDB;
2071 
2072 
2073  if(isset($obj_cache[$a_role_id]) and $obj_cache[$a_role_id])
2074  {
2075  return $obj_cache[$a_role_id];
2076  }
2077 
2078  $query = 'SELECT obr.obj_id FROM rbac_fa rfa '.
2079  'JOIN object_reference obr ON rfa.parent = obr.ref_id '.
2080  'WHERE assign = '.$ilDB->quote('y','text'). ' '.
2081  'AND rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
2082  'AND deleted IS NULL';
2083 
2084  #$query = "SELECT obr.obj_id FROM rbac_fa rfa ".
2085  # "JOIN tree ON rfa.parent = tree.child ".
2086  # "JOIN object_reference obr ON tree.parent = obr.ref_id ".
2087  # "WHERE tree.tree = 1 ".
2088  # "AND assign = 'y' ".
2089  # "AND rol_id = ".$ilDB->quote($a_role_id,'integer')." ";
2090  $res = $ilDB->query($query);
2091 
2092  $obj_cache[$a_role_id] = 0;
2093  while($row = $ilDB->fetchObject($res))
2094  {
2095  $obj_cache[$a_role_id] = $row->obj_id;
2096  }
2097  return $obj_cache[$a_role_id];
2098  }
2099 
2106  public function getObjectReferenceOfRole($a_role_id)
2107  {
2108  global $ilDB;
2109 
2110  $query = 'SELECT parent role_ref FROM rbac_fa '.
2111  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
2112  'AND assign = '.$ilDB->quote('y','text');
2113 
2114  $res = $ilDB->query($query);
2115  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2116  {
2117  return $row->role_ref;
2118  }
2119  return 0;
2120  }
2121 
2129  public function isRoleDeleted ($a_role_id)
2130  {
2131  $rolf_list = $this->getFoldersAssignedToRole($a_role_id, false);
2132  $deleted = true;
2133  if (count($rolf_list))
2134  {
2135  foreach ($rolf_list as $rolf) {
2136  // only list roles that are not set to status "deleted"
2137  if (!$this->isDeleted($rolf))
2138  {
2139  $deleted = false;
2140  break;
2141  }
2142  }
2143  }
2144  return $deleted;
2145  }
2146 
2147 
2155  public function getRolesForIDs($role_ids, $use_templates)
2156  {
2157  global $ilDB;
2158 
2159  $role_list = array();
2160 
2161  $where = $this->__setTemplateFilter($use_templates);
2162 
2163  $query = "SELECT * FROM object_data ".
2164  "JOIN rbac_fa ON object_data.obj_id = rbac_fa.rol_id ".
2165  $where.
2166  "AND rbac_fa.assign = 'y' " .
2167  'AND '.$ilDB->in('object_data.obj_id',$role_ids,false,'integer');
2168 
2169  $res = $ilDB->query($query);
2170  while($row = $ilDB->fetchAssoc($res))
2171  {
2172  $row["desc"] = $row["description"];
2173  $row["user_id"] = $row["owner"];
2174  $role_list[] = $row;
2175  }
2176 
2177  $role_list = $this->__setRoleType($role_list);
2178  return $role_list;
2179  }
2180 
2186  public function getOperationAssignment()
2187  {
2188  global $ilDB;
2189 
2190  $query = 'SELECT ta.typ_id, obj.title, ops.ops_id, ops.operation FROM rbac_ta ta '.
2191  'JOIN object_data obj ON obj.obj_id = ta.typ_id '.
2192  'JOIN rbac_operations ops ON ops.ops_id = ta.ops_id ';
2193  $res = $ilDB->query($query);
2194 
2195  $counter = 0;
2196  while($row = $ilDB->fetchObject($res))
2197  {
2198  $info[$counter]['typ_id'] = $row->typ_id;
2199  $info[$counter]['type'] = $row->title;
2200  $info[$counter]['ops_id'] = $row->ops_id;
2201  $info[$counter]['operation'] = $row->operation;
2202  $counter++;
2203  }
2204  return $info ? $info : array();
2205 
2206  }
2207 
2215  public function isDeleteable($a_role_id, $a_rolf_id)
2216  {
2217  if(!$this->isAssignable($a_role_id, $a_rolf_id))
2218  {
2219  return false;
2220  }
2221  if($a_role_id == SYSTEM_ROLE_ID or $a_role_id == ANONYMOUS_ROLE_ID)
2222  {
2223  return false;
2224  }
2225  if(substr(ilObject::_lookupTitle($a_role_id),0,3) == 'il_')
2226  {
2227  return false;
2228  }
2229  return true;
2230  }
2231 
2238  public function isSystemGeneratedRole($a_role_id)
2239  {
2240  $title = ilObject::_lookupTitle($a_role_id);
2241  return substr($title,0,3) == 'il_' ? true : false;
2242  }
2243 
2244 
2252  public function getRoleFolderOfRole($a_role_id)
2253  {
2254  global $ilDB;
2255 
2256  if(ilObject::_lookupType($a_role_id) == 'role')
2257  {
2258  $and = ('AND assign = '.$ilDB->quote('y','text'));
2259  }
2260  else
2261  {
2262  $and = '';
2263  }
2264 
2265  $query = 'SELECT * FROM rbac_fa '.
2266  'WHERE rol_id = '.$ilDB->quote($a_role_id,'integer').' '.
2267  $and;
2268  $res = $ilDB->query($query);
2269  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
2270  {
2271  return $row->parent;
2272  }
2273  return 0;
2274  }
2275 
2283  public function getUserPermissionsOnObject($a_user_id, $a_ref_id)
2284  {
2285  global $ilDB;
2286 
2287  $query = "SELECT ops_id FROM rbac_pa JOIN rbac_ua ".
2288  "ON (rbac_pa.rol_id = rbac_ua.rol_id) ".
2289  "WHERE rbac_ua.usr_id = ".$ilDB->quote($a_user_id,'integer')." ".
2290  "AND rbac_pa.ref_id = ".$ilDB->quote($a_ref_id,'integer')." ";
2291 
2292  $res = $ilDB->query($query);
2293  $all_ops = array();
2294  while ($row = $ilDB->fetchObject($res))
2295  {
2296  $ops = unserialize($row->ops_id);
2297  $all_ops = array_merge($all_ops, $ops);
2298  }
2299  $all_ops = array_unique($all_ops);
2300 
2301  $set = $ilDB->query("SELECT operation FROM rbac_operations ".
2302  " WHERE ".$ilDB->in("ops_id", $all_ops, false, "integer"));
2303  $perms = array();
2304  while ($rec = $ilDB->fetchAssoc($set))
2305  {
2306  $perms[] = $rec["operation"];
2307  }
2308 
2309  return $perms;
2310  }
2311 
2318  public function setAssignedCacheEntry($a_role_id,$a_user_id, $a_value)
2319  {
2320  self::$is_assigned_cache[$a_role_id][$a_user_id] = $a_value;
2321  }
2322 
2329  public function getAssignedCacheEntry($a_role_id,$a_user_id)
2330  {
2331  return self::$is_assigned_cache[$a_role_id][$a_user_id];
2332  }
2333 
2334 } // END class.ilRbacReview
2335 ?>