diff --git a/lib/accesslib.php b/lib/accesslib.php index 69c8f449a97..af6386780c8 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -921,749 +921,6 @@ function get_context_users_byrole ($context, $roleid, $fields=NULL, $where=NULL, return $users; } -/** - * This function returns whether the current user has the capability of performing a function - * For example, we can do has_capability('mod/forum:replypost',$context) in forum - * This is a recursive function. - * @uses $USER - * @param string $capability - name of the capability (or debugcache or clearcache) - * @param object $context - a context object (record from context table) - * @param integer $userid - a userid number - * @param bool $doanything - if false, ignore do anything - * @return bool - */ -function has_capability_old($capability, $context=NULL, $userid=NULL, $doanything=true) { - - global $USER, $CONTEXT, $CFG; - - static $capcache = array(); // Cache of capabilities - - -/// Cache management - - if ($capability == 'clearcache') { - $capcache = array(); // Clear ALL the capability cache - return false; - } - -/// Some sanity checks - if (debugging('',DEBUG_DEVELOPER)) { - if ($capability == 'debugcache') { - print_object($capcache); - return true; - } - if (!record_exists('capabilities', 'name', $capability)) { - debugging('Capability "'.$capability.'" was not found! This should be fixed in code.'); - } - if ($doanything != true and $doanything != false) { - debugging('Capability parameter "doanything" is wierd ("'.$doanything.'"). This should be fixed in code.'); - } - if (!is_object($context) && $context !== NULL) { - debugging('Incorrect context parameter "'.$context.'" for has_capability(), object expected! This should be fixed in code.'); - } - } - -/// Make sure we know the current context - if (empty($context)) { // Use default CONTEXT if none specified - if (empty($CONTEXT)) { - return false; - } else { - $context = $CONTEXT; - } - } else { // A context was given to us - if (empty($CONTEXT)) { - $CONTEXT = $context; // Store FIRST used context in this global as future default - } - } - -/// Check and return cache in case we've processed this one before. - $requsteduser = empty($userid) ? $USER->id : $userid; // find out the requested user id, $USER->id might have been changed - $cachekey = $capability.'_'.$context->id.'_'.intval($requsteduser).'_'.intval($doanything); - - if (isset($capcache[$cachekey])) { - return $capcache[$cachekey]; - } - - -/// Load up the capabilities list or item as necessary - if ($userid) { - if (empty($USER->id) or ($userid != $USER->id) or empty($USER->capabilities)) { - - //caching - helps user switching in cron - static $guestuserid = false; // guest user id - static $guestcaps = false; // guest caps - static $defcaps = false; // default user caps - this might help cron - - if ($guestuserid === false) { - $guestuserid = get_field('user', 'id', 'username', 'guest'); - } - - if ($userid == $guestuserid) { - if ($guestcaps === false) { - $guestcaps = load_guest_role(true); - } - $capabilities = $guestcaps; - - } else { - // This big SQL is expensive! We reduce it a little by avoiding checking for changed enrolments (false) - $capabilities = load_user_capability($capability, $context, $userid, false); - if ($defcaps === false) { - $defcaps = load_defaultuser_role(true); - } - $capabilities = merge_role_caps($capabilities, $defcaps); - } - - } else { //$USER->id == $userid and needed capabilities already present - $capabilities = $USER->capabilities; - } - - } else { // no userid - if (empty($USER->capabilities)) { - load_all_capabilities(); // expensive - but we have to do it once anyway - } - $capabilities = $USER->capabilities; - $userid = $USER->id; - } - -/// We act a little differently when switchroles is active - - $switchroleactive = false; // Assume it isn't active in this context - - -/// First deal with the "doanything" capability - - if ($doanything) { - - /// First make sure that we aren't in a "switched role" - - if (!empty($USER->switchrole)) { // Switchrole is active somewhere! - if (!empty($USER->switchrole[$context->id])) { // Because of current context - $switchroleactive = true; - } else { // Check parent contexts - if ($parentcontextids = get_parent_contexts($context)) { - foreach ($parentcontextids as $parentcontextid) { - if (!empty($USER->switchrole[$parentcontextid])) { // Yep, switchroles active here - $switchroleactive = true; - break; - } - } - } - } - } - - /// Check the site context for doanything (most common) first - - if (empty($switchroleactive)) { // Ignore site setting if switchrole is active - $sitecontext = get_context_instance(CONTEXT_SYSTEM); - if (isset($capabilities[$sitecontext->id]['moodle/site:doanything'])) { - $result = (0 < $capabilities[$sitecontext->id]['moodle/site:doanything']); - $capcache[$cachekey] = $result; - return $result; - } - } - /// If it's not set at site level, it is possible to be set on other levels - /// Though this usage is not common and can cause risks - switch ($context->contextlevel) { - - case CONTEXT_COURSECAT: - // Check parent cats. - $parentcats = get_parent_cats($context); - foreach ($parentcats as $parentcat) { - if (isset($capabilities[$parentcat]['moodle/site:doanything'])) { - $result = (0 < $capabilities[$parentcat]['moodle/site:doanything']); - $capcache[$cachekey] = $result; - return $result; - } - } - break; - - case CONTEXT_COURSE: - // Check parent cat. - $parentcats = get_parent_cats($context); - - foreach ($parentcats as $parentcat) { - if (isset($capabilities[$parentcat]['do_anything'])) { - $result = (0 < $capabilities[$parentcat]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - break; - - case CONTEXT_GROUP: - // Find course. - $courseid = get_field('groups', 'courseid', 'id', $context->instanceid); - $courseinstance = get_context_instance(CONTEXT_COURSE, $courseid); - - $parentcats = get_parent_cats($courseinstance); - foreach ($parentcats as $parentcat) { - if (isset($capabilities[$parentcat]['do_anything'])) { - $result = (0 < $capabilities[$parentcat]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - - $coursecontext = ''; - if (isset($capabilities[$courseinstance->id]['do_anything'])) { - $result = (0 < $capabilities[$courseinstance->id]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - - break; - - case CONTEXT_MODULE: - // Find course. - $cm = get_record('course_modules', 'id', $context->instanceid); - $courseinstance = get_context_instance(CONTEXT_COURSE, $cm->course); - - if ($parentcats = get_parent_cats($courseinstance)) { - foreach ($parentcats as $parentcat) { - if (isset($capabilities[$parentcat]['do_anything'])) { - $result = (0 < $capabilities[$parentcat]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - } - - if (isset($capabilities[$courseinstance->id]['do_anything'])) { - $result = (0 < $capabilities[$courseinstance->id]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - - break; - - case CONTEXT_BLOCK: - // not necessarily 1 to 1 to course. - $block = get_record('block_instance','id',$context->instanceid); - if ($block->pagetype == 'course-view') { - $courseinstance = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check - $parentcats = get_parent_cats($courseinstance); - - foreach ($parentcats as $parentcat) { - if (isset($capabilities[$parentcat]['do_anything'])) { - $result = (0 < $capabilities[$parentcat]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - - if (isset($capabilities[$courseinstance->id]['do_anything'])) { - $result = (0 < $capabilities[$courseinstance->id]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - // blocks that do not have course as parent do not need to do any more checks - already done above - - break; - - default: - // CONTEXT_SYSTEM: CONTEXT_PERSONAL: CONTEXT_USER: - // Do nothing, because the parents are site context - // which has been checked already - break; - } - - // Last: check self. - if (isset($capabilities[$context->id]['do_anything'])) { - $result = (0 < $capabilities[$context->id]['do_anything']); - $capcache[$cachekey] = $result; - return $result; - } - } - // do_anything has not been set, we now look for it the normal way. - $result = (0 < capability_search($capability, $context, $capabilities, $switchroleactive)); - $capcache[$cachekey] = $result; - return $result; - -} - - -/** - * In a separate function so that we won't have to deal with do_anything. - * again. Used by function has_capability(). - * @param $capability - capability string - * @param $context - the context object - * @param $capabilities - either $USER->capability or loaded array (for other users) - * @return permission (int) - */ -function capability_search($capability, $context, $capabilities, $switchroleactive=false) { - - global $USER, $CFG, $COURSE; - - if (!isset($context->id)) { - return 0; - } - // if already set in the array explicitly, no need to look for it in parent - // context any longer - if (isset($capabilities[$context->id][$capability])) { - return ($capabilities[$context->id][$capability]); - } - - /* Then, we check the cache recursively */ - $permission = 0; - - switch ($context->contextlevel) { - - case CONTEXT_SYSTEM: // by now it's a definite an inherit - $permission = 0; - break; - - case CONTEXT_PERSONAL: - $parentcontext = get_context_instance(CONTEXT_SYSTEM); - $permission = capability_search($capability, $parentcontext, $capabilities, $switchroleactive); - break; - - case CONTEXT_USER: - $parentcontext = get_context_instance(CONTEXT_SYSTEM); - $permission = capability_search($capability, $parentcontext, $capabilities, $switchroleactive); - break; - - case CONTEXT_COURSE: - if ($switchroleactive) { - // if switchrole active, do not check permissions above the course context, blocks are an exception - break; - } - // break is not here intentionally - because the code is the same for category and course - case CONTEXT_COURSECAT: // Coursecat -> coursecat or site - $parents = get_parent_cats($context); // cached internally - - // non recursive - should be faster - foreach ($parents as $parentid) { - $parentcontext = get_context_instance_by_id($parentid); - if (isset($capabilities[$parentcontext->id][$capability])) { - return ($capabilities[$parentcontext->id][$capability]); - } - } - // finally check system context - $parentcontext = get_context_instance(CONTEXT_SYSTEM); - $permission = capability_search($capability, $parentcontext, $capabilities, $switchroleactive); - break; - - case CONTEXT_GROUP: // 1 to 1 to course - $courseid = get_field('groups', 'courseid', 'id', $context->instanceid); - $parentcontext = get_context_instance(CONTEXT_COURSE, $courseid); - $permission = capability_search($capability, $parentcontext, $capabilities, $switchroleactive); - break; - - case CONTEXT_MODULE: // 1 to 1 to course - $cm = get_record('course_modules','id',$context->instanceid); - $parentcontext = get_context_instance(CONTEXT_COURSE, $cm->course); - $permission = capability_search($capability, $parentcontext, $capabilities, $switchroleactive); - break; - - case CONTEXT_BLOCK: // not necessarily 1 to 1 to course - $block = get_record('block_instance','id',$context->instanceid); - if ($block->pagetype == 'course-view') { - $parentcontext = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check - } else { - $parentcontext = get_context_instance(CONTEXT_SYSTEM); - } - // ignore the $switchroleactive beause we want the real block view capability defined in system context - $permission = capability_search($capability, $parentcontext, $capabilities, false); - break; - - default: - error ('This is an unknown context (' . $context->contextlevel . ') in capability_search!'); - return false; - } - - return $permission; -} - -/** - * auxillary function for load_user_capabilities() - * checks if context c1 is a parent (or itself) of context c2 - * @param int $c1 - context id of context 1 - * @param int $c2 - context id of context 2 - * @return bool - */ -function is_parent_context($c1, $c2) { - static $parentsarray; - - // context can be itself and this is ok - if ($c1 == $c2) { - return true; - } - // hit in cache? - if (isset($parentsarray[$c1][$c2])) { - return $parentsarray[$c1][$c2]; - } - - if (!$co2 = get_record('context', 'id', $c2)) { - return false; - } - - if (!$parents = get_parent_contexts($co2)) { - return false; - } - - foreach ($parents as $parent) { - $parentsarray[$parent][$c2] = true; - } - - if (in_array($c1, $parents)) { - return true; - } else { // else not a parent, set the cache anyway - $parentsarray[$c1][$c2] = false; - return false; - } -} - - -/** - * auxillary function for load_user_capabilities() - * handler in usort() to sort contexts according to level - * @param object contexta - * @param object contextb - * @return int - */ -function roles_context_cmp($contexta, $contextb) { - if ($contexta->contextlevel == $contextb->contextlevel) { - return 0; - } - return ($contexta->contextlevel < $contextb->contextlevel) ? -1 : 1; -} - -/** - * It will build an array of all the capabilities at each level - * i.e. site/metacourse/course_category/course/moduleinstance - * Note we should only load capabilities if they are explicitly assigned already, - * we should not load all module's capability! - * - * [Capabilities] => [26][forum_post] = 1 - * [26][forum_start] = -8990 - * [26][forum_edit] = -1 - * [273][blah blah] = 1 - * [273][blah blah blah] = 2 - * - * @param $capability string - Only get a specific capability (string) - * @param $context object - Only get capabilities for a specific context object - * @param $userid integer - the id of the user whose capabilities we want to load - * @param $checkenrolments boolean - Should we check enrolment plugins (potentially expensive) - * @return array of permissions (or nothing if they get assigned to $USER) - */ -function load_user_capability($capability='', $context=NULL, $userid=NULL, $checkenrolments=true) { - - global $USER, $CFG; - - // this flag has not been set! - // (not clean install, or upgraded successfully to 1.7 and up) - if (empty($CFG->rolesactive)) { - return false; - } - - if (empty($userid)) { - if (empty($USER->id)) { // We have no user to get capabilities for - debugging('User not logged in for load_user_capability!'); - return false; - } - unset($USER->capabilities); // We don't want possible older capabilites hanging around - unset($USER->access); - - if ($checkenrolments) { // Call "enrol" system to ensure that we have the correct picture - check_enrolment_plugins($USER); - } - - $userid = $USER->id; - $otheruserid = false; - } else { - if (!$user = get_record('user', 'id', $userid)) { - debugging('Non-existent userid in load_user_capability!'); - return false; - } - - if ($checkenrolments) { // Call "enrol" system to ensure that we have the correct picture - check_enrolment_plugins($user); - } - - $otheruserid = $userid; - } - - -/// First we generate a list of all relevant contexts of the user - - $usercontexts = array(); - - if ($context) { // if context is specified - $usercontexts = get_parent_contexts($context); - $usercontexts[] = $context->id; // Add the current context as well - } else { // else, we load everything - if ($userroles = get_records('role_assignments','userid',$userid)) { - foreach ($userroles as $userrole) { - if (!in_array($userrole->contextid, $usercontexts)) { - $usercontexts[] = $userrole->contextid; - } - } - } - } - -/// Set up SQL fragments for searching contexts - - if ($usercontexts) { - $listofcontexts = '('.implode(',', $usercontexts).')'; - $searchcontexts1 = "c1.id IN $listofcontexts AND"; - } else { - $searchcontexts1 = ''; - } - - if ($capability) { - // the doanything may override the requested capability - $capsearch = " AND (rc.capability = '$capability' OR rc.capability = 'moodle/site:doanything') "; - } else { - $capsearch =""; - } - -/// Then we use 1 giant SQL to bring out all relevant capabilities. -/// The first part gets the capabilities of orginal role. -/// The second part gets the capabilities of overriden roles. - - $siteinstance = get_context_instance(CONTEXT_SYSTEM); - $capabilities = array(); // Reinitialize. - - // SQL for normal capabilities - $SQL1 = "SELECT rc.capability, c1.id as id1, c1.id as id2, (c1.contextlevel * 100) AS aggrlevel, - SUM(rc.permission) AS sum - FROM - {$CFG->prefix}role_assignments ra, - {$CFG->prefix}role_capabilities rc, - {$CFG->prefix}context c1 - WHERE - ra.contextid=c1.id AND - ra.roleid=rc.roleid AND - ra.userid=$userid AND - $searchcontexts1 - rc.contextid=$siteinstance->id - $capsearch - GROUP BY - rc.capability, c1.id, c1.contextlevel * 100 - HAVING - SUM(rc.permission) != 0 - - UNION ALL - - SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel, - SUM(rc.permission) AS sum - FROM - {$CFG->prefix}role_assignments ra INNER JOIN - {$CFG->prefix}role_capabilities rc on ra.roleid = rc.roleid INNER JOIN - {$CFG->prefix}context c1 on ra.contextid = c1.id INNER JOIN - {$CFG->prefix}context c2 on rc.contextid = c2.id INNER JOIN - {$CFG->prefix}context_rel cr on cr.c1 = c2.id AND cr.c2 = c1.id - WHERE - ra.userid=$userid AND - $searchcontexts1 - rc.contextid != $siteinstance->id - $capsearch - GROUP BY - rc.capability, c1.id, c2.id, c1.contextlevel * 100 + c2.contextlevel - HAVING - SUM(rc.permission) != 0 - ORDER BY - aggrlevel ASC"; - - if (!$rs = get_recordset_sql($SQL1)) { - error("Query failed in load_user_capability."); - } - - if ($rs && $rs->RecordCount() > 0) { - while ($caprec = rs_fetch_next_record($rs)) { - $array = (array)$caprec; - $temprecord = new object; - - foreach ($array as $key=>$val) { - if ($key == 'aggrlevel') { - $temprecord->contextlevel = $val; - } else { - $temprecord->{$key} = $val; - } - } - $capabilities[] = $temprecord; - } - rs_close($rs); - } - - // SQL for overrides - // this is take out because we have no way of making sure c1 is indeed related to c2 (parent) - // if we do not group by sum, it is possible to have multiple records of rc.capability, c1.id, c2.id, tuple having - // different values, we can maually sum it when we go through the list - - /* - - $SQL2 = "SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel, - rc.permission AS sum - FROM - {$CFG->prefix}role_assignments ra, - {$CFG->prefix}role_capabilities rc, - {$CFG->prefix}context c1, - {$CFG->prefix}context c2 - WHERE - ra.contextid=c1.id AND - ra.roleid=rc.roleid AND - ra.userid=$userid AND - rc.contextid=c2.id AND - $searchcontexts1 - rc.contextid != $siteinstance->id - $capsearch - - GROUP BY - rc.capability, (c1.contextlevel * 100 + c2.contextlevel), c1.id, c2.id, rc.permission - ORDER BY - aggrlevel ASC - ";*/ - -/* - if (!$rs = get_recordset_sql($SQL2)) { - error("Query failed in load_user_capability."); - } - - if ($rs && $rs->RecordCount() > 0) { - while ($caprec = rs_fetch_next_record($rs)) { - $array = (array)$caprec; - $temprecord = new object; - - foreach ($array as $key=>$val) { - if ($key == 'aggrlevel') { - $temprecord->contextlevel = $val; - } else { - $temprecord->{$key} = $val; - } - } - // for overrides, we have to make sure that context2 is a child of context1 - // otherwise the combination makes no sense - //if (is_parent_context($temprecord->id1, $temprecord->id2)) { - $capabilities[] = $temprecord; - //} // only write if relevant - } - rs_close($rs); - } - - // this step sorts capabilities according to the contextlevel - // it is very important because the order matters when we - // go through each capabilities later. (i.e. higher level contextlevel - // will override lower contextlevel settings - usort($capabilities, 'roles_context_cmp'); -*/ - /* so up to this point we should have somethign like this - * $capabilities[1] ->contextlevel = 1000 - ->module = 0 // changed from SITEID in 1.8 (??) - ->capability = do_anything - ->id = 1 (id is the context id) - ->sum = 0 - - * $capabilities[2] ->contextlevel = 1000 - ->module = 0 // changed from SITEID in 1.8 (??) - ->capability = post_messages - ->id = 1 - ->sum = -9000 - - * $capabilittes[3] ->contextlevel = 3000 - ->module = course - ->capability = view_course_activities - ->id = 25 - ->sum = 1 - - * $capabilittes[4] ->contextlevel = 3000 - ->module = course - ->capability = view_course_activities - ->id = 26 - ->sum = 0 (this is another course) - - * $capabilities[5] ->contextlevel = 3050 - ->module = course - ->capability = view_course_activities - ->id = 25 (override in course 25) - ->sum = -1 - * .... - * now we proceed to write the session array, going from top to bottom - * at anypoint, we need to go up and check parent to look for prohibit - */ - // print_object($capabilities); - - /* This is where we write to the actualy capabilities array - * what we need to do from here on is - * going down the array from lowest level to highest level - * 1) recursively check for prohibit, - * if any, we write prohibit - * else, we write the value - * 2) at an override level, we overwrite current level - * if it's not set to prohibit already, and if different - * ........ that should be it ........ - */ - - // This is the flag used for detecting the current context level. Since we are going through - // the array in ascending order of context level. For normal capabilities, there should only - // be 1 value per (capability, contextlevel, context), because they are already summed. But, - // for overrides, since we are processing them separate, we need to sum the relevcant entries. - // We set this flag when we hit a new level. - // If the flag is already set, we keep adding (summing), otherwise, we just override previous - // settings (from lower level contexts) - $capflags = array(); // (contextid, contextlevel, capability) - $usercap = array(); // for other user's capabilities - foreach ($capabilities as $capability) { - - if (!$context = get_context_instance_by_id($capability->id2)) { - continue; // incorrect stale context - } - - if (!empty($otheruserid)) { // we are pulling out other user's capabilities, do not write to session - - if (capability_prohibits($capability->capability, $context, $capability->sum, $usercap)) { - $usercap[$capability->id2][$capability->capability] = CAP_PROHIBIT; - continue; - } - if (isset($usercap[$capability->id2][$capability->capability])) { // use isset because it can be sum 0 - if (!empty($capflags[$capability->id2][$capability->contextlevel][$capability->capability])) { - $usercap[$capability->id2][$capability->capability] += $capability->sum; - } else { // else we override, and update flag - $usercap[$capability->id2][$capability->capability] = $capability->sum; - $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true; - } - } else { - $usercap[$capability->id2][$capability->capability] = $capability->sum; - $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true; - } - - } else { - - if (capability_prohibits($capability->capability, $context, $capability->sum)) { // if any parent or parent's parent is set to prohibit - $USER->capabilities[$capability->id2][$capability->capability] = CAP_PROHIBIT; - continue; - } - - // if no parental prohibit set - // just write to session, i am not sure this is correct yet - // since 3050 shows up after 3000, and 3070 shows up after 3050, - // it should be ok just to overwrite like this, provided that there's no - // parental prohibits - // we need to write even if it's 0, because it could be an inherit override - if (isset($USER->capabilities[$capability->id2][$capability->capability])) { - if (!empty($capflags[$capability->id2][$capability->contextlevel][$capability->capability])) { - $USER->capabilities[$capability->id2][$capability->capability] += $capability->sum; - } else { // else we override, and update flag - $USER->capabilities[$capability->id2][$capability->capability] = $capability->sum; - $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true; - } - } else { - $USER->capabilities[$capability->id2][$capability->capability] = $capability->sum; - $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true; - } - } - } - - // now we don't care about the huge array anymore, we can dispose it. - unset($capabilities); - unset($capflags); - - if (!empty($otheruserid)) { - return $usercap; // return the array - } -} - /** * It will return a nested array showing role assignments * all relevant role capabilities for the user at @@ -2226,139 +1483,6 @@ function check_enrolment_plugins(&$user) { unset($inprogress[$user->id]); // Unset the flag } - -/** - * This is a recursive function that checks whether the capability in this - * context, or the parent capabilities are set to prohibit. - * - * At this point, we can probably just use the values already set in the - * session variable, since we are going down the level. Any prohit set in - * parents would already reflect in the session. - * - * @param $capability - capability name - * @param $sum - sum of all capabilities values - * @param $context - the context object - * @param $array - when loading another user caps, their caps are not stored in session but an array - */ -function capability_prohibits($capability, $context, $sum='', $array='') { - global $USER; - - // caching, mainly to save unnecessary sqls - static $prohibits; //[capability][contextid] - if (isset($prohibits[$capability][$context->id])) { - return $prohibits[$capability][$context->id]; - } - - if (empty($context->id)) { - $prohibits[$capability][$context->id] = false; - return false; - } - - if (empty($capability)) { - $prohibits[$capability][$context->id] = false; - return false; - } - - if ($sum < (CAP_PROHIBIT/2)) { - // If this capability is set to prohibit. - $prohibits[$capability][$context->id] = true; - return true; - } - - if (!empty($array)) { - if (isset($array[$context->id][$capability]) - && $array[$context->id][$capability] < (CAP_PROHIBIT/2)) { - $prohibits[$capability][$context->id] = true; - return true; - } - } else { - // Else if set in session. - if (isset($USER->capabilities[$context->id][$capability]) - && $USER->capabilities[$context->id][$capability] < (CAP_PROHIBIT/2)) { - $prohibits[$capability][$context->id] = true; - return true; - } - } - switch ($context->contextlevel) { - - case CONTEXT_SYSTEM: - // By now it's a definite an inherit. - return 0; - break; - - case CONTEXT_PERSONAL: - $parent = get_context_instance(CONTEXT_SYSTEM); - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - case CONTEXT_USER: - $parent = get_context_instance(CONTEXT_SYSTEM); - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - case CONTEXT_COURSECAT: - case CONTEXT_COURSE: - $parents = get_parent_cats($context); // cached internally - // no workaround for recursion now - it needs some more work and maybe fixing - - if (empty($parents)) { - // system context - this is either top category or frontpage course - $parent = get_context_instance(CONTEXT_SYSTEM); - } else { - // parent context - recursion - $parentid = array_pop($parents); - $parent = get_context_instance_by_id($parentid); - } - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - case CONTEXT_GROUP: - // 1 to 1 to course. - if (!$courseid = get_field('groups', 'courseid', 'id', $context->instanceid)) { - $prohibits[$capability][$context->id] = false; - return false; - } - $parent = get_context_instance(CONTEXT_COURSE, $courseid); - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - case CONTEXT_MODULE: - // 1 to 1 to course. - if (!$cm = get_record('course_modules','id',$context->instanceid)) { - $prohibits[$capability][$context->id] = false; - return false; - } - $parent = get_context_instance(CONTEXT_COURSE, $cm->course); - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - case CONTEXT_BLOCK: - // not necessarily 1 to 1 to course. - if (!$block = get_record('block_instance','id',$context->instanceid)) { - $prohibits[$capability][$context->id] = false; - return false; - } - if ($block->pagetype == 'course-view') { - $parent = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check - } else { - $parent = get_context_instance(CONTEXT_SYSTEM); - } - $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); - return $prohibits[$capability][$context->id]; - break; - - default: - print_error('unknowncontext'); - return false; - } -} - - /** * A print form function. This should either grab all the capabilities from * files or a central table for that particular module instance, then present