Skip to content

Commit

Permalink
unenrol
Browse files Browse the repository at this point in the history
  • Loading branch information
rdebleu committed Oct 7, 2024
1 parent e907a5e commit 158f795
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 39 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v4.4.4 (2024-10-07)

* version update
* unenrol when plugin is suppporting self unenrolment
* readme

## v4.4.4 (2024-10-06)

* version update
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Course completed enrolment handles the enrolment of users upon completion of a c
* Administrators can also enrol users who completed past courses.
* Administrators can bulk modify and delete users (works only when 1 instance is installed [MDL-66652](https://tracker.moodle.org/browse/MDL-66652)).
* When a user is part of a group in the first course, the user will also be part of the group with the same name in the second course.
* When a user can use self unenrolment in the course that has to be completed, the enrolment method will try to unenroll this user when configured.
* When you want to enrol all users only after a particular date, configure this date as part of the course completion.
* When you want that this plugin only works for a limited period, configure enrolment start and end date. Before and after this date, this plugin will do nothing.
* Now you can also enrol a user in the future (the welcome message will also be sent only the moment the user is enrolled).
Expand Down Expand Up @@ -83,7 +84,7 @@ Stable

[![Build Status](https://github.com/ewallah/moodle-enrol_coursecompleted/workflows/Tests/badge.svg)](https://github.com/ewallah/moodle-enrol_coursecompleted/actions)
[![Coverage Status](https://coveralls.io/repos/github/ewallah/moodle-enrol_coursecompleted/badge.svg?branch=MOODLE_404_STABLE)](https://coveralls.io/github/ewallah/moodle-enrol_coursecompleted?branch=MOODLE_404_STABLE)
![Mutation score](https://badgen.net/badge/Mutation%20Score%20Indicator/87)
![Mutation score](https://badgen.net/badge/Mutation%20Score%20Indicator/88)

## Copyright

Expand Down
21 changes: 20 additions & 1 deletion classes/hook_listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use core_enrol\hook\after_enrol_instance_status_updated;
use core_enrol\hook\after_user_enrolled;
use core_user;
use moodle_page;
use stdClass;

/**
Expand All @@ -39,7 +40,7 @@ class hook_listener {
* @param \core_enrol\hook\after_user_enrolled $hook
*/
public static function send_course_welcome_message(after_user_enrolled $hook): void {
global $CFG;
global $CFG, $DB;
$instance = $hook->get_enrolinstance();
if ($instance->enrol == 'coursecompleted') {
if (enrol_is_enabled('coursecompleted')) {
Expand Down Expand Up @@ -81,6 +82,24 @@ public static function send_course_welcome_message(after_user_enrolled $hook): v
}
}
}
// Try unenrol the user from the completed course.
if ($instance->customint5 > 0) {
if ($context = context_course::instance($instance->customint1, IGNORE_MISSING)) {
$page = new moodle_page();
require_once($CFG->dirroot . '/enrol/locallib.php');
$course = get_course($instance->customint1);
$cem = new \course_enrolment_manager($page, $course);
$enrols = $cem->get_user_enrolments($hook->get_userid());
foreach ($enrols as $enrol) {
$plugin = enrol_get_plugin($enrol->enrolmentinstance->enrol);
if ($instance = $DB->get_record('enrol', ['id' => $enrol->enrolid], '*', MUST_EXIST)) {
if ($plugin->allow_unenrol_user($instance, $enrol)) {
$plugin->unenrol_user($instance, $hook->get_userid());
}
}
}
}
}
}
}
}
Expand Down
31 changes: 18 additions & 13 deletions classes/plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ public function use_standard_editing_ui(): bool {
* @return bool
*/
public function edit_instance_form($instance, \MoodleQuickForm $mform, $context) {
$plugin = 'enrol_coursecompleted';
$options = [ENROL_INSTANCE_ENABLED => get_string('yes'), ENROL_INSTANCE_DISABLED => get_string('no')];
$mform->addElement('select', 'status', get_string('enabled', 'admin'), $options);
$mform->setDefault('status', $this->get_config('status'));
Expand All @@ -371,40 +372,44 @@ public function edit_instance_form($instance, \MoodleQuickForm $mform, $context)
$mform->setDefault('roleid', $this->get_config('roleid'));

$arr = ['optional' => true, 'defaulttime' => $start];
$mform->addElement('date_time_selector', 'customint4', get_string('enroldate', 'enrol_coursecompleted'), $arr);
$mform->addHelpButton('customint4', 'enroldate', 'enrol_coursecompleted');
$mform->addElement('date_time_selector', 'customint4', get_string('enroldate', $plugin), $arr);
$mform->addHelpButton('customint4', 'enroldate', $plugin);

$arr = ['optional' => true, 'defaultunit' => 86400];
$mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_coursecompleted'), $arr);
$mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', $plugin), $arr);
$mform->setDefault('enrolperiod', $this->get_config('enrolperiod'));
$mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_coursecompleted');
$mform->addHelpButton('enrolperiod', 'enrolperiod', $plugin);

$conditions = ['onlywithcompletion' => true, 'multiple' => false, 'includefrontpage' => false];
$mform->addElement('course', 'customint1', get_string('course'), $conditions);
$mform->addRule('customint1', get_string('required'), 'required', null, 'client');
$mform->addHelpButton('customint1', 'compcourse', 'enrol_coursecompleted');
$mform->addHelpButton('customint1', 'compcourse', $plugin);

$mform->addElement('advcheckbox', 'customint3', get_string('groups'), get_string('group', 'enrol_coursecompleted'));
$mform->addHelpButton('customint3', 'group', 'enrol_coursecompleted');
$mform->addElement('advcheckbox', 'customint5', get_string('unenrol', 'enrol'), get_string('tryunenrol', $plugin));
$mform->addHelpButton('customint5', 'tryunenrol', $plugin);
$mform->setDefault('customint5', $this->get_config('tryunenrol'));

$mform->addElement('advcheckbox', 'customint3', get_string('groups'), get_string('group', $plugin));
$mform->addHelpButton('customint3', 'group', $plugin);
$mform->setDefault('customint3', $this->get_config('keepgroup'));

$options = self::email_options();
$mform->addElement('select', 'customint2', get_string('categoryemail', 'admin'), $options);

$mform->addHelpButton('customint2', 'welcome', 'enrol_coursecompleted');
$mform->addHelpButton('customint2', 'welcome', $plugin);
$mform->setDefault('customint2', $this->get_config('welcome'));

$arr = ['cols' => '60', 'rows' => '8'];
$mform->addElement('textarea', 'customtext1', get_string('customwelcome', 'enrol_coursecompleted'), $arr);
$mform->addHelpButton('customtext1', 'customwelcome', 'enrol_coursecompleted');
$mform->addElement('textarea', 'customtext1', get_string('customwelcome', $plugin), $arr);
$mform->addHelpButton('customtext1', 'customwelcome', $plugin);
$mform->disabledIf('customtext1', 'customint2', 'notchecked');

$arr = ['optional' => true, 'defaulttime' => $start];
$mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_coursecompleted'), $arr);
$mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_coursecompleted');
$mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', $plugin), $arr);
$mform->addHelpButton('enrolstartdate', 'enrolstartdate', $plugin);

$arr['defaulttime'] = $start + get_config('moodlecourse', 'courseduration');
$mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_coursecompleted'), $arr);
$mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', $plugin), $arr);
$mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_coursecompleted');
}

Expand Down
3 changes: 3 additions & 0 deletions lang/en/enrol_coursecompleted.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
$string['status_link'] = 'enrol/coursecompleted';
$string['svglearnpath'] = 'Display learning path';
$string['svglearnpath_help'] = 'Display (possible) learning path using svg icons.';
$string['tryunenrol'] = 'Unenrol user from completed course.';
$string['tryunenrol_help'] = 'Try to self unenrol user from completed course.
If the user was enrolled with a method that allows self unenrolment, then this plugin will try to self unenrol the user.';
$string['unenrolusers'] = 'Unenrol users';
$string['uponcompleting'] = 'Upon completing course {$a}';
$string['usersenrolled'] = '{$a} Users enrolled';
Expand Down
50 changes: 30 additions & 20 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@

$settings->add(
new admin_setting_heading(
'enrol_coursecompleted_settings',
$plugin . '_settings',
'',
get_string('pluginname_desc', $plugin),
get_string('pluginname_desc', $plugin)
)
);

$settings->add(
new admin_setting_heading(
'enrol_coursecompleted_defaults',
$plugin . '_defaults',
get_string('enrolinstancedefaults', 'admin'),
get_string('enrolinstancedefaults_desc', 'admin'),
)
);

$settings->add(
new admin_setting_configcheckbox(
'enrol_coursecompleted/defaultenrol',
"$plugin/defaultenrol",
get_string('defaultenrol', 'enrol'),
get_string('defaultenrol_desc', 'enrol'),
0
Expand All @@ -67,64 +67,74 @@

$settings->add(
new admin_setting_configselect(
name: 'enrol_coursecompleted/expiredaction',
name: "$plugin/expiredaction",
visiblename: get_string(
identifier: 'expiredaction',
component: 'enrol_fee',
component: 'enrol_fee'
),
description: get_string(
identifier: 'expiredaction_help',
component: 'enrol_fee',
component: 'enrol_fee'
),
defaultsetting: ENROL_EXT_REMOVED_SUSPENDNOROLES,
choices: $roptions,
choices: $roptions
)
);

$settings->add(
new admin_setting_configselect(
name: 'enrol_coursecompleted/roleid',
name: "$plugin/roleid",
visiblename: get_string(
identifier: 'defaultrole',
component: $plugin,
component: $plugin
),
description: get_string(
identifier: 'defaultrole_desc',
component: $plugin,
component: $plugin
),
defaultsetting: $student->id,
choices: $options,
choices: $options
)
);
}

$settings->add(
new admin_setting_configduration(
'enrol_coursecompleted/enrolperiod',
"$plugin/enrolperiod",
get_string('enrolperiod', 'enrol_fee'),
get_string('enrolperiod_desc', 'enrol_fee'),
0,
0
)
);

$settings->add(
new admin_setting_configcheckbox(
"$plugin/tryunenrol",
get_string('tryunenrol', $plugin),
get_string('tryunenrol_help', $plugin),
0
)
);

$settings->add(
new admin_setting_configselect(
name: 'enrol_coursecompleted/welcome',
name: "$plugin/welcome",
visiblename: get_string(
identifier: 'welcome',
component: $plugin,
component: $plugin
),
description: get_string(
identifier: 'welcome_help',
component: $plugin,
component: $plugin
),
defaultsetting: ENROL_SEND_EMAIL_FROM_COURSE_CONTACT,
choices: enrol_coursecompleted_plugin::email_options(),
choices: enrol_coursecompleted_plugin::email_options()
)
);

$settings->add(
new admin_setting_configcheckbox(
'enrol_coursecompleted/svglearnpath',
"$plugin/svglearnpath",
get_string('svglearnpath', $plugin),
get_string('svglearnpath_help', $plugin),
1
Expand All @@ -133,7 +143,7 @@

$settings->add(
new admin_setting_configcheckbox(
'enrol_coursecompleted/keepgroup',
"$plugin/keepgroup",
get_string('keepgroup', $plugin),
get_string('keepgroup_help', $plugin),
1
Expand Down
11 changes: 10 additions & 1 deletion tests/behat/enrol_groups.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Feature: Groups kept during enrolment on course completion
Scenario: User stays in same group after completing one or several courses
Given I log in as "admin"
And I am on "Course 1" course homepage
And I navigate to course participants
And I should see "2 participants found"

And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the field "Teacher" to "1"
Expand All @@ -35,7 +38,8 @@ Feature: Groups kept during enrolment on course completion

When I am on the "C2" "Course" page logged in as "teacher1"
And I add "Course completed enrolment" enrolment method in "Course 2" with:
| Course | Course 1 |
| Course | Course 1 |
| Unenrol | 1 |
And I am on "Course 1" course homepage
And I navigate to "Reports" in current page administration
And I click on "Course completion" "link" in the "region-main" "region"
Expand All @@ -51,3 +55,8 @@ Feature: Groups kept during enrolment on course completion
And I set the field "Type or select..." in the "Filter 1" "fieldset" to "Group 1"
And I click on "Apply filters" "button"
And I should see "1 participants found"

# Student user should be unenrolled.
And I am on "Course 1" course homepage
And I navigate to course participants
And I should see "1 participants found"
5 changes: 4 additions & 1 deletion tests/enrol_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ protected function setUp(): void {
'status' => ENROL_INSTANCE_ENABLED,
'customint1' => $this->course1->id,
'customint2' => ENROL_SEND_EMAIL_FROM_NOREPLY,
'customint4' => 100,
'roleid' => $studentrole,
]
);
Expand Down Expand Up @@ -361,7 +362,7 @@ public function test_library_functions(): void {
public function test_library_other_functionality(): void {
global $DB;
$studentrole = $DB->get_field('role', 'id', ['shortname' => 'student']);
$arr = ['status' => 0, 'customint4' => 666, 'enrolenddate' => time(), 'enrolstartdate' => time() + 10000];
$arr = ['status' => 0, 'customint1' => 666, 'enrolenddate' => time(), 'enrolstartdate' => time() + 10000];
$tmp = $this->plugin->edit_instance_validation($arr, null, $this->instance, null);
$this->assertEquals('The specified course does not exist', $tmp['customint1']);
$this->assertEquals('The enrolment end date cannot be earlier than the start date.', $tmp['enrolenddate']);
Expand Down Expand Up @@ -437,6 +438,8 @@ public function test_form(): void {
$this->assertStringContainsString('d="id_enrolstartdate_enabled"value="1">Enable</label>', $cleaned);
$this->assertStringContainsString('cols="60"rows="8"', $cleaned);
$this->assertStringContainsString('name="customint3"class="form-check-input"value="1"id="id_customint3"', $cleaned);
$this->assertStringContainsString('fieldsetdata-fieldtype="date_time"class="m-0p-0border-0"id="id_customint4"', $cleaned);
$this->assertStringContainsString('name="customint5"class="form-check-input"value="1"id="id_customint5"', $cleaned);
$this->assertStringContainsString(
'<selectclass="custom-select"name="status"id="id_status"><optionvalue="0">Yes</option>',
$cleaned
Expand Down
Loading

0 comments on commit 158f795

Please sign in to comment.