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
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