function checkAccessOfUser($a_user_id, $a_operations, $a_ref_id, $a_type = "")
 {
     global $ilUser, $rbacreview, $ilObjDataCache, $ilDB, $ilLog;
     // Create the user cache key
     $cacheKey = $a_user_id . ':' . $a_operations . ':' . $a_ref_id . ':' . $a_type;
     // Create the cache if it does not yet exist
     if (!is_array(self::$_checkAccessOfUserCache)) {
         self::$_checkAccessOfUserCache = array();
     }
     // Try to return result from cache
     if (array_key_exists($cacheKey, self::$_checkAccessOfUserCache)) {
         return self::$_checkAccessOfUserCache[$cacheKey];
     }
     #echo ++$counter;
     // DISABLED
     // Check For owner
     // Owners do always have full access to their objects
     // Excluded are the permissions create and perm
     // This method call return all operations that are NOT granted by the owner status
     if (!($a_operations = $this->__filterOwnerPermissions($a_user_id, $a_operations, $a_ref_id))) {
         // Store positive outcome in cache.
         // Note: we only cache up to 1000 results to avoid memory overflows
         if (count(self::$_checkAccessOfUserCache) < 1000) {
             self::$_checkAccessOfUserCache[$cacheKey] = true;
         }
         return true;
     }
     // get roles using role cache
     $roles = $this->fetchAssignedRoles($a_user_id, $a_ref_id);
     // exclude system role from rbac
     if (in_array(SYSTEM_ROLE_ID, $roles)) {
         // Store positive outcome in cache.
         // Note: we only cache up to 1000 results to avoid memory overflows
         if (count(self::$_checkAccessOfUserCache) < 1000) {
             self::$_checkAccessOfUserCache[$cacheKey] = true;
         }
         return true;
     }
     if (!isset($a_operations) or !isset($a_ref_id)) {
         $GLOBALS['ilLog']->logStack();
         $this->ilErr->raiseError(get_class($this) . "::checkAccess(): Missing parameter! " . "ref_id: " . $a_ref_id . " operations: " . $a_operations, $this->ilErr->WARNING);
     }
     if (!is_string($a_operations)) {
         $GLOBALS['ilLog']->logStack();
         $this->ilErr->raiseError(get_class($this) . "::checkAccess(): Wrong datatype for operations!", $this->ilErr->WARNING);
     }
     // Create the PA cache if it does not exist yet
     $paCacheKey = $a_user_id . ':' . $a_ref_id;
     if (!is_array(self::$_paCache)) {
         self::$_paCache = array();
     }
     if (array_key_exists($paCacheKey, self::$_paCache)) {
         // Return result from PA cache
         $ops = self::$_paCache[$paCacheKey];
     } else {
         // Data is not in PA cache, perform database query
         $q = "SELECT * FROM rbac_pa " . "WHERE ref_id = " . $ilDB->quote($a_ref_id, 'integer');
         $r = $this->ilDB->query($q);
         $ops = array();
         while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT)) {
             if (in_array($row->rol_id, $roles)) {
                 $ops = array_merge($ops, unserialize(stripslashes($row->ops_id)));
             }
         }
         // Cache up to 1000 entries in the PA cache
         if (count(self::$_paCache) < 1000) {
             self::$_paCache[$paCacheKey] = $ops;
         }
     }
     $operations = explode(",", $a_operations);
     foreach ($operations as $operation) {
         if ($operation == "create") {
             if (empty($a_type)) {
                 $this->ilErr->raiseError(get_class($this) . "::CheckAccess(): Expect a type definition for checking a 'create' permission", $this->ilErr->WARNING);
             }
             $ops_id = ilRbacReview::_getOperationIdByName($operation . "_" . $a_type);
         } else {
             $ops_id = ilRbacReview::_getOperationIdByName($operation);
         }
         if (!in_array($ops_id, (array) $ops)) {
             //$ilLog->write('PERMISSION: '.$a_ref_id.' -> '.$a_ops_id.' failed');
             // Store negative outcome in cache.
             // Note: we only cache up to 1000 results to avoid memory overflows
             if (count(self::$_checkAccessOfUserCache) < 1000) {
                 self::$_checkAccessOfUserCache[$cacheKey] = false;
             }
             return false;
         }
     }
     // Store positive outcome in cache.
     // Note: we only cache up to 1000 results to avoid memory overflows
     if (count(self::$_checkAccessOfUserCache) < 1000) {
         //$ilLog->write('PERMISSION: '.$a_ref_id.' -> '.$ops_id.' granted');
         self::$_checkAccessOfUserCache[$cacheKey] = true;
     }
     return true;
 }
 function getRolesWithContribute($a_node_id)
 {
     global $rbacreview;
     include_once "Services/AccessControl/classes/class.ilObjRole.php";
     $contr_op_id = ilRbacReview::_getOperationIdByName("contribute");
     $contr_role_id = $this->getLocalContributorRole($a_node_id);
     $res = array();
     foreach ($rbacreview->getParentRoleIds($a_node_id) as $role_id => $role) {
         if ($role_id != $contr_role_id && in_array($contr_op_id, $rbacreview->getActiveOperationsOfRole($a_node_id, $role_id))) {
             $res[$role_id] = ilObjRole::_getTranslation($role["title"]);
         }
     }
     return $res;
 }