/** * Finds whether this section is available at the moment for the current user. * * The value can be accessed publicly as $sectioninfo->available * * @return bool */ private function get_available() { global $CFG; $userid = $this->modinfo->get_user_id(); if ($this->_available !== null || $userid == -1) { // Has already been calculated or does not need calculation. return $this->_available; } if (!empty($CFG->enableavailability)) { require_once($CFG->libdir. '/conditionlib.php'); // Get availability information $ci = new condition_info_section($this); $this->_available = $ci->is_available($this->_availableinfo, true, $userid, $this->modinfo); if ($this->_availableinfo === '' && $this->_groupingid) { // Still may have some extra text in availableinfo because of groupping. // Set as undefined so the next call to get_availabeinfo() calculates it. $this->_availableinfo = null; } } else { $this->_available = true; $this->_availableinfo = ''; } return $this->_available; }
/** * Tests the is_available function for sections. */ public function test_section_is_available() { global $DB; // Create course. $generator = $this->getDataGenerator(); $course = $generator->create_course(array('numsections' => 2), array('createsections' => true)); // Set one of the sections unavailable. $time = time() + 100; $avail = '{"op":"|","show":true,"c":[{"type":"date","d":">=","t":' . $time . '}]}'; $DB->set_field('course_sections', 'availability', $avail, array('course' => $course->id, 'section' => 2)); $modinfo = get_fast_modinfo($course); // No conditions. $ci = new condition_info_section($modinfo->get_section_info(1)); $this->assertDebuggingCalled(); $this->assertTrue($ci->is_available($text, false, 0)); $this->assertDebuggingCalled(); $this->assertEquals('', $text); // Date condition. $ci = new condition_info_section($modinfo->get_section_info(2)); $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); }
/** * Constructs object from database information plus extra required data. * @param object $data Array entry from cached sectioncache * @param int $number Section number (array key) * @param int $courseid Course ID * @param int $sequence Sequence of course-module ids contained within * @param course_modinfo $modinfo Owner (needed for checking availability) * @param int $userid User ID */ public function __construct($data, $number, $courseid, $sequence, $modinfo, $userid) { global $CFG; // Data that is always present $this->_id = $data->id; $defaults = self::$sectioncachedefaults + array('conditionscompletion' => array(), 'conditionsgrade' => array(), 'conditionsfield' => array()); // Data that may use default values to save cache size foreach ($defaults as $field => $value) { if (isset($data->{$field})) { $this->{'_' . $field} = $data->{$field}; } else { $this->{'_' . $field} = $value; } } // cached course format data $formatoptionsdef = course_get_format($courseid)->section_format_options(); foreach ($formatoptionsdef as $field => $option) { if (!empty($option['cache'])) { if (isset($data->{$field})) { $this->cachedformatoptions[$field] = $data->{$field}; } else { if (array_key_exists('cachedefault', $option)) { $this->cachedformatoptions[$field] = $option['cachedefault']; } } } } // Other data from other places $this->_course = $courseid; $this->_section = $number; $this->_sequence = $sequence; // Availability data if (!empty($CFG->enableavailability)) { // Get availability information $ci = new condition_info_section($this); $this->_available = $ci->is_available($this->_availableinfo, true, $userid, $modinfo); // Display grouping info if available & not already displaying // (it would already display if current user doesn't have access) // for people with managegroups - same logic/class as grouping label // on individual activities. $context = context_course::instance($courseid); if ($this->_availableinfo === '' && $this->_groupingid && has_capability('moodle/course:managegroups', $context)) { $groupings = groups_get_all_groupings($courseid); $this->_availableinfo = html_writer::tag('span', '(' . format_string($groupings[$this->_groupingid]->name, true, array('context' => $context)) . ')', array('class' => 'groupinglabel')); } } else { $this->_available = true; } // Update visibility for current user $this->update_user_visible($userid); }
public function test_section_is_available() { global $DB, $USER; $courseid = $this->make_course(); // Enrol user (needed for groups) $enrolplugin = enrol_get_plugin('manual'); $course = $DB->get_record('course', array('id' => $courseid)); $enrolplugin->add_instance($course); $enrolinstances = enrol_get_instances($courseid, false); foreach ($enrolinstances as $enrolinstance) { if ($enrolinstance->enrol === 'manual') { break; } } $enrolplugin->enrol_user($enrolinstance, $USER->id); // Module for conditions later $cmid = $this->make_course_module($courseid); // No conditions $sectionid = $this->make_section($courseid, array($cmid), 1); $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $this->assertTrue($ci->is_available($text, false, 0)); $this->assertEquals('', $text); // Time (from) $time = time() + 100; $sectionid = $this->make_section($courseid, array(), 2, array('availablefrom' => $time)); $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $this->assertFalse($ci->is_available($text)); $timetext = userdate($time, get_string('strftimedate', 'langconfig')); $this->assertRegExp('~' . preg_quote($timetext) . '~', $text); $time=time()-100; $sectionid = $this->make_section($courseid, array(), 3, array('availablefrom' => $time)); $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $this->assertTrue($ci->is_available($text)); $this->assertEquals('', $text); $timetext = userdate($time, get_string('strftimedate', 'langconfig')); $this->assertRegExp('~' . preg_quote($timetext) . '~', $ci->get_full_information()); // Time (until) $sectionid = $this->make_section($courseid, array(), 4, array('availableuntil' => time() - 100)); $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $this->assertFalse($ci->is_available($text)); $this->assertEquals('', $text); // Completion: first set up cm $sectionid = $this->make_section($courseid, array(), 5); $cm = $DB->get_record('course_modules', array('id' => $cmid)); $cm->completion = COMPLETION_TRACKING_MANUAL; $DB->update_record('course_modules', $cm); // Completion: Reset modinfo after changing the options rebuild_course_cache($courseid); $reset = 'reset'; get_fast_modinfo($reset); // Completion: Add condition $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $ci->add_completion_condition($cmid, COMPLETION_COMPLETE); condition_info_section::wipe_session_cache(); // Completion: Check $this->assertFalse($ci->is_available($text, false)); $this->assertEquals(get_string('requires_completion_1', 'condition', 'xxx'), $text); completion_info::wipe_session_cache(); $completion = new completion_info($DB->get_record('course', array('id' => $courseid))); $completion->update_state($cm, COMPLETION_COMPLETE); completion_info::wipe_session_cache(); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); $this->assertFalse($ci->is_available($text, false, $USER->id + 1)); // Completion: Uncheck completion_info::wipe_session_cache(); condition_info_section::wipe_session_cache(); $completion = new completion_info($DB->get_record('course', array('id' => $courseid))); $completion->update_state($cm, COMPLETION_INCOMPLETE); $this->assertFalse($ci->is_available($text)); // Completion: Incomplete condition $ci->wipe_conditions(); $ci->add_completion_condition($cmid, COMPLETION_INCOMPLETE); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); $this->assertTrue($ci->is_available($text, false, $USER->id + 1)); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text, true)); // Grade: Add a fake grade item $gradeitemid = $DB->insert_record('grade_items', (object)array( 'courseid' => $courseid, 'itemname' => 'frog')); // Grade: Add a condition on a value existing $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, null, null, true); $this->assertFalse($ci->is_available($text)); $this->assertEquals(get_string('requires_grade_any', 'condition', 'frog'), $text); // Grade: Fake it existing $DB->insert_record('grade_grades', (object)array( 'itemid' => $gradeitemid, 'userid' => $USER->id, 'finalgrade' => 3.78)); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text, true)); // Grade: Now require that user gets more than 3.78001 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3.78001, null, true); condition_info_section::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEquals(get_string('requires_grade_min', 'condition', 'frog'), $text); // Grade: ...just on 3.78... $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3.78, null, true); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // Grade: ...less than 3.78 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, null, 3.78, true); condition_info_section::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEquals(get_string('requires_grade_max', 'condition', 'frog'), $text); // Grade: ...less than 3.78001 $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, null, 3.78001, true); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // Grade: ...in a range that includes it $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 3, 4, true); condition_info_section::wipe_session_cache(); $this->assertTrue($ci->is_available($text)); // Grade: ...in a range that doesn't include it $ci->wipe_conditions(); $ci->add_grade_condition($gradeitemid, 4, 5, true); condition_info_section::wipe_session_cache(); $this->assertFalse($ci->is_available($text)); $this->assertEquals(get_string('requires_grade_range', 'condition', 'frog'), $text); // Grouping: Not member $groupingid = $this->make_grouping($courseid, 'Grouping'); $groupid = $this->make_group($courseid, 'Group', $groupingid); $sectionid = $this->make_section($courseid, array(), 6, array('groupingid' => $groupingid)); $ci = new condition_info_section((object)array('id' => $sectionid), CONDITION_MISSING_EVERYTHING); $this->assertFalse($ci->is_available($text)); $this->assertEquals(trim(get_string('groupingnoaccess', 'condition')), $text); // Grouping: Member $this->assertTrue(groups_add_member($groupid, $USER->id)); condition_info_section::init_global_cache(); $this->assertTrue($ci->is_available($text)); $this->assertEquals('', $text); $this->assertTrue($ci->is_available($text, true)); // Grouping: Somebody else $this->assertFalse($ci->is_available($text, false, $USER->id + 1)); $this->assertFalse($ci->is_available($text, true, $USER->id + 1)); }