public function test_glossary_view() { global $CFG; $origcompletion = $CFG->enablecompletion; $CFG->enablecompletion = true; $this->resetAfterTest(true); // Generate all the things. $c1 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1)); $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1)); $u1 = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($u1->id, $c1->id); $modinfo = course_modinfo::instance($c1->id); $cm1 = $modinfo->get_cm($g1->cmid); $cm2 = $modinfo->get_cm($g2->cmid); $ctx1 = $cm1->context; $completion = new completion_info($c1); $this->setUser($u1); // Confirm what we've set up. $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed); $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate); $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed); $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate); // Simulate the view call. $sink = $this->redirectEvents(); glossary_view($g1, $c1, $cm1, $ctx1, 'letter'); $events = $sink->get_events(); // Assertions. $this->assertCount(3, $events); $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[0]->eventname); $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[1]->eventname); $this->assertEquals('\\mod_glossary\\event\\course_module_viewed', $events[2]->eventname); $this->assertEquals($g1->id, $events[2]->objectid); $this->assertEquals('letter', $events[2]->other['mode']); $this->assertEquals(COMPLETION_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed); $this->assertEquals(COMPLETION_COMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate); $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed); $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate); // Tear down. $sink->close(); $CFG->enablecompletion = $origcompletion; }
/** * Returns reference to full info about modules in course (including visibility). * Cached and as fast as possible (0 or 1 db query). * * use get_fast_modinfo($courseid, 0, true) to reset the static cache for particular course * use get_fast_modinfo(0, 0, true) to reset the static cache for all courses * * use rebuild_course_cache($courseid, true) to reset the application AND static cache * for particular course when it's contents has changed * * @param int|stdClass $courseorid object from DB table 'course' (must have field 'id' * and recommended to have field 'cacherev') or just a course id. Just course id * is enough when calling get_fast_modinfo() for current course or site or when * calling for any other course for the second time. * @param int $userid User id to populate 'availble' and 'uservisible' attributes of modules and sections. * Set to 0 for current user (default). Set to -1 to avoid calculation of dynamic user-depended data. * @param bool $resetonly whether we want to get modinfo or just reset the cache * @return course_modinfo|null Module information for course, or null if resetting * @throws moodle_exception when course is not found (nothing is thrown if resetting) */ function get_fast_modinfo($courseorid, $userid = 0, $resetonly = false) { // compartibility with syntax prior to 2.4: if ($courseorid === 'reset') { debugging("Using the string 'reset' as the first argument of get_fast_modinfo() is deprecated. Use get_fast_modinfo(0,0,true) instead.", DEBUG_DEVELOPER); $courseorid = 0; $resetonly = true; } // Function get_fast_modinfo() can never be called during upgrade unless it is used for clearing cache only. if (!$resetonly) { upgrade_ensure_not_running(); } // Function is called with $reset = true if ($resetonly) { course_modinfo::clear_instance_cache($courseorid); return null; } // Function is called with $reset = false, retrieve modinfo return course_modinfo::instance($courseorid, $userid); }
/** * Returns the contexts the user can access. * * The returned value is a multidimensional array because some search engines can group * information and there will be a performance benefit on passing only some contexts * instead of the whole context array set. * * @return bool|array Indexed by area identifier (component + area name). Returns true if the user can see everything. */ protected function get_areas_user_accesses() { global $CFG, $USER; // All results for admins. Eventually we could add a new capability for managers. if (is_siteadmin()) { return true; } $areasbylevel = array(); // Split areas by context level so we only iterate only once through courses and cms. $searchareas = static::get_search_areas_list(true); foreach ($searchareas as $areaid => $unused) { $classname = static::get_area_classname($areaid); $searcharea = new $classname(); foreach ($classname::get_levels() as $level) { $areasbylevel[$level][$areaid] = $searcharea; } } // This will store area - allowed contexts relations. $areascontexts = array(); if (!empty($areasbylevel[CONTEXT_SYSTEM])) { // We add system context to all search areas working at this level. Here each area is fully responsible of // the access control as we can not automate much, we can not even check guest access as some areas might // want to allow guests to retrieve data from them. $systemcontextid = \context_system::instance()->id; foreach ($areasbylevel[CONTEXT_SYSTEM] as $areaid => $searchclass) { $areascontexts[$areaid][] = $systemcontextid; } } // Get the courses where the current user has access. $courses = enrol_get_my_courses(array('id', 'cacherev')); $courses[SITEID] = get_course(SITEID); $site = \course_modinfo::instance(SITEID); foreach ($courses as $course) { // Info about the course modules. $modinfo = get_fast_modinfo($course); if (!empty($areasbylevel[CONTEXT_COURSE])) { // Add the course contexts the user can view. $coursecontext = \context_course::instance($course->id); foreach ($areasbylevel[CONTEXT_COURSE] as $areaid => $searchclass) { if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) { $areascontexts[$areaid][$coursecontext->id] = $coursecontext->id; } } } if (!empty($areasbylevel[CONTEXT_MODULE])) { // Add the module contexts the user can view (cm_info->uservisible). foreach ($areasbylevel[CONTEXT_MODULE] as $areaid => $searchclass) { // Removing the plugintype 'mod_' prefix. $modulename = substr($searchclass->get_component_name(), 4); $modinstances = $modinfo->get_instances_of($modulename); foreach ($modinstances as $modinstance) { if ($modinstance->uservisible) { $areascontexts[$areaid][$modinstance->context->id] = $modinstance->context->id; } } } } } return $areascontexts; }