MDL-77544 enrol_database: include start and end dates
This commit is contained in:
@@ -49,11 +49,15 @@ $string['localcategoryfield'] = 'Local category field';
|
||||
$string['localcoursefield'] = 'Local course field';
|
||||
$string['localrolefield'] = 'Local role field';
|
||||
$string['localuserfield'] = 'Local user field';
|
||||
$string['newcourseenddate'] = 'New course end date field';
|
||||
$string['newcourseenddate_desc'] = 'Optional. If not set, then the course end date will be set as configured default course duration. If set, then template value will be overridden.';
|
||||
$string['newcoursetable'] = 'Remote new courses table';
|
||||
$string['newcoursetable_desc'] = 'Specify of the name of the table that contains list of courses that should be created automatically. Empty means no courses are created.';
|
||||
$string['newcoursecategory'] = 'New course category field';
|
||||
$string['newcoursefullname'] = 'New course full name field';
|
||||
$string['newcourseidnumber'] = 'New course ID number field';
|
||||
$string['newcoursestartdate'] = 'New course start date field';
|
||||
$string['newcoursestartdate_desc'] = 'Optional. If not set then, the course start date will be set to the current date. If set, then template value will be overridden.';
|
||||
$string['newcourseshortname'] = 'New course short name field';
|
||||
$string['pluginname'] = 'External database';
|
||||
$string['pluginname_desc'] = 'You can use an external database (of nearly any kind) to control your enrolments. It is assumed your external database contains at least a field containing a course ID, and a field containing a user ID. These are compared against fields that you choose in the local course and user tables.';
|
||||
|
||||
+63
-1
@@ -669,17 +669,24 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$courseconfig = get_config('moodlecourse');
|
||||
|
||||
$table = $this->get_config('newcoursetable');
|
||||
$fullname = trim($this->get_config('newcoursefullname'));
|
||||
$shortname = trim($this->get_config('newcourseshortname'));
|
||||
$idnumber = trim($this->get_config('newcourseidnumber'));
|
||||
$category = trim($this->get_config('newcoursecategory'));
|
||||
|
||||
$startdate = trim($this->get_config('newcoursestartdate'));
|
||||
$enddate = trim($this->get_config('newcourseenddate'));
|
||||
|
||||
// Lowercased versions - necessary because we normalise the resultset with array_change_key_case().
|
||||
$fullname_l = strtolower($fullname);
|
||||
$shortname_l = strtolower($shortname);
|
||||
$idnumber_l = strtolower($idnumber);
|
||||
$category_l = strtolower($category);
|
||||
$startdatelowercased = strtolower($startdate);
|
||||
$enddatelowercased = strtolower($enddate);
|
||||
|
||||
$localcategoryfield = $this->get_config('localcategoryfield', 'id');
|
||||
$defaultcategory = $this->get_config('defaultcategory');
|
||||
@@ -698,6 +705,13 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
if ($idnumber) {
|
||||
$sqlfields[] = $idnumber;
|
||||
}
|
||||
if ($startdate) {
|
||||
$sqlfields[] = $startdate;
|
||||
}
|
||||
if ($enddate) {
|
||||
$sqlfields[] = $enddate;
|
||||
}
|
||||
|
||||
$sql = $this->db_get_sql($table, array(), $sqlfields, true);
|
||||
$createcourses = array();
|
||||
if ($rs = $extdb->Execute($sql)) {
|
||||
@@ -722,6 +736,7 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
$course->fullname = $fields[$fullname_l];
|
||||
$course->shortname = $fields[$shortname_l];
|
||||
$course->idnumber = $idnumber ? $fields[$idnumber_l] : '';
|
||||
|
||||
if ($category) {
|
||||
if (empty($fields[$category_l])) {
|
||||
// Empty category means use default.
|
||||
@@ -738,6 +753,35 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
} else {
|
||||
$course->category = $defaultcategory;
|
||||
}
|
||||
|
||||
if ($startdate) {
|
||||
if (!empty($fields[$startdatelowercased])) {
|
||||
$course->startdate = is_number($fields[$startdatelowercased])
|
||||
? $fields[$startdatelowercased]
|
||||
: strtotime($fields[$startdatelowercased]);
|
||||
|
||||
// Broken start date. Stop syncing this course.
|
||||
if ($course->startdate === false) {
|
||||
$trace->output('error: invalid external course start date value: ' . json_encode($fields), 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($enddate) {
|
||||
if (!empty($fields[$enddatelowercased])) {
|
||||
$course->enddate = is_number($fields[$enddatelowercased])
|
||||
? $fields[$enddatelowercased]
|
||||
: strtotime($fields[$enddatelowercased]);
|
||||
|
||||
// Broken end date. Stop syncing this course.
|
||||
if ($course->enddate === false) {
|
||||
$trace->output('error: invalid external course end date value: ' . json_encode($fields), 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$createcourses[] = $course;
|
||||
}
|
||||
}
|
||||
@@ -769,7 +813,6 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
}
|
||||
}
|
||||
if (!$template) {
|
||||
$courseconfig = get_config('moodlecourse');
|
||||
$template = new stdClass();
|
||||
$template->summary = '';
|
||||
$template->summaryformat = FORMAT_HTML;
|
||||
@@ -798,6 +841,25 @@ class enrol_database_plugin extends enrol_plugin {
|
||||
$newcourse->idnumber = $fields->idnumber;
|
||||
$newcourse->category = $fields->category;
|
||||
|
||||
if (isset($fields->startdate)) {
|
||||
$newcourse->startdate = $fields->startdate;
|
||||
}
|
||||
|
||||
if (isset($fields->enddate)) {
|
||||
// Validating end date.
|
||||
if ($fields->enddate > 0 && $newcourse->startdate > $fields->enddate) {
|
||||
$trace->output(
|
||||
"can not insert new course, the end date must be after the start date: " . $newcourse->shortname, 1
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$newcourse->enddate = $fields->enddate;
|
||||
} else {
|
||||
if ($courseconfig->courseenddateenabled) {
|
||||
$newcourse->enddate = $newcourse->startdate + $courseconfig->courseduration;
|
||||
}
|
||||
}
|
||||
|
||||
// Detect duplicate data once again, above we can not find duplicates
|
||||
// in external data using DB collation rules...
|
||||
if ($DB->record_exists('course', array('shortname' => $newcourse->shortname))) {
|
||||
|
||||
@@ -113,6 +113,16 @@ if ($ADMIN->fulltree) {
|
||||
|
||||
$settings->add(new admin_setting_configtext('enrol_database/newcourseidnumber', get_string('newcourseidnumber', 'enrol_database'), '', 'idnumber'));
|
||||
|
||||
$settings->add(new admin_setting_configtext(
|
||||
'enrol_database/newcoursestartdate',
|
||||
get_string('newcoursestartdate', 'enrol_database'),
|
||||
get_string('newcoursestartdate_desc', 'enrol_database'), ''));
|
||||
|
||||
$settings->add(new admin_setting_configtext(
|
||||
'enrol_database/newcourseenddate',
|
||||
get_string('newcourseenddate', 'enrol_database'),
|
||||
get_string('newcourseenddate_desc', 'enrol_database'), ''));
|
||||
|
||||
$settings->add(new admin_setting_configtext('enrol_database/newcoursecategory', get_string('newcoursecategory', 'enrol_database'), '', ''));
|
||||
|
||||
$settings->add(new admin_settings_coursecat_select('enrol_database/defaultcategory',
|
||||
|
||||
@@ -151,6 +151,8 @@ class sync_test extends \advanced_testcase {
|
||||
$table->add_field('shortname', XMLDB_TYPE_CHAR, '255', null, null, null);
|
||||
$table->add_field('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null);
|
||||
$table->add_field('category', XMLDB_TYPE_CHAR, '255', null, null, null);
|
||||
$table->add_field('startdate', XMLDB_TYPE_CHAR, '255', null, null, null);
|
||||
$table->add_field('enddate', XMLDB_TYPE_CHAR, '255', null, null, null);
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
||||
if ($dbman->table_exists($table)) {
|
||||
$dbman->drop_table($table);
|
||||
@@ -441,7 +443,6 @@ class sync_test extends \advanced_testcase {
|
||||
|
||||
// Test basic enrol sync for one user after login.
|
||||
|
||||
$this->reset_enrol_database();
|
||||
$plugin->set_config('localcoursefield', 'idnumber');
|
||||
$plugin->set_config('localuserfield', 'idnumber');
|
||||
$plugin->set_config('localrolefield', 'shortname');
|
||||
@@ -799,8 +800,148 @@ class sync_test extends \advanced_testcase {
|
||||
$this->assertEquals(1+2+1+4+1+count(self::$courses), $DB->count_records('course'));
|
||||
$this->assertTrue($DB->record_exists('course', array('idnumber' => 'ncid9')));
|
||||
|
||||
|
||||
// Final cleanup - remove extra tables, fixtures and caches.
|
||||
$this->cleanup_enrol_database();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test syncing courses with start and end dates.
|
||||
*
|
||||
* @covers \enrol_database_plugin::sync_courses
|
||||
*/
|
||||
public function test_sync_courses_start_end_dates(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->preventResetByRollback();
|
||||
$this->init_enrol_database();
|
||||
|
||||
$courseconfig = get_config('moodlecourse');
|
||||
$nextyear = (int) date('Y') + 1;
|
||||
$prev = (int) date('Y') - 1;
|
||||
|
||||
$midnightstartdate = usergetmidnight(time());
|
||||
$midnightenddate = usergetmidnight(time()) + $courseconfig->courseduration;
|
||||
|
||||
$plugin = enrol_get_plugin('database');
|
||||
|
||||
$trace = new \null_progress_trace();
|
||||
|
||||
$course1 = ['fullname' => 'C1', 'shortname' => 'c1', 'idnumber' => '', 'startdate' => 0,
|
||||
'enddate' => 0];
|
||||
$course2 = ['fullname' => 'C2', 'shortname' => 'c2', 'idnumber' => '', 'startdate' => null,
|
||||
'enddate' => null];
|
||||
// This course won't be created. Broken start date.
|
||||
$course3 = ['fullname' => 'C3', 'shortname' => 'c3', 'idnumber' => '', 'startdate' => 'not date',
|
||||
'enddate' => 0];
|
||||
// This course won't be created. Broken end date.
|
||||
$course4 = ['fullname' => 'C4', 'shortname' => 'c4', 'idnumber' => '', 'startdate' => 0,
|
||||
'enddate' => 'not date'];
|
||||
// This course won't be created. Start date after end date.
|
||||
$course5 = ['fullname' => 'C5', 'shortname' => 'c5', 'idnumber' => '', 'startdate' => '12.05.2024',
|
||||
'enddate' => '12.05.2021'];
|
||||
$course6 = ['fullname' => 'C6', 'shortname' => 'c6', 'idnumber' => '', 'startdate' => '2024-05-22',
|
||||
'enddate' => '2027-05-12'];
|
||||
$course7 = ['fullname' => 'C7', 'shortname' => 'c7', 'idnumber' => '', 'startdate' => null,
|
||||
'enddate' => '12.05.' . $nextyear];
|
||||
$course8 = ['fullname' => 'C8', 'shortname' => 'c8', 'idnumber' => '', 'startdate' => '12.05.2024',
|
||||
'enddate' => null];
|
||||
// This course won't be created. Start date is not set, but it should be set to date after end date.
|
||||
$course9 = ['fullname' => 'C9', 'shortname' => 'c9', 'idnumber' => '', 'startdate' => null,
|
||||
'enddate' => '12.05.' . $prev];
|
||||
|
||||
$DB->insert_record('enrol_database_test_courses', $course1);
|
||||
$DB->insert_record('enrol_database_test_courses', $course2);
|
||||
$DB->insert_record('enrol_database_test_courses', $course3);
|
||||
$DB->insert_record('enrol_database_test_courses', $course4);
|
||||
$DB->insert_record('enrol_database_test_courses', $course5);
|
||||
$DB->insert_record('enrol_database_test_courses', $course6);
|
||||
$DB->insert_record('enrol_database_test_courses', $course7);
|
||||
$DB->insert_record('enrol_database_test_courses', $course8);
|
||||
$DB->insert_record('enrol_database_test_courses', $course9);
|
||||
|
||||
// Mess with case as we need to check that fields are lower cased.
|
||||
$plugin->set_config('newcoursestartdate', 'StartDaTE');
|
||||
$plugin->set_config('newcourseenddate', 'ENDdATE');
|
||||
|
||||
$plugin->sync_courses($trace);
|
||||
|
||||
// Course 3, course 4, course 5 and course 9 should not be created.
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course1['shortname']]));
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course2['shortname']]));
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course3['shortname']]));
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course4['shortname']]));
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course5['shortname']]));
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course6['shortname']]));
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course7['shortname']]));
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course8['shortname']]));
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course9['shortname']]));
|
||||
|
||||
// Check dates for created courses.
|
||||
$this->assertEquals($midnightstartdate, $DB->get_field('course', 'startdate', ['shortname' => $course1['shortname']]));
|
||||
$this->assertEquals($midnightenddate, $DB->get_field('course', 'enddate', ['shortname' => $course1['shortname']]));
|
||||
|
||||
$this->assertEquals($midnightstartdate, $DB->get_field('course', 'startdate', ['shortname' => $course2['shortname']]));
|
||||
$this->assertEquals($midnightenddate, $DB->get_field('course', 'enddate', ['shortname' => $course2['shortname']]));
|
||||
|
||||
$this->assertEquals(strtotime('22.05.2024'), $DB->get_field('course', 'startdate', ['shortname' => $course6['shortname']]));
|
||||
$this->assertEquals(strtotime('12.05.2027'), $DB->get_field('course', 'enddate', ['shortname' => $course6['shortname']]));
|
||||
|
||||
$this->assertEquals($midnightstartdate, $DB->get_field('course', 'startdate', ['shortname' => $course7['shortname']]));
|
||||
$expected = strtotime('12.05.' . $nextyear);
|
||||
$this->assertEquals($expected, $DB->get_field('course', 'enddate', ['shortname' => $course7['shortname']]));
|
||||
|
||||
$this->assertEquals(strtotime('12.05.2024'), $DB->get_field('course', 'startdate', ['shortname' => $course8['shortname']]));
|
||||
$expected = strtotime('12.05.2024') + $courseconfig->courseduration;
|
||||
$this->assertEquals($expected, $DB->get_field('course', 'enddate', ['shortname' => $course8['shortname']]));
|
||||
|
||||
// Push course with dates as timestamp.
|
||||
$course10 = ['fullname' => 'C10', 'shortname' => 'c10', 'idnumber' => '', 'startdate' => 1810051200,
|
||||
'enddate' => 1810051211];
|
||||
$DB->insert_record('enrol_database_test_courses', $course10);
|
||||
|
||||
$plugin->sync_courses($trace);
|
||||
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course10['shortname']]));
|
||||
$this->assertEquals(1810051200, $DB->get_field('course', 'startdate', ['shortname' => $course10['shortname']]));
|
||||
$this->assertEquals(1810051211, $DB->get_field('course', 'enddate', ['shortname' => $course10['shortname']]));
|
||||
|
||||
// Push course with broken dates, but delete dates from plugin configuration before syncing.
|
||||
$course11 = ['fullname' => 'C11', 'shortname' => 'c11', 'idnumber' => '', 'startdate' => 'not date',
|
||||
'enddate' => 'not date'];
|
||||
$DB->insert_record('enrol_database_test_courses', $course11);
|
||||
|
||||
$plugin->set_config('newcoursestartdate', '');
|
||||
$plugin->set_config('newcourseenddate', '');
|
||||
$plugin->sync_courses($trace);
|
||||
|
||||
$this->assertTrue($DB->record_exists('course', ['shortname' => $course11['shortname']]));
|
||||
$this->assertEquals($midnightstartdate, $DB->get_field('course', 'startdate', ['shortname' => $course11['shortname']]));
|
||||
$this->assertEquals($midnightenddate, $DB->get_field('course', 'enddate', ['shortname' => $course11['shortname']]));
|
||||
|
||||
// Push courses with correct dates, but set date configuration to not existing date fields.
|
||||
$course12 = ['fullname' => 'C12', 'shortname' => 'c12', 'idnumber' => '', 'startdate' => '2024-05-22',
|
||||
'enddate' => '2027-05-12'];
|
||||
$DB->insert_record('enrol_database_test_courses', $course11);
|
||||
|
||||
$plugin->set_config('newcoursestartdate', 'startdate');
|
||||
$plugin->set_config('newcourseenddate', 'ed');
|
||||
$plugin->sync_courses($trace);
|
||||
|
||||
// Course should not be synced to prevent setting up incorrect dates.
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course12['shortname']]));
|
||||
|
||||
$course13 = ['fullname' => 'C13', 'shortname' => 'c13', 'idnumber' => '', 'startdate' => '2024-05-22',
|
||||
'enddate' => '2027-05-12'];
|
||||
$DB->insert_record('enrol_database_test_courses', $course11);
|
||||
|
||||
$plugin->set_config('newcoursestartdate', 'sd');
|
||||
$plugin->set_config('newcourseenddate', 'enddate');
|
||||
$plugin->sync_courses($trace);
|
||||
|
||||
// Course should not be synced to prevent setting up incorrect dates.
|
||||
$this->assertFalse($DB->record_exists('course', ['shortname' => $course13['shortname']]));
|
||||
|
||||
$this->cleanup_enrol_database();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2024042201; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2024041600; // Requires this Moodle version.
|
||||
$plugin->component = 'enrol_database'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
Reference in New Issue
Block a user