MDL-48762 core: Add scheduled tasks to set course visibility
Two new scheduled tasks, show_started_courses_task and hide_ended_courses_task have been added, to automatically change the course visibility when the start/end course date match the current one. They are disabled by default, to keep the current behaviour. When admins enable any of them, they are executed once per day by default (around midnight). These scheduled tasks are based on the "CUL Course Visibility Update" third-party plugin created by Tim Gagen and refactored and currently maintained by Amanda Doughty: https://moodle.org/plugins/local_culcourse_visibility Thanks!! :-)
This commit is contained in:
@@ -97,6 +97,7 @@ $string['enabledownloadcoursecontent'] = 'Enable download course content';
|
||||
$string['errorendbeforestart'] = 'The end date ({$a}) is before the course start date.';
|
||||
$string['favourite'] = 'Starred course';
|
||||
$string['gradetopassnotset'] = 'This course does not have a grade to pass set. It may be set in the grade item of the course (Gradebook setup).';
|
||||
$string['hideendedcoursestask'] = 'Hide courses on end date';
|
||||
$string['informationformodule'] = 'Information about the {$a} activity';
|
||||
$string['module'] = 'Activity';
|
||||
$string['namewithlink'] = 'Category name with link';
|
||||
@@ -128,6 +129,7 @@ $string['relativedatessubmissionduedatebefore'] = '{$a->datediffstr} before cour
|
||||
$string['searchactivitiesbyname'] = 'Search for activities by name';
|
||||
$string['searchresults'] = 'Search results: {$a}';
|
||||
$string['sectionlink'] = 'Permalink';
|
||||
$string['showstartedcoursestask'] = 'Show courses on start date';
|
||||
$string['submitsearch'] = 'Submit search';
|
||||
$string['studentsatriskincourse'] = 'Students at risk in {$a} course';
|
||||
$string['studentsatriskinfomessage'] = 'Hi {$a->userfirstname},
|
||||
|
||||
@@ -814,6 +814,7 @@ $string['eventcoursecategoryviewed'] = 'Category viewed';
|
||||
$string['eventcoursecontentdeleted'] = 'Course content deleted';
|
||||
$string['eventcoursecreated'] = 'Course created';
|
||||
$string['eventcoursedeleted'] = 'Course deleted';
|
||||
$string['eventcourseended'] = 'Course ended';
|
||||
$string['eventcourseinformationviewed'] = 'Course summary viewed';
|
||||
$string['eventcoursemodulecreated'] = 'Course module created';
|
||||
$string['eventcoursemoduledeleted'] = 'Course module deleted';
|
||||
@@ -823,6 +824,7 @@ $string['eventcoursessearched'] = 'Courses searched';
|
||||
$string['eventcourseresetended'] = 'Course reset ended';
|
||||
$string['eventcourseresetstarted'] = 'Course reset started';
|
||||
$string['eventcourserestored'] = 'Course restored';
|
||||
$string['eventcoursestarted'] = 'Course started';
|
||||
$string['eventcourseupdated'] = 'Course updated';
|
||||
$string['eventcoursesectioncreated'] = 'Course section created';
|
||||
$string['eventcoursesectiondeleted'] = 'Course section deleted';
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\event;
|
||||
|
||||
/**
|
||||
* Course ended event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - string fullname: fullname of course.
|
||||
* - string shortname: (optional) shortname of course.
|
||||
* }
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_ended extends base {
|
||||
|
||||
/**
|
||||
* Initialise the event data.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'course';
|
||||
$this->data['crud'] = 'u';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventcourseended');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-localised description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The course with id '$this->courseid' has ended.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/course/view.php', ['id' => $this->objectid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->other['fullname'])) {
|
||||
throw new \coding_exception('The \'fullname\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_objectid_mapping() {
|
||||
return [
|
||||
'db' => 'course',
|
||||
'restore' => 'course',
|
||||
];
|
||||
}
|
||||
|
||||
public static function get_other_mapping() {
|
||||
// Nothing to map.
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\event;
|
||||
|
||||
/**
|
||||
* Course started event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - string fullname: fullname of course.
|
||||
* - string shortname: (optional) shortname of course.
|
||||
* }
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_started extends base {
|
||||
|
||||
/**
|
||||
* Initialise the event data.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'course';
|
||||
$this->data['crud'] = 'u';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventcoursestarted');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-localised description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The course with id '$this->courseid' has started.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/course/view.php', ['id' => $this->objectid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->other['fullname'])) {
|
||||
throw new \coding_exception('The \'fullname\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_objectid_mapping() {
|
||||
return [
|
||||
'db' => 'course',
|
||||
'restore' => 'course',
|
||||
];
|
||||
}
|
||||
|
||||
public static function get_other_mapping() {
|
||||
// Nothing to map.
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\task;
|
||||
|
||||
/**
|
||||
* Simple task to automatically set the course visibility to hidden when the course end date matches the current day.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]> based on code from 2016 Tim Gagen and Amanda Doughty
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class hide_ended_courses_task extends show_started_courses_task {
|
||||
|
||||
/**
|
||||
* Get a descriptive name for this task (shown to admins).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return get_string('hideendedcoursestask', 'course');
|
||||
}
|
||||
|
||||
protected function get_field_date(): string {
|
||||
return 'enddate';
|
||||
}
|
||||
|
||||
protected function get_visibility(): int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function get_trace_message(): string {
|
||||
return 'Hide';
|
||||
}
|
||||
|
||||
protected function get_event_classname(): string {
|
||||
return '\core\event\course_ended';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\task;
|
||||
|
||||
/**
|
||||
* Simple task to automatically set the course visibility to shown when the course start date matches the current day.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]> based on code from 2016 Tim Gagen and Amanda Doughty
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class show_started_courses_task extends scheduled_task {
|
||||
|
||||
/**
|
||||
* Get a descriptive name for this task (shown to admins).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return get_string('showstartedcoursestask', 'course');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update course visibility.
|
||||
* IMPORTANT: It only processes courses with start/end dates within the past 24 hours and with start/end dates higher than
|
||||
* the current one, to avoid updating the course visibility early.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute() {
|
||||
global $CFG, $DB;
|
||||
|
||||
// Use the configured timezone.
|
||||
date_default_timezone_set($CFG->timezone);
|
||||
|
||||
$start = time();
|
||||
|
||||
// Get list of courses to update.
|
||||
mtrace('\n Searching for courses to set visibility to ' . $this->get_trace_message() . ' ...');
|
||||
$fielddate = $this->get_field_date();
|
||||
// Only process courses with dates in the past 24 hours with start/end dates higher than the current, to avoid updating
|
||||
// the course visibility early.
|
||||
$select = "visible = :visibility AND
|
||||
{$fielddate} BETWEEN :beginofday AND :endofday";
|
||||
$params = [
|
||||
// Get courses that have the opposite visibility to the one we want to set.
|
||||
'visibility' => !$this->get_visibility(),
|
||||
'beginofday' => strtotime('-1 day', $start),
|
||||
'endofday' => $start,
|
||||
];
|
||||
$courses = $DB->get_recordset_select('course', $select, $params);
|
||||
$this->update_courses_visibility($courses, $this->get_visibility());
|
||||
$courses->close();
|
||||
|
||||
$end = time();
|
||||
mtrace(($end - $start) / 60 . ' mins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Make course visible or hidden if the start date has become due.
|
||||
*
|
||||
* @param \moodle_recordset $courses
|
||||
* @param int $visibility The given courses will be set to this visibility
|
||||
* @return void
|
||||
*/
|
||||
private function update_courses_visibility(\moodle_recordset $courses, int $visibility): void {
|
||||
global $DB;
|
||||
|
||||
mtrace("\n There are courses to change visibility...");
|
||||
foreach ($courses as $course) {
|
||||
if (!$DB->set_field('course', 'visible', $visibility, ['id' => $course->id])) {
|
||||
mtrace(" Error updating course visibility for {$course->id}: {$course->shortname}.");
|
||||
} else {
|
||||
mtrace(" {$course->id}: {$course->shortname} visibility is now '" . $this->get_trace_message() . "'");
|
||||
$this->trigger_event($course);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to trigger a course event.
|
||||
*
|
||||
* @param \stdClass $course The course that has been updated.
|
||||
*/
|
||||
private function trigger_event(\stdClass $course): void {
|
||||
$params = [
|
||||
'objectid' => $course->id,
|
||||
'context' => \context_course::instance($course->id),
|
||||
'other' => [
|
||||
'shortname' => $course->shortname,
|
||||
'fullname' => $course->fullname,
|
||||
'idnumber' => $course->idnumber,
|
||||
],
|
||||
];
|
||||
$event = call_user_func([$this->get_event_classname(), 'create'], $params);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database field where the date to check is stored (startdate for showing courses and enddate for hiding courses).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_field_date(): string {
|
||||
return 'startdate';
|
||||
}
|
||||
|
||||
/**
|
||||
* The expected visibility of the courses after running this task (show = 1 and hidden = 0).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get_visibility(): int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The text to display in the trace message about the action that has been applied to the course.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_trace_message(): string {
|
||||
return 'Show';
|
||||
}
|
||||
|
||||
/**
|
||||
* The event classname to be triggered for the courses that need to be updated.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_event_classname(): string {
|
||||
return '\core\event\course_started';
|
||||
}
|
||||
}
|
||||
@@ -437,4 +437,24 @@ $tasks = array(
|
||||
'dayofweek' => '*',
|
||||
'month' => '*'
|
||||
],
|
||||
[
|
||||
'classname' => 'core\task\show_started_courses_task',
|
||||
'blocking' => 0,
|
||||
'minute' => '00',
|
||||
'hour' => '01',
|
||||
'day' => '*',
|
||||
'dayofweek' => '*',
|
||||
'month' => '*',
|
||||
'disabled' => true,
|
||||
],
|
||||
[
|
||||
'classname' => 'core\task\hide_ended_courses_task',
|
||||
'blocking' => 0,
|
||||
'minute' => '00',
|
||||
'hour' => '01',
|
||||
'day' => '*',
|
||||
'dayofweek' => '*',
|
||||
'month' => '*',
|
||||
'disabled' => true,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\task;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once(__DIR__ . '/show_started_courses_task_test.php');
|
||||
|
||||
/**
|
||||
* Class containing unit tests for the hide ended courses task.
|
||||
*
|
||||
* It automatically sets the course visibility to hidden when the course end date matches the current day.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core\task\hide_ended_courses_task
|
||||
*/
|
||||
class hide_ended_courses_task_test extends \core\task\show_started_courses_task_test {
|
||||
|
||||
/**
|
||||
* Test hide_ended_courses cron task.
|
||||
*
|
||||
* @dataProvider get_courses_provider
|
||||
* @covers ::execute
|
||||
*
|
||||
* @param int $nextweekvisible Number of courses with the end date set to next week to be created.
|
||||
* @param int $yesterdayvisible Number of courses with the end date set to yesterday to be created.
|
||||
* @param int $tomorrowvisible Number of courses with the end date set to tomorrow to be created.
|
||||
* @param bool $createhidden Whether hidden courses should be created or not.
|
||||
*/
|
||||
public function test_hide_ended_courses(
|
||||
int $nextweekvisible,
|
||||
int $yesterdayvisible,
|
||||
int $tomorrowvisible,
|
||||
bool $createhidden = true
|
||||
) {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$visiblecourses = [];
|
||||
$hiddencourses = [];
|
||||
|
||||
$now = time();
|
||||
$nextweek = $now + WEEKSECS;
|
||||
$yesterday = $now - DAYSECS + MINSECS;
|
||||
$tomorrow = $now + DAYSECS;
|
||||
|
||||
// Visible course that finishes last week.
|
||||
for ($i = 0; $i < $nextweekvisible; $i++) {
|
||||
$generator->create_course(['visible' => true, 'enddate' => $nextweek]);
|
||||
}
|
||||
// Visible course that finished yesterday.
|
||||
for ($i = 0; $i < $yesterdayvisible; $i++) {
|
||||
$visiblecourses[] = $generator->create_course(
|
||||
['visible' => true, 'startdate' => $yesterday - MINSECS , 'enddate' => $yesterday]
|
||||
)->id;
|
||||
}
|
||||
// Visible course that hasn't finished yet.
|
||||
for ($i = 0; $i < $tomorrowvisible; $i++) {
|
||||
$generator->create_course(['visible' => true, 'enddate' => $tomorrow]);
|
||||
}
|
||||
if ($createhidden) {
|
||||
// Visible course that already finished.
|
||||
$hiddencourses[] = $generator->create_course(
|
||||
['visible' => false, 'startdate' => $yesterday - MINSECS, 'enddate' => $yesterday]
|
||||
)->id;
|
||||
// Visible course that hasn't finished yet.
|
||||
$hiddencourses[] = $generator->create_course(['visible' => false, 'enddate' => $tomorrow])->id;
|
||||
}
|
||||
$hiddentotal = count($hiddencourses);
|
||||
// Course total also includes site course.
|
||||
$coursetotal = $hiddentotal + $nextweekvisible + $yesterdayvisible + $tomorrowvisible + 1;
|
||||
|
||||
// Check current courses have been created correctly.
|
||||
$this->assertEquals($coursetotal, $DB->count_records('course'));
|
||||
$this->assertEquals(count($hiddencourses), $DB->count_records('course', ['visible' => 0]));
|
||||
|
||||
$sink = $this->redirectEvents();
|
||||
|
||||
// Run the hide ended courses task.
|
||||
ob_start();
|
||||
$task = new hide_ended_courses_task();
|
||||
$task->execute();
|
||||
ob_end_clean();
|
||||
|
||||
// Confirm the courses with yesterday as ending date are hidden too. The rest should remain visible.
|
||||
$courses = $DB->get_records('course', ['visible' => 0], '', 'id');
|
||||
$this->assertCount($hiddentotal + $yesterdayvisible, $courses);
|
||||
$expected = array_merge($hiddencourses, $visiblecourses);
|
||||
$this->assertEquals(asort($expected), asort($courses));
|
||||
|
||||
// Check the ended course event has been raised.
|
||||
$events = $sink->get_events();
|
||||
$sink->close();
|
||||
$this->assertCount($yesterdayvisible, $events);
|
||||
foreach ($events as $event) {
|
||||
$this->assertInstanceOf('\\core\\event\\course_ended', $event);
|
||||
$this->assertArrayHasKey($event->courseid, array_flip($expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\task;
|
||||
|
||||
use advanced_testcase;
|
||||
|
||||
/**
|
||||
* Class containing unit tests for the show started courses task.
|
||||
*
|
||||
* It automatically sets the course visibility to shown when the course start date matches the current day.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2023 Sara Arjona <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \core\task\show_started_courses_task
|
||||
*/
|
||||
class show_started_courses_task_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test show_started_courses cron task.
|
||||
*
|
||||
* @dataProvider get_courses_provider
|
||||
* @covers ::execute
|
||||
*
|
||||
* @param int $lastweekhidden Number of courses with the start date set to last week to be created.
|
||||
* @param int $yesterdayhidden Number of courses with the start date set to yesterday to be created.
|
||||
* @param int $tomorrowhidden Number of courses with the start date set to tomorrow to be created.
|
||||
* @param bool $createvisible Whether visible courses should be created or not.
|
||||
*/
|
||||
public function test_show_started_courses(
|
||||
int $lastweekhidden,
|
||||
int $yesterdayhidden,
|
||||
int $tomorrowhidden,
|
||||
bool $createvisible = true
|
||||
) {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$visiblecourses = [];
|
||||
$hiddencourses = [];
|
||||
|
||||
$now = time();
|
||||
$lastweek = $now - WEEKSECS;
|
||||
$yesterday = $now - DAYSECS + 60;
|
||||
$tomorrow = $now + DAYSECS;
|
||||
|
||||
// Hidden course that started last week.
|
||||
for ($i = 0; $i < $lastweekhidden; $i++) {
|
||||
$generator->create_course(['visible' => false, 'startdate' => $lastweek]);
|
||||
}
|
||||
// Hidden course that started yesterday.
|
||||
for ($i = 0; $i < $yesterdayhidden; $i++) {
|
||||
$hiddencourses[] = $generator->create_course(['visible' => false, 'startdate' => $yesterday])->id;
|
||||
}
|
||||
// Hidden course that hasn't started yet.
|
||||
for ($i = 0; $i < $tomorrowhidden; $i++) {
|
||||
$generator->create_course(['visible' => false, 'startdate' => $tomorrow]);
|
||||
}
|
||||
if ($createvisible) {
|
||||
// Visible course that already started.
|
||||
$visiblecourses[] = $generator->create_course(['visible' => true, 'startdate' => $yesterday])->id;
|
||||
// Visible course that hasn't started yet.
|
||||
$visiblecourses[] = $generator->create_course(['visible' => true, 'startdate' => $tomorrow])->id;
|
||||
}
|
||||
$visibletotal = count($visiblecourses) + 1;
|
||||
$coursetotal = $visibletotal + $lastweekhidden + $yesterdayhidden + $tomorrowhidden;
|
||||
|
||||
// Check current courses have been created correctly.
|
||||
$this->assertEquals($coursetotal, $DB->count_records('course'));
|
||||
$this->assertEquals($visibletotal, $DB->count_records('course', ['visible' => 1]));
|
||||
|
||||
$sink = $this->redirectEvents();
|
||||
|
||||
// Run the show started courses task.
|
||||
ob_start();
|
||||
$task = new show_started_courses_task();
|
||||
$task->execute();
|
||||
ob_end_clean();
|
||||
|
||||
// Confirm the courses with yesterday as starting date are visible too. The rest should remain hidden.
|
||||
$this->assertEquals($coursetotal, $DB->count_records('course'));
|
||||
$courses = $DB->get_records('course', ['visible' => 1], '', 'id');
|
||||
$this->assertCount($visibletotal + $yesterdayhidden, $courses);
|
||||
$expected = array_merge($hiddencourses, $visiblecourses);
|
||||
$this->assertEquals(asort($expected), asort($courses));
|
||||
|
||||
// Check the started course event has been raised.
|
||||
$events = $sink->get_events();
|
||||
$sink->close();
|
||||
$this->assertCount($yesterdayhidden, $events);
|
||||
foreach ($events as $event) {
|
||||
$this->assertInstanceOf('\\core\\event\\course_started', $event);
|
||||
$this->assertArrayHasKey($event->courseid, array_flip($expected));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_show_started_courses.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_courses_provider(): array {
|
||||
return [
|
||||
'No hidden courses' => [
|
||||
'lastweek' => 0,
|
||||
'yesterday' => 0,
|
||||
'tomorrow' => 0,
|
||||
],
|
||||
'No hidden courses (without visible courses)' => [
|
||||
'lastweek' => 0,
|
||||
'yesterday' => 0,
|
||||
'tomorrow' => 0,
|
||||
'createvisible' => false,
|
||||
],
|
||||
'Hidden courses with last week or tomorrow dates' => [
|
||||
'lastweek' => 2,
|
||||
'yesterday' => 0,
|
||||
'tomorrow' => 2,
|
||||
],
|
||||
'One hidden course of each type (last week, yesterday and tomorrow)' => [
|
||||
'lastweek' => 1,
|
||||
'yesterday' => 1,
|
||||
'tomorrow' => 1,
|
||||
],
|
||||
'Different hidden courses of each type' => [
|
||||
'lastweek' => 2,
|
||||
'yesterday' => 3,
|
||||
'tomorrow' => 4,
|
||||
],
|
||||
'A couple of hidden courses of each type (without visible courses)' => [
|
||||
'lastweek' => 2,
|
||||
'yesterday' => 2,
|
||||
'tomorrow' => 2,
|
||||
'createvisible' => false,
|
||||
],
|
||||
'Only a few hidden courses for yesterday' => [
|
||||
'lastweek' => 0,
|
||||
'yesterday' => 5,
|
||||
'tomorrow' => 0,
|
||||
],
|
||||
'Only a few hidden courses for yesterday (without visible courses)' => [
|
||||
'lastweek' => 0,
|
||||
'yesterday' => 5,
|
||||
'tomorrow' => 0,
|
||||
'createvisible' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,12 @@ information provided here is intended especially for developers.
|
||||
* Introduce a new public function \core_external\util::generate_token_name()
|
||||
* Legacy (and custom) Behat --skip-passed option has been removed completely. Please, use the standard
|
||||
--rerun option that provides exactly the same (execution of failed scenarios only).
|
||||
* New scheduled tasks show_started_courses_task and hide_ended_courses_task that updates the course visibility when the current
|
||||
day matches course start date/end date. They are disabled by default. Once they are enabled, only courses with start/end dates
|
||||
near the past 24 hours will be checked. The visibility of these courses will only changed when their start/end dates are higher
|
||||
than the current one, to avoid updating the course visibility early.
|
||||
* New events course_started and course_ended have been created. For now, they are triggered when courses change automatically their
|
||||
visibility through the new scheduled tasks to hide/show courses based on their start/end dates.
|
||||
|
||||
=== 4.2 ===
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2023062900.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2023062900.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '4.3dev (Build: 20230629)'; // Human-friendly version name
|
||||
|
||||
Reference in New Issue
Block a user