Skip to content

Commit

Permalink
MDL-37765 course: Add capability to ignore availability restrictions.
Browse files Browse the repository at this point in the history
Allow a role to view activities without addressing the restriction rules.
  • Loading branch information
jacac committed Mar 27, 2017
1 parent 216ea39 commit 6a36b85
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 13 deletions.
2 changes: 1 addition & 1 deletion availability/classes/info_module.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public function filter_user_list(array $users) {
}

protected function get_view_hidden_capability() {
return 'moodle/course:viewhiddenactivities';
return 'moodle/course:ignoreavailabilityrestrictions';
}

public function get_user_list_sql($onlyactive = true) {
Expand Down
2 changes: 1 addition & 1 deletion availability/classes/info_section.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function get_context() {
}

protected function get_view_hidden_capability() {
return 'moodle/course:viewhiddensections';
return 'moodle/course:ignoreavailabilityrestrictions';
}

protected function set_in_database($availability) {
Expand Down
2 changes: 1 addition & 1 deletion availability/tests/fixtures/mock_info.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function get_context() {
}

protected function get_view_hidden_capability() {
return 'moodle/course:viewhiddensections';
return 'moodle/course:ignoreavailabilityrestrictions';
}

protected function set_in_database($availability) {
Expand Down
4 changes: 2 additions & 2 deletions availability/tests/info_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ public function test_filter_user_list() {
// If the students have viewhiddenactivities, they get past the module
// restriction.
role_change_permission($studentroleid, context_module::instance($page2->cmid),
'moodle/course:viewhiddenactivities', CAP_ALLOW);
'moodle/course:ignoreavailabilityrestrictions', CAP_ALLOW);
$expected = array($u1->id, $u2->id);
$this->assertEquals($expected, array_keys($info->filter_user_list($allusers)));
list ($sql, $params) = $info->get_user_list_sql(true);
Expand All @@ -503,7 +503,7 @@ public function test_filter_user_list() {
// If they have viewhiddensections, they also get past the section
// restriction.
role_change_permission($studentroleid, context_course::instance($course->id),
'moodle/course:viewhiddensections', CAP_ALLOW);
'moodle/course:ignoreavailabilityrestrictions', CAP_ALLOW);
$expected = array($u1->id, $u2->id, $u3->id);
$this->assertEquals($expected, array_keys($info->filter_user_list($allusers)));
list ($sql, $params) = $info->get_user_list_sql(true);
Expand Down
53 changes: 48 additions & 5 deletions course/tests/courseformat_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,32 @@ public function test_available_hook() {
course_create_sections_if_missing($course1, array(0, 1));
$assign0 = $generator->create_module('assign', array('course' => $course1, 'section' => 0));
$assign1 = $generator->create_module('assign', array('course' => $course1, 'section' => 1));
$assign2 = $generator->create_module('assign', array('course' => $course1, 'section' => 0, 'visible' => 0));

// Enrol student and teacher.
$roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
// Create a courseoverview role based on the student role.
$roleattr = array('name' => 'courseoverview', 'shortname' => 'courseoverview', 'archetype' => 'student');
$generator->create_role($roleattr);

// Create user student, editingteacher, teacher and courseoverview.
$student = $generator->create_user();
$generator->enrol_user($student->id, $course1->id, $roleids['student']);
$teacher = $generator->create_user();
$generator->enrol_user($teacher->id, $course1->id, $roleids['editingteacher']);
$editingteacher = $generator->create_user();
$courseoverviewuser = $generator->create_user();

// Enrol users into their roles.
$roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
$generator->enrol_user($student->id, $course1->id, $roleids['student']);
$generator->enrol_user($teacher->id, $course1->id, $roleids['teacher']);
$generator->enrol_user($editingteacher->id, $course1->id, $roleids['editingteacher']);
$generator->enrol_user($courseoverviewuser->id, $course1->id, $roleids['courseoverview']);

// Remove the ignoreavailabilityrestrictions from the teacher role.
role_change_permission($roleids['teacher'], context_system::instance(0),
'moodle/course:ignoreavailabilityrestrictions', CAP_PREVENT);

// Allow the courseoverview role to ingore available restriction.
role_change_permission($roleids['courseoverview'], context_system::instance(0),
'moodle/course:ignoreavailabilityrestrictions', CAP_ALLOW);

// Make sure that initially both sections and both modules are available and visible for a student.
$modinfostudent = get_fast_modinfo($course1, $student->id);
Expand All @@ -55,6 +74,7 @@ public function test_available_hook() {
$this->assertTrue($modinfostudent->get_cm($assign0->cmid)->uservisible);
$this->assertTrue($modinfostudent->get_cm($assign1->cmid)->available);
$this->assertTrue($modinfostudent->get_cm($assign1->cmid)->uservisible);
$this->assertFalse($modinfostudent->get_cm($assign2->cmid)->uservisible);

// Set 'hideoddsections' for the course to 1.
// Section1 and assign1 will be unavailable, uservisible will be false for student and true for teacher.
Expand All @@ -68,15 +88,38 @@ public function test_available_hook() {
$this->assertTrue($modinfostudent->get_cm($assign0->cmid)->uservisible);
$this->assertFalse($modinfostudent->get_cm($assign1->cmid)->available);
$this->assertFalse($modinfostudent->get_cm($assign1->cmid)->uservisible);
$this->assertFalse($modinfostudent->get_cm($assign2->cmid)->uservisible);

$modinfoteacher = get_fast_modinfo($course1, $teacher->id);
$this->assertFalse($modinfoteacher->get_section_info(1)->available);
$this->assertEmpty($modinfoteacher->get_section_info(1)->availableinfo);
$this->assertFalse($modinfoteacher->get_section_info(1)->uservisible);
$this->assertTrue($modinfoteacher->get_cm($assign0->cmid)->available);
$this->assertTrue($modinfoteacher->get_cm($assign0->cmid)->uservisible);
$this->assertFalse($modinfoteacher->get_cm($assign1->cmid)->available);
$this->assertFalse($modinfoteacher->get_cm($assign1->cmid)->uservisible);
$this->assertTrue($modinfoteacher->get_cm($assign2->cmid)->available);
$this->assertTrue($modinfoteacher->get_cm($assign2->cmid)->uservisible);

$modinfoteacher = get_fast_modinfo($course1, $editingteacher->id);
$this->assertFalse($modinfoteacher->get_section_info(1)->available);
$this->assertEmpty($modinfoteacher->get_section_info(1)->availableinfo);
$this->assertTrue($modinfoteacher->get_section_info(1)->uservisible);
$this->assertTrue($modinfoteacher->get_cm($assign0->cmid)->available);
$this->assertTrue($modinfoteacher->get_cm($assign0->cmid)->uservisible);
$this->assertFalse($modinfoteacher->get_cm($assign1->cmid)->available);
$this->assertTrue($modinfoteacher->get_cm($assign1->cmid)->uservisible);
$this->assertTrue($modinfoteacher->get_cm($assign2->cmid)->uservisible);

$modinfocourseoverview = get_fast_modinfo($course1, $courseoverviewuser->id);
$this->assertFalse($modinfocourseoverview->get_section_info(1)->available);
$this->assertEmpty($modinfocourseoverview->get_section_info(1)->availableinfo);
$this->assertTrue($modinfocourseoverview->get_section_info(1)->uservisible);
$this->assertTrue($modinfocourseoverview->get_cm($assign0->cmid)->available);
$this->assertTrue($modinfocourseoverview->get_cm($assign0->cmid)->uservisible);
$this->assertFalse($modinfocourseoverview->get_cm($assign1->cmid)->available);
$this->assertTrue($modinfocourseoverview->get_cm($assign1->cmid)->uservisible);
$this->assertFalse($modinfocourseoverview->get_cm($assign2->cmid)->uservisible);

// Set 'hideoddsections' for the course to 2.
// Section1 and assign1 will be unavailable, uservisible will be false for student and true for teacher.
Expand All @@ -92,7 +135,7 @@ public function test_available_hook() {
$this->assertFalse($modinfostudent->get_cm($assign1->cmid)->available);
$this->assertFalse($modinfostudent->get_cm($assign1->cmid)->uservisible);

$modinfoteacher = get_fast_modinfo($course1, $teacher->id);
$modinfoteacher = get_fast_modinfo($course1, $editingteacher->id);
$this->assertFalse($modinfoteacher->get_section_info(1)->available);
$this->assertNotEmpty($modinfoteacher->get_section_info(1)->availableinfo);
$this->assertTrue($modinfoteacher->get_section_info(1)->uservisible);
Expand Down
1 change: 1 addition & 0 deletions lang/en/role.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
$string['course:changesummary'] = 'Change course summary';
$string['course:enrolconfig'] = 'Configure enrol instances in courses';
$string['course:enrolreview'] = 'Review course enrolments';
$string['course:ignoreavailabilityrestrictions'] = 'Ignore availability restrictions';
$string['course:ignorefilesizelimits'] = 'Use files larger than any file size restrictions';
$string['course:isincompletionreports'] = 'Be shown on completion reports';
$string['course:manageactivities'] = 'Manage activities';
Expand Down
12 changes: 12 additions & 0 deletions lib/db/access.php
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,18 @@
)
),

'moodle/course:ignoreavailabilityrestrictions' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
),
'clonepermissionsfrom' => 'moodle/course:viewhiddenactivities'
),

'moodle/course:ignorefilesizelimits' => array(

'captype' => 'write',
Expand Down
10 changes: 7 additions & 3 deletions lib/modinfolib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1930,8 +1930,9 @@ private function update_user_visible() {

// If the user cannot access the activity set the uservisible flag to false.
// Additional checks are required to determine whether the activity is entirely hidden or just greyed out.
if ((!$this->visible or !$this->get_available()) and
!has_capability('moodle/course:viewhiddenactivities', $this->get_context(), $userid)) {
if ((!$this->visible && !has_capability('moodle/course:viewhiddenactivities', $this->get_context(), $userid)) ||
(!$this->get_available() &&
!has_capability('moodle/course:ignoreavailabilityrestrictions', $this->get_context(), $userid))) {

$this->uservisible = false;
}
Expand Down Expand Up @@ -2760,7 +2761,10 @@ private function get_uservisible() {
$this->_uservisible = true;
if (!$this->_visible || !$this->get_available()) {
$coursecontext = context_course::instance($this->get_course());
if (!has_capability('moodle/course:viewhiddensections', $coursecontext, $userid)) {
if (!$this->_visible && !has_capability('moodle/course:viewhiddensections', $coursecontext, $userid) ||
(!$this->get_available() &&
!has_capability('moodle/course:ignoreavailabilityrestrictions', $coursecontext, $userid))) {

$this->_uservisible = false;
}
}
Expand Down

0 comments on commit 6a36b85

Please sign in to comment.