From: toyomoyo ';
+ while (!feof ($fp)) {
+ $user = new object();
+ // by default, use the local mnet id (this may be changed in the file)
+ $user->mnethostid = $CFG->mnet_localhost_id;
+ $line = explode($csv_delimiter, fgets($fp,LINE_MAX_SIZE));
+ ++$linenum;
+ $ok = true;
+ // add fields to user object
+ foreach ($line as $key => $value) {
+ if($value !== '') {
+ $key = $headers[$key];
+ //decode encoded commas
+ $value = str_replace($csv_encode,$csv_delimiter,trim($value));
+ // special fields: password and username
+ if ($key == 'password' && !empty($value)) {
+ $user->$key = hash_internal_user_password($value);
+ } else if($key == 'username') {
+ $user->$key = addslashes($textlib->strtolower($value));
+ } else {
+ $user->$key = addslashes($value);
}
}
- // check for required fields
- foreach ($required as $key => $value) {
- if ($value) { //required field missing
- error(get_string('fieldrequired', 'error', $key), 'uploaduser.php?sesskey='.$USER->sesskey);
- }
+ }
+ // add default values for remaining fields
+ foreach ($fields as $key => $value) {
+ if(isset($user->$key)) {
+ continue;
}
- $linenum = 2; // since header is line 1
-
- $usersnew = 0;
- $usersupdated = 0;
- $userserrors = 0;
- $renames = 0;
- $renameerrors = 0;
-
- // Will use this course array a lot
- // so fetch it early and keep it in memory
- $courses = get_courses('all','c.sortorder','c.id,c.shortname,c.fullname,c.sortorder,c.teacher,c.visible');
-
- while (!feof ($fp)) {
- foreach ($optionalDefaults as $key => $value) {
- $user->$key = addslashes($adminuser->$key);
+ if(!isset($formdata->$key) || $formdata->$key==='') { // no default value was submited
+ if($value) { // the field is required
+ notify(get_string('erroronline', 'error', $linenum). ': ' .get_string('missingfield', 'error', $key));
+ $ok = false;
}
- //Note: commas within a field should be encoded as , (for comma separated csv files)
- //Note: semicolon within a field should be encoded as ; (for semicolon separated csv files)
- $line = split($csv_delimiter, fgets($fp,1024));
- foreach ($line as $key => $value) {
- //decode encoded commas
- $record[$header[$key]] = preg_replace($csv_encode,$csv_delimiter2,trim($value));
- }
- if ($record[$header[0]]) {
- // add a new user to the database
-
- // add fields to object $user
- foreach ($record as $name => $value) {
- // check for required values
- if (isset($required[$name]) and !$value) {
- error(get_string('missingfield', 'error', $name). " ".
- get_string('erroronline', 'error', $linenum) .". ".
- get_string('processingstops', 'error'),
- 'uploaduser.php?sesskey='.$USER->sesskey);
- }
- // password needs to be encrypted
- else if ($name == "password" && !empty($value)) {
- $user->password = hash_internal_user_password($value);
- }
- else if ($name == "username") {
- $user->username = addslashes(moodle_strtolower($value));
- }
- // normal entry
- else {
- $user->{$name} = addslashes($value);
+ continue;
+ }
+ // process templates
+ $template = $formdata->$key;
+ $templatelen = strlen($template);
+ $value = '';
+ for ($i = 0 ; $i < $templatelen; ++$i) {
+ if($template[$i] == '%') {
+ $case = 0; // 1=lowercase, 2=uppercase
+ $len = 0; // number of characters to keep
+ $info = null; // data to process
+ for($j = $i + 1; is_null($info) && $j < $templatelen; ++$j) {
+ $car = $template[$j];
+ if ($car >= '0' && $car <= '9') {
+ $len = $len * 10 + (int)$car;
+ } else if($car == '-') {
+ $case = 1;
+ } else if($car == '+') {
+ $case = 2;
+ } else if($car == 'f') { // first name
+ $info = @$user->firstname;
+ } else if($car == 'l') { // last name
+ $info = @$user->lastname;
+ } else if($car == 'u') { // username
+ $info = @$user->username;
+ } else if($car == '%' && $j == $i+1) {
+ $info = '%';
+ } else { // invalid character
+ $info = '';
}
}
- $user->confirmed = 1;
- $user->timemodified = time();
- $linenum++;
- $username = $user->username;
- $addcourse[0] = isset($user->course1) ? $user->course1 : NULL;
- $addcourse[1] = isset($user->course2) ? $user->course2 : NULL;
- $addcourse[2] = isset($user->course3) ? $user->course3 : NULL;
- $addcourse[3] = isset($user->course4) ? $user->course4 : NULL;
- $addcourse[4] = isset($user->course5) ? $user->course5 : NULL;
- $addgroup[0] = isset($user->group1) ? $user->group1 : NULL;
- $addgroup[1] = isset($user->group2) ? $user->group2 : NULL;
- $addgroup[2] = isset($user->group3) ? $user->group3 : NULL;
- $addgroup[3] = isset($user->group4) ? $user->group4 : NULL;
- $addgroup[4] = isset($user->group5) ? $user->group5 : NULL;
- $addtype[0] = isset($user->type1) ? $user->type1 : NULL;
- $addtype[1] = isset($user->type2) ? $user->type2 : NULL;
- $addtype[2] = isset($user->type3) ? $user->type3 : NULL;
- $addtype[3] = isset($user->type4) ? $user->type4 : NULL;
- $addtype[4] = isset($user->type5) ? $user->type5 : NULL;
- $addrole[0] = isset($user->role1) ? $user->role1 : NULL;
- $addrole[1] = isset($user->role2) ? $user->role2 : NULL;
- $addrole[2] = isset($user->role3) ? $user->role3 : NULL;
- $addrole[3] = isset($user->role4) ? $user->role4 : NULL;
- $addrole[4] = isset($user->role5) ? $user->role5 : NULL;
-
- for ($i=0; $i<5; $i++) {
- $course[$i]=NULL;
+ if($info==='' || is_null($info)) { // invalid template
+ continue;
}
- foreach ($courses as $eachcourse) {
- for ($i=0; $i<5; $i++) {
- if ($eachcourse->shortname == $addcourse[$i]) {
- $course[$i] = $eachcourse;
- }
- }
+ $i = $j - 1;
+ // change case
+ if($case == 1) {
+ $info = $textlib->strtolower($info);
+ } else if($case == 2) {
+ $info = $textlib->strtoupper($info);
}
-
- // before insert/update, check whether we should be updating
- // an old record instead
- if ($allowrenames && !empty($user->oldusername) ) {
- $user->oldusername = moodle_strtolower($user->oldusername);
- if ($olduser = get_record('user', 'username', $user->oldusername, 'mnethostid', $user->mnethostid)) {
- if (set_field('user', 'username', $user->username, 'username', $user->oldusername)) {
- notify(get_string('userrenamed', 'admin') . " : $user->oldusername $user->username");
- $renames++;
- } else {
- notify(get_string('usernotrenamedexists', 'error') . " : $user->oldusername $user->username");
- $renameerrors++;
- continue;
- }
- } else {
- notify(get_string('usernotrenamedmissing', 'error') . " : $user->oldusername $user->username");
- $renameerrors++;
- continue;
- }
+ if($len) { // truncate data
+ $info = $textlib->substr($info, 0, $len);
+ }
+ $value .= $info;
+ } else {
+ $value .= $template[$i];
+ }
+ }
+
+ if($key == 'username') {
+ $value = $textlib->strtolower($value);
+ if(empty($CFG->extendedusernamechars)) {
+ $value = eregi_replace('[^(-\.[:alnum:])]', '', $value);
+ }
+ // check for new username duplicates
+ if(empty($newusernames[$value])) {
+ $newusernames[$value] = 1;
+ } else {
+ if($skipduplicates) {
+ notify($strduplicateusername . ': ' . $value);
+ $ok = false;
+ continue;
+ } else {
+ ++$newusernames[$value];
+ $value .= $newusernames[$value];
}
+ }
+ }
+ $user->$key = $value;
+ }
+ if(!$ok) {
+ ++$userserrors;
+ continue;
+ }
- if ($olduser = get_record("user", "username", $username, "mnethostid", $user->mnethostid)) {
- if ($updateaccounts) {
- // Record is being updated
- $user->id = $olduser->id;
- if (update_record('user', $user)) {
- notify("$user->id , $user->username ".get_string('useraccountupdated', 'admin'));
- $usersupdated++;
- } else {
- notify(get_string('usernotupdatederror', 'error', $username));
- $userserrors++;
- continue;
- }
- } else {
- //Record not added - user is already registered
- //In this case, output userid from previous registration
- //This can be used to obtain a list of userids for existing users
- notify("$olduser->id ".get_string('usernotaddedregistered', 'error', $username));
- $userserrors++;
- }
+ $user->confirmed = 1;
+ $user->timemodified = time();
+
+ // save the user to the database
+ $username = $user->username;
+
+ // before insert/update, check whether we should be updating an old record instead
+ if ($allowrenames && !empty($user->oldusername) ) {
+ $user->oldusername = $textlib->strtolower($user->oldusername);
+ $info = ': ' . $user->oldusername . '-->' . $user->username . '. ';
+ if ($olduser = get_record('user', 'username', $user->oldusername, 'mnethostid', $user->mnethostid)) {
+ if (set_field('user', 'username', $user->username, 'id', $olduser->id)) {
+ echo $struserrenamed . $info;
+ $renames++;
+ } else {
+ notify($strusernotrenamedexists . $info);
+ $renameerrors++;
+ continue;
+ }
+ } else {
+ notify($strusernotrenamedmissing . $info);
+ $renameerrors++;
+ continue;
+ }
+ }
- } else { // new user
- if ($user->id = insert_record("user", $user)) {
- notify("$struser: $user->id = $user->username");
- $usersnew++;
- if (empty($user->password) && $createpassword) {
- // passwords will be created and sent out on cron
- insert_record('user_preferences', array( 'userid' => $user->id,
- 'name' => 'create_password',
- 'value' => 1));
- insert_record('user_preferences', array( 'userid' => $user->id,
- 'name' => 'auth_forcepasswordchange',
- 'value' => 1));
- }
- } else {
- // Record not added -- possibly some other error
- notify(get_string('usernotaddederror', 'error', $username));
- $userserrors++;
- continue;
- }
- }
- for ($i=0; $i<5; $i++) {
- if ($addcourse[$i] && !$course[$i]) {
- notify(get_string('unknowncourse', 'error', $addcourse[$i]));
- }
- }
- for ($i=0; $i<5; $i++) {
- $groupid[$i] = 0;
- if ($addgroup[$i]) {
- if (!$course[$i]) {
- notify(get_string('coursegroupunknown','error',$addgroup[$i]));
- } else {
- if ($gid = groups_get_group_by_name($course[$i]->id, $addgroup[$i])) {
- $groupid[$i] = $gid;
- } else {
- notify(get_string('groupunknown','error',$addgroup[$i]));
- }
- }
- }
- }
- for ($i=0; $i<5; $i++) { /// Enrol into courses if necessary
- if ($course[$i]) {
- if (isset($addrole[$i])) {
- $coursecontext = get_context_instance(CONTEXT_COURSE, $course[$i]->id);
- if (!user_can_assign($coursecontext, $addrole[$i])) {
- notify('--> Can not assign role in course'); //TODO: localize
- }
- $ret = role_assign($addrole[$i], $user->id, 0, $coursecontext->id);
- } else if (isset($addtype[$i])) {
- switch ($addtype[$i]) {
- case 2: // teacher
- $ret = add_teacher($user->id, $course[$i]->id, 1);
- break;
+ // save the information
+ if ($olduser = get_record('user', 'username', $username, 'mnethostid', $user->mnethostid)) {
+ $user->id = $olduser->id;
+ $info = ': ' . $username .' (ID = ' . $user->id . ')';
+ if ($updateaccounts) {
+ // Record is being updated
+ if (update_record('user', $user)) {
+ echo $struserupdated . $info . '
';
+ $usersupdated++;
+ } else {
+ notify($strusernotupdated . $info);
+ $userserrors++;
+ continue;
+ }
+ } else {
+ //Record not added - user is already registered
+ //In this case, output userid from previous registration
+ //This can be used to obtain a list of userids for existing users
+ echo $strusernotadded . $info . '
';
+ $userserrors++;
+ }
+ } else { // new user
+ if ($user->id = insert_record('user', $user)) {
+ $info = ': ' . $username .' (ID = ' . $user->id . ')';
+ echo $struseradded . $info . '
';
+ $usersnew++;
+ if (empty($user->password) && $createpassword) {
+ // passwords will be created and sent out on cron
+ insert_record('user_preferences', array( 'userid' => $user->id, 'name' => 'create_password', 'value' => 1));
+ insert_record('user_preferences', array( 'userid' => $user->id, 'name' => 'auth_forcepasswordchange', 'value' => 1));
+ }
+ } else {
+ // Record not added -- possibly some other error
+ notify($strusernotaddederror . ': ' . $username);
+ $userserrors++;
+ continue;
+ }
+ }
- case 3: // non-editing teacher
- $ret = add_teacher($user->id, $course[$i]->id, 0);
- break;
+ // find course enrolments, groups and roles/types
+ for($ncourses = 1; $addcourse = @$user->{'course' . $ncourses}; ++$ncourses) {
+ // find course
+ if(!$course = @$courses[$addcourse]) {
+ notify(get_string('unknowncourse', 'error', $addcourse));
+ continue;
+ }
+ // find role
+ if ($addrole = @$user->{'role' . $ncourses}) {
+ $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+ if (!$ok = role_assign($addrole, $user->id, 0, $coursecontext->id)) {
+ echo $strindent . $strcannotassignrole . '
';
+ }
+ } else {
+ // if no role, then find "old" enrolment type
+ switch ($addtype = @$user->{'type' . $ncourses}) {
+ case 2: // teacher
+ $ok = add_teacher($user->id, $course->id, 1);
+ break;
+ case 3: // non-editing teacher
+ $ok = add_teacher($user->id, $course->id, 0);
+ break;
+ case 1: // student
+ default:
+ $ok = enrol_student($user->id, $course->id);
+ break;
+ }
+ }
+ if ($ok) { // OK
+ echo $strindent . get_string('enrolledincourse', '', $addcourse) . '
';
+ } else {
+ notify(get_string('enrolledincoursenot', '', $addcourse));
+ }
- default: // student
- $ret = enrol_student($user->id, $course[$i]->id);
- break;
- }
- } else {
- $ret = enrol_student($user->id, $course[$i]->id);
- }
- if ($ret) { // OK
- notify('-->'. get_string('enrolledincourse', '', $addcourse[$i]));
- } else {
- notify('-->'.get_string('enrolledincoursenot', '', $addcourse[$i]));
- }
- }
- }
- for ($i=0; $i<5; $i++) { // Add user to groups if necessary
- if ($course[$i] && $groupid[$i]) {
- $coursecontext = get_context_instance(CONTEXT_COURSE, $course[$i]->id);
- if (count(get_user_roles($coursecontext, $user->id))) {
- if (groups_add_member($groupid[$i], $user->id)) {
- notify('-->' . get_string('addedtogroup','',$addgroup[$i]));
- } else {
- notify('-->' . get_string('addedtogroupnot','',$addgroup[$i]));
- }
- } else {
- notify('-->' . get_string('addedtogroupnotenrolled','',$addgroup[$i]));
- }
+ // find group to add to
+ if ($addgroup = @$user->{'group' . $ncourses}) {
+ if ($gid = groups_get_group_by_name($course->id, $addgroup)) {
+ $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+ if (count(get_user_roles($coursecontext, $user->id))) {
+ if (groups_add_member($gid, $user->id)) {
+ echo $strindent . get_string('addedtogroup','',$addgroup) . '
';
+ } else {
+ notify(get_string('addedtogroupnot','',$addgroup));
}
+ } else {
+ notify(get_string('addedtogroupnotenrolled','',$addgroup));
}
-
- unset ($user);
+ } else {
+ notify(get_string('groupunknown','error',$addgroup));
}
}
- fclose($fp);
- notify("$strusersnew: $usersnew");
- notify(get_string('usersupdated', 'admin') . ": $usersupdated");
- notify(get_string('errors', 'admin') . ": $userserrors");
- if ($allowrenames) {
- notify(get_string('usersrenamed', 'admin') . ": $renames");
- notify(get_string('renameerrors', 'admin') . ": $renameerrors");
- }
- echo '
';
+ }
+ }
+ echo '
Required fieldnames: these fields must be included in the first record, and defined for each user
-- -
username, password, firstname, lastname, email
Default fieldnames: these are optional - if they are not included then the values are taken from the primary admin
--
institution, department, city, country, lang, auth, timezone
Optional fieldnames: all of these are completely optional. The course names are the "shortnames" of the courses - if present then the user will be enrolled as students in those courses. Group names must be associated to the corresponding courses, i.e. group1 to course1, etc.
-+
idnumber, icq, phone1, phone2, address, url, description, mailformat, maildisplay, htmleditor, autosubscribe, course1, course2, course3, course4, course5, group1, group2, group3, group4, group5, type1, type2, type3, type4, type5, role1, role2, role3, role4, role5, emailstop
+
firstname, lastname
Optional fieldnames: all of these are completely optional. If a values is present for the field in the file, then that value is used; else, the default value for that field is used.
++
institution, department, city, country, lang, auth, timezone, idnumber, icq, phone1, phone2, address, url, description, mailformat, maildisplay, htmleditor, autosubscribe, emailstop
Enrolment fieldnames (optional): The course names are the "shortnames" of the courses - if present then the user will be enrolled in those courses. For groups use group name; for roles use id. Group names must be associated to the corresponding courses, i.e. group1 to course1, etc.
+
course1, group1, type1, role1, course2, group2, type2, role2, etc.
Here is an example of a valid import file:
username, password, firstname, lastname, email, lang, idnumber, maildisplay, course1, group1, type1
jonest, verysecret, Tom, Jones, jonest@someplace.edu, en, 3663737, 1, Intro101, Section 1, 1
reznort, somesecret, Trent, Reznor, reznort@someplace.edu, en_us, 6736733, 0, Advanced202, Section 3, 3
The default values are processed as templates in which the following codes are allowed:
+%l
- will be replaced by the lastname%f
- will be replaced by the firstname%u
- will be replaced by the username%%
- will be replaced by the %Between the percent sign (%) and any code letter (l, f or u) the following modifiers are allowed:
+For example, if the firstname is John and the lastname is Doe, the following values will be obtained with the specified templates:
+Template processing is done only on default values, and not on the values retrieved from the CSV file.
+In order to create corect Moodle usernames, the username is always converted to lowercase. Moreover, if the "Allow extended characters in usernames" option in the Site policies page is off, characters different to letters, digits, dash (-) and dot (.) are removed. +For example if the firstname is John Jr. and the lastname is Doe, the username %-f%-l will produce john jr.doe when Allow extended characters in usernames is on, and johnjr.doe when off (notice the extra space).
+When the "New username duplicate handling" setting is set to Append counter, an auto-increment counter will be append to duplicate usernames produced by the template. +For example, if the CSV file contains the users named John Doe, Jane Doe and Jenny Doe without explicit usernames, the default username is %-1f%-l and New username duplicate handling is set to Append counter, then the usernames produced will be jdoe, jdoe2 and jdoe3. +
+By default Moodle assumes that you will be creating new user accounts, and skips records where the username matches an existing account. However, if you set "Update existing accounts" to Yes, the existing user account will be updated.