/** * Get accessdata for a given user. * * @private * @param int $userid * @param bool $preloadonly true means do not return access array * @return array accessdata */ function get_user_accessdata($userid, $preloadonly = false) { global $CFG, $ACCESSLIB_PRIVATE, $USER; if (!empty($USER->acces['rdef']) and empty($ACCESSLIB_PRIVATE->rolepermissions)) { // share rdef from USER session with rolepermissions cache in order to conserve memory foreach ($USER->acces['rdef'] as $k => $v) { $ACCESSLIB_PRIVATE->rolepermissions[$k] =& $USER->acces['rdef'][$k]; } $ACCESSLIB_PRIVATE->accessdatabyuser[$USER->id] = $USER->acces; } if (!isset($ACCESSLIB_PRIVATE->accessdatabyuser[$userid])) { if (empty($userid)) { if (!empty($CFG->notloggedinroleid)) { $accessdata = get_role_access($CFG->notloggedinroleid); } else { // weird return get_empty_accessdata(); } } else { if (isguestuser($userid)) { if ($guestrole = get_guest_role()) { $accessdata = get_role_access($guestrole->id); } else { //weird return get_empty_accessdata(); } } else { $accessdata = get_user_access_sitewide($userid); // includes default role and frontpage role } } $ACCESSLIB_PRIVATE->accessdatabyuser[$userid] = $accessdata; } if ($preloadonly) { return; } else { return $ACCESSLIB_PRIVATE->accessdatabyuser[$userid]; } }
/** * A convenience function to completely load all the capabilities * for the current user. This is what gets called from complete_user_login() * for example. Call it only _after_ you've setup $USER and called * check_enrolment_plugins(); * */ function load_all_capabilities() { global $USER, $CFG, $ACCESSLIB_PRIVATE; // roles not installed yet - we are in the middle of installation if (empty($CFG->rolesactive)) { return; } $base = '/' . SYSCONTEXTID; if (isguestuser()) { $guest = get_guest_role(); // Load the rdefs $USER->access = get_role_access($guest->id); // Put the ghost enrolment in place... $USER->access['ra'][$base] = array($guest->id); } else { if (isloggedin()) { $accessdata = get_user_access_sitewide($USER->id); // // provide "default role" & set 'dr' // if (!empty($CFG->defaultuserroleid)) { $accessdata = get_role_access($CFG->defaultuserroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array($CFG->defaultuserroleid); } else { array_push($accessdata['ra'][$base], $CFG->defaultuserroleid); } $accessdata['dr'] = $CFG->defaultuserroleid; } $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID); // // provide "default frontpage role" // if (!empty($CFG->defaultfrontpageroleid)) { $base = '/' . SYSCONTEXTID . '/' . $frontpagecontext->id; $accessdata = get_default_frontpage_role_access($CFG->defaultfrontpageroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array($CFG->defaultfrontpageroleid); } else { array_push($accessdata['ra'][$base], $CFG->defaultfrontpageroleid); } } $USER->access = $accessdata; } else { if (!empty($CFG->notloggedinroleid)) { $USER->access = get_role_access($CFG->notloggedinroleid); $USER->access['ra'][$base] = array($CFG->notloggedinroleid); } } } // Timestamp to read dirty context timestamps later $USER->access['time'] = time(); $ACCESSLIB_PRIVATE->dirtycontexts = array(); // Clear to force a refresh unset($USER->mycourses); }
/** * true or false function to see if user can roll dates on restore (any course is enough) * @return bool */ function restore_user_can_roll_dates() { global $USER; // if user has moodle/restore:rolldates capability at system or any course cat return true if (has_capability('moodle/restore:rolldates', get_context_instance(CONTEXT_SYSTEM))) { return true; } // Non-cached - get accessinfo if (isset($USER->access)) { $accessinfo = $USER->access; } else { $accessinfo = get_user_access_sitewide($USER->id); } $courses = get_user_courses_bycap($USER->id, 'moodle/restore:rolldates', $accessinfo, true); return !empty($courses); }
/** * Convenience function - lists courses that a user has access to view. * * For admins and others with access to "every" course in the system, we should * try to get courses with explicit RAs. * * NOTE: this function is heavily geared towards the perspective of the user * passed in $userid. So it will hide courses that the user cannot see * (for any reason) even if called from cron or from another $USER's * perspective. * * If you really want to know what courses are assigned to the user, * without any hiding or scheming, call the lower-level * get_user_courses_bycap(). * * * Notes inherited from get_user_courses_bycap(): * * - $fields is an array of fieldnames to ADD * so name the fields you really need, which will * be added and uniq'd * * - the course records have $c->context which is a fully * valid context object. Saves you a query per course! * * @uses $CFG,$USER * @param int $userid The user of interest * @param string $sort the sortorder in the course table * @param array $fields - names of _additional_ fields to return (also accepts a string) * @param bool $doanything True if using the doanything flag * @param int $limit Maximum number of records to return, or 0 for unlimited * @return array {@link $COURSE} of course objects */ function get_my_courses($userid, $sort = 'visible DESC,sortorder ASC', $fields = NULL, $doanything = false, $limit = 0) { global $CFG, $USER, $DB; // Guest's do not have any courses $sitecontext = get_context_instance(CONTEXT_SYSTEM); if (has_capability('moodle/legacy:guest', $sitecontext, $userid, false)) { return array(); } $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber', 'guest', 'startdate', 'visible', 'newsitems', 'cost', 'enrol', 'groupmode', 'groupmodeforce'); if (!is_null($fields) && is_string($fields)) { if (empty($fields)) { $fields = $basefields; } else { // turn the fields from a string to an array that // get_user_courses_bycap() will like... $fields = explode(',', $fields); $fields = array_map('trim', $fields); $fields = array_unique(array_merge($basefields, $fields)); } } elseif (is_array($fields)) { $fields = array_unique(array_merge($basefields, $fields)); } else { $fields = $basefields; } $orderby = ''; $sort = trim($sort); if (!empty($sort)) { $rawsorts = explode(',', $sort); $sorts = array(); foreach ($rawsorts as $rawsort) { $rawsort = trim($rawsort); if (strpos($rawsort, 'c.') === 0) { $rawsort = substr($rawsort, 2); } $sorts[] = trim($rawsort); } $sort = 'c.' . implode(',c.', $sorts); $orderby = "ORDER BY {$sort}"; } // // Logged-in user - Check cached courses // // NOTE! it's a _string_ because // - it's all we'll ever use // - it serialises much more compact than an array // this a big concern here - cost of serialise // and unserialise gets huge as the session grows // // If the courses are too many - it won't be set // for large numbers of courses, caching in the session // has marginal benefits (costs too much, not // worthwhile...) and we may hit SQL parser limits // because we use IN() // if ($userid === $USER->id) { if (isset($USER->loginascontext) && $USER->loginascontext->contextlevel == CONTEXT_COURSE) { // list _only_ this course // anything else is asking for trouble... $courseids = $USER->loginascontext->instanceid; } elseif (isset($USER->mycourses) && is_string($USER->mycourses)) { if ($USER->mycourses === '') { // empty str means: user has no courses // ... so do the easy thing... return array(); } else { $courseids = $USER->mycourses; } } if (isset($courseids)) { // The data massaging here MUST be kept in sync with // get_user_courses_bycap() so we return // the same... // (but here we don't need to check has_cap) $coursefields = 'c.' . join(',c.', $fields); $sql = "SELECT {$coursefields},\n ctx.id AS ctxid, ctx.path AS ctxpath,\n ctx.depth as ctxdepth, ctx.contextlevel AS ctxlevel,\n cc.path AS categorypath\n FROM {course} c\n JOIN {course_categories} cc ON c.category=cc.id\n JOIN {context} ctx\n ON (c.id=ctx.instanceid AND ctx.contextlevel=" . CONTEXT_COURSE . ")\n WHERE c.id IN ({$courseids})\n {$orderby}"; $rs = $DB->get_recordset_sql($sql); $courses = array(); $cc = 0; // keep count foreach ($rs as $c) { // build the context obj $c = make_context_subobj($c); $courses[$c->id] = $c; if ($limit > 0 && $cc++ > $limit) { break; } } $rs->close(); return $courses; } } // Non-cached - get accessinfo if ($userid === $USER->id && isset($USER->access)) { $accessinfo = $USER->access; } else { $accessinfo = get_user_access_sitewide($userid); } $courses = get_user_courses_bycap($userid, 'moodle/course:view', $accessinfo, $doanything, $sort, $fields, $limit); $cats = NULL; // If we have to walk category visibility // to eval course visibility, get the categories if (empty($CFG->allowvisiblecoursesinhiddencategories)) { $sql = "SELECT cc.id, cc.path, cc.visible,\n ctx.id AS ctxid, ctx.path AS ctxpath,\n ctx.depth as ctxdepth, ctx.contextlevel AS ctxlevel\n FROM {course_categories} cc\n JOIN {context} ctx ON (cc.id = ctx.instanceid)\n WHERE ctx.contextlevel = " . CONTEXT_COURSECAT . "\n ORDER BY cc.id"; $rs = $DB->get_recordset_sql($sql); // Using a temporary array instead of $cats here, to avoid a "true" result when isnull($cats) further down $categories = array(); foreach ($rs as $course_cat) { // build the context obj $course_cat = make_context_subobj($course_cat); $categories[$course_cat->id] = $course_cat; } $rs->close(); if (!empty($categories)) { $cats = $categories; } unset($course_cat); } // // Strangely, get_my_courses() is expected to return the // array keyed on id, which messes up the sorting // So do that, and also cache the ids in the session if appropriate // $kcourses = array(); $courses_count = count($courses); $cacheids = NULL; $vcatpaths = array(); if ($userid === $USER->id && $courses_count < 500) { $cacheids = array(); } for ($n = 0; $n < $courses_count; $n++) { // // Check whether $USER (not $userid) can _actually_ see them // Easy if $CFG->allowvisiblecoursesinhiddencategories // is set, and we don't have to care about categories. // Lots of work otherwise... (all in mem though!) // $cansee = false; if (is_null($cats)) { // easy rules! if ($courses[$n]->visible == true) { $cansee = true; } elseif (has_capability('moodle/course:viewhiddencourses', $courses[$n]->context, $USER->id)) { $cansee = true; } } else { // // Is the cat visible? // we have to assume it _is_ visible // so we can shortcut when we find a hidden one // $viscat = true; $cpath = $courses[$n]->categorypath; if (isset($vcatpaths[$cpath])) { $viscat = $vcatpaths[$cpath]; } else { $cpath = substr($cpath, 1); // kill leading slash $cpath = explode('/', $cpath); $ccct = count($cpath); for ($m = 0; $m < $ccct; $m++) { $ccid = $cpath[$m]; if ($cats[$ccid]->visible == false) { $viscat = false; break; } } $vcatpaths[$courses[$n]->categorypath] = $viscat; } // // Perhaps it's actually visible to $USER // check moodle/category:viewhiddencategories // // The name isn't obvious, but the description says // "See hidden categories" so the user shall see... // But also check if the allowvisiblecoursesinhiddencategories setting is true, and check for course visibility if ($viscat === false) { $catctx = $cats[$courses[$n]->category]->context; if (has_capability('moodle/category:viewhiddencategories', $catctx, $USER->id)) { $vcatpaths[$courses[$n]->categorypath] = true; $viscat = true; } elseif ($CFG->allowvisiblecoursesinhiddencategories && $courses[$n]->visible == true) { $viscat = true; } } // // Decision matrix // if ($viscat === true) { if ($courses[$n]->visible == true) { $cansee = true; } elseif (has_capability('moodle/course:viewhiddencourses', $courses[$n]->context, $USER->id)) { $cansee = true; } } } if ($cansee === true) { $kcourses[$courses[$n]->id] = $courses[$n]; if (is_array($cacheids)) { $cacheids[] = $courses[$n]->id; } } } if (is_array($cacheids)) { // Only happens // - for the logged in user // - below the threshold (500) // empty string is _valid_ $USER->mycourses = join(',', $cacheids); } elseif ($userid === $USER->id && isset($USER->mycourses)) { // cheap sanity check unset($USER->mycourses); } return $kcourses; }
/** * Function used to return a list of users where the given user has a particular capability. * * This is used e.g. to find all the users where someone is able to manage their learning plans, * it also would be useful for mentees etc. * * @param string $capability - The capability string we are filtering for. If '' is passed, * an always matching filter is returned. * @param int $userid - The user id we are using for the access checks. Defaults to current user. * @param int $type - The type of named params to return (passed to $DB->get_in_or_equal). * @param string $prefix - The type prefix for the db table (passed to $DB->get_in_or_equal). * @return list($sql, $params) Same as $DB->get_in_or_equal(). * @todo MDL-52243 Move this function to lib/accesslib.php */ public static function filter_users_with_capability_on_user_context_sql($capability, $userid = 0, $type = SQL_PARAMS_QM, $prefix = 'param') { global $USER, $DB; $allresultsfilter = array('> 0', array()); $noresultsfilter = array('= -1', array()); if (empty($capability)) { return $allresultsfilter; } if (!($capinfo = get_capability_info($capability))) { throw new coding_exception('Capability does not exist: ' . $capability); } if (empty($userid)) { $userid = $USER->id; } // Make sure the guest account and not-logged-in users never get any risky caps no matter what the actual settings are. if ($capinfo->captype === 'write' or $capinfo->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS)) { if (isguestuser($userid) or $userid == 0) { return $noresultsfilter; } } if (is_siteadmin($userid)) { // No filtering for site admins. return $allresultsfilter; } // Check capability on system level. $syscontext = context_system::instance(); $hassystem = has_capability($capability, $syscontext, $userid); $access = get_user_access_sitewide($userid); // Build up a list of level 2 contexts (candidates to be user context). $filtercontexts = array(); foreach ($access['ra'] as $path => $role) { $parts = explode('/', $path); if (count($parts) == 3) { $filtercontexts[$parts[2]] = $parts[2]; } else { if (count($parts) > 3) { // We know this is not a user context because there is another path with more than 2 levels. unset($filtercontexts[$parts[2]]); } } } // Add all contexts in which a role may be overidden. foreach ($access['rdef'] as $pathandroleid => $def) { $matches = array(); if (!isset($def[$capability])) { // The capability is not mentioned, we can ignore. continue; } list($contextpath, $roleid) = explode(':', $pathandroleid, 2); $parts = explode('/', $contextpath); if (count($parts) != 3) { // Only get potential user contexts, they only ever have 2 slashes /parentId/Id. continue; } $filtercontexts[$parts[2]] = $parts[2]; } // No interesting contexts - return all or no results. if (empty($filtercontexts)) { if ($hassystem) { return $allresultsfilter; } else { return $noresultsfilter; } } // Fetch all interesting contexts for further examination. list($insql, $params) = $DB->get_in_or_equal($filtercontexts, SQL_PARAMS_NAMED); $params['level'] = CONTEXT_USER; $fields = context_helper::get_preload_record_columns_sql('ctx'); $interestingcontexts = $DB->get_recordset_sql('SELECT ' . $fields . ' FROM {context} ctx WHERE ctx.contextlevel = :level AND ctx.id ' . $insql . ' ORDER BY ctx.id', $params); if ($hassystem) { // If allowed at system, search for exceptions prohibiting the capability at user context. $excludeusers = array(); foreach ($interestingcontexts as $contextrecord) { $candidateuserid = $contextrecord->ctxinstance; context_helper::preload_from_record($contextrecord); $usercontext = context_user::instance($candidateuserid); // Has capability should use the data already preloaded. if (!has_capability($capability, $usercontext, $userid)) { $excludeusers[$candidateuserid] = $candidateuserid; } } // Construct SQL excluding users with this role assigned for this user. if (empty($excludeusers)) { $interestingcontexts->close(); return $allresultsfilter; } list($sql, $params) = $DB->get_in_or_equal($excludeusers, $type, $prefix, false); } else { // If not allowed at system, search for exceptions allowing the capability at user context. $allowusers = array(); foreach ($interestingcontexts as $contextrecord) { $candidateuserid = $contextrecord->ctxinstance; context_helper::preload_from_record($contextrecord); $usercontext = context_user::instance($candidateuserid); // Has capability should use the data already preloaded. if (has_capability($capability, $usercontext, $userid)) { $allowusers[$candidateuserid] = $candidateuserid; } } // Construct SQL excluding users with this role assigned for this user. if (empty($allowusers)) { $interestingcontexts->close(); return $noresultsfilter; } list($sql, $params) = $DB->get_in_or_equal($allowusers, $type, $prefix); } $interestingcontexts->close(); // Return the goods!. return array($sql, $params); }
/** * hook for the messagebyroletab. * not correctly namespaced because of limitations in messaging. * * unfortunately we don't seem to be able to pass * parameters from the request here... */ function message_print_byrole() { global $CFG, $USER; require_once $CFG->dirroot . '/local/lib/messagelib.php'; $target = optional_param('target', 0, PARAM_INT); $course = optional_param('lp', 0, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); $perpage = optional_param('perpage', 10, PARAM_INT); $sitecontext = get_context_instance(CONTEXT_COURSE, SITEID); $cansearch = has_capability('moodle/local:cansearchforlptomessage', $sitecontext); $searchform = null; $messageform = null; $courses = array(); $totalcount = 0; if (!empty($course) || !empty($target)) { $c = get_record('course', 'id', $course); $targetobject = (object) tao_message_target_get($target, $c); if ($count = tao_message_count_recipients_by_target($targetobject, $c)) { $targetobject->key = $target; require_capability('moodle/local:' . $targetobject->capability, get_context_instance(CONTEXT_COURSE, $c->id)); // give the message send form require_once $CFG->dirroot . '/local/forms.php'; $messageform = new tao_message_send_form('', array('course' => $c, 'target' => $targetobject)); if ($data = $messageform->get_data()) { // send message $eventdata = array('body' => $data->body, 'from' => $USER->id, 'format' => $data->format, 'course' => $c, 'target' => $targetobject); events_trigger('tao_message_role', $eventdata); echo get_string('messagequeued', 'local'); print_continue($CFG->wwwroot . '/message/index.php?tab=byrole'); return; } else { if (!$messageform->is_cancelled()) { $messageform->display(); return; } } } else { notify(get_string('messagenorecipients', 'local')); } } if ($cansearch) { // set up the search form object and process any search requests require_capability('moodle/local:cansearchforlptomessage', $sitecontext); require_once $CFG->dirroot . '/local/forms.php'; $searchform = new tao_message_lpsearch_form('', array(), 'get'); if ($data = $searchform->get_data()) { $search = trim(strip_tags($data->search)); // trim & clean raw searched string if ($search) { $searchterms = explode(" ", $search); // Search for words independently foreach ($searchterms as $key => $searchterm) { if (strlen($searchterm) < 1) { unset($searchterms[$key]); } } $search = trim(implode(" ", $searchterms)); } if (count($searchterms) > 0) { $courses = get_courses_search($searchterms, "fullname ASC", $page, $perpage, $totalcount); } if (empty($courses)) { $nosearchresults = true; } } } // print the main part of the page $targets = (object) tao_message_targets(); // SITE wide message groups first $sitecontent = ''; foreach ($targets->site as $key => $target) { $target = (object) $target; $target->key = $key; $sitecontent .= tao_print_target($target); } $lpcontent = ''; if (empty($courses)) { // if we haven't come from a search, get all courses they have a direct relationship with if (has_capability('moodle/local:hasdirectlprelationship', $sitecontext)) { // Non-cached - get accessinfo if (isset($USER->access)) { $accessinfo = $USER->access; } else { $accessinfo = get_user_access_sitewide($USER->id); } $courses = get_user_courses_bycap($USER->id, 'moodle/local:hasdirectlprelationship', $accessinfo, false, 'c.fullname', array('fullname')); } } if ($courses) { // either from a search, or from the 'direct' relationships foreach ($courses as $course) { // print the targets for each course $coursecontent = ''; foreach ($targets->lp as $key => $target) { $target = (object) $target; $target->key = $key; $coursecontent .= tao_print_target($target, $course, !empty($search)); } if (!empty($coursecontent)) { $lpcontent .= '<b>' . $course->fullname . '</b><br />' . $coursecontent . '<br />'; } } if (!empty($searchform) && !empty($search)) { $url = $searchform->get_fake_url($CFG->wwwroot . '/message/index.php', array('search' => urlencode(stripslashes($search)), 'perpage' => $perpage)); $lpcontent .= print_paging_bar($totalcount, $page, $perpage, $url, 'page', $perpage == 99999, true); } } if (empty($sitecontent) && empty($lpcontent) && empty($cansearch)) { print_error('nomessagetargets', 'local'); } if (!empty($sitecontent)) { print_heading(get_string('sitelists', 'local')); echo $sitecontent . '<br /><br />'; } if (!empty($lpcontent)) { print_heading(get_string('lplists', 'local')); echo $lpcontent; $lpprinted = true; } if (!empty($searchform)) { if (empty($lpprinted)) { print_heading(get_string('lplists', 'local')); } else { echo '<br /><br />'; } if (!empty($nosearchresults)) { notify(get_string('noresults')); } $searchform->display(); } }
/** * A convenience function to completely load all the capabilities * for the current user. This is what gets called from complete_user_login() * for example. Call it only _after_ you've setup $USER and called * check_enrolment_plugins(); * @see check_enrolment_plugins() * * @return void */ function load_all_capabilities() { global $CFG, $ACCESSLIB_PRIVATE; //NOTE: we can not use $USER here because it may no be linked to $_SESSION['USER'] yet! // roles not installed yet - we are in the middle of installation if (during_initial_install()) { return; } $base = '/' . SYSCONTEXTID; if (isguestuser($_SESSION['USER'])) { $guest = get_guest_role(); // Load the rdefs $_SESSION['USER']->access = get_role_access($guest->id); // Put the ghost enrolment in place... $_SESSION['USER']->access['ra'][$base] = array($guest->id => $guest->id); } else { if (!empty($_SESSION['USER']->id)) { // can not use isloggedin() yet $accessdata = get_user_access_sitewide($_SESSION['USER']->id); // // provide "default role" & set 'dr' // if (!empty($CFG->defaultuserroleid)) { $accessdata = get_role_access($CFG->defaultuserroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array(); } $accessdata['ra'][$base][$CFG->defaultuserroleid] = $CFG->defaultuserroleid; $accessdata['dr'] = $CFG->defaultuserroleid; } $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID); // // provide "default frontpage role" // if (!empty($CFG->defaultfrontpageroleid)) { $base = '/' . SYSCONTEXTID . '/' . $frontpagecontext->id; $accessdata = get_default_frontpage_role_access($CFG->defaultfrontpageroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array(); } $accessdata['ra'][$base][$CFG->defaultfrontpageroleid] = $CFG->defaultfrontpageroleid; } $_SESSION['USER']->access = $accessdata; } else { if (!empty($CFG->notloggedinroleid)) { $_SESSION['USER']->access = get_role_access($CFG->notloggedinroleid); $_SESSION['USER']->access['ra'][$base] = array($CFG->notloggedinroleid => $CFG->notloggedinroleid); } } } // Timestamp to read dirty context timestamps later $_SESSION['USER']->access['time'] = time(); $ACCESSLIB_PRIVATE->dirtycontexts = array(); // Clear to force a refresh unset($_SESSION['USER']->mycourses); }
/** * A convenience function to completely load all the capabilities * for the current user. This is what gets called from login, for example. */ function load_all_capabilities() { global $USER, $CFG; $base = '/' . SYSCONTEXTID; if (isguestuser()) { $guest = get_guest_role(); // Load the rdefs $USER->access = get_role_access($guest->id); // Put the ghost enrolment in place... $USER->access['ra'][$base] = array($guest->id); } else { if (isloggedin()) { check_enrolment_plugins($USER); $accessdata = get_user_access_sitewide($USER->id); // // provide "default role" & set 'dr' // if (!empty($CFG->defaultuserroleid)) { $accessdata = get_role_access($CFG->defaultuserroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array($CFG->defaultuserroleid); } else { array_push($accessdata['ra'][$base], $CFG->defaultuserroleid); } $accessdata['dr'] = $CFG->defaultuserroleid; } $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID); // // provide "default frontpage role" // if (!empty($CFG->defaultfrontpageroleid)) { $base = '/' . SYSCONTEXTID . '/' . $frontpagecontext->id; $accessdata = get_default_frontpage_role_access($CFG->defaultfrontpageroleid, $accessdata); if (!isset($accessdata['ra'][$base])) { $accessdata['ra'][$base] = array($CFG->defaultfrontpageroleid); } else { array_push($accessdata['ra'][$base], $CFG->defaultfrontpageroleid); } } $USER->access = $accessdata; } else { if (!empty($CFG->notloggedinroleid)) { $USER->access = get_role_access($CFG->notloggedinroleid); $USER->access['ra'][$base] = array($CFG->notloggedinroleid); } } } // Timestamp to read // dirty context timestamps $USER->access['time'] = time(); // Clear to force a refresh unset($USER->mycourses); }
/** * This function does all the work for the add_member and remove_member events. The code is essentially the same * for both. The only difference is the group function called: add or remove. * * @param object $eventdata The user and group id. * @param string $function The group function to apply. * @return boolean Always return true so that the event gets cleared. * */ function fn_groups_member_change($eventdata, $function) { global $CFG; // static $eventinprogress; /// Set a semaphore so that we don't do this for any new member adds from here. /// Without this, we would do the same operations again for every new membership made in this function. // if (!empty($eventinprogress)) { // return true; // } else { // $eventinprogress = true; // } /// If we aren't using site groups, do nothing. if (empty($CFG->block_fn_site_groups_enabled)) { return true; } /// If data is incomplete, do nothing. if (empty($eventdata->groupid) || empty($eventdata->userid)) { trigger_error('Event groups_member_added sent invalid data.'); return true; } $cgroup = groups_get_group($eventdata->groupid); /// Should never happen. if (empty($cgroup)) { trigger_error('Event groups_member_added sent invalid group.'); return true; } /// If added to a course group, add them to the site group. if ($cgroup->courseid != SITEID) { $sql = 'SELECT g.* ' . 'FROM ' . $CFG->prefix . 'block_fn_site_groups sg ' . 'INNER JOIN ' . $CFG->prefix . 'groups g ON g.id = sg.sitegroupid ' . 'WHERE sg.coursegroupid = ' . $cgroup->id; $sgroup = get_record_sql($sql); /// Might happen. Problem if a site group with same name doesn't exist. if (empty($sgroup)) { trigger_error('Event groups_member_added could not find matching site group.'); return true; } $function($sgroup->id, $eventdata->userid); } else { $sgroup = $cgroup; } /// Find all the courses this user is in and add them to those groups. $courses = get_user_courses_bycap($eventdata->userid, 'moodle/course:view', get_user_access_sitewide($eventdata->userid), false); if (empty($courses)) { $courses = array(); } foreach ($courses as $course) { if ($cgroupid = get_field('block_fn_site_groups', 'coursegroupid', 'sitegroupid', $sgroup->id, 'courseid', $course->id)) { $function($cgroupid, $eventdata->userid); } } return true; }
/** * Get the listing of all courses for an instructor * @param int $user_id [optional] the unique user id for an instructor (default to current user) * @return array the list of courses (maybe be empty array) */ public static function get_courses_for_instructor($user_id = null) { // make this only get courses for this instructor // http://docs.moodle.org/en/Category:Capabilities - moodle/course:update if (!isset($user_id)) { $user_id = self::get_current_user_id(); } if (class_exists('context_course')) { // NOTE: there is no maximum limit to this so self::$max_courses_to_fetch has no effect // for Moodle 2.2+ $results = enrol_get_users_courses($user_id, true, array('fullname', 'summary', 'timecreated', 'visible'), null); foreach ($results as $id => $course) { $context = context_course::instance($id); if (!has_capability('moodle/course:update', $context, $user_id)) { unset($results[$id]); } } } else { // Moodle pre 2.2 global $USER; if ($user_id === $USER->id && isset($USER->access)) { $accessinfo = $USER->access; } else { $accessinfo = get_user_access_sitewide($user_id); } /** @noinspection PhpDeprecationInspection */ $results = get_user_courses_bycap($user_id, 'moodle/course:update', $accessinfo, false, 'c.sortorder', array('fullname', 'summary', 'timecreated', 'visible'), self::$max_courses_to_fetch); } if (!$results) { $results = array(); } else { // update the course titles foreach ($results as $course) { $course->title = $course->fullname; if (iclicker_service::$enable_course_shortname && !empty($course->shortname)) { $course->title = $course->fullname . ' (' . $course->shortname . ')'; } } } return $results; }
$groupingid = optional_param('groupingid', 0, PARAM_INT); $groupid = optional_param('groupid', 0, PARAM_INT); $defrole = get_default_course_role($course); $roleid = optional_param('roleid', $defrole->id, PARAM_INT); // Non-cached - get accessinfo if ($capallusers) { $userid = 0; } else { if ($capgroupusers) { $userid = $USER->id; } } if (isset($USER->access)) { $accessinfo = $USER->access; } else { $accessinfo = get_user_access_sitewide($USER->id); } $acourses = get_user_courses_bycap($USER->id, 'moodle/role:assign', $accessinfo, true, 'c.fullname ASC', array('id', 'fullname')); if ($acourses) { $scourses = array(); foreach ($acourses as $acourse) { $scourses[$acourse->id] = $acourse->fullname; } } else { notify(get_string('nocoursesassigned', 'block_fn_site_groups')); break; } /// If a valid course isn't currently selected, default to the first in the list. if (empty($courseid) || $courseid == SITEID || !key_exists($courseid, $scourses)) { reset($scourses); $courseid = key($scourses);
/** * Get a list of the avaialble templates for a given course. * * @uses $CFG * @uses $USER * @param object $course The course database object. * @return array An array of course template information. */ function course_get_avail_templates($course) { global $CFG, $USER; $return = array(); $cats = array(); /// Fetch the courses that the user has direct access to. $fields = array('id', 'category', 'fullname', 'shortname'); $accessinfo = isset($USER->access) ? $USER->access : get_user_access_sitewide($USER->id); $courses = get_user_courses_bycap($USER->id, 'moodle/course:update', $accessinfo, false, 'c.sortorder ASC', $fields); $cids = array(); if (!empty($courses)) { foreach ($courses as $crs) { $cids[] = $crs->id; } } $sql = "SELECT c.id, c.category, c.fullname, c.shortname, 1 as shared\n FROM {$CFG->prefix}course c\n INNER JOIN {$CFG->prefix}block_admin_share cs ON cs.courseid = c.id\n WHERE c.shortname = '{$course->shortname}'\n AND cs.userid != {$USER->id}"; if (!empty($cids)) { $sql .= ' AND c.id NOT IN (' . implode(', ', $cids) . ')'; } $sql .= ' ORDER BY c.sortorder ASC'; if ($shares = get_records_sql($sql)) { array_merge($courses, $shares); } if (!empty($courses)) { foreach ($courses as $crs) { if (SHARE_RESTRICT_LISTING) { if ($crs->shortname != $course->shortname || !course_using_template($crs->id) || $course->id == $crs->id) { continue; } } else { if ($crs->shortname != $course->shortname || $course->id == $crs->id) { continue; } } if (!isset($cats[$crs->category])) { $cats[$crs->category] = get_field('course_categories', 'name', 'id', $crs->category); } $crs->catname = $cats[$crs->category]; $crs->crn = get_crn_from_coursename($crs); $crs->displayname = isset($crs->shared) ? '<i>' . $crs->catname . ' ' . $crs->shortname . ' ' . ' CRN ' . $crs->crn . '</i>' : $crs->catname . ' ' . $crs->shortname . ' ' . ' CRN ' . $crs->crn; $return[] = $crs; } } if (!empty($return)) { usort($return, 'sort_template_courses'); } return $return; }