ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjRole.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 
5 require_once "./classes/class.ilObject.php";
6 
15 class ilObjRole extends ilObject
16 {
21 
22 
30  var $parent;
31 
34 
37 
44  function ilObjRole($a_id = 0,$a_call_by_reference = false)
45  {
46  $this->type = "role";
47  $this->disk_quota = 0;
48  $this->ilObject($a_id,$a_call_by_reference);
49  }
50 
55  public function validate()
56  {
57  global $ilErr;
58 
59  if(substr($this->getTitle(),0,3) == 'il_')
60  {
61  $ilErr->setMessage('msg_role_reserved_prefix');
62  return false;
63  }
64  return true;
65  }
66 
67  function toggleAssignUsersStatus($a_assign_users)
68  {
69  $this->assign_users = (int) $a_assign_users;
70  }
72  {
73  return $this->assign_users ? $this->assign_users : 0;
74  }
75  // Same method (static)
76  function _getAssignUsersStatus($a_role_id)
77  {
78  global $ilDB;
79 
80  $query = "SELECT assign_users FROM role_data WHERE role_id = ".$ilDB->quote($a_role_id,'integer')." ";
81  $res = $ilDB->query($query);
82  while($row = $ilDB->fetchObject($res))
83  {
84  return $row->assign_users ? true : false;
85  }
86  return false;
87  }
88 
93  function read ()
94  {
95  global $ilDB;
96 
97  $query = "SELECT * FROM role_data WHERE role_id= ".$ilDB->quote($this->id,'integer')." ";
98 
99  $res = $ilDB->query($query);
100  if ($res->numRows() > 0)
101  {
102  $data = $ilDB->fetchAssoc($res);
103 
104  // fill member vars in one shot
105  $this->assignData($data);
106  }
107  else
108  {
109  $this->ilias->raiseError("<b>Error: There is no dataset with id ".$this->id."!</b><br />class: ".get_class($this)."<br />Script: ".__FILE__."<br />Line: ".__LINE__, $this->ilias->FATAL);
110  }
111 
112  parent::read();
113  }
114 
120  function assignData($a_data)
121  {
122  $this->setTitle(ilUtil::stripSlashes($a_data["title"]));
123  $this->setDescription(ilUtil::stripslashes($a_data["desc"]));
124  $this->setAllowRegister($a_data["allow_register"]);
125  $this->toggleAssignUsersStatus($a_data['assign_users']);
126  $this->setDiskQuota($a_data['disk_quota']);
127  }
128 
133  function update ()
134  {
135  global $ilDB;
136 
137  $query = "UPDATE role_data SET ".
138  "allow_register= ".$ilDB->quote($this->allow_register,'integer').", ".
139  "assign_users = ".$ilDB->quote($this->getAssignUsersStatus(),'integer').", ".
140  "disk_quota = ".$ilDB->quote($this->getDiskQuota(),'integer')." ".
141  "WHERE role_id= ".$ilDB->quote($this->id,'integer')." ";
142  $res = $ilDB->manipulate($query);
143 
144  parent::update();
145 
146  $this->read();
147 
148  return true;
149  }
150 
158  function create()
159  {
160  global $ilDB;
161 
162  $this->id = parent::create();
163 
164  $query = "INSERT INTO role_data ".
165  "(role_id,allow_register,assign_users,disk_quota) ".
166  "VALUES ".
167  "(".$ilDB->quote($this->id,'integer').",".
168  $ilDB->quote($this->getAllowRegister(),'integer').",".
169  $ilDB->quote($this->getAssignUsersStatus(),'integer').",".
170  $ilDB->quote($this->getDiskQuota(),'integer').")"
171  ;
172  $res = $ilDB->query($query);
173 
174  return $this->id;
175  }
176 
183  function setAllowRegister($a_allow_register)
184  {
185  if (empty($a_allow_register))
186  {
187  $a_allow_register == 0;
188  }
189 
190  $this->allow_register = (int) $a_allow_register;
191  }
192 
199  function getAllowRegister()
200  {
201  return $this->allow_register ? $this->allow_register : false;
202  }
203 
212  function setDiskQuota($a_disk_quota)
213  {
214  $this->disk_quota = $a_disk_quota;
215  }
216 
226  function getDiskQuota()
227  {
228  return $this->disk_quota;
229  }
237  {
238  global $ilDB;
239 
240  $query = "SELECT * FROM role_data ".
241  "JOIN object_data ON object_data.obj_id = role_data.role_id ".
242  "WHERE allow_register = 1";
243  $res = $ilDB->query($query);
244 
245  $roles = array();
246  while($role = $ilDB->fetchAssoc($res))
247  {
248  $roles[] = array("id" => $role["obj_id"],
249  "title" => $role["title"],
250  "auth_mode" => $role['auth_mode']);
251  }
252 
253  return $roles;
254  }
255 
262  function _lookupAllowRegister($a_role_id)
263  {
264  global $ilDB;
265 
266  $query = "SELECT * FROM role_data ".
267  " WHERE role_id =".$ilDB->quote($a_role_id,'integer');
268 
269  $res = $ilDB->query($query);
270  if ($role_rec = $ilDB->fetchAssoc($res))
271  {
272  if ($role_rec["allow_register"])
273  {
274  return true;
275  }
276  }
277  return false;
278  }
279 
287  function setParent($a_parent_ref)
288  {
289  $this->parent = $a_parent_ref;
290  }
291 
298  function getParent()
299  {
300  return $this->parent;
301  }
302 
303 
310  function delete()
311  {
312  global $rbacadmin, $rbacreview,$ilDB;
313 
314  $role_folders = $rbacreview->getFoldersAssignedToRole($this->getId());
315 
316  if ($rbacreview->isAssignable($this->getId(),$this->getParent()))
317  {
318  // do not delete a global role, if the role is the last
319  // role a user is assigned to.
320  //
321  // Performance improvement: In the code section below, we
322  // only need to consider _global_ roles. We don't need
323  // to check for _local_ roles, because a user who has
324  // a local role _always_ has a global role too.
325  $last_role_user_ids = array();
326  if ($this->getParent() == ROLE_FOLDER_ID)
327  {
328  // The role is a global role: check if
329  // we find users who aren't assigned to any
330  // other global role than this one.
331  $user_ids = $rbacreview->assignedUsers($this->getId());
332 
333  foreach ($user_ids as $user_id)
334  {
335  // get all roles each user has
336  $role_ids = $rbacreview->assignedRoles($user_id);
337 
338  // is last role?
339  if (count($role_ids) == 1)
340  {
341  $last_role_user_ids[] = $user_id;
342  }
343  }
344  }
345 
346  // users with last role found?
347  if (count($last_role_user_ids) > 0)
348  {
349  foreach ($last_role_user_ids as $user_id)
350  {
351 //echo "<br>last role for user id:".$user_id.":";
352  // GET OBJECT TITLE
353  $tmp_obj = $this->ilias->obj_factory->getInstanceByObjId($user_id);
354  $user_names[] = $tmp_obj->getFullname();
355  unset($tmp_obj);
356  }
357 
358  // TODO: This check must be done in rolefolder object because if multiple
359  // roles were selected the other roles are still deleted and the system does not
360  // give any feedback about this.
361  $users = implode(', ',$user_names);
362  $this->ilias->raiseError($this->lng->txt("msg_user_last_role1")." ".
363  $users."<br/>".$this->lng->txt("msg_user_last_role2"),$this->ilias->error_obj->WARNING);
364  }
365  else
366  {
367  // IT'S A BASE ROLE
368  $rbacadmin->deleteRole($this->getId(),$this->getParent());
369 
370  // Delete ldap role group mappings
371  include_once('./Services/LDAP/classes/class.ilLDAPRoleGroupMappingSettings.php');
373 
374  // delete object_data entry
375  parent::delete();
376 
377  // delete role_data entry
378  $query = "DELETE FROM role_data WHERE role_id = ".$ilDB->quote($this->getId(),'integer');
379  $res = $ilDB->manipulate($query);
380 
381  include_once './classes/class.ilRoleDesktopItem.php';
382  $role_desk_item_obj =& new ilRoleDesktopItem($this->getId());
383  $role_desk_item_obj->deleteAll();
384 
385  }
386  }
387  else
388  {
389  // linked local role: INHERITANCE WAS STOPPED, SO DELETE ONLY THIS LOCAL ROLE
390  $rbacadmin->deleteLocalRole($this->getId(),$this->getParent());
391  }
392 
393  // purge empty rolefolders
394  //
395  // Performance improvement: We filter out all role folders
396  // which still contain roles, _before_ we attempt to purge them.
397  // This is faster than attempting to purge all role folders,
398  // and let function purge() of the role folder find out, if
399  // purging is possible.
400 
401  $non_empty_role_folders = $rbacreview->filterEmptyRoleFolders($role_folders);
402  $role_folders = array_diff($role_folders,$non_empty_role_folders);
403 
404  // Attempt to purge the role folders
405  foreach ($role_folders as $rolf)
406  {
407  if (ilObject::_exists($rolf,true))
408  {
409  $rolfObj = $this->ilias->obj_factory->getInstanceByRefId($rolf);
410  $rolfObj->purge();
411  unset($rolfObj);
412  }
413  }
414 
415  return true;
416  }
417 
418  function getCountMembers()
419  {
420  global $rbacreview;
421 
422  return count($rbacreview->assignedUsers($this->getId()));
423  }
424 
425  function _getTranslation($a_role_title)
426  {
427  global $lng;
428 
429  $test_str = explode('_',$a_role_title);
430 
431  if ($test_str[0] == 'il')
432  {
433  $test2 = (int) $test_str[3];
434  if ($test2 > 0)
435  {
436  unset($test_str[3]);
437  }
438 
439  return $lng->txt(implode('_',$test_str));
440  }
441 
442  return $a_role_title;
443  }
444 
445 
446 
447  function _updateAuthMode($a_roles)
448  {
449  global $ilDB;
450 
451  foreach ($a_roles as $role_id => $auth_mode)
452  {
453  $query = "UPDATE role_data SET ".
454  "auth_mode= ".$ilDB->quote($auth_mode,'text')." ".
455  "WHERE role_id= ".$ilDB->quote($role_id,'integer')." ";
456  $res = $ilDB->manipulate($query);
457  }
458  }
459 
460  function _getAuthMode($a_role_id)
461  {
462  global $ilDB;
463 
464  $query = "SELECT auth_mode FROM role_data ".
465  "WHERE role_id= ".$ilDB->quote($a_role_id,'integer')." ";
466  $res = $ilDB->query($query);
467  $row = $ilDB->fetchAssoc($res);
468 
469  return $row['auth_mode'];
470  }
471 
479  public static function _getRolesByAuthMode($a_auth_mode)
480  {
481  global $ilDB;
482 
483  $query = "SELECT * FROM role_data ".
484  "WHERE auth_mode = ".$ilDB->quote($a_auth_mode,'text');
485  $res = $ilDB->query($query);
486  while($row = $ilDB->fetchObject($res))
487  {
488  $roles[] = $row->role_id;
489  }
490  return $roles ? $roles : array();
491  }
492 
501  public static function _resetAuthMode($a_auth_mode)
502  {
503  global $ilDB;
504 
505  $query = "UPDATE role_data SET auth_mode = 'default' WHERE auth_mode = ".$ilDB->quote($a_auth_mode,'text');
506  $res = $ilDB->manipulate($query);
507  }
508 
509  // returns array of operation/objecttype definitions
510  // private
512  {
513  global $ilDB, $lng, $objDefinition,$rbacreview;
514 
515  $operation_info = $rbacreview->getOperationAssignment();
516  foreach($operation_info as $info)
517  {
518  if($objDefinition->getDevMode($info['type']))
519  {
520  continue;
521  }
522  $rbac_objects[$info['typ_id']] = array("obj_id" => $info['typ_id'],
523  "type" => $info['type']);
524 
525  // handle plugin permission texts
526  $txt = $objDefinition->isPlugin($info['type'])
527  ? ilPlugin::lookupTxt("rep_robj", $info['type'], $info['type']."_".$info['operation'])
528  : $lng->txt($info['type']."_".$info['operation']);
529  if (substr($info['operation'], 0, 7) == "create_" &&
530  $objDefinition->isPlugin(substr($info['operation'], 7)))
531  {
532  $txt = ilPlugin::lookupTxt("rep_robj", substr($info['operation'], 7), $info['type']."_".$info['operation']);
533  }
534  $rbac_operations[$info['typ_id']][$info['ops_id']] = array(
535  "ops_id" => $info['ops_id'],
536  "title" => $info['operation'],
537  "name" => $txt);
538 
539  }
540  return array($rbac_objects,$rbac_operations);
541  }
542 
548  public function isDeletable($a_role_folder_id)
549  {
550  global $rbacreview;
551 
552  if($this->getId() == SYSTEM_ROLE_ID or $this->getId() == ANONYMOUS_ROLE_ID)
553  {
554  return false;
555  }
556 
557  if(!$rbacreview->isAssignable($this->getId(), $a_role_folder_id))
558  {
559  return false;
560  }
561 
562  if(substr($this->getTitle(),0,3) == 'il_')
563  {
564  return false;
565  }
566  return true;
567 
568  }
569 
570  public static function isAutoGenerated($a_role_id)
571  {
572  return substr(ilObject::_lookupTitle($a_role_id), 0, 3) == 'il_';
573  }
574 
582  public function changeExistingObjects($a_start_node,$a_mode,$a_filter)
583  {
584  global $tree,$rbacreview;
585 
586  // Get node info of subtree
587  $nodes = $tree->getRbacSubtreeInfo($a_start_node);
588 
589  #var_dump($nodes);
590 
591  // get local policies
592  $all_local_policies = $rbacreview->getObjectsWithStopedInheritance($this->getId());
593 
594 
595  // filter relevant roles
596  $local_policies = array();
597  foreach($all_local_policies as $lp)
598  {
599  if(isset($nodes[$lp]))
600  {
601  $local_policies[] = $lp;
602  }
603  }
604 
605  // Delete deprecated policies
606  switch($a_mode)
607  {
608  case self::MODE_UNPROTECTED_DELETE_LOCAL_POLICIES:
609  case self::MODE_PROTECTED_DELETE_LOCAL_POLICIES:
610  $local_policies = $this->deleteLocalPolicies($a_start_node,$local_policies,$a_filter);
611  #$local_policies = array($a_start_node == ROOT_FOLDER_ID ? SYSTEM_FOLDER_ID : $a_start_node);
612  break;
613  }
614  $this->adjustPermissions($a_mode,$nodes,$local_policies,$a_filter);
615 
616  #var_dump(memory_get_peak_usage());
617  #var_dump(memory_get_usage());
618  }
619 
625  protected function deleteLocalPolicies($a_start,$a_policies,$a_filter)
626  {
627  global $rbacreview,$rbacadmin;
628 
629  $local_policies = array();
630  foreach($a_policies as $policy)
631  {
632  if($policy == $a_start or $policy == SYSTEM_FOLDER_ID)
633  {
634  $local_policies[] = $policy;
635  continue;
636  }
637  if(!in_array('all',$a_filter) and !in_array(ilObject::_lookupType(ilObject::_lookupObjId($policy)),$a_filter))
638  {
639  $local_policies[] = $policy;
640  continue;
641  }
642 
643  if($rolf = $rbacreview->getRoleFolderIdOfObject($policy))
644  {
645  $rbacadmin->deleteLocalRole($this->getId(),$rolf);
646  }
647  }
648  return $local_policies;
649  }
650 
658  protected function adjustPermissions($a_mode,$a_nodes,$a_policies,$a_filter)
659  {
660  global $rbacadmin;
661 
662  $operation_stack = array();
663  $policy_stack = array();
664  $left_stack = array();
665  $right_stack = array();
666 
667  $start_node = current($a_nodes);
668  array_push($left_stack, $start_node['lft']);
669  array_push($right_stack, $start_node['rgt']);
670  $this->updatePolicyStack($policy_stack, $start_node['child']);
671  $this->updateOperationStack($operation_stack, $start_node['child']);
672 
673  $local_policy = false;
674  foreach($a_nodes as $node)
675  {
676  $lft = end($left_stack);
677  $rgt = end($right_stack);
678 
679  #echo "----STACK---- ".$lft.' - '.$rgt.'<br/>';
680 
681  if(($node['lft'] < $lft) or ($node['rgt'] > $rgt))
682  {
683  #echo "LEFT ".$node['child'].'<br>';
684  array_pop($operation_stack);
685  array_pop($policy_stack);
686  array_pop($left_stack);
687  array_pop($right_stack);
688  $local_policy = false;
689  }
690 
691  if($local_policy)
692  {
693  #echo "LOCAL ".$node['child'].' left:'.$node['lft'].' right: '.$node['rgt'].'<br>';
694  // Continue if inside of local policy
695  continue;
696  }
697 
698  // Start node => set permissions and continue
699  if($node['child'] == $start_node['child'])
700  {
701  if($this->isHandledObjectType($a_filter,$node['type']))
702  {
703  // Set permissions
704  $perms = end($operation_stack);
705  $rbacadmin->grantPermission(
706  $this->getId(),
707  (array) $perms[$node['type']],
708  $node['child']
709  );
710  }
711  continue;
712  }
713 
714  // Node has local policies => update permission stack and continue
715  if(in_array($node['child'], $a_policies) and ($node['child'] != SYSTEM_FOLDER_ID))
716  {
717  #echo "POLICIES ".$node['child'].' left:'.$node['lft'].' right: '.$node['rgt'].'<br>';
718  $local_policy = true;
719  $this->updatePolicyStack($policy_stack, $node['child']);
720  $this->updateOperationStack($operation_stack, $node['child']);
721  array_push($left_stack,$node['lft']);
722  array_push($right_stack, $node['rgt']);
723  continue;
724  }
725 
726  // Continue if this object type is in filter
727  if(!$this->isHandledObjectType($a_filter,$node['type']))
728  {
729  continue;
730  }
731 
732  #echo "MODE: ".$a_mode.'TYPE: '.$node['type'].'<br>';
733  // Node is course => create course permission intersection
734  if(($a_mode == self::MODE_UNPROTECTED_DELETE_LOCAL_POLICIES or
735  $a_mode == self::MODE_UNPROTECTED_KEEP_LOCAL_POLICIES) and ($node['type'] == 'crs'))
736 
737  {
738  #echo "CRS ".$node['child'].'<br>';
739  // Copy role permission intersection
740 
741  $perms = end($operation_stack);
742  $this->createPermissionIntersection($policy_stack,$perms['crs'],$node['child'],$node['type']);
743  if($this->updateOperationStack($operation_stack,$node['child']))
744  {
745  #echo "CRS SUCCESS ".$node['child'].'<br>';
746  $this->updatePolicyStack($policy_stack, $node['child']);
747  array_push($left_stack, $node['lft']);
748  array_push($right_stack, $node['rgt']);
749  }
750  }
751 
752  // Node is group => create group permission intersection
753  if(($a_mode == self::MODE_UNPROTECTED_DELETE_LOCAL_POLICIES or
754  $a_mode == self::MODE_UNPROTECTED_KEEP_LOCAL_POLICIES) and ($node['type'] == 'grp'))
755  {
756  #echo "GRP ".$node['child'].'<br>';
757  // Copy role permission intersection
758  $perms = end($operation_stack);
759  $this->createPermissionIntersection($policy_stack,$perms['grp'],$node['child'],$node['type']);
760  if($this->updateOperationStack($operation_stack,$node['child']))
761  {
762  #echo "GRP SUCCESS ".$node['child'].'<br>';
763  $this->updatePolicyStack($policy_stack, $node['child']);
764  array_push($left_stack, $node['lft']);
765  array_push($right_stack, $node['rgt']);
766  }
767  }
768 
769  #echo "GRANTED ".$node['child'].'<br>';
770  // Set permission
771  $perms = end($operation_stack);
772  $rbacadmin->grantPermission(
773  $this->getId(),
774  (array) $perms[$node['type']],
775  $node['child']
776  );
777  #var_dump("ALL INFO ",$this->getId(),$perms[$node['type']]);
778  }
779  }
780 
787  protected function isHandledObjectType($a_filter,$a_type)
788  {
789  if(in_array('all',$a_filter))
790  {
791  return true;
792  }
793  return in_array($a_type,$a_filter);
794  }
795 
802  protected function updateOperationStack(&$a_stack,$a_node)
803  {
804  global $rbacreview;
805 
806  if($a_node == ROOT_FOLDER_ID)
807  {
808  $rolf = ROLE_FOLDER_ID;
809  }
810  else
811  {
812  $rolf = $rbacreview->getRoleFolderIdOfObject($a_node);
813  }
814 
815  if(!$rolf)
816  {
817  return false;
818  }
819 
820  $a_stack[] = $rbacreview->getAllOperationsOfRole(
821  $this->getId(),
822  $rolf
823  );
824  return true;
825  }
826 
832  protected function updatePolicyStack(&$a_stack,$a_node)
833  {
834  global $rbacreview;
835 
836  if($a_node == ROOT_FOLDER_ID)
837  {
838  $rolf = ROLE_FOLDER_ID;
839  }
840  else
841  {
842  $rolf = $rbacreview->getRoleFolderIdOfObject($a_node);
843  }
844 
845  if(!$rolf)
846  {
847  return false;
848  }
849 
850  $a_stack[] = $rolf;
851  return true;
852  }
853 
861  protected function createPermissionIntersection($policy_stack,$a_current_ops,$a_id,$a_type)
862  {
863  global $ilDB, $rbacreview,$rbacadmin;
864 
865  static $course_non_member_id = null;
866  static $group_non_member_id = null;
867  static $group_open_id = null;
868  static $group_closed_id = null;
869 
870  // Get template id
871  switch($a_type)
872  {
873  case 'grp':
874 
875  include_once './Modules/Group/classes/class.ilObjGroup.php';
877  #var_dump("GROUP TYPE",$type);
878  switch($type)
879  {
880  case GRP_TYPE_CLOSED:
881  if(!$group_closed_id)
882  {
883  $query = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_grp_status_closed'";
884  $res = $ilDB->query($query);
885  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
886  {
887  $group_closed_id = $row->obj_id;
888  }
889  }
890  $template_id = $group_closed_id;
891  #var_dump("GROUP CLOSED id:" . $template_id);
892  break;
893 
894  case GRP_TYPE_OPEN:
895  default:
896  if(!$group_open_id)
897  {
898  $query = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_grp_status_open'";
899  $res = $ilDB->query($query);
900  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
901  {
902  $group_open_id = $row->obj_id;
903  }
904  }
905  $template_id = $group_open_id;
906  #var_dump("GROUP OPEN id:" . $template_id);
907  break;
908  }
909  break;
910 
911  case 'crs':
912  if(!$course_non_member_id)
913  {
914  $query = "SELECT obj_id FROM object_data WHERE type='rolt' AND title='il_crs_non_member'";
915  $res = $ilDB->query($query);
916  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
917  {
918  $course_non_member_id = $row->obj_id;
919  }
920  }
921  $template_id = $course_non_member_id;
922  break;
923  }
924 
925  $current_ops = $a_current_ops[$a_type];
926 
927  // Create intersection template permissions
928  if($template_id)
929  {
930  $rolf = $rbacreview->getRoleFolderIdOfObject($a_id);
931 
932  $rbacadmin->copyRolePermissionIntersection(
933  $template_id, ROLE_FOLDER_ID,
934  $this->getId(), end($policy_stack),
935  $rolf,$this->getId()
936  );
937  }
938  else
939  {
940  #echo "No template id for ".$a_id.' of type'.$a_type.'<br>';
941  }
942  #echo "ROLE ASSIGN: ".$rolf.' AID'.$a_id;
943  if($rolf)
944  {
945  $rbacadmin->assignRoleToFolder($this->getId(),$rolf,"n");
946  }
947  return true;
948  }
949 
950 } // END class.ilObjRole
951 ?>