/** * Prepare list of roles for display, apply aliases and localise default role names. * * @param array $roleoptions array roleid => roleobject (with optional coursealias), strings are accepted for backwards compatibility only * @param context $context the context, null means system context * @param int $rolenamedisplay * @param bool $returnmenu null means keep the same format as $roleoptions, true means id=>localname, false means id=>rolerecord * @return array Array of context-specific role names, or role objects with a ->localname field added. */ function role_fix_names($roleoptions, context $context = null, $rolenamedisplay = ROLENAME_ALIAS, $returnmenu = null) { global $DB; if (empty($roleoptions)) { return array(); } if (!$context or !$coursecontext = $context->get_course_context(false)) { $coursecontext = null; } // We usually need all role columns... $first = reset($roleoptions); if ($returnmenu === null) { $returnmenu = !is_object($first); } if (!is_object($first) or !property_exists($first, 'shortname')) { $allroles = get_all_roles($context); foreach ($roleoptions as $rid => $unused) { $roleoptions[$rid] = $allroles[$rid]; } } // Inject coursealias if necessary. if ($coursecontext and ($rolenamedisplay == ROLENAME_ALIAS_RAW or $rolenamedisplay == ROLENAME_ALIAS or $rolenamedisplay == ROLENAME_BOTH)) { $first = reset($roleoptions); if (!property_exists($first, 'coursealias')) { $aliasnames = $DB->get_records('role_names', array('contextid'=>$coursecontext->id)); foreach ($aliasnames as $alias) { if (isset($roleoptions[$alias->roleid])) { $roleoptions[$alias->roleid]->coursealias = $alias->name; } } } } // Add localname property. foreach ($roleoptions as $rid => $role) { $roleoptions[$rid]->localname = role_get_name($role, $coursecontext, $rolenamedisplay); } if (!$returnmenu) { return $roleoptions; } $menu = array(); foreach ($roleoptions as $rid => $role) { $menu[$rid] = $role->localname; } return $menu; }
/** * Returns current course id or null if outside of course based on context parameter. * * @deprecated since 2.2, use $context->get_course_context instead * @param context $context * @return int|bool related course id or false */ function get_courseid_from_context(context $context) { if ($coursecontext = $context->get_course_context(false)) { return $coursecontext->instanceid; } else { return false; } }
/** * Return a list of page types * @param string $pagetype current page type * @param context $parentcontext Block's parent context * @param context $currentcontext Current context of block * @return array array of page types */ function course_page_type_list($pagetype, $parentcontext, $currentcontext) { if ($pagetype === 'course-index' || $pagetype === 'course-index-category') { // For courses and categories browsing pages (/course/index.php) add option to show on ANY category page $pagetypes = array('*' => get_string('page-x', 'pagetype'), 'course-index-*' => get_string('page-course-index-x', 'pagetype')); } else { if ($currentcontext && (!($coursecontext = $currentcontext->get_course_context(false)) || $coursecontext->instanceid == SITEID)) { // We know for sure that despite pagetype starts with 'course-' this is not a page in course context (i.e. /course/search.php, etc.) $pagetypes = array('*' => get_string('page-x', 'pagetype')); } else { // Otherwise consider it a page inside a course even if $currentcontext is null $pagetypes = array('*' => get_string('page-x', 'pagetype'), 'course-*' => get_string('page-course-x', 'pagetype'), 'course-view-*' => get_string('page-course-view-x', 'pagetype')); } } return $pagetypes; }
/** * Returns current course id or false if outside of course based on context parameter. * * @see context::get_course_context() * @deprecated since 2.2 * @param context $context * @return int|bool related course id or false */ function get_courseid_from_context(context $context) { debugging('get_courseid_from_context() is deprecated, please use $context->get_course_context(false) instead.', DEBUG_DEVELOPER); if ($coursecontext = $context->get_course_context(false)) { return $coursecontext->instanceid; } else { return false; } }
/** * Given context and array of users, returns array of user ids whose enrolment status is suspended, * or enrolment has expired or not started. * * @param context $context context in which user enrolment is checked. * @param bool $usecache Enable or disable (default) the request cache * @return array list of suspended user id's. */ function get_suspended_userids(context $context, $usecache = false) { global $DB; if ($usecache) { $cache = cache::make('core', 'suspended_userids'); $susers = $cache->get($context->id); if ($susers !== false) { return $susers; } } $coursecontext = $context->get_course_context(); $susers = array(); // Front page users are always enrolled, so suspended list is empty. if ($coursecontext->instanceid != SITEID) { list($sql, $params) = get_enrolled_sql($context, null, null, false, true); $susers = $DB->get_fieldset_sql($sql, $params); $susers = array_combine($susers, $susers); } // Cache results for the remainder of this request. if ($usecache) { $cache->set($context->id, $susers); } return $susers; }
/** * Returns array with sql joins and parameters returning all ids * of users enrolled into course. * * This function is using 'ej[0-9]+_' prefix for table names and parameters. * * @throws coding_exception * * @param context $context * @param string $useridcolumn User id column used the calling query, e.g. u.id * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param bool $onlysuspended inverse of onlyactive, consider only suspended enrolments * @return \core\dml\sql_join Contains joins, wheres, params */ function get_enrolled_join(context $context, $useridcolumn, $onlyactive = false, $onlysuspended = false) { // Use unique prefix just in case somebody makes some SQL magic with the result. static $i = 0; $i++; $prefix = 'ej' . $i . '_'; // First find the course context. $coursecontext = $context->get_course_context(); $isfrontpage = $coursecontext->instanceid == SITEID; if ($onlyactive && $onlysuspended) { throw new coding_exception("Both onlyactive and onlysuspended are set, this is probably not what you want!"); } if ($isfrontpage && $onlysuspended) { throw new coding_exception("onlysuspended is not supported on frontpage; please add your own early-exit!"); } $joins = array(); $wheres = array(); $params = array(); $wheres[] = "1 = 1"; // Prevent broken where clauses later on. // Note all users are "enrolled" on the frontpage, but for others... if (!$isfrontpage) { $where1 = "{$prefix}ue.status = :{$prefix}active AND {$prefix}e.status = :{$prefix}enabled"; $where2 = "{$prefix}ue.timestart < :{$prefix}now1 AND ({$prefix}ue.timeend = 0 OR {$prefix}ue.timeend > :{$prefix}now2)"; $ejoin = "JOIN {enrol} {$prefix}e ON ({$prefix}e.id = {$prefix}ue.enrolid AND {$prefix}e.courseid = :{$prefix}courseid)"; $params[$prefix . 'courseid'] = $coursecontext->instanceid; if (!$onlysuspended) { $joins[] = "JOIN {user_enrolments} {$prefix}ue ON {$prefix}ue.userid = {$useridcolumn}"; $joins[] = $ejoin; if ($onlyactive) { $wheres[] = "{$where1} AND {$where2}"; } } else { // Suspended only where there is enrolment but ALL are suspended. // Consider multiple enrols where one is not suspended or plain role_assign. $enrolselect = "SELECT DISTINCT {$prefix}ue.userid FROM {user_enrolments} {$prefix}ue {$ejoin} WHERE {$where1} AND {$where2}"; $joins[] = "JOIN {user_enrolments} {$prefix}ue1 ON {$prefix}ue1.userid = {$useridcolumn}"; $joins[] = "JOIN {enrol} {$prefix}e1 ON ({$prefix}e1.id = {$prefix}ue1.enrolid\n AND {$prefix}e1.courseid = :{$prefix}_e1_courseid)"; $params["{$prefix}_e1_courseid"] = $coursecontext->instanceid; $wheres[] = "{$useridcolumn} NOT IN ({$enrolselect})"; } if ($onlyactive || $onlysuspended) { $now = round(time(), -2); // Rounding helps caching in DB. $params = array_merge($params, array($prefix . 'enabled' => ENROL_INSTANCE_ENABLED, $prefix . 'active' => ENROL_USER_ACTIVE, $prefix . 'now1' => $now, $prefix . 'now2' => $now)); } } $joins = implode("\n", $joins); $wheres = implode(" AND ", $wheres); return new \core\dml\sql_join($joins, $wheres, $params); }
/** * Gets sql joins for finding users with a capability in the given context * * @param context $context * @param string $capability * @param string $useridcolumn e.g. u.id * @return \core\dml\sql_join Contains joins, wheres, params */ function get_with_capability_join(context $context, $capability, $useridcolumn) { global $DB, $CFG; // Use unique prefix just in case somebody makes some SQL magic with the result. static $i = 0; $i++; $prefix = 'eu' . $i . '_'; // First find the course context. $coursecontext = $context->get_course_context(); $isfrontpage = $coursecontext->instanceid == SITEID; $joins = array(); $wheres = array(); $params = array(); list($contextids, $contextpaths) = get_context_info_list($context); list($incontexts, $cparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED, 'ctx'); $cparams['cap'] = $capability; $defs = array(); $sql = "SELECT rc.id, rc.roleid, rc.permission, ctx.path\n FROM {role_capabilities} rc\n JOIN {context} ctx on rc.contextid = ctx.id\n WHERE rc.contextid {$incontexts} AND rc.capability = :cap"; $rcs = $DB->get_records_sql($sql, $cparams); foreach ($rcs as $rc) { $defs[$rc->path][$rc->roleid] = $rc->permission; } $access = array(); if (!empty($defs)) { foreach ($contextpaths as $path) { if (empty($defs[$path])) { continue; } foreach ($defs[$path] as $roleid => $perm) { if ($perm == CAP_PROHIBIT) { $access[$roleid] = CAP_PROHIBIT; continue; } if (!isset($access[$roleid])) { $access[$roleid] = (int) $perm; } } } } unset($defs); // Make lists of roles that are needed and prohibited. $needed = array(); // One of these is enough. $prohibited = array(); // Must not have any of these. foreach ($access as $roleid => $perm) { if ($perm == CAP_PROHIBIT) { unset($needed[$roleid]); $prohibited[$roleid] = true; } else { if ($perm == CAP_ALLOW and empty($prohibited[$roleid])) { $needed[$roleid] = true; } } } $defaultuserroleid = isset($CFG->defaultuserroleid) ? $CFG->defaultuserroleid : 0; $defaultfrontpageroleid = isset($CFG->defaultfrontpageroleid) ? $CFG->defaultfrontpageroleid : 0; $nobody = false; if ($isfrontpage) { if (!empty($prohibited[$defaultuserroleid]) or !empty($prohibited[$defaultfrontpageroleid])) { $nobody = true; } else { if (!empty($needed[$defaultuserroleid]) or !empty($needed[$defaultfrontpageroleid])) { // Everybody not having prohibit has the capability. $needed = array(); } else { if (empty($needed)) { $nobody = true; } } } } else { if (!empty($prohibited[$defaultuserroleid])) { $nobody = true; } else { if (!empty($needed[$defaultuserroleid])) { // Everybody not having prohibit has the capability. $needed = array(); } else { if (empty($needed)) { $nobody = true; } } } } if ($nobody) { // Nobody can match so return some SQL that does not return any results. $wheres[] = "1 = 2"; } else { if ($needed) { $ctxids = implode(',', $contextids); $roleids = implode(',', array_keys($needed)); $joins[] = "JOIN {role_assignments} {$prefix}ra3\n ON ({$prefix}ra3.userid = {$useridcolumn}\n AND {$prefix}ra3.roleid IN ({$roleids})\n AND {$prefix}ra3.contextid IN ({$ctxids}))"; } if ($prohibited) { $ctxids = implode(',', $contextids); $roleids = implode(',', array_keys($prohibited)); $joins[] = "LEFT JOIN {role_assignments} {$prefix}ra4\n ON ({$prefix}ra4.userid = {$useridcolumn}\n AND {$prefix}ra4.roleid IN ({$roleids})\n AND {$prefix}ra4.contextid IN ({$ctxids}))"; $wheres[] = "{$prefix}ra4.id IS NULL"; } } $wheres[] = "{$useridcolumn} <> :{$prefix}guestid"; $params["{$prefix}guestid"] = $CFG->siteguest; $joins = implode("\n", $joins); $wheres = "(" . implode(" AND ", $wheres) . ")"; return new \core\dml\sql_join($joins, $wheres, $params); }