diff --git a/CHANGES.md b/CHANGES.md index 71bb2e7..db33ab9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,10 @@ moodle-local_bulkenrol Changes ------- +### v4.0-r3 + +* 2022-10-06 - Lets Teachers choose different fields other than email to enrol users by. + ### v4.0-r2 * 2022-07-12 - Fix README description how this plugin works in Moodle 4.0 diff --git a/README.md b/README.md index 45a9657..9ffdc47 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ moodle-local_bulkenrol [![Moodle Plugin CI](https://github.com/moodle-an-hochschulen/moodle-local_bulkenrol/workflows/Moodle%20Plugin%20CI/badge.svg?branch=master)](https://github.com/moodle-an-hochschulen/moodle-local_bulkenrol/actions?query=workflow%3A%22Moodle+Plugin+CI%22+branch%3Amaster) -Moodle plugin which provides the possibility to bulk enrol a list of users who are identified by their e-mail adresses into a course. +Moodle plugin which provides the possibility to bulk enrol a list of users who are identified by their e-mail adresses, username or idnumber into a course. Requirements @@ -20,7 +20,7 @@ In some organizations or some teaching scenarios, manually enrolling students in To ease the life of teachers, there is the need for a bulk enrolment tool. There are already plugins out there which provide this functionality, so this is just another one. The goal of this bulk enrolment implementation is not to fulfil everybody's needs, but to do one thing and to do this well. So, the key features of this plugin are: -1. to let teachers submit a line-separated list of email addresses to enrol them into a course, +1. to let teachers submit a line-separated list of email addresses, username or idnumber to enrol them into a course, 2. to let teachers submit this list to a textarea within their course instead of requiring them to create and upload a CSV file first. @@ -41,11 +41,19 @@ After installing the plugin, it does not do anything to Moodle yet. To configure the plugin and its behaviour, please visit: Site administration -> Plugins -> Enrolments -> User bulk enrolment -There, you find only one setting: +There, you find three settings: ### 1. Enrolment plugin The enrolment method to be used to bulk enrol the users. If the configured enrolment method is not active / added in the course when the users are bulk-enrolled, it is automatically added / activated. +### 2. Role +The role assigned to the bulk enrolled users. + +### 3. Field options +The key fields available to the teachers to identify the users to enroll. If no field is enabled, the plugin will be disabled. +The plugin supports custom field defined with "forceunique" set to on. +Please note that e-mail address uniqueness can be disabled by the adminstrator. +Morover, Moodle doesn't enforce idnumber uniqueness. Capabilities ------------ @@ -61,7 +69,7 @@ How this plugin works Teachers (rather users who have been granted the capability which is described in the "Capabilities" section above) will find an additional "User bulk enrolment" menu item within the jump menu on the course's participants page. -To enrol existing Moodle users into the course, the teacher will then have to add a list of e-mail adresses to the form on this page, one user / e-mail adress per line. +To enrol existing Moodle users into the course, the teacher will then have to add a list of e-mail adresses, username or idnumber to the form on this page, one user / key identifier per line. Example: ``` @@ -85,7 +93,7 @@ dave@example.com Limitations ----------- -This plugin currently only accepts a list of e-mail adresses to be enrolled into a course. It does especially not accept lists of user names, matriculation IDs or something else. +This plugin currently only accepts a list of e-mail addresses, username or idnumber to be enrolled into a course. It does not accept any other field because only these are managed as key in Moodle. Additionally, this plugin only enrols users who already exist in Moodle. It won't create Moodle user accounts on-the-fly. @@ -192,3 +200,7 @@ Communication and Information Centre (kiz)\ Alexander Bias It was contributed to the Moodle an Hochschulen e.V. plugin catalogue in 2022. + +This plugin contains contributes from: +- University of Münster, Learnweb by ZHLdigital +- University of Genoa, AulaWeb staff \ No newline at end of file diff --git a/classes/bulkenrol_form.php b/classes/bulkenrol_form.php index c0169a4..7266aba 100644 --- a/classes/bulkenrol_form.php +++ b/classes/bulkenrol_form.php @@ -50,15 +50,51 @@ protected function definition() { $mform = $this->_form; + // Selector for database field to match list to. + $availablefieldsstring = get_config('local_bulkenrol', 'fieldoptions'); + $availablefieldsarray = explode(',', $availablefieldsstring); + if (count($availablefieldsarray) < 1 or $availablefieldsarray[0] == '') { + print_error(get_string('error_no_options_available', 'local_bulkenrol')); + } + + $selectoptions = []; + foreach ($availablefieldsarray as $fieldoption) { + $selectoptions[$fieldoption] = $this->get_fieldname($fieldoption); + } + + // Format CSV, replace last , with 'or' and add spaces after remaining. + $fieldnamestring = implode(', ', $selectoptions); + $formattedfieldnamestring = $this->str_last_replace(', ', ' ' . get_string('or', 'local_bulkenrol') . ' ', $fieldnamestring); + // Infotext. - $msg = get_string('bulkenrol_form_intro', 'local_bulkenrol'); + $msg = get_string('bulkenrol_form_intro', 'local_bulkenrol', $formattedfieldnamestring); $mform->addElement('html', '
'.$msg.'
'); - // Textarea for Emails. - $mform->addElement('textarea', 'usermails', - get_string('usermails', 'local_bulkenrol'), 'wrap="virtual" rows="10" cols="80"'); - $mform->addRule('usermails', null, 'required'); - $mform->addHelpButton('usermails', 'usermails', 'local_bulkenrol'); + // Helptext. + if ($availablefieldsarray[0] == 'u_username') { + $helpstringidentifier = 'userlist_username'; + } else if ($availablefieldsarray[0] == 'u_idnumber') { + $helpstringidentifier = 'userlist_idnumber'; + } else { + $helpstringidentifier = 'userlist_email'; + } + + $singleoption = count($availablefieldsarray) == 1; + if (!$singleoption) { + $mform->addElement('select', 'dbfield', get_string('choose_field', 'local_bulkenrol'), $selectoptions); + $listfieldtitle = get_string('userlist', 'local_bulkenrol'); + } else { + $field = $availablefieldsarray[0]; + $mform->addElement('hidden', 'dbfield'); + $mform->setType('dbfield', PARAM_TEXT); + $mform->setDefault('dbfield', $field); + $listfieldtitle = get_string('userlist_singleoption', 'local_bulkenrol', $this->get_fieldname($field)); + } + // Textarea for uservalues. + $mform->addElement('textarea', 'uservalues', + $listfieldtitle, 'wrap="virtual" rows="10" cols="80"'); + $mform->addRule('uservalues', null, 'required'); + $mform->addHelpButton('uservalues', $helpstringidentifier, 'local_bulkenrol'); // Add form content if the user came back to check his input. $localbulkenroleditlist = optional_param('editlist', 0, PARAM_ALPHANUMEXT); @@ -66,8 +102,10 @@ protected function definition() { $localbulkenroldata = $localbulkenroleditlist.'_data'; if (!empty($localbulkenroldata) && !empty($SESSION->local_bulkenrol_inputs) && array_key_exists($localbulkenroldata, $SESSION->local_bulkenrol_inputs)) { - $formdatatmp = $SESSION->local_bulkenrol_inputs[$localbulkenroldata]; - $mform->setDefault('usermails', $formdatatmp); + $formdatatmp = $SESSION->local_bulkenrol_inputs[$localbulkenroldata]['users']; + $dbfield = $SESSION->local_bulkenrol_inputs[$localbulkenroldata]['dbfield']; + $mform->setDefault('uservalues', $formdatatmp); + $mform->setDefault('dbfield', $dbfield); } } @@ -89,10 +127,47 @@ protected function definition() { public function validation($data, $files) { $retval = array(); - if (empty($data['usermails'])) { - $retval['usermails'] = get_string('error_usermails_empty', 'local_bulkenrol'); + if (empty($data['uservalues'])) { + $retval['uservalues'] = get_string('error_list_empty', 'local_bulkenrol'); } return $retval; } + + /** + * Returns the name of a fieldoption without its table prefix + * @param string $fieldoption fieldname with type prefix + * @return string name of field without type prefix + * @throws \UnexpectedValueException Field is not prefixed by c_ or u_ + * @throws \dml_exception Database connection error + */ + private function get_fieldname($fieldoption) { + global $DB; + $fieldinfo = explode("_", $fieldoption, 2); + switch ($fieldinfo[0]) { + case "u": + return $fieldinfo[1]; + case "c": + return $DB->get_field('user_info_field', 'name', array("id" => intval($fieldinfo[1]))); + default: + throw new \UnexpectedValueException("field is not from usertable (u_) or customfield (c_)"); + } + } + + /** + * Replaces the last occurence of the needle in a string. + * @param string $search needle to search for + * @param string $replace string replacement for needle + * @param string $subject string subject string to search + * @return string subject string with the last occurence of the needle replaced + */ + private function str_last_replace($search, $replace, $subject) { + $pos = strrpos($subject, $search); + + if ($pos !== false) { + $subject = substr_replace($subject, $replace, $pos, strlen($search)); + } + + return $subject; + } } diff --git a/db/upgrade.php b/db/upgrade.php new file mode 100644 index 0000000..3d205ba --- /dev/null +++ b/db/upgrade.php @@ -0,0 +1,43 @@ +. + +/** + * bulkenrol plugin upgrade code + * + * @package local_bulkenrol + * @copyright 2022 Marco Ferrante, University of Genoa (I) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die(); + +/** + * Function to upgrade bulkenrol. + * @param int $oldversion the version we are upgrading from + * @return bool result + */ +function xmldb_local_bulkenrol_upgrade($oldversion) { + global $CFG, $DB; + + if ($oldversion < 2022100600) { + // Enable e-mail address as key field if unique + if (empty($CFG->allowaccountssameemail)) { + set_config('fieldoptions', ["u_email"], 'local_bulkenrol'); + upgrade_plugin_savepoint(true, 2022100600, 'local', 'bulkenrol'); + } + } + + return true; +} diff --git a/index.php b/index.php index 8885e67..628001e 100644 --- a/index.php +++ b/index.php @@ -59,10 +59,17 @@ if (empty($localbulkenrolkey)) { $form = new bulkenrol_form(null, array('courseid' => $id)); if ($formdata = $form->get_data()) { - $emails = $formdata->usermails; + $datafield = $formdata->dbfield; + $uservalues = $formdata->uservalues; $courseid = $formdata->id; - $checkedmails = local_bulkenrol_check_user_mails($emails, $courseid); + $availablefieldsstring = get_config('local_bulkenrol', 'fieldoptions'); + $availablefieldsarray = explode(',', $availablefieldsstring); + if (!in_array($datafield, $availablefieldsarray)) { + print_error('The provided datafield has not been approved by the administrator.', 'local_bulkenrol'); + } + + $checkedusers = local_bulkenrol_check_user_data($uservalues, $courseid, $datafield); // Create local_bulkenrol array in Session. if (!isset($SESSION->local_bulkenrol)) { @@ -70,14 +77,14 @@ } // Save data in Session. $localbulkenrolkey = $courseid.'_'.time(); - $SESSION->local_bulkenrol[$localbulkenrolkey] = $checkedmails; + $SESSION->local_bulkenrol[$localbulkenrolkey] = $checkedusers; // Create local_bulkenrol_inputs array in session. if (!isset($SESSION->local_bulkenrol_inputs)) { $SESSION->local_bulkenrol_inputs = array(); } $localbulkenroldata = $localbulkenrolkey.'_data'; - $SESSION->local_bulkenrol_inputs[$localbulkenroldata] = $emails; + $SESSION->local_bulkenrol_inputs[$localbulkenroldata] = array('users' => $uservalues, 'dbfield' => $datafield); } else if ($form->is_cancelled()) { if (!empty($id)) { redirect($CFG->wwwroot .'/course/view.php?id='.$id, '', 0); @@ -130,13 +137,13 @@ } // Show notification if there aren't any valid email addresses to enrol. - if (!empty($localbulkenroldata) && isset($localbulkenroldata->validemailfound) && - empty($localbulkenroldata->validemailfound)) { + if (!empty($localbulkenroldata) && isset($localbulkenroldata->validusersfound) && + empty($localbulkenroldata->validusersfound)) { $a = new stdClass(); $url = new moodle_url('/local/bulkenrol/index.php', array('id' => $id, 'editlist' => $localbulkenrolkey)); $a->url = $url->out(); $notification = new \core\output\notification( - get_string('error_no_valid_email_in_list', 'local_bulkenrol', $a), + get_string('error_no_valid_data_in_list', 'local_bulkenrol', $a), \core\output\notification::NOTIFY_WARNING); $notification->set_show_closebutton(false); echo $OUTPUT->render($notification); diff --git a/lang/en/local_bulkenrol.php b/lang/en/local_bulkenrol.php index ed36989..5399c6f 100644 --- a/lang/en/local_bulkenrol.php +++ b/lang/en/local_bulkenrol.php @@ -25,7 +25,8 @@ defined('MOODLE_INTERNAL') || die(); $string['bulkenrol:enrolusers'] = 'Use user bulk enrolment'; -$string['bulkenrol_form_intro'] = 'Here, you can bulk enrol users to your course. A user to be enrolled is identified by his e-mail address stored in his Moodle account.'; +$string['bulkenrol_form_intro'] = 'Here, you can bulk enrol users to your course. A user to be enrolled is identified by their {$a}.'; +$string['choose_field'] = 'Choose field to match list to'; $string['enrol_users_successful'] = 'User bulk enrolment successful'; $string['enrol_users'] = 'Enrol users'; $string['enrolinfo_headline'] = 'Enrolment details'; @@ -33,32 +34,41 @@ $string['enrolplugin_desc'] = 'The enrolment method to be used to bulk enrol the users. If the configured enrolment method is not active / added in the course when the users are bulk-enrolled, it is automatically added / activated.'; $string['error_empty_line'] = 'Line {$a->line} is empty and will be ignored.'; $string['error_enrol_users'] = 'There was a problem when enrolling the users to the course.'; -$string['error_enrol_user'] = 'There was a problem when enrolling the user with e-mail {$a->email} to the course.'; +$string['error_enrol_user'] = 'There was a problem when enrolling the user {$a->data} to the course.'; $string['error_exception_info'] = 'Exception information'; -$string['error_getting_user_for_email'] = 'There was a problem when getting the user record for e-mail address {$a} from the database.'; +$string['error_getting_user_for_data'] = 'There was a problem when getting the user record for {$a} from the database.'; $string['error_group_add_members'] = 'There was a problem when adding the users to the course group(s).'; -$string['error_group_add_member'] = 'There was a problem when adding the user with e-mail {$a->email} to the course group {$a->group}.'; -$string['error_invalid_email'] = 'Invalid e-mail address found in line {$a->row} ({$a->email}). This line will be ignored.'; -$string['error_more_than_one_record_for_email'] = 'More than one existing Moodle user account with e-mail address {$a} found.
This line will be ignored, none of the existing Moodle users will be enrolled.'; -$string['error_no_email'] = 'No e-mail address found in line {$a->line} ({$a->content}). This line will be ignored.'; -$string['error_no_valid_email_in_list'] = 'No valid e-mail address was found in the given list.
Please url}\'>go back and check your input.'; -$string['error_no_record_found_for_email'] = 'No existing Moodle user account with e-mail address {$a}.
This line will be ignored, there won\'t be a Moodle user account created on-the-fly.'; -$string['error_usermails_empty'] = 'List of e-mail addresses is empty. Please add at least one e-mail address.'; -$string['error_check_is_already_member'] = 'Error checking if the user ({$a->email}) is already a member of group ({$a->groupname}). {$a->error}'; +$string['error_group_add_member'] = 'There was a problem when adding the user {$a->data} to the course group {$a->group}.'; +$string['error_more_than_one_record_for_data'] = 'More than one existing Moodle user account with {$a->field} {$a->identifier} found.
This line will be ignored, none of the existing Moodle users will be enrolled.'; +$string['error_no_valid_data_in_list'] = 'No valid entrys were found in the given list.
Please url}\'>go back and check your input.'; $string['groupinfos_headline'] = 'Groups included in the list'; $string['group_name_headline'] = 'Group name'; $string['group_status_create'] = 'Group will be created'; $string['group_status_exists'] = 'Group already exists'; $string['group_status_headline'] = 'Group status'; $string['hints'] = 'Hints'; +$string['error_no_data'] = 'No data found ({$a}). This line will be ignored.'; +$string['error_no_record_found_for_data'] = 'No existing Moodle user account {$a} was found.
This line will be ignored, there won\'t be a Moodle user account created on-the-fly.'; +$string['error_no_options_available'] = 'Your administrator has disabled all options. Please contact your administrator'; +$string['error_list_empty'] = 'List is empty. Please add at least one fieldvalue'; +$string['error_check_is_already_member'] = 'Error checking if the user ({$a->data}) is already a member of group ({$a->groupname}). {$a->error}'; +$string['fieldoptions'] = 'Field options'; +$string['fieldoptions_desc'] = 'Fields, that teachers can use as identifier to enrol students by.'; $string['pluginname'] = 'User bulk enrolment'; +$string['or'] = 'or'; $string['privacy:metadata'] = 'The user bulk enrolment plugin acts as a tool to enrol users into courses, but does not store any personal data.'; $string['role'] = 'Role'; $string['role_assigned'] = 'Assigned role'; $string['role_description'] = 'The role to be used to bulk enrol the users.'; $string['row'] = 'Row'; -$string['usermails'] = 'List of e-mail addresses'; -$string['usermails_help'] = 'To enrol an existing Moodle user into this course, add his e-mail address to this form, one user / e-mail address per line.

Example:
alice@example.com
bob@example.com

Optionally, you are able to create groups and add the enrolled users to the groups. All you have to do is to add a heading line with a hash sign and the group\'s name, separating the list of users.

Example:
# Group 1
alice@example.com
bob@example.com
# Group 2
carol@example.com
dave@example.com'; +$string['userlist'] = 'List of users identified by your chosen field'; +$string['userlist_singleoption'] = 'List of users identified by their {$a}'; +$string['userlist_email'] = 'data input'; +$string['userlist_username'] = 'data input'; +$string['userlist_idnumber'] = 'data input'; +$string['userlist_email_help'] = 'To enrol an existing Moodle user into this course, choose a field to identify the user by and add the identifier to the list.

Example for field "email" :
alice@example.com
bob@example.com

Optionally, you are able to create groups and add the enrolled users to the groups. All you have to do is to add a heading line with a hash sign and the group\'s name, separating the list of users.

Example:
# Group 1
alice@example.com
bob@example.com
# Group 2
carol@example.com
dave@example.com'; +$string['userlist_username_help'] = 'To enrol an existing Moodle user into this course, choose a field to identify the user by and add the identifier to the list.

Example for field "username" :
alice
bob

Optionally, you are able to create groups and add the enrolled users to the groups. All you have to do is to add a heading line with a hash sign and the group\'s name, separating the list of users.

Example:
# Group 1
alice
bob
# Group 2
carol
dave'; +$string['userlist_idnumber_help'] = 'To enrol an existing Moodle user into this course, choose a field to identify the user by and add the identifier to the list.

Example for field "idnumber" :
1001
1002

Optionally, you are able to create groups and add the enrolled users to the groups. All you have to do is to add a heading line with a hash sign and the group\'s name, separating the list of users.

Example:
# Group 1
1001
1002
# Group 2
1003
1004'; $string['users_to_enrol_in_course'] = 'Users to be enrolled into the course'; $string['user_enroled'] = 'User enrolment'; $string['user_enroled_yes'] = 'User will be enrolled'; @@ -68,3 +78,5 @@ $string['user_groups_already'] = 'User is already group member'; $string['parameter_empty'] = 'Parameter empty'; $string['type_enrol'] = 'Enrolment method'; +$string['identifying_data'] = 'Data'; + diff --git a/locallib.php b/locallib.php index 69672de..fbde949 100644 --- a/locallib.php +++ b/locallib.php @@ -27,209 +27,175 @@ define('LOCALBULKENROL_GROUPINFOS', 'groupinfos'); /** - * Check list of submitted user mails and creates a data structure for displaying information on the confirm page and + * Check list of submitted user data and creates a data structure for displaying information on the confirm page and * for performing the bulkenrol. * - * @param string $emailstextfield Text field value to be checked for emails and course groups. + * @param string $userdatatext Text field value to be checked for identifying data and course groups. * @param int $courseid ID of the course, used to determine the context for checking whether a user is already enroled. + * @param string $datafield To which database field to compare the user data. + * u_* for Fields of the user-table, c_* for custom fields. * * @return stdClass Object containing information to be displayed on confirm page and being used for bulkenrol. */ -function local_bulkenrol_check_user_mails($emailstextfield, $courseid) { +function local_bulkenrol_check_user_data($userdatatext, $courseid, $datafield = 'u_email') { - $checkedemails = new stdClass(); - $checkedemails->emails_to_ignore = array(); - $checkedemails->error_messages = array(); - $checkedemails->moodleusers_for_email = array(); - $checkedemails->course_groups = array(); - $checkedemails->user_groups = array(); - $checkedemails->user_enroled = array(); - $checkedemails->validemailfound = 0; + $checkeddata = new stdClass(); + $checkeddata->data_to_ignore = array(); + $checkeddata->error_messages = array(); + $checkeddata->moodleusers_for_data = array(); + $checkeddata->course_groups = array(); + $checkeddata->user_groups = array(); + $checkeddata->user_enroled = array(); + $checkeddata->validusersfound = 0; - $emaildelimiters = array(', ', ' ', ','); + $possibledelimiters = array(', ', ' ', ','); - if (!empty($emailstextfield)) { - - $emailslines = local_bulkenrol_parse_emails($emailstextfield); + if (empty($userdatatext)) { + return $checkeddata; + } - $linecnt = 0; + $datafieldsstring = get_config('local_bulkenrol', 'fieldoptions'); + $datafields = explode(",", $datafieldsstring); + if (!is_array($datafields) || !in_array($datafield, $datafields)) { + return $checkeddata; + } - $currentgroup = ''; + $datalines = local_bulkenrol_parse_data($userdatatext); - $context = null; + $linecnt = 0; - if (!empty($courseid)) { - $context = context_course::instance($courseid, MUST_EXIST); - } + $currentgroup = ''; - // Process emails from textfield. - foreach ($emailslines as $emailline) { - $linecnt++; + $context = null; - $error = ''; - - $emailline = trim($emailline); + if (!empty($courseid)) { + $context = context_course::instance($courseid, MUST_EXIST); + } - // Check for course group. - $grouppos = strpos($emailline , '#'); - if ($grouppos !== false) { + // Process data from textfield. + foreach ($datalines as $dataline) { + $linecnt++; - $groupname = substr($emailline, $grouppos + 1); - $currentgroup = trim($groupname); - $checkedemails->course_groups[$currentgroup] = array(); - continue; - } + $error = ''; - // Check number of emails in current row/line. - $emailsinlinecnt = substr_count($emailline , '@'); + $dataline = trim($dataline); - // No email in row/line. - if ($emailsinlinecnt == 0) { + // Check for course group. + $grouppos = strpos($dataline, '#'); + if ($grouppos !== false) { - $a = new stdClass(); - $a->line = $linecnt; - $a->content = $emailline; - if (trim($a->content != "")) { - $error = get_string('error_no_email', 'local_bulkenrol', $a); - } else { - $error = get_string('error_empty_line', 'local_bulkenrol', $a); - } - $checkedemails->error_messages[$linecnt] = $error; + $groupname = substr($dataline, $grouppos + 1); + $currentgroup = trim($groupname); + $checkeddata->course_groups[$currentgroup] = array(); + continue; + } - // One email in row/line. - } else if ($emailsinlinecnt == 1) { - $email = $emailline; - local_bulkenrol_check_email($email, $linecnt, $courseid, $context, $currentgroup, $checkedemails); + // Check delimiters. + foreach ($possibledelimiters as $possibledelimiter) { + $pos = strpos($dataline, $possibledelimiter); + if ($pos) { + $delimiter = $possibledelimiter; + break; } - // More than one email in row/line. - if ($emailsinlinecnt > 1) { - $delimiter = ''; - - // Check delimiters. - foreach ($emaildelimiters as $emaildelimiter) { - $pos = strpos($emailline, $emaildelimiter); - if ($pos) { - $delimiter = $emaildelimiter; - break; - } - } - if (!empty($delimiter)) { - $emailsinline = explode($delimiter, $emailline); - - // Iterate emails in row/line. - foreach ($emailsinline as $emailinline) { + } + if (empty($delimiter)) { + // Could possibly be only one students data. + local_bulkenrol_check_data($dataline, $datafield, $linecnt, $courseid, $context, $currentgroup, $checkeddata); + } else { + $alldatainline = explode($delimiter, $dataline); - $email = trim($emailinline); - local_bulkenrol_check_email($email, $linecnt, $courseid, $context, $currentgroup, $checkedemails); - } - } + // Iterate over students data in row/line. + foreach ($alldatainline as $datainline) { + $data = trim($datainline); + local_bulkenrol_check_data($data, $linecnt, $datafield, $courseid, $context, $currentgroup, $checkeddata); } } } - return $checkedemails; + return $checkeddata; } /** * - * Check submitted email, working on the $checkedemails array + * Check submitted user data, working on the $checkeddata array * - * @param string $email e-mail of the user that should be enroled + * @param string $data identifying data of the user that should be enroled + * @param string $datafield To which database field to compare the user data. + * u_* for Fields of the user-table, c_* for custom fields. * @param int $linecnt line counter used for error messages * @param int $courseid course id * @param context_course $context context instance of the course the user should be enroled into * @param string $currentgroup name of the group a user should be added to as member - * @param object $checkedemails Object containing information to be displayed on confirm page and being used for bulkenrol. + * @param object $checkeddata Object containing information to be displayed on confirm page and being used for bulkenrol. */ -function local_bulkenrol_check_email($email, $linecnt, $courseid, $context, $currentgroup, &$checkedemails) { - // Check for valid email. - $emailisvalid = validate_email($email); - // Email is not valid. - if (!$emailisvalid) { - $checkedemails->emails_to_ignore[] = $email; - $a = new stdClass(); - $a->row = $linecnt; - $a->email = $email; - $error = get_string('error_invalid_email', 'local_bulkenrol', $a); - if (array_key_exists($linecnt, $checkedemails->error_messages)) { - $errors = $checkedemails->error_messages[$linecnt]; - $errors .= "
".$error; - $checkedemails->error_messages[$linecnt] = $errors; +function local_bulkenrol_check_data($data, $datafield, $linecnt, $courseid, $context, $currentgroup, &$checkeddata) { + // Check for moodle user with specified data. + list($error, $userrecord) = local_bulkenrol_get_user($data, $datafield); + if (!empty($error)) { + $checkeddata->data_to_ignore[] = $data; + if (array_key_exists($linecnt, $checkeddata->error_messages)) { + $errors = $checkeddata->error_messages[$linecnt]; + $errors .= "
" . $error; + $checkeddata->error_messages[$linecnt] = $errors; } else { - $checkedemails->error_messages[$linecnt] = $error; + $checkeddata->error_messages[$linecnt] = $error; } - - // Email is valid. - } else { - // Check for moodle user with email. - list($error, $userrecord) = local_bulkenrol_get_user($email); - if (!empty($error)) { - $checkedemails->emails_to_ignore[] = $email; - if (array_key_exists($linecnt, $checkedemails->error_messages)) { - $errors = $checkedemails->error_messages[$linecnt]; - $errors .= "
".$error; - $checkedemails->error_messages[$linecnt] = $errors; - } else { - $checkedemails->error_messages[$linecnt] = $error; - } - } else if (!empty($userrecord) && !empty($userrecord->id)) { - $checkedemails->validemailfound += 1; - - $useralreadyenroled = false; - if (!empty($context) && !empty($userrecord)) { - $useralreadyenroled = is_enrolled($context, $userrecord->id); - } - $checkedemails->moodleusers_for_email[$email] = $userrecord; - if (empty($useralreadyenroled)) { - $checkedemails->user_enroled[$email] = $userrecord; - } - if (!empty($currentgroup) && array_key_exists($currentgroup, $checkedemails->course_groups)) { - $checkedemails->course_groups[$currentgroup][] = $userrecord; - } - if (!array_key_exists($email, $checkedemails->user_groups)) { - $checkedemails->user_groups[$email] = array(); + } else if (!empty($userrecord) && !empty($userrecord->id)) { + $checkeddata->validusersfound += 1; + $useralreadyenroled = false; + if (!empty($context) && !empty($userrecord)) { + $useralreadyenroled = is_enrolled($context, $userrecord->id); + } + $checkeddata->moodleusers_for_data[$data] = $userrecord; + if (empty($useralreadyenroled)) { + $checkeddata->user_enroled[$data] = $userrecord; + } + if (!empty($currentgroup) && array_key_exists($currentgroup, $checkeddata->course_groups)) { + $checkeddata->course_groups[$currentgroup][$data] = $userrecord; + } + if (!array_key_exists($data, $checkeddata->user_groups)) { + $checkeddata->user_groups[$data] = array(); + } + if (!empty($currentgroup) && !array_key_exists($currentgroup, $checkeddata->user_groups[$data])) { + // Check if user is already member of the group. + $result = local_bulkenrol_is_already_member($courseid, $currentgroup, $userrecord->id); + if (!empty($result->error)) { + $a = new stdClass(); + $a->row = $linecnt; + $a->data = $data; + $a->groupname = $currentgroup; + $a->error = $result->error; + $error = get_string('error_check_is_already_member', 'local_bulkenrol', $a); + $checkeddata->error_messages[$linecnt] = $error; } - if (!empty($currentgroup) && !array_key_exists($currentgroup, $checkedemails->user_groups[$email])) { - // Check if user is already member of the group. - $result = local_bulkenrol_is_already_member($courseid, $currentgroup, $userrecord->id); - if (!empty($result->error)) { - $a = new stdClass(); - $a->row = $linecnt; - $a->email = $email; - $a->groupname = $currentgroup; - $a->error = $result->error; - $error = get_string('error_check_is_already_member', 'local_bulkenrol', $a); - $checkedemails->error_messages[$linecnt] = $error; - } - $alreadymember = $result->already_member; - // Compose group information. - if (empty($alreadymember)) { - $groupinfo = html_writer::tag('span', - get_string('user_groups_yes', 'local_bulkenrol'), - array('class' => 'badge badge-secondary')); - } else { - $groupinfo = html_writer::tag('span', - get_string('user_groups_already', 'local_bulkenrol'), - array('class' => 'badge badge-success')); - } - $checkedemails->user_groups[$email][] = $currentgroup .': '. $groupinfo; + $alreadymember = $result->already_member; + // Compose group information + if (empty($alreadymember)) { + $groupinfo = html_writer::tag('span', + get_string('user_groups_yes', 'local_bulkenrol'), + array('class' => 'badge badge-secondary')); + } else { + $groupinfo = html_writer::tag('span', + get_string('user_groups_already', 'local_bulkenrol'), + array('class' => 'badge badge-success')); } + $checkeddata->user_groups[$data][] = $currentgroup . $groupinfo; } } } /** - * Takes input from text area containing a list of e-mail adresses (optionally group names starting with '#'). + * Takes input from text area containing a list of data that specifies users (optionally group names starting with '#'). * Returns an array representation of the input. * - * @param mixed $emails input value of the text area. - * @return string[] of e-emails and optional group names + * @param mixed $data input value of the text area. + * @return string[] of data and optional group names */ -function local_bulkenrol_parse_emails($emails) { - if (empty($emails)) { +function local_bulkenrol_parse_data($data) { + if (empty($data)) { return array(); } else { - $rawlines = explode(PHP_EOL, $emails); + $rawlines = explode(PHP_EOL, $data); $result = array(); foreach ($rawlines as $rawline) { $result[] = trim($rawline); @@ -241,38 +207,52 @@ function local_bulkenrol_parse_emails($emails) { /** * Takes an e-mail and returns a moodle user record and error string (if occured). * - * @param string $email E-mail used to search for a user - * @return string,object[] + * @param string $data Data used to search for a user + * @param string $datafield To which database field to compare the user data. + * u_* for Fields of the user-table, c_* for custom fields. + * @return array [string,object[]] */ -function local_bulkenrol_get_user($email) { +function local_bulkenrol_get_user($data, $datafield) { global $DB; $error = null; $userrecord = null; - if (empty($email)) { + if (empty($data)) { + $error = get_string('error_no_data', 'local_bulkenrol', $data); return array($error, $userrecord); - } else { - // Get user records for email. - try { - $userrecords = $DB->get_records('user', array('email' => $email)); - $count = count($userrecords); - if (!empty($count)) { - // More than one user with email -> ignore email and don't enrol users later! - if ($count > 1) { - $error = get_string('error_more_than_one_record_for_email', 'local_bulkenrol', $email); - } else { - $userrecord = current($userrecords); - } + } + + // Get user records for data. + try { + $prefix = substr($datafield, 0, 2); + $usertablefield = substr($datafield, 2, strlen($datafield) - 2); + if ($prefix === 'u_') { + $userrecords = $DB->get_records('user', array($usertablefield => $data)); + } else if ($prefix === 'c_') { + $userrecords = $DB->get_records_sql( + 'SELECT u.* FROM {user} u ' . + 'JOIN {user_info_data} data ON data.userid = u.id ' . + 'WHERE data.fieldid = :fieldid AND data.data = :data', + array('fieldid' => $usertablefield, 'data' => $data)); + } + + $count = count($userrecords); + if (!empty($count)) { + // More than one user with data -> ignore data and don't enrol users later! + if ($count > 1) { + $error = get_string('error_more_than_one_record_for_data', 'local_bulkenrol', array('identifier' => $data, "field" => $datafield)); } else { - $error = get_string('error_no_record_found_for_email', 'local_bulkenrol', $email); + $userrecord = current($userrecords); } - } catch (Exception $e) { - $error = get_string('error_getting_user_for_email', 'local_bulkenrol', $email).local_bulkenrol_get_exception_info($e); + } else { + $error = get_string('error_no_record_found_for_data', 'local_bulkenrol', $data); } - - return array($error, $userrecord); + } catch (Exception $e) { + $error = get_string('error_getting_user_for_data', 'local_bulkenrol', $data) . local_bulkenrol_get_exception_info($e); } + + return array($error, $userrecord); } /** @@ -315,7 +295,7 @@ function local_bulkenrol_users($localbulkenrolkey) { $courseid = $tmpdata[0]; } - $userstoenrol = $localbulkenroldata->moodleusers_for_email; + $userstoenrol = $localbulkenroldata->moodleusers_for_data; if (!empty($courseid) && !empty($userstoenrol)) { try { @@ -366,7 +346,7 @@ function local_bulkenrol_users($localbulkenrolkey) { // Get the course context. $coursecontext = context_course::instance($courseid); - foreach ($userstoenrol as $user) { + foreach ($userstoenrol as $data => $user) { try { // Check if user is already enrolled with another enrolment method. $userisenrolled = is_enrolled($coursecontext, $user->id, '', false); @@ -381,7 +361,7 @@ function local_bulkenrol_users($localbulkenrolkey) { } } catch (Exception $e) { $a = new stdClass(); - $a->email = $user->email; + $a->data = $data; $msg = get_string('error_enrol_user', 'local_bulkenrol', $a). local_bulkenrol_get_exception_info($e); @@ -429,14 +409,14 @@ function local_bulkenrol_users($localbulkenrolkey) { if (empty($useradded)) { $a = new stdClass(); - $a->email = $member->email; + $a->data = $key; $a->group = $groupname; $msg = get_string('error_group_add_member', 'local_bulkenrol', $a); $exceptionsmsg[] = $msg; } } catch (Exception $e) { $a = new stdClass(); - $a->email = $member->email; + $a->data = $key; $a->group = $groupname; $msg = get_string('error_group_add_member', 'local_bulkenrol', $a). local_bulkenrol_get_exception_info($e); @@ -532,14 +512,14 @@ function local_bulkenrol_display_table($localbulkenroldata, $key) { break; case LOCALBULKENROL_ENROLUSERS: - $data = array(); + $rowdata = array(); - if (!empty($localbulkenroldata->moodleusers_for_email)) { - foreach ($localbulkenroldata->moodleusers_for_email as $email => $user) { + if (!empty($localbulkenroldata->moodleusers_for_data)) { + foreach ($localbulkenroldata->moodleusers_for_data as $data => $user) { $row = array(); $cell = new html_table_cell(); - $cell->text = $user->email; + $cell->text = $data; $row[] = $cell; $cell = new html_table_cell(); @@ -552,7 +532,7 @@ function local_bulkenrol_display_table($localbulkenroldata, $key) { $cell = new html_table_cell(); $cell->text = ''; - if (!empty($localbulkenroldata->user_enroled[$email])) { + if (!empty($localbulkenroldata->user_enroled[$data])) { $cell->text = html_writer::tag('span', get_string('user_enroled_yes', 'local_bulkenrol'), array('class' => 'badge badge-secondary')); @@ -565,12 +545,12 @@ function local_bulkenrol_display_table($localbulkenroldata, $key) { $cell = new html_table_cell(); $cell->text = ''; - if (!empty($localbulkenroldata->user_groups[$email])) { - $cell->text = implode(',
', $localbulkenroldata->user_groups[$email]); + if (!empty($localbulkenroldata->user_groups[$data])) { + $cell->text = implode(',
', $localbulkenroldata->user_groups[$data]); } $row[] = $cell; - $data[] = $row; + $rowdata[] = $row; } } @@ -580,14 +560,14 @@ function local_bulkenrol_display_table($localbulkenroldata, $key) { $table->summary = get_string('users_to_enrol_in_course', 'local_bulkenrol'); $table->size = array('20%', '17%', '17%', '20%', '26%'); $table->head = array(); - $table->head[] = get_string('email'); + $table->head[] = get_string('identifying_data', 'local_bulkenrol'); $table->head[] = get_string('firstname'); $table->head[] = get_string('lastname'); $table->head[] = get_string('user_enroled', 'local_bulkenrol'); $table->head[] = get_string('user_groups', 'local_bulkenrol'); - $table->data = $data; + $table->data = $rowdata; - if (!empty($data)) { + if (!empty($rowdata)) { echo $OUTPUT->heading(get_string('users_to_enrol_in_course', 'local_bulkenrol'), 3); echo html_writer::tag('div', html_writer::table($table), array('class' => 'flexible-wrap')); } @@ -706,7 +686,7 @@ function local_bulkenrol_is_already_member($courseid, $groupname, $userid) { } } catch (Exception $e) { $msg = get_string('error_group_add_members', 'local_bulkenrol').local_bulkenrol_get_exception_info($e); - $exceptionsmsg[] = $msg; + $result->error = $msg; } return $result; } diff --git a/settings.php b/settings.php index 166df67..9239f7e 100644 --- a/settings.php +++ b/settings.php @@ -24,6 +24,18 @@ defined('MOODLE_INTERNAL') || die; +$filtercustombyunique = true; + +$usertableoptions = [ + "email", + "idnumber", + "username" +]; + +$standardoptions = [ + "u_email" +]; + if ($hassiteconfig) { $settings = new admin_settingpage('local_bulkenrol', get_string('pluginname', 'local_bulkenrol', null, true)); @@ -44,6 +56,7 @@ ); unset($enroloptions); + // Create role chooser widget. $roleoptions = array(); // Get some basic data we are going to need. @@ -74,6 +87,36 @@ $roleoptions) ); unset($roleoptions); + + global $DB; + $fields = []; + // The same e-mail address could be shared between users. + if (!empty($CFG->allowaccountssameemail)) { + $usertableoptions = array_diff($usertableoptions, ['email']); + } + foreach ($usertableoptions as $fieldname) { + if (!in_array($fieldname, $usertableoptions)) { + continue; + } + $fields["u_" . $fieldname] = $fieldname; + } + + $sql = "SELECT id, name, forceunique FROM {user_info_field} WHERE forceunique = 1"; + $customfields = $DB->get_records_sql_menu($sql); + + foreach ($customfields as $id => $name) { + $fields["c_" . $id] = $name; + } + + $settings->add( + new admin_setting_configmultiselect( + 'local_bulkenrol/fieldoptions', + get_string('fieldoptions', 'local_bulkenrol'), + get_string('fieldoptions_desc', 'local_bulkenrol'), + $standardoptions, + $fields + ) + ); } $ADMIN->add('enrolments', $settings); diff --git a/tests/behat/local_bulkenrol_groups.feature b/tests/behat/local_bulkenrol_groups.feature index 16feac4..e6063f3 100644 --- a/tests/behat/local_bulkenrol_groups.feature +++ b/tests/behat/local_bulkenrol_groups.feature @@ -20,6 +20,7 @@ Feature: Using the local_bulkenrol plugin for group management And the following config values are set as admin: | config | value | plugin | | enrolplugin | manual | local_bulkenrol | + | fieldoptions | u_email,u_idnumber,u_username | local_bulkenrol | Given I log in as "admin" And I navigate to "Plugins > Enrolments > User bulk enrolment" in site administration And I set the following fields to these values: @@ -40,7 +41,7 @@ Feature: Using the local_bulkenrol plugin for group management And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ # Group 1 student1@example.com @@ -80,7 +81,7 @@ Feature: Using the local_bulkenrol plugin for group management And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ # Group 1 student1@example.com @@ -119,7 +120,7 @@ Feature: Using the local_bulkenrol plugin for group management And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ # Group 1 student1@example.com @@ -149,7 +150,7 @@ Feature: Using the local_bulkenrol plugin for group management And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ # Group 1 student1@example.com diff --git a/tests/behat/local_bulkenrol_users.feature b/tests/behat/local_bulkenrol_users.feature index e6c1d83..ca046f8 100644 --- a/tests/behat/local_bulkenrol_users.feature +++ b/tests/behat/local_bulkenrol_users.feature @@ -9,17 +9,18 @@ Feature: Using the local_bulkenrol plugin for user enrolments | fullname | shortname | format | | Course 1 | C1 | topics | And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | student3 | Student | 3 | student3@example.com | + | username | firstname | lastname | email | idnumber | + | teacher1 | Teacher | 1 | teacher1@example.com | 1 | + | student1 | Student | 1 | student1@example.com | 2 | + | student2 | Student | 2 | student2@example.com | 3 | + | student3 | Student | 3 | student3@example.com | 4 | And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | And the following config values are set as admin: | config | value | plugin | | enrolplugin | manual | local_bulkenrol | + | fieldoptions | u_email,u_idnumber,u_username | local_bulkenrol | Given I log in as "admin" And I navigate to "Plugins > Enrolments > User bulk enrolment" in site administration And I set the following fields to these values: @@ -38,7 +39,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com student2@example.com @@ -66,7 +67,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com student2@example.com @@ -100,7 +101,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com student2@example.com @@ -123,6 +124,77 @@ Feature: Using the local_bulkenrol plugin for user enrolments | student3@example.com | Student | 3 | Teacher | And "div[data-fullname='Student 1'][data-enrolinstancename='Manual enrolments'][data-status='Active']" "css_element" should exist + Scenario: Bulk enrol users into the course by their ID + Given I log in as "admin" + And I navigate to "Plugins > Enrolments > User bulk enrolment" in site administration + And I set the following fields to these values: + | Fieldoptions | idnumber,email,username | + And I press "Save changes" + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage + And I navigate to "Users > User bulk enrolment" in current page administration + Then the "dbfield" select box should contain "email" + And the "dbfield" select box should contain "idnumber" + And the "dbfield" select box should contain "username" + And I set the field "List of users identified by your chosen field" to multiline: + """ + 2 + 3 + 4 + """ + And I click on "Enrol users" "button" + Then the following should exist in the "localbulkenrol_enrolusers" table: + | idnumber | First name | Surname | User enrolment | + | 1 | Student | 1 | User will be enrolled | + | 2 | Student | 2 | User will be enrolled | + | 3 | Student | 3 | User will be enrolled | + And the following should exist in the "localbulkenrol_enrolinfo" table: + | Enrolment method | Assigned role | + | Manual enrolments | Student | + And I click on "Enrol users" "button" + Then the following should exist in the "participants" table: + | Email address | First name | Surname | Roles | + | student1@example.com | Student | 1 | Student | + | student2@example.com | Student | 2 | Student | + | student3@example.com | Student | 3 | Student | + When I click on "[data-enrolinstancename='Manual enrolments'] a[data-action=showdetails]" "css_element" in the "Student 1" "table_row" + Then I should see "Manual enrolments" + + Scenario: Bulk enrol students when there is only a single datafield option. It should automatically change the helptext. + Given I log in as "admin" + And I navigate to "Plugins > Enrolments > User bulk enrolment" in site administration + And I set the following fields to these values: + | Fieldoptions | email | + And I press "Save changes" + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage + And I navigate to "Users > User bulk enrolment" in current page administration + And I set the field "List of users identified by their email" to multiline: + """ + student1@example.com + student2@example.com + student3@example.com + """ + And I click on "Enrol users" "button" + Then the following should exist in the "localbulkenrol_enrolusers" table: + | idnumber | First name | Surname | User enrolment | + | 1 | Student | 1 | User will be enrolled | + | 2 | Student | 2 | User will be enrolled | + | 3 | Student | 3 | User will be enrolled | + And the following should exist in the "localbulkenrol_enrolinfo" table: + | Enrolment method | Assigned role | + | Manual enrolments | Student | + And I click on "Enrol users" "button" + Then the following should exist in the "participants" table: + | Email address | First name | Surname | Roles | + | student1@example.com | Student | 1 | Student | + | student2@example.com | Student | 2 | Student | + | student3@example.com | Student | 3 | Student | + When I click on "[data-enrolinstancename='Manual enrolments'] a[data-action=showdetails]" "css_element" in the "Student 1" "table_row" + Then I should see "Manual enrolments" + Scenario: Bulk enrol students into the course with students already enrolled Given the following "course enrolments" exist: | user | course | role | @@ -131,7 +203,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com student2@example.com @@ -166,7 +238,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com """ @@ -186,25 +258,25 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student4@example.com """ And I click on "Enrol users" "button" - Then I should see "No existing Moodle user account with e-mail address student4@example.com." + Then I should see "No existing Moodle user account student4@example.com was found." Scenario: Try to bulk enrol a list of invalid users. When I log in as "teacher1" And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ foo bar """ And I click on "Enrol users" "button" - Then I should see "No valid e-mail address was found in the given list." + Then I should see " No valid entrys were found in the given list." And I should see "Please go back and check your input" And "Enrol users" "button" should not exist @@ -213,7 +285,7 @@ Feature: Using the local_bulkenrol plugin for user enrolments And I am on "Course 1" course homepage And I select "Participants" from secondary navigation And I select "User bulk enrolment" from the "jump" singleselect - And I set the field "List of e-mail addresses" to multiline: + And I set the field "List of users identified by your chosen field" to multiline: """ student1@example.com diff --git a/version.php b/version.php index 555d5d7..b11b0a0 100644 --- a/version.php +++ b/version.php @@ -26,8 +26,8 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'local_bulkenrol'; -$plugin->version = 2022071201; -$plugin->release = 'v4.0-r2'; +$plugin->version = 2022100600; +$plugin->release = 'v4.0-r3'; $plugin->requires = 2022041900; $plugin->supported = [400, 400]; $plugin->maturity = MATURITY_STABLE;