/**
  * Checks wether a user may invoke a command or not
  * (this method is called by ilAccessHandler::checkAccess)
  *
  * Please do not check any preconditions handled by
  * ilConditionHandler here. Also don't do any RBAC checks.
  *
  * @param	string		$a_cmd			command (not permission!)
  * @param	string		$a_permission	permission
  * @param	int			$a_ref_id		reference id
  * @param	int			$a_obj_id		object id
  * @param	int			$a_user_id		user id (if not provided, current user is taken)
  *
  * @return	boolean		true, if everything is ok
  */
 function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "")
 {
     global $ilAccess;
     switch ($a_permission) {
         case 'visible':
         case 'read':
             include_once './Modules/CourseReference/classes/class.ilObjCourseReference.php';
             $target_ref_id = ilObjCourseReference::_lookupTargetRefId($a_obj_id);
             if (!$ilAccess->checkAccessOfUser($a_user_id, $a_permission, $a_cmd, $target_ref_id)) {
                 return false;
             }
             break;
     }
     return true;
 }
 function addReference($sid, $a_source_id, $a_target_id)
 {
     $this->initAuth($sid);
     $this->initIlias();
     if (!$this->__checkSession($sid)) {
         return $this->__raiseError($this->__getMessage(), $this->__getMessageCode());
     }
     if (!is_numeric($a_source_id)) {
         return $this->__raiseError('No source id given.', 'Client');
     }
     if (!is_numeric($a_target_id)) {
         return $this->__raiseError('No target id given.', 'Client');
     }
     global $objDefinition, $rbacsystem, $tree;
     if (!($source_obj =& ilObjectFactory::getInstanceByRefId($a_source_id, false))) {
         return $this->__raiseError('No valid source id given.', 'Client');
     }
     if (!($target_obj =& ilObjectFactory::getInstanceByRefId($a_target_id, false))) {
         return $this->__raiseError('No valid target id given.', 'Client');
     }
     if (!$objDefinition->allowLink($source_obj->getType()) and $source_obj->getType() != 'cat' and $source_obj->getType() != 'crs') {
         return $this->__raiseError('Linking of object type: ' . $source_obj->getType() . ' is not allowed', 'Client');
     }
     $allowed_subtypes = $objDefinition->getSubObjects($target_obj->getType());
     foreach ($allowed_subtypes as $row) {
         if ($row['name'] != 'rolf') {
             $allowed[] = $row['name'];
         }
     }
     if (!in_array($source_obj->getType(), $allowed)) {
         return $this->__raiseError('Objects of type: ' . $source_obj->getType() . ' are not allowed to be subobjects of type ' . $target_obj->getType() . '!', 'Client');
     }
     // Permission checks
     if (!$rbacsystem->checkAccess('create', $target_obj->getRefId(), $source_obj->getType())) {
         return $this->__raiseError('No permission to create objects of type ' . $source_obj->getType() . '!', 'Client');
     }
     if (!$rbacsystem->checkAccess('delete', $source_obj->getRefId())) {
         return $this->__raiseError('No permission to link object with id: ' . $source_obj->getRefId() . '!', 'Client');
     }
     if ($source_obj->getType() != 'cat' and $source_obj->getType() != 'crs') {
         // check if object already linked to target
         $possibleChilds = $tree->getChildsByType($target_obj->getRefId(), $source_obj->getType());
         foreach ($possibleChilds as $child) {
             if ($child["obj_id"] == $source_obj->getId()) {
                 return $this->__raiseError("Object already linked to target.", "Client");
             }
         }
         // Finally link it to target position
         $new_ref_id = $source_obj->createReference();
         $source_obj->putInTree($target_obj->getRefId());
         $source_obj->setPermissions($target_obj->getRefId());
         return $new_ref_id ? $new_ref_id : "0";
     } else {
         switch ($source_obj->getType()) {
             case 'cat':
                 include_once './Modules/CategoryReference/classes/class.ilObjCategoryReference.php';
                 $new_ref = new ilObjCategoryReference();
                 break;
             case 'crs':
                 include_once './Modules/CourseReference/classes/class.ilObjCourseReference.php';
                 $new_ref = new ilObjCourseReference();
                 break;
         }
         $new_ref->create();
         $new_ref_id = $new_ref->createReference();
         $new_ref->putInTree($target_obj->getRefId());
         $new_ref->setPermissions($target_obj->getRefId());
         $new_ref->setTargetId($source_obj->getId());
         $new_ref->update();
         return $new_ref_id ? $new_ref_id : 0;
     }
 }