/** * If dynamic data for this course-module is not yet available, gets it. * * This function is automatically called when requesting any course_modinfo property * that can be modified by modules (have a set_xxx method). * * Dynamic data is data which does not come directly from the cache but is calculated at * runtime based on the current user. Primarily this concerns whether the user can access * the module or not. * * As part of this function, the module's _cm_info_dynamic function from its lib.php will * be called (if it exists). * @return void */ private function obtain_dynamic_data() { global $CFG; $userid = $this->modinfo->get_user_id(); if ($this->state >= self::STATE_BUILDING_DYNAMIC || $userid == -1) { return; } $this->state = self::STATE_BUILDING_DYNAMIC; if (!empty($CFG->enableavailability)) { require_once($CFG->libdir. '/conditionlib.php'); // Get availability information $ci = new condition_info($this); // Note that the modinfo currently available only includes minimal details (basic data) // but we know that this function does not need anything more than basic data. $this->available = $ci->is_available($this->availableinfo, true, $userid, $this->modinfo); // Check parent section $parentsection = $this->modinfo->get_section_info($this->sectionnum); if (!$parentsection->available) { // Do not store info from section here, as that is already // presented from the section (if appropriate) - just change // the flag $this->available = false; } } else { $this->available = true; } // Update visible state for current user $this->update_user_visible(); // Let module make dynamic changes at this point $this->call_mod_function('cm_info_dynamic'); $this->state = self::STATE_DYNAMIC; }
/** * Determine whether a course module is visible within a course, * this is different from instance_is_visible() - faster and visibility for user * * @global object * @global object * @uses DEBUG_DEVELOPER * @uses CONTEXT_MODULE * @uses CONDITION_MISSING_EXTRATABLE * @param object $cm object * @param int $userid empty means current user * @return bool Success */ function coursemodule_visible_for_user($cm, $userid = 0) { global $USER, $CFG; if (empty($cm->id)) { debugging("Incorrect course module parameter!", DEBUG_DEVELOPER); return false; } if (empty($userid)) { $userid = $USER->id; } if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id), $userid)) { return false; } if ($CFG->enableavailability) { require_once $CFG->libdir . '/conditionlib.php'; $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE); if (!$ci->is_available($cm->availableinfo, false, $userid) and !has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $cm->id), $userid)) { return false; } } return groups_course_module_visible($cm, $userid); }
/** * Returns reference to full info about modules in course (including visibility). * Cached and as fast as possible (0 or 1 db query). * * @global object * @global object * @global object * @uses CONTEXT_MODULE * @uses MAX_MODINFO_CACHE_SIZE * @param mixed $course object or 'reset' string to reset caches, modinfo may be updated in db * @param int $userid Defaults to current user id * @return mixed courseinfo object or nothing if resetting */ function &get_fast_modinfo(&$course, $userid = 0) { global $CFG, $USER, $DB; require_once $CFG->dirroot . '/course/lib.php'; if (!empty($CFG->enableavailability)) { require_once $CFG->libdir . '/conditionlib.php'; } static $cache = array(); if ($course === 'reset') { $cache = array(); $nothing = null; return $nothing; // we must return some reference } if (empty($userid)) { $userid = $USER->id; } if (array_key_exists($course->id, $cache) and $cache[$course->id]->userid == $userid) { return $cache[$course->id]; } if (empty($course->modinfo)) { // no modinfo yet - load it rebuild_course_cache($course->id); $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id)); } $modinfo = new object(); $modinfo->courseid = $course->id; $modinfo->userid = $userid; $modinfo->sections = array(); $modinfo->cms = array(); $modinfo->instances = array(); $modinfo->groups = null; // loaded only when really needed - the only one db query $info = unserialize($course->modinfo); if (!is_array($info)) { // hmm, something is wrong - lets try to fix it rebuild_course_cache($course->id); $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id)); $info = unserialize($course->modinfo); if (!is_array($info)) { return $modinfo; } } if ($info) { // detect if upgrade required $first = reset($info); if (!isset($first->id)) { rebuild_course_cache($course->id); $course->modinfo = $DB->get_field('course', 'modinfo', array('id' => $course->id)); $info = unserialize($course->modinfo); if (!is_array($info)) { return $modinfo; } } } $modlurals = array(); // If we haven't already preloaded contexts for the course, do it now preload_course_contexts($course->id); foreach ($info as $mod) { if (empty($mod->name)) { // something is wrong here continue; } // reconstruct minimalistic $cm $cm = new object(); $cm->id = $mod->cm; $cm->instance = $mod->id; $cm->course = $course->id; $cm->modname = $mod->mod; $cm->name = urldecode($mod->name); $cm->visible = $mod->visible; $cm->sectionnum = $mod->section; $cm->groupmode = $mod->groupmode; $cm->groupingid = $mod->groupingid; $cm->groupmembersonly = $mod->groupmembersonly; $cm->indent = $mod->indent; $cm->completion = $mod->completion; $cm->extra = isset($mod->extra) ? urldecode($mod->extra) : ''; $cm->icon = isset($mod->icon) ? $mod->icon : ''; $cm->uservisible = true; if (!empty($CFG->enableavailability)) { // We must have completion information from modinfo. If it's not // there, cache needs rebuilding if (!isset($mod->availablefrom)) { debugging('enableavailability option was changed; rebuilding ' . 'cache for course ' . $course->id); rebuild_course_cache($course->id, true); // Re-enter this routine to do it all properly return get_fast_modinfo($course, $userid); } $cm->availablefrom = $mod->availablefrom; $cm->availableuntil = $mod->availableuntil; $cm->showavailability = $mod->showavailability; $cm->conditionscompletion = $mod->conditionscompletion; $cm->conditionsgrade = $mod->conditionsgrade; } // preload long names plurals and also check module is installed properly if (!isset($modlurals[$cm->modname])) { if (!file_exists("{$CFG->dirroot}/mod/{$cm->modname}/lib.php")) { continue; } $modlurals[$cm->modname] = get_string('modulenameplural', $cm->modname); } $cm->modplural = $modlurals[$cm->modname]; $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); if (!empty($CFG->enableavailability)) { // Unfortunately the next call really wants to call // get_fast_modinfo, but that would be recursive, so we fake up a // modinfo for it already if (empty($minimalmodinfo)) { $minimalmodinfo = new stdClass(); $minimalmodinfo->cms = array(); foreach ($info as $mod) { $minimalcm = new stdClass(); $minimalcm->id = $mod->cm; $minimalcm->name = urldecode($mod->name); $minimalmodinfo->cms[$minimalcm->id] = $minimalcm; } } // Get availability information $ci = new condition_info($cm); $cm->available = $ci->is_available($cm->availableinfo, true, $userid, $minimalmodinfo); } else { $cm->available = true; } if ((!$cm->visible or !$cm->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) { $cm->uservisible = false; } else { if (!empty($CFG->enablegroupings) and !empty($cm->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) { if (is_null($modinfo->groups)) { $modinfo->groups = groups_get_user_groups($course->id, $userid); } if (empty($modinfo->groups[$cm->groupingid])) { $cm->uservisible = false; } } } if (!isset($modinfo->instances[$cm->modname])) { $modinfo->instances[$cm->modname] = array(); } $modinfo->instances[$cm->modname][$cm->instance] =& $cm; $modinfo->cms[$cm->id] =& $cm; // reconstruct sections if (!isset($modinfo->sections[$cm->sectionnum])) { $modinfo->sections[$cm->sectionnum] = array(); } $modinfo->sections[$cm->sectionnum][] = $cm->id; unset($cm); } unset($cache[$course->id]); // prevent potential reference problems when switching users $cache[$course->id] = $modinfo; // Ensure cache does not use too much RAM if (count($cache) > MAX_MODINFO_CACHE_SIZE) { reset($cache); $key = key($cache); unset($cache[$key]); } return $cache[$course->id]; }
/** * If dynamic data for this course-module is not yet available, gets it. * * This function is automatically called when constructing course_modinfo, so users don't * need to call it. * * Dynamic data is data which does not come directly from the cache but is calculated at * runtime based on the current user. Primarily this concerns whether the user can access * the module or not. * * As part of this function, the module's _cm_info_dynamic function from its lib.php will * be called (if it exists). * @return void */ public function obtain_dynamic_data() { global $CFG; if ($this->state >= self::STATE_DYNAMIC) { return; } $userid = $this->modinfo->get_user_id(); if (!empty($CFG->enableavailability)) { // Get availability information $ci = new condition_info($this); // Note that the modinfo currently available only includes minimal details (basic data) // so passing it to this function is a bit dangerous as it would cause infinite // recursion if it tried to get dynamic data, however we know that this function only // uses basic data. $this->available = $ci->is_available($this->availableinfo, true, $userid, $this->modinfo); } else { $this->available = true; } // Update visible state for current user $this->update_user_visible(); // Let module make dynamic changes at this point $this->call_mod_function('cm_info_dynamic'); $this->state = self::STATE_DYNAMIC; }
/** * Tests the is_available function for modules. This does not test all the * conditions and stuff, because it only needs to check that the system * connects through to the real availability API. Also tests * get_full_information function. */ public function test_is_available() { // Create course. $generator = $this->getDataGenerator(); $course = $generator->create_course(); // Create activity with no restrictions and one with date restriction. $page1 = $generator->get_plugin_generator('mod_page')->create_instance(array('course' => $course)); $time = time() + 100; $avail = '{"op":"|","show":true,"c":[{"type":"date","d":">=","t":' . $time . '}]}'; $page2 = $generator->get_plugin_generator('mod_page')->create_instance(array('course' => $course, 'availability' => $avail)); // No conditions. $ci = new condition_info((object) array('id' => $page1->cmid), CONDITION_MISSING_EVERYTHING); $this->assertDebuggingCalled(); $this->assertTrue($ci->is_available($text, false, 0)); $this->assertDebuggingCalled(); $this->assertEquals('', $text); // Date condition. $ci = new condition_info((object) array('id' => $page2->cmid), CONDITION_MISSING_EVERYTHING); $this->assertDebuggingCalled(); $this->assertFalse($ci->is_available($text)); $this->assertDebuggingCalled(); $expectedtime = userdate($time, get_string('strftimedate', 'langconfig')); $this->assertContains($expectedtime, $text); // Full information display. $text = $ci->get_full_information(); $this->assertDebuggingCalled(); $expectedtime = userdate($time, get_string('strftimedate', 'langconfig')); $this->assertContains($expectedtime, $text); }
function test_is_available() { global $DB, $USER; $courseid = $this->make_course(); // No conditions $cmid = $this->make_course_module($courseid); $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING); $this->assertTrue($ci->is_available($text, false, 0)); $this->assertEqual('', $text); // Time (from) $time = time() + 100; $cmid = $this->make_course_module($courseid, array('availablefrom' => $time)); $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING); $this->assertFalse($ci->is_available($text)); $this->assert(new PatternExpectation('/' . preg_quote(userdate($time, get_string('strftimedate', 'langconfig'))) . '/'), $text); $time = time() - 100; $cmid = $this->make_course_module($courseid, array('availablefrom' => $time)); $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING); $this->assertTrue($ci->is_available($text)); $this->assertEqual('', $text); $this->assert(new PatternExpectation('/' . preg_quote(userdate($time, get_string('strftimedate', 'langconfig'))) . '/'), $ci->get_full_information()); // Time (until) $cmid = $this->make_course_module($courseid, array('availableuntil' => time() - 100)); $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING); $this->assertFalse($ci->is_available($text)); $this->assertEqual('', $text); // Completion $oldid = $cmid; $cmid = $this->make_course_module($courseid); $this->make_section($courseid, array($oldid, $cmid)); $oldcm = $DB->get_record('course_modules', array('id' => $oldid)); $oldcm->completion = COMPLETION_TRACKING_MANUAL; $DB->update_record('course_modules', $oldcm); $ci = new condition_info((object) array('id' => $cmid), CONDITION_MISSING_EVERYTHING); $ci->add_completion_condition($oldid, COMPLETION_COMPLETE); $this->assertFalse($ci->is_available($text, false)); $this->assertEqual(get_string('requires_completion_1', 'condition', 'xxx'), $text); $completion = new completion_info($DB->get_record('course', array('id' => $courseid))); $completion->update_state($oldcm, COMPLETION_COMPLETE); completion_info::wipe_session_cache(); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); $this->assertFalse($ci->is_available($text, false, $USER->id + 1)); completion_info::wipe_session_cache(); condition_info::wipe_session_cache(); $completion = new completion_info($DB->get_record('course', array('id' => $courseid))); $completion->update_state($oldcm, COMPLETION_INCOMPLETE); $this->assertFalse($ci->is_available($text)); $ci->wipe_conditions(); $ci->add_completion_condition($oldid, COMPLETION_INCOMPLETE); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); $this->assertTrue($ci->is_available($text, false, $USER->id + 1)); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text, true)); // Grade $ci->wipe_conditions(); // Add a fake grade item $gradeitemid = $DB->insert_record('grade_items', (object) array('courseid' => $courseid, 'itemname' => 'frog')); // Add a condition on a value existing... $ci->add_grade_condition($gradeitemid, null, null, true); $this->assertFalse($ci->is_available($text)); $this->assertEqual(get_string('requires_grade_any', 'condition', 'frog'), $text); // Fake it existing $DB->insert_record('grade_grades', (object) array('itemid' => $gradeitemid, 'userid' => $USER->id, 'finalgrade' => 3.78)); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text, true)); // Now require that user gets more than 3.78001 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3.78001, null, true); condition_info::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEqual(get_string('requires_grade_min', 'condition', 'frog'), $text); // ...just on 3.78... $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3.78, null, true); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // ...less than 3.78 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, null, 3.78, true); condition_info::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEqual(get_string('requires_grade_max', 'condition', 'frog'), $text); // ...less than 3.78001 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, null, 3.78001, true); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // ...in a range that includes it $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3, 4, true); condition_info::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // ...in a range that doesn't include it $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 4, 5, true); condition_info::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEqual(get_string('requires_grade_range', 'condition', 'frog'), $text); }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the coursemodule is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * @uses $CFG * @uses $SESSION * @uses $USER * @uses $FULLME * @uses SITEID * @uses $COURSE * @param mixed $courseorid id of the course or course object * @param bool $autologinguest * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 */ function require_login($courseorid = 0, $autologinguest = true, $cm = null, $setwantsurltome = true) { global $CFG, $SESSION, $USER, $COURSE, $FULLME, $PAGE, $SITE, $DB; /// setup global $COURSE, themes, language and locale if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid)); if (!$course) { throw new moodle_exception('invalidcourseid'); } } } $PAGE->set_course($course); } else { // If $PAGE->course, and hence $PAGE->context, have not already been set // up properly, set them up now. $PAGE->set_course($PAGE->course); } /// If the user is not even logged in yet then make sure they are if (!isloggedin()) { //NOTE: $USER->site check was obsoleted by session test cookie, // $USER->confirmed test is in login/index.php if ($setwantsurltome) { $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests) and ($COURSE->id == SITEID or $COURSE->guest)) { $loginguest = true; } else { $loginguest = false; } redirect(get_login_url($loginguest)); exit; // never reached } /// loginas as redirection if needed if ($COURSE->id != SITEID and session_is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $COURSE->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } /// check whether the user should be changing password (but only if it is REALLY them) if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password()) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url redirect($changeurl); } else { //use moodle internal method if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { print_error('nopasswordchangeforced', 'auth'); } } /// Check that the user account is properly set up if (user_not_fully_set_up($USER)) { $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } /// Make sure the USER has a sesskey set up. Used for checking script parameters. sesskey(); // Check that the user has agreed to a site policy if there is one if (!empty($CFG->sitepolicy)) { if (!$USER->policyagreed) { $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } } // Fetch the system context, we are going to use it a lot. $sysctx = get_context_instance(CONTEXT_SYSTEM); /// If the site is currently under maintenance, then print a message if (!has_capability('moodle/site:config', $sysctx)) { if (file_exists($CFG->dataroot . '/' . SITEID . '/maintenance.html')) { print_maintenance_message(); exit; } } /// groupmembersonly access control if (!empty($CFG->enablegroupings) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { if (isguestuser() or !groups_has_membership($cm)) { print_error('groupmembersonlyerror', 'group', $CFG->wwwroot . '/course/view.php?id=' . $cm->course); } } // Fetch the course context, and prefetch its child contexts if (!isset($COURSE->context)) { if (!($COURSE->context = get_context_instance(CONTEXT_COURSE, $COURSE->id))) { print_error('nocontext'); } } if (!empty($cm) && !isset($cm->context)) { if (!($cm->context = get_context_instance(CONTEXT_MODULE, $cm->id))) { print_error('nocontext'); } } // Conditional activity access control if (!empty($CFG->enableavailability) and $cm) { // We cache conditional access in session if (!isset($SESSION->conditionaccessok)) { $SESSION->conditionaccessok = array(); } // If you have been allowed into the module once then you are allowed // in for rest of session, no need to do conditional checks if (!array_key_exists($cm->id, $SESSION->conditionaccessok)) { // Get condition info (does a query for the availability table) require_once $CFG->libdir . '/conditionlib.php'; $ci = new condition_info($cm, CONDITION_MISSING_EXTRATABLE); // Check condition for user (this will do a query if the availability // information depends on grade or completion information) if ($ci->is_available($junk) || has_capability('moodle/course:viewhiddenactivities', $cm->context)) { $SESSION->conditionaccessok[$cm->id] = true; } else { print_error('activityiscurrentlyhidden'); } } } if ($COURSE->id == SITEID) { /// Eliminate hidden site activities straight away if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) { redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; } else { /// Check if the user can be in a particular course if (empty($USER->access['rsw'][$COURSE->context->path])) { // // MDL-13900 - If the course or the parent category are hidden // and the user hasn't the 'course:viewhiddencourses' capability, prevent access // if (!($COURSE->visible && course_parent_visible($COURSE)) && !has_capability('moodle/course:viewhiddencourses', $COURSE->context)) { print_header_simple(); notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } /// Non-guests who don't currently have access, check if they can be allowed in as a guest if ($USER->username != 'guest' and !has_capability('moodle/course:view', $COURSE->context)) { if ($COURSE->guest == 1) { // Temporarily assign them guest role for this context, if it fails later user is asked to enrol $USER->access = load_temp_role($COURSE->context, $CFG->guestroleid, $USER->access); } } /// If the user is a guest then treat them according to the course policy about guests if (has_capability('moodle/legacy:guest', $COURSE->context, NULL, false)) { if (has_capability('moodle/site:doanything', $sysctx)) { // administrators must be able to access any course - even if somebody gives them guest access user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; } switch ($COURSE->guest) { /// Check course policy about guest access case 1: /// Guests always allowed if (!has_capability('moodle/course:view', $COURSE->context)) { // Prohibited by capability print_header_simple(); notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), get_login_url()); } if (!empty($cm) and !$cm->visible) { // Not allowed to see module, send to course page redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; // User is allowed to see this course break; case 2: /// Guests allowed with key if (!empty($USER->enrolkey[$COURSE->id])) { // Set by enrol/manual/enrol.php user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return true; } // otherwise drop through to logic below (--> enrol.php) break; default: /// Guests not allowed $strloggedinasguest = get_string('loggedinasguest'); print_header_simple('', '', build_navigation(array(array('name' => $strloggedinasguest, 'link' => null, 'type' => 'misc')))); if (empty($USER->access['rsw'][$COURSE->context->path])) { // Normal guest notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), get_login_url()); } else { notify(get_string('guestsnotallowed', '', format_string($COURSE->fullname))); echo '<div class="notifyproblem">' . switchroles_form($COURSE->id) . '</div>'; print_footer($COURSE); exit; } break; } /// For non-guests, check if they have course view access } else { if (has_capability('moodle/course:view', $COURSE->context)) { if (session_is_loggedinas()) { // Make sure the REAL person can also access this course $realuser = session_get_realuser(); if (!has_capability('moodle/course:view', $COURSE->context, $realuser->id)) { print_header_simple(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } /// Make sure they can read this activity too, if specified if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) { redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; // User is allowed to see this course } } /// Currently not enrolled in the course, so see if they want to enrol $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/course/enrol.php?id=' . $COURSE->id); die; } }
/** * Checks whether a user can be subscribed to the forum, regardless of * subscription option. Includes a variety of other checks. [These are * supposed to be the same as checks done when building the list of people * for email.] * @param int $userid User ID or 0 for current * @return bool True if user can be subscribed */ private function can_be_subscribed($userid = 0) { global $USER; $userid = mod_forumng_utils::get_real_userid($userid); $cm = $this->get_course_module(); $course = $this->get_course(); $context = $this->get_context(); // Guests cannot subscribe if (!isloggedin() || isguestuser($userid)) { return false; } // Get from cache if possible if (!isset($this->cache->can_be_subscribed)) { $this->cache->can_be_subscribed = array(); } if (array_key_exists($userid, $this->cache->can_be_subscribed)) { return $this->cache->can_be_subscribed[$userid]; } // This is not a loop, just so I can use break do { // Check user can see forum if (!has_capability('mod/forumng:viewdiscussion', $context, $userid)) { $result = false; break; } // For current user, can take shortcut if ($userid == $USER->id) { if (empty($cm->uservisible)) { $uservisible = false; } else { $uservisible = true; } if (!$uservisible) { $result = false; break; } } else { $visible = $cm->visible; // Note: It is pretty terrible that this code is placed here. // Shouldn't there be a function in cm_info to do this? :( // Unfortunately I didn't think of that when redesigning // cm_info, it can only work for current user. $conditioninfo = new condition_info($cm); $visible = $visible && $conditioninfo->is_available($crap, false, $userid); if (!$visible && !has_capability('moodle/site:viewhiddenactivities', $context, $userid)) { $result = false; break; } if ($cm->groupmembersonly && !has_capability('moodle/site:accessallgroups', $context, $userid)) { // If the forum is restricted to group members only, then // limit it to people within groups on the course - or // groups in the grouping, if one is selected $groupobjs = groups_get_all_groups($course->id, $userid, $cm->groupingid, 'g.id'); if (!$groupobjs || count($groupobjs) == 0) { $result = false; break; } } } $result = true; break; } while (false); $this->cache->can_be_subscribed[$userid] = $result; return $result; }
/** * Created to accomodate forumng on shared activities * where the shared activites course does not hold cm information * in the course table's modinfo field * @param $course * @param $cmid * @return $modinfo */ private function get_fast_modinfo($course, $cmid) { global $CFG; if (class_exists('ouflags')) { require_once $CFG->dirroot . '/course/format/sharedactv/sharedactv.php'; if (sharedactv_is_magic_course($course)) { // get_fast_modinfo will only ever return a minimal object, so build own $modinfo = new object(); $modinfo->courseid = $course->id; $modinfo->userid = 0; $modinfo->sections = array(); $modinfo->instances = array(); $modinfo->groups = null; if (!($cm = get_coursemodule_from_id('forumng', $cmid, $course->id))) { throw new forum_exception('Could not find the forum course module.'); } if (!empty($CFG->enableavailability)) { $cm->conditionscompletion = array(); $cm->conditionsgrade = array(); // Unfortunately the next call really wants to call // get_fast_modinfo, but that would be recursive, so we fake up a // modinfo for it already if (empty($minimalmodinfo)) { $minimalmodinfo = new stdClass(); $minimalmodinfo->cms = array(); $minimalcm = new stdClass(); $minimalcm->id = $cmid; $minimalcm->name = 'forumng'; $minimalmodinfo->cms[$cmid] = $minimalcm; } // Get availability information $ci = new condition_info($cm); $cm->available = $ci->is_available($cm->availableinfo, true, 0, $minimalmodinfo); } else { $cm->available = true; } $cm->uservisible = true; $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); if ((!$cm->visible or !$cm->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, 0)) { $cm->uservisible = false; } else { if (!empty($CFG->enablegroupings) and !empty($cm->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, 0)) { if (is_null($modinfo->groups)) { $modinfo->groups = groups_get_user_groups($course->id, 0); } if (empty($modinfo->groups[$cm->groupingid])) { $cm->uservisible = false; } } } $modinfo->cms = array($cmid => $cm); } else { $modinfo = get_fast_modinfo($course); } } else { $modinfo = get_fast_modinfo($course); } return $modinfo; }