Skip to content

Commit

Permalink
MDL-73839 tool_uploadcourse: Enable cohort enrolment for course upload.
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyatregubov committed Jun 30, 2023
1 parent 491a784 commit fb4304b
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 3 deletions.
16 changes: 13 additions & 3 deletions admin/tool/uploadcourse/classes/course.php
Expand Up @@ -956,9 +956,13 @@ protected function validate_enrolment_data(int $courseid, array $enrolmentdata):
}
}

if ($courseid) {
$plugin = $enrolmentplugins[$method];
$plugin = $enrolmentplugins[$method];
$errors += $plugin->validate_enrol_plugin_data($options, $courseid);
if ($errors) {
break;
}

if ($courseid) {
// Find matching instances by enrolment method.
$methodinstances = array_filter($instances, static function (stdClass $instance) use ($method) {
return (strcmp($instance->enrol, $method) == 0);
Expand Down Expand Up @@ -1053,10 +1057,16 @@ protected function process_enrolment_data($course) {
$plugin = $enrolmentplugins[$enrolmethod];

$status = ($todisable) ? ENROL_INSTANCE_DISABLED : ENROL_INSTANCE_ENABLED;
$method = $plugin->fill_enrol_custom_fields($method, $course->id);

// Create a new instance if necessary.
if (empty($instance) && $plugin->can_add_instance($course->id)) {
$instanceid = $plugin->add_default_instance($course);
$error = $plugin->validate_plugin_data_context($method, $course->id);
if ($error) {
$this->error('contextnotallowed', $error);
break;
}
$instanceid = $plugin->add_instance($course, $method);
$instance = $DB->get_record('enrol', ['id' => $instanceid]);
$instance->roleid = $plugin->get_config('roleid');
// On creation the user can decide the status.
Expand Down
105 changes: 105 additions & 0 deletions admin/tool/uploadcourse/tests/behat/cohorts.feature
@@ -0,0 +1,105 @@
@tool @tool_uploadcourse @_file_upload
Feature: An admin can create courses with cohort enrolments using a CSV file
In order to create courses using a CSV file with cohort enrolment
As an admin
I need to be able to upload a CSV file and navigate through the import process

Background:
Given the following "categories" exist:
| name | category | idnumber |
| Cat 0 | 0 | CAT0 |
| Cat 1 | CAT0 | CAT1 |
| Cat 1 | CAT0 | CAT2 |
And the following "cohorts" exist:
| name | idnumber | contextlevel | reference | visible |
| Cohort 1 | CV1 | Category | CAT1 | 1 |
| Cohort 2 | CV2 | Category | CAT2 | 1 |
| Cohort 3 | CV3 | Category | CAT2 | 1 |
| Cohort 4 | CV4 | Category | CAT1 | 1 |
| Cohort 5 | CV5 | Category | CAT1 | 1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | CAT1 |
And I log in as "admin"
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"

@javascript
Scenario: Upload cohort enrolment if plugin is disabled
Given the following config values are set as admin:
| enrol_plugins_enabled | manual,guest,self |
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_cohort.csv" file to "File" filemanager
When I click on "Preview" "button"
Then I should see "Cohort sync plugin is disabled"

@javascript
Scenario: Validation of cohorts for uploaded courses
Given I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_cohort.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "Unknown cohort (Not exist)!"
And I should see "Cohort Cohort 3 not allowed in this context."
When I click on "Upload courses" "button"
And I should see "Unknown cohort (Not exist)!"
And I should see "Cohort Cohort 3 not allowed in this context."
And I should see "Cohort Cohort 4 not allowed in this context."
And I should see "Courses created: 2"
And I should see "Courses updated: 0"
And I should see "Courses errors: 3"
And I am on the "Course 1" "enrolment methods" page
Then I should not see "Cohort sync (Cohort 3 - Student)"
And I am on the "Course 2" "enrolment methods" page
And I should not see "Cohort sync (Cohort 4 - Student)"
And I am on the "Course 3" "enrolment methods" page
And I should see "Cohort sync (Cohort 5 - Student)"
And I click on "Edit" "link" in the "Cohort 5" "table_row"
And the field "Add to group" matches value "None"

@javascript
Scenario: Validation of groups for uploaded courses with cohort enrolments
Given the following "groups" exist:
| name | course | idnumber |
| group1 | C1 | G1 |
# Test that groupname can't be set when addtogroup is used.
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_cohort_addtogroup_groupname.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "You cannot specify groupname when addtogroup is set."
# Test creating a new group when uploading a course.
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_cohort_addtogroup.csv" file to "File" filemanager
And I click on "Preview" "button"
And I click on "Upload courses" "button"
And I should see "Courses created: 2"
And I should see "Courses errors: 0"
And I am on the "Course 2" "enrolment methods" page
And I should see "Cohort sync (Cohort 2 - Student)"
And I click on "Edit" "link" in the "Cohort 2" "table_row"
And the field "Add to group" matches value "Cohort 2 cohort"
And I am on the "Course 2" "groups" page
And I should see "Cohort 2 cohort"
And I am on the "Course 3" "enrolment methods" page
And I should see "Cohort sync (Cohort 1 - Student)"
And I click on "Edit" "link" in the "Cohort 1" "table_row"
And the field "Add to group" matches value "None"
And I am on the "Course 3" "groups" page
And I should not see "Cohort 1 cohort"

# Test assigning to an existing group when uploading a course.
And I navigate to "Courses > Upload courses" in site administration
And I set the field "Upload mode" to "Create new courses, or update existing ones"
And I set the field "Update mode" to "Update with CSV data only"
And I upload "admin/tool/uploadcourse/tests/fixtures/enrolment_cohort_groups.csv" file to "File" filemanager
And I click on "Preview" "button"
And I should see "Error, invalid group notexist"
When I click on "Upload courses" "button"
And I should see "Error, invalid group notexist"
And I should see "Courses updated: 1"
And I should see "Courses errors: 1"
And I am on the "Course 1" "enrolment methods" page
Then I should see "Cohort sync (Cohort 1 - Student)"
And I click on "Edit" "link" in the "Cohort 1" "table_row"
And the field "Add to group" matches value "group1"
And I am on the "Course 1" "groups" page
And I should see "group1"
5 changes: 5 additions & 0 deletions admin/tool/uploadcourse/tests/fixtures/enrolment_cohort.csv
@@ -0,0 +1,5 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_role,enrolment_1_cohortname
C1,Course 1,CAT1,cohort,student,Not exist
C1,Course 1,CAT1,cohort,student,Cohort 3
C2,Course 2,CAT2,cohort,student,Cohort 4
C3,Course 3,CAT1,cohort,student,Cohort 5
@@ -0,0 +1,3 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_role,enrolment_1_cohortname,enrolment_1_addtogroup
C2,Course 2,CAT2,cohort,student,Cohort 2,1
C3,Course 3,CAT1,cohort,student,Cohort 1,0
@@ -0,0 +1,2 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_role,enrolment_1_cohortname,enrolment_1_addtogroup,enrolment_1_groupname
C1,Course 1,CAT1,cohort,student,Cohort 1,0,group1
@@ -0,0 +1,3 @@
shortname,fullname,category_idnumber,enrolment_1,enrolment_1_role,enrolment_1_cohortname,enrolment_1_groupname
C1,Course 1,CAT1,cohort,student,Cohort 1,notexist
C1,Course 1,CAT1,cohort,student,Cohort 1,group1
1 change: 1 addition & 0 deletions enrol/cohort/lang/en/enrol_cohort.php
Expand Up @@ -29,6 +29,7 @@
$string['defaultgroupnametext'] = '{$a->name} cohort {$a->increment}';
$string['enrolcohortsynctask'] = 'Cohort enrolment sync task';
$string['instanceexists'] = 'Cohort is already synchronised with selected role';
$string['plugindisabled'] = 'Cohort sync plugin is disabled';
$string['pluginname'] = 'Cohort sync';
$string['pluginname_desc'] = 'Cohort enrolment plugin synchronises cohort members with course participants.';
$string['status'] = 'Active';
Expand Down
111 changes: 111 additions & 0 deletions enrol/cohort/lib.php
Expand Up @@ -29,6 +29,12 @@
*/
define('COHORT_CREATE_GROUP', -1);

/**
* COHORT_NOGROUP constant for using no group for a cohort.
*/
define('COHORT_NOGROUP', 0);


/**
* Cohort enrolment plugin implementation.
* @author Petr Skoda
Expand Down Expand Up @@ -498,6 +504,111 @@ public function edit_instance_validation($data, $files, $instance, $context) {
}
return $errors;
}

/**
* Check if data is valid for a given enrolment plugin
*
* @param array $enrolmentdata enrolment data to validate.
* @param int|null $courseid Course ID.
* @return array Errors
*/
public function validate_enrol_plugin_data(array $enrolmentdata, ?int $courseid = null) : array {
global $DB;

$errors = [];
if (!enrol_is_enabled('cohort')) {
$errors['plugindisabled'] =
new lang_string('plugindisabled', 'enrol_cohort');
}

if (isset($enrolmentdata['addtogroup'])) {
$addtogroup = $enrolmentdata['addtogroup'];
if (($addtogroup == - COHORT_CREATE_GROUP) || $addtogroup == COHORT_NOGROUP) {
if (isset($enrolmentdata['groupname'])) {
$errors['erroraddtogroupgroupname'] =
new lang_string('erroraddtogroupgroupname', 'group');
}
} else {
$errors['erroraddtogroup'] =
new lang_string('erroraddtogroup', 'group');
}
}

if ($courseid) {
$enrolmentdata = $this->fill_enrol_custom_fields($enrolmentdata, $courseid);
$error = $this->validate_plugin_data_context($enrolmentdata, $courseid);
if ($error) {
$errors['contextnotallowed'] = $error;
}

if (isset($enrolmentdata['groupname']) && $enrolmentdata['groupname']) {
$groupname = $enrolmentdata['groupname'];
if (!groups_get_group_by_name($courseid, $groupname)) {
$errors['errorinvalidgroup'] =
new lang_string('errorinvalidgroup', 'group', $groupname);
}
}
}

if (!isset($enrolmentdata['cohortname'])) {
$errors['missingmandatoryfields'] =
new lang_string('missingmandatoryfields', 'tool_uploadcourse',
'cohortname');
} else {
$cohortname = $enrolmentdata['cohortname'];
// Cohort name is not unique.
$cohortid = $DB->get_field('cohort', 'MIN(id)', ['name' => $cohortname]);

if (!$cohortid) {
$errors['unknowncohort'] =
new lang_string('unknowncohort', 'cohort', $cohortname);
}
}
return $errors;
}

/**
* Fill custom fields data for a given enrolment plugin.
*
* @param array $enrolmentdata enrolment data.
* @param int $courseid Course ID.
* @return array Updated enrolment data with custom fields info.
*/
public function fill_enrol_custom_fields(array $enrolmentdata, int $courseid) : array {
global $DB;

// Cohort name is not unique.
$enrolmentdata['customint1'] =
$DB->get_field('cohort', 'MIN(id)', ['name' => $enrolmentdata['cohortname']]);

if (isset($enrolmentdata['addtogroup'])) {
if ($enrolmentdata['addtogroup'] == COHORT_NOGROUP) {
$enrolmentdata['customint2'] = COHORT_NOGROUP;
} else if ($enrolmentdata['addtogroup'] == - COHORT_CREATE_GROUP) {
$enrolmentdata['customint2'] = COHORT_CREATE_GROUP;
}
} else if (isset($enrolmentdata['groupname'])) {
$enrolmentdata['customint2'] = groups_get_group_by_name($courseid, $enrolmentdata['groupname']);
}
return $enrolmentdata;
}

/**
* Check if plugin custom data is allowed in relevant context.
*
* @param array $enrolmentdata enrolment data to validate.
* @param int|null $courseid Course ID.
* @return lang_string|null Error
*/
public function validate_plugin_data_context(array $enrolmentdata, ?int $courseid = null) : ?lang_string {
$error = null;
$cohortid = $enrolmentdata['customint1'];
$coursecontext = \context_course::instance($courseid);
if (!cohort_get_cohort($cohortid, $coursecontext)) {
$error = new lang_string('contextcohortnotallowed', 'cohort', $enrolmentdata['cohortname']);
}
return $error;
}
}

/**
Expand Down

0 comments on commit fb4304b

Please sign in to comment.