Example #1
0
/**
 * Add to the access ctrl array the data needed by a user for a given course.
 *
 * This function injects all course related access info into the accessdata array.
 *
 * @private
 * @param int $userid the id of the user
 * @param context_course $coursecontext course context
 * @param array $accessdata accessdata array (modified)
 * @return void modifies $accessdata parameter
 */
function load_course_context($userid, context_course $coursecontext, &$accessdata)
{
    global $DB, $CFG, $ACCESSLIB_PRIVATE;
    if (empty($coursecontext->path)) {
        // weird, this should not happen
        return;
    }
    if (isset($accessdata['loaded'][$coursecontext->instanceid])) {
        // already loaded, great!
        return;
    }
    $roles = array();
    if (empty($userid)) {
        if (!empty($CFG->notloggedinroleid)) {
            $roles[$CFG->notloggedinroleid] = $CFG->notloggedinroleid;
        }
    } else {
        if (isguestuser($userid)) {
            if ($guestrole = get_guest_role()) {
                $roles[$guestrole->id] = $guestrole->id;
            }
        } else {
            // Interesting role assignments at, above and below the course context
            list($parentsaself, $params) = $DB->get_in_or_equal($coursecontext->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'pc_');
            $params['userid'] = $userid;
            $params['children'] = $coursecontext->path . "/%";
            $sql = "SELECT ra.*, ctx.path\n                  FROM {role_assignments} ra\n                  JOIN {context} ctx ON ra.contextid = ctx.id\n                 WHERE ra.userid = :userid AND (ctx.id {$parentsaself} OR ctx.path LIKE :children)";
            $rs = $DB->get_recordset_sql($sql, $params);
            // add missing role definitions
            foreach ($rs as $ra) {
                $accessdata['ra'][$ra->path][(int) $ra->roleid] = (int) $ra->roleid;
                $roles[$ra->roleid] = $ra->roleid;
            }
            $rs->close();
            // add the "default frontpage role" when on the frontpage
            if (!empty($CFG->defaultfrontpageroleid)) {
                $frontpagecontext = context_course::instance(get_site()->id);
                if ($frontpagecontext->id == $coursecontext->id) {
                    $roles[$CFG->defaultfrontpageroleid] = $CFG->defaultfrontpageroleid;
                }
            }
            // do not forget the default role
            if (!empty($CFG->defaultuserroleid)) {
                $roles[$CFG->defaultuserroleid] = $CFG->defaultuserroleid;
            }
        }
    }
    if (!$roles) {
        // weird, default roles must be missing...
        $accessdata['loaded'][$coursecontext->instanceid] = 1;
        return;
    }
    // now get overrides of interesting roles in all interesting contexts (this course + children + parents)
    $params = array('c' => $coursecontext->id);
    list($parentsaself, $rparams) = $DB->get_in_or_equal($coursecontext->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'pc_');
    $params = array_merge($params, $rparams);
    list($roleids, $rparams) = $DB->get_in_or_equal($roles, SQL_PARAMS_NAMED, 'r_');
    $params = array_merge($params, $rparams);
    $sql = "SELECT ctx.path, rc.roleid, rc.capability, rc.permission\n                 FROM {role_capabilities} rc\n                 JOIN {context} ctx\n                      ON (ctx.id = rc.contextid)\n                 JOIN {context} cctx\n                      ON (cctx.id = :c\n                          AND (ctx.id {$parentsaself} OR ctx.path LIKE " . $DB->sql_concat('cctx.path', "'/%'") . "))\n                WHERE rc.roleid {$roleids}\n             ORDER BY rc.capability";
    // fixed capability order is necessary for rdef dedupe
    $rs = $DB->get_recordset_sql($sql, $params);
    $newrdefs = array();
    foreach ($rs as $rd) {
        $k = $rd->path . ':' . $rd->roleid;
        if (isset($accessdata['rdef'][$k])) {
            continue;
        }
        $newrdefs[$k][$rd->capability] = (int) $rd->permission;
    }
    $rs->close();
    // share new role definitions
    foreach ($newrdefs as $k => $unused) {
        if (!isset($ACCESSLIB_PRIVATE->rolepermissions[$k])) {
            $ACCESSLIB_PRIVATE->rolepermissions[$k] = $newrdefs[$k];
        }
        $accessdata['rdef_count']++;
        $accessdata['rdef'][$k] =& $ACCESSLIB_PRIVATE->rolepermissions[$k];
    }
    $accessdata['loaded'][$coursecontext->instanceid] = 1;
    // we want to deduplicate the USER->access from time to time, this looks like a good place,
    // because we have to do it before the end of session
    dedupe_user_access();
}