Skip to content

Commit

Permalink
MDL-68843 enrol_lti: auto disable orphaned enrolment instances
Browse files Browse the repository at this point in the history
- pre_course_module_deletion hook to disable on mod delete
- upgrade step dealing with legacy orphaned records
  • Loading branch information
snake committed Jul 18, 2022
1 parent 15eec33 commit 5ac9ff1
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
12 changes: 12 additions & 0 deletions enrol/lti/db/upgrade.php
Expand Up @@ -459,5 +459,17 @@ function xmldb_enrol_lti_upgrade($oldversion) {
// Automatically generated Moodle v4.0.0 release upgrade line.
// Put any upgrade step following this.

if ($oldversion < 2022041901) {
// Disable all orphaned enrolment method instances.
$sql = "id IN (SELECT t.enrolid
FROM {enrol_lti_tools} t
LEFT JOIN {context} c ON (t.contextid = c.id)
WHERE c.id IS NULL)";
$DB->set_field_select('enrol', 'status', 1, $sql);

// Lti savepoint reached.
upgrade_plugin_savepoint(true, 2022041901, 'enrol', 'lti');
}

return true;
}
15 changes: 15 additions & 0 deletions enrol/lti/lib.php
Expand Up @@ -479,3 +479,18 @@ function enrol_lti_get_fontawesome_icon_map() {
'enrol_lti:enrolinstancewarning' => 'fa-exclamation-circle text-danger',
];
}

/**
* Pre-delete course module hook which disables any methods referring to the deleted module, preventing launches and allowing remap.
*
* @param stdClass $cm The deleted course module record.
*/
function enrol_lti_pre_course_module_delete(stdClass $cm) {
global $DB;
$sql = "id IN (SELECT t.enrolid
FROM {enrol_lti_tools} t
JOIN {context} c ON (t.contextid = c.id)
WHERE c.contextlevel = :contextlevel
AND c.instanceid = :cmid)";
$DB->set_field_select('enrol', 'status', ENROL_INSTANCE_DISABLED, $sql, ['contextlevel' => CONTEXT_MODULE, 'cmid' => $cm->id]);
}
32 changes: 32 additions & 0 deletions enrol/lti/tests/lib_test.php
Expand Up @@ -216,4 +216,36 @@ public function test_get_user_enrolment_actions() {
// LTI enrolment has 1 enrol actions for active users -- unenrol.
$this->assertCount(1, $actions);
}

/**
* Test the behaviour of an enrolment method when the activity to which it provides access is deleted.
*
* @covers \enrol_lti_pre_course_module_delete
*/
public function test_course_module_deletion() {
// Create two modules and publish them.
$course = $this->getDataGenerator()->create_course();
$mod = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$mod2 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$tooldata = [
'cmid' => $mod->cmid,
'courseid' => $course->id,
];
$tool = $this->getDataGenerator()->create_lti_tool((object)$tooldata);
$tooldata['cmid'] = $mod2->cmid;
$tool2 = $this->getDataGenerator()->create_lti_tool((object)$tooldata);

// Verify the instances are both enabled.
$modinstance = helper::get_lti_tool($tool->id);
$mod2instance = helper::get_lti_tool($tool2->id);
$this->assertEquals(ENROL_INSTANCE_ENABLED, $modinstance->status);
$this->assertEquals(ENROL_INSTANCE_ENABLED, $mod2instance->status);

// Delete a module and verify the associated instance is disabled.
course_delete_module($mod->cmid);
$modinstance = helper::get_lti_tool($tool->id);
$mod2instance = helper::get_lti_tool($tool2->id);
$this->assertEquals(ENROL_INSTANCE_DISABLED, $modinstance->status);
$this->assertEquals(ENROL_INSTANCE_ENABLED, $mod2instance->status);
}
}
7 changes: 5 additions & 2 deletions enrol/lti/tests/local/ltiadvantage/task/sync_grades_test.php
Expand Up @@ -419,6 +419,8 @@ public function test_sync_grades_no_service_endpoint() {
*/
public function test_sync_grades_deleted_context() {
$this->resetAfterTest();
global $DB;

[$course, $resource] = $this->create_test_environment();
$launchservice = $this->get_tool_launch_service();

Expand All @@ -427,10 +429,11 @@ public function test_sync_grades_deleted_context() {
$instructoruser = $this->getDataGenerator()->create_user();
[$userid] = $launchservice->user_launches_tool($instructoruser, $teachermocklaunch);

global $CFG;
require_once($CFG->dirroot . '/course/lib.php');
// Delete the activity, then enable the enrolment method (it is disabled during activity deletion).
$modcontext = \context::instance_by_id($resource->contextid);
course_delete_module($modcontext->instanceid);
$enrol = ['id' => $resource->enrolid, 'status' => ENROL_INSTANCE_ENABLED];
$DB->update_record('enrol', $enrol);

$task = $this->get_task_with_mocked_grade_service();
$this->expectOutputRegex(
Expand Down
2 changes: 1 addition & 1 deletion enrol/lti/version.php
Expand Up @@ -24,7 +24,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2022041901; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2022041200; // Requires this Moodle version.
$plugin->component = 'enrol_lti'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = [
Expand Down

0 comments on commit 5ac9ff1

Please sign in to comment.