From 23765039d4a8676659e0a11bd729aeb5594769f0 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Fri, 8 Jan 2021 17:34:55 +0000 Subject: [PATCH] MDL-69816 tool_uploadcourse: configure course content download value. --- admin/tool/uploadcourse/classes/course.php | 25 ++++- .../tool/uploadcourse/classes/step2_form.php | 18 ++++ .../lang/en/tool_uploadcourse.php | 2 + admin/tool/uploadcourse/tests/course_test.php | 98 ++++++++++++++++++- 4 files changed, 140 insertions(+), 3 deletions(-) diff --git a/admin/tool/uploadcourse/classes/course.php b/admin/tool/uploadcourse/classes/course.php index 4c45b1a0bb6..6d6433c44eb 100644 --- a/admin/tool/uploadcourse/classes/course.php +++ b/admin/tool/uploadcourse/classes/course.php @@ -95,7 +95,7 @@ class tool_uploadcourse_course { /** @var array fields allowed as course data. */ static protected $validfields = array('fullname', 'shortname', 'idnumber', 'category', 'visible', 'startdate', 'enddate', 'summary', 'format', 'theme', 'lang', 'newsitems', 'showgrades', 'showreports', 'legacyfiles', 'maxbytes', - 'groupmode', 'groupmodeforce', 'enablecompletion'); + 'groupmode', 'groupmodeforce', 'enablecompletion', 'downloadcontent'); /** @var array fields required on course creation. */ static protected $mandatoryfields = array('fullname', 'category'); @@ -412,7 +412,8 @@ class tool_uploadcourse_course { * @return bool false is any error occured. */ public function prepare() { - global $DB, $SITE; + global $DB, $SITE, $CFG; + $this->prepared = true; // Validate the shortname. @@ -768,6 +769,26 @@ class tool_uploadcourse_course { return false; } + // Ensure that user is allowed to configure course content download and the field contains a valid value. + if (isset($coursedata['downloadcontent'])) { + if (!$CFG->downloadcoursecontentallowed || + !has_capability('moodle/course:configuredownloadcontent', $context)) { + + $this->error('downloadcontentnotallowed', new lang_string('downloadcontentnotallowed', 'tool_uploadcourse')); + return false; + } + + $downloadcontentvalues = [ + DOWNLOAD_COURSE_CONTENT_DISABLED, + DOWNLOAD_COURSE_CONTENT_ENABLED, + DOWNLOAD_COURSE_CONTENT_SITE_DEFAULT, + ]; + if (!in_array($coursedata['downloadcontent'], $downloadcontentvalues)) { + $this->error('invaliddownloadcontent', new lang_string('invaliddownloadcontent', 'tool_uploadcourse')); + return false; + } + } + // Saving data. $this->data = $coursedata; diff --git a/admin/tool/uploadcourse/classes/step2_form.php b/admin/tool/uploadcourse/classes/step2_form.php index 9f1a79927aa..a6875f68263 100644 --- a/admin/tool/uploadcourse/classes/step2_form.php +++ b/admin/tool/uploadcourse/classes/step2_form.php @@ -93,6 +93,24 @@ class tool_uploadcourse_step2_form extends tool_uploadcourse_base_form { $mform->addHelpButton('defaults[visible]', 'coursevisibility'); $mform->setDefault('defaults[visible]', $courseconfig->visible); + if ($CFG->downloadcoursecontentallowed && + has_capability('moodle/course:configuredownloadcontent', context::instance_by_id($contextid))) { + + $downloadchoices = [ + DOWNLOAD_COURSE_CONTENT_DISABLED => get_string('no'), + DOWNLOAD_COURSE_CONTENT_ENABLED => get_string('yes'), + ]; + + $sitedefaultstring = $downloadchoices[$courseconfig->downloadcontentsitedefault]; + $downloadchoices[DOWNLOAD_COURSE_CONTENT_SITE_DEFAULT] = get_string('sitedefaultspecified', '', $sitedefaultstring); + $downloadselectdefault = $courseconfig->downloadcontent ?? DOWNLOAD_COURSE_CONTENT_SITE_DEFAULT; + + $mform->addElement('select', 'defaults[downloadcontent]', get_string('enabledownloadcoursecontent', 'course'), + $downloadchoices); + $mform->addHelpButton('defaults[downloadcontent]', 'downloadcoursecontent', 'course'); + $mform->setDefault('defaults[downloadcontent]', $downloadselectdefault); + } + $mform->addElement('date_time_selector', 'defaults[startdate]', get_string('startdate')); $mform->addHelpButton('defaults[startdate]', 'startdate'); $mform->setDefault('defaults[startdate]', time() + 3600 * 24); diff --git a/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php b/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php index 9a96d1091e1..4eb3720c4b2 100644 --- a/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php +++ b/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php @@ -76,6 +76,7 @@ $string['csvfileerror'] = 'There is something wrong with the format of the CSV f $string['csvline'] = 'Line'; $string['defaultvalues'] = 'Default course values'; $string['defaultvaluescustomfieldcategory'] = 'Default values for \'{$a}\''; +$string['downloadcontentnotallowed'] = 'Configuring download of course content not allowed'; $string['encoding'] = 'Encoding'; $string['encoding_help'] = 'Encoding of the CSV file.'; $string['errorcannotcreateorupdateenrolment'] = 'Cannot create or update enrolment method \'{$a}\''; @@ -91,6 +92,7 @@ $string['idnumberalreadyinuse'] = 'ID number already used by a course'; $string['invalidbackupfile'] = 'Invalid backup file'; $string['invalidcourseformat'] = 'Invalid course format'; $string['invalidcsvfile'] = 'Invalid input CSV file'; +$string['invaliddownloadcontent'] = 'Invalid download of course content value'; $string['invalidencoding'] = 'Invalid encoding'; $string['invalidmode'] = 'Invalid mode selected'; $string['invalideupdatemode'] = 'Invalid update mode selected'; diff --git a/admin/tool/uploadcourse/tests/course_test.php b/admin/tool/uploadcourse/tests/course_test.php index cd3dd413a62..7a2108e205d 100644 --- a/admin/tool/uploadcourse/tests/course_test.php +++ b/admin/tool/uploadcourse/tests/course_test.php @@ -119,6 +119,88 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $this->assertArrayHasKey('invalidvisibilitymode', $co->get_errors()); } + /** + * Test setting 'downloadcontent' field when the feature is globally disabled + */ + public function test_downloadcontent_disabled(): void { + $this->resetAfterTest(); + $this->setAdminUser(); + + set_config('downloadcoursecontentallowed', 0); + + $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; + $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; + + $upload = new tool_uploadcourse_course($mode, $updatemode, [ + 'category' => 1, + 'fullname' => 'Testing', + 'shortname' => 'T101', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_ENABLED, + ]); + + $this->assertFalse($upload->prepare()); + $this->assertArrayHasKey('downloadcontentnotallowed', $upload->get_errors()); + } + + /** + * Test setting 'downloadcontent' field when user doesn't have required capability + */ + public function test_downloadcontent_capability(): void { + global $DB; + + $this->resetAfterTest(); + + set_config('downloadcoursecontentallowed', 1); + + // Create category in which to create the new course. + $category = $this->getDataGenerator()->create_category(); + $categorycontext = context_coursecat::instance($category->id); + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + + // Assign the user as a manager of the category, disable ability to configure course content download. + $roleid = $DB->get_field('role', 'id', ['shortname' => 'manager']); + role_assign($roleid, $user->id, $categorycontext); + role_change_permission($roleid, $categorycontext, 'moodle/course:configuredownloadcontent', CAP_PROHIBIT); + + $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; + $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; + + $upload = new tool_uploadcourse_course($mode, $updatemode, [ + 'category' => $category->id, + 'fullname' => 'Testing', + 'shortname' => 'T101', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_ENABLED, + ]); + + $this->assertFalse($upload->prepare()); + $this->assertArrayHasKey('downloadcontentnotallowed', $upload->get_errors()); + } + + /** + * Test setting 'downloadcontent' field to an invalid value + */ + public function test_downloadcontent_invalid(): void { + $this->resetAfterTest(); + $this->setAdminUser(); + + set_config('downloadcoursecontentallowed', 1); + + $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; + $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; + + $upload = new tool_uploadcourse_course($mode, $updatemode, [ + 'category' => 1, + 'fullname' => 'Testing', + 'shortname' => 'T101', + 'downloadcontent' => 42, + ]); + + $this->assertFalse($upload->prepare()); + $this->assertArrayHasKey('invaliddownloadcontent', $upload->get_errors()); + } + public function test_create() { global $DB; $this->resetAfterTest(true); @@ -322,10 +404,12 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { public function test_data_saved() { global $DB; - $this->resetAfterTest(true); + $this->resetAfterTest(true); $this->setAdminUser(); // To avoid warnings related to 'moodle/course:setforcedlanguage' capability check. + set_config('downloadcoursecontentallowed', 1); + // Create. $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; $updatemode = tool_uploadcourse_processor::UPDATE_NOTHING; @@ -334,6 +418,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'fullname' => 'Fullname', 'category' => '1', 'visible' => '0', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_DISABLED, 'idnumber' => '123abc', 'summary' => 'Summary', 'format' => 'topics', @@ -384,6 +469,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $this->assertEquals($data['fullname'], $course->fullname); $this->assertEquals($data['category'], $course->category); $this->assertEquals($data['visible'], $course->visible); + $this->assertEquals($data['downloadcontent'], $course->downloadcontent); $this->assertEquals(mktime(0, 0, 0, 6, 8, 1990), $course->startdate); $this->assertEquals(mktime(0, 0, 0, 6, 18, 1990), $course->enddate); $this->assertEquals($data['idnumber'], $course->idnumber); @@ -437,6 +523,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'fullname' => 'Fullname 2', 'category' => $cat->id, 'visible' => '1', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_ENABLED, 'idnumber' => 'changeidn', 'summary' => 'Summary 2', 'format' => 'topics', @@ -487,6 +574,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $this->assertEquals($data['fullname'], $course->fullname); $this->assertEquals($data['category'], $course->category); $this->assertEquals($data['visible'], $course->visible); + $this->assertEquals($data['downloadcontent'], $course->downloadcontent); $this->assertEquals(mktime(0, 0, 0, 6, 11, 1984), $course->startdate); $this->assertEquals(mktime(0, 0, 0, 6, 31, 1984), $course->enddate); $this->assertEquals($data['idnumber'], $course->idnumber); @@ -531,7 +619,11 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { public function test_default_data_saved() { global $DB; + $this->resetAfterTest(true); + $this->setAdminUser(); + + set_config('downloadcoursecontentallowed', 1); // Create. $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; @@ -543,6 +635,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'fullname' => 'Fullname', 'category' => '1', 'visible' => '0', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_DISABLED, 'startdate' => 644803200, 'enddate' => 645667200, 'idnumber' => '123abc', @@ -571,6 +664,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $this->assertEquals($defaultdata['fullname'], $course->fullname); $this->assertEquals($defaultdata['category'], $course->category); $this->assertEquals($defaultdata['visible'], $course->visible); + $this->assertEquals($defaultdata['downloadcontent'], $course->downloadcontent); $this->assertEquals($defaultdata['startdate'], $course->startdate); $this->assertEquals($defaultdata['enddate'], $course->enddate); $this->assertEquals($defaultdata['idnumber'], $course->idnumber); @@ -598,6 +692,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'fullname' => 'Fullname 2', 'category' => $cat->id, 'visible' => '1', + 'downloadcontent' => DOWNLOAD_COURSE_CONTENT_ENABLED, 'startdate' => 455760000, 'enddate' => 457488000, 'idnumber' => 'changedid', @@ -626,6 +721,7 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $this->assertEquals($defaultdata['fullname'], $course->fullname); $this->assertEquals($defaultdata['category'], $course->category); $this->assertEquals($defaultdata['visible'], $course->visible); + $this->assertEquals($defaultdata['downloadcontent'], $course->downloadcontent); $this->assertEquals($defaultdata['startdate'], $course->startdate); $this->assertEquals($defaultdata['enddate'], $course->enddate); $this->assertEquals($defaultdata['idnumber'], $course->idnumber);