Use the new, central, create_guest_record() function. MDL-10375
[pfb-moodle.git] / admin / uploaduser.php
blob5b67a793484ecd7414fb5508a96e964ebd3db453
1 <?php // $Id$
3 /// Bulk user registration script from a comma separated file
4 /// Returns list of users with their user ids
6 require_once('../config.php');
7 require_once($CFG->libdir.'/adminlib.php');
8 require_once('uploaduser_form.php');
10 admin_externalpage_setup('uploadusers');
12 require_capability('moodle/site:uploadusers', get_context_instance(CONTEXT_SYSTEM));
14 if (! $site = get_site()) {
15 error("Could not find site-level course");
18 if (!$adminuser = get_admin()) {
19 error("Could not find site admin");
22 $struser = get_string('user');
23 $strusersnew = get_string('usersnew');
25 $csv_encode = '/\&\#44/';
26 if (isset($CFG->CSV_DELIMITER)) {
27 $csv_delimiter = '\\' . $CFG->CSV_DELIMITER;
28 $csv_delimiter2 = $CFG->CSV_DELIMITER;
30 if (isset($CFG->CSV_ENCODE)) {
31 $csv_encode = '/\&\#' . $CFG->CSV_ENCODE . '/';
33 } else {
34 $csv_delimiter = "\,";
35 $csv_delimiter2 = ",";
38 /// Print the header
40 admin_externalpage_print_header();
42 $mform = new admin_uploaduser_form();
44 /// If a file has been uploaded, then process it
46 if ( $formdata = $mform->get_data() ) {
48 $createpassword = $formdata->createpassword;
49 $updateaccounts = $formdata->updateaccounts;
50 $allowrenames = $formdata->allowrenames;
52 $filename = $mform->get_userfile_name();
54 // Large files are likely to take their time and memory. Let PHP know
55 // that we'll take longer, and that the process should be recycled soon
56 // to free up memory.
57 @set_time_limit(0);
58 @raise_memory_limit("192M");
59 if (function_exists('apache_child_terminate')) {
60 @apache_child_terminate();
63 $text = my_file_get_contents($filename);
64 //trim utf-8 bom
65 $textlib = new textlib();
66 $text = $textlib->trim_utf8_bom($text);
67 //Fix mac/dos newlines
68 $text = preg_replace('!\r\n?!',"\n",$text);
69 $fp = fopen($filename, "w");
70 fwrite($fp,$text);
71 fclose($fp);
73 $fp = fopen($filename, "r");
75 // make arrays of valid fields for error checking
76 $required = array("username" => 1,
77 "password" => !$createpassword,
78 "firstname" => 1,
79 "lastname" => 1,
80 "email" => 1);
81 $optionalDefaults = array("mnethostid" => 1,
82 "institution" => 1,
83 "department" => 1,
84 "city" => 1,
85 "country" => 1,
86 "lang" => 1,
87 "auth" => 1,
88 "timezone" => 1);
89 $optional = array("idnumber" => 1,
90 "icq" => 1,
91 "phone1" => 1,
92 "phone2" => 1,
93 "address" => 1,
94 "url" => 1,
95 "description" => 1,
96 "mailformat" => 1,
97 "maildisplay" => 1,
98 "htmleditor" => 1,
99 "autosubscribe" => 1,
100 "idnumber" => 1,
101 "icq" => 1,
102 "course1" => 1,
103 "course2" => 1,
104 "course3" => 1,
105 "course4" => 1,
106 "course5" => 1,
107 "group1" => 1,
108 "group2" => 1,
109 "group3" => 1,
110 "group4" => 1,
111 "group5" => 1,
112 "type1" => 1,
113 "type2" => 1,
114 "type3" => 1,
115 "type4" => 1,
116 "type5" => 1,
117 "role1" => 1,
118 "role2" => 1,
119 "role3" => 1,
120 "role4" => 1,
121 "role5" => 1,
122 "password" => $createpassword,
123 "oldusername" => $allowrenames);
125 // --- get header (field names) ---
126 $header = split($csv_delimiter, fgets($fp,1024));
127 // check for valid field names
128 foreach ($header as $i => $h) {
129 $h = trim($h); $header[$i] = $h; // remove whitespace
130 if (!(isset($required[$h]) or isset($optionalDefaults[$h]) or isset($optional[$h]))) {
131 error(get_string('invalidfieldname', 'error', $h), 'uploaduser.php?sesskey='.$USER->sesskey);
133 if (isset($required[$h])) {
134 $required[$h] = 0;
137 // check for required fields
138 foreach ($required as $key => $value) {
139 if ($value) { //required field missing
140 error(get_string('fieldrequired', 'error', $key), 'uploaduser.php?sesskey='.$USER->sesskey);
143 $linenum = 2; // since header is line 1
145 $usersnew = 0;
146 $usersupdated = 0;
147 $userserrors = 0;
148 $renames = 0;
149 $renameerrors = 0;
151 // Will use this course array a lot
152 // so fetch it early and keep it in memory
153 $courses = get_courses('all','c.sortorder','c.id,c.shortname,c.fullname,c.sortorder,c.teacher,c.visible');
155 while (!feof ($fp)) {
156 foreach ($optionalDefaults as $key => $value) {
157 $user->$key = addslashes($adminuser->$key);
159 //Note: commas within a field should be encoded as &#44 (for comma separated csv files)
160 //Note: semicolon within a field should be encoded as &#59 (for semicolon separated csv files)
161 $line = split($csv_delimiter, fgets($fp,1024));
162 foreach ($line as $key => $value) {
163 //decode encoded commas
164 $record[$header[$key]] = preg_replace($csv_encode,$csv_delimiter2,trim($value));
166 if ($record[$header[0]]) {
167 // add a new user to the database
169 // add fields to object $user
170 foreach ($record as $name => $value) {
171 // check for required values
172 if (isset($required[$name]) and !$value) {
173 error(get_string('missingfield', 'error', $name). " ".
174 get_string('erroronline', 'error', $linenum) .". ".
175 get_string('processingstops', 'error'),
176 'uploaduser.php?sesskey='.$USER->sesskey);
178 // password needs to be encrypted
179 else if ($name == "password" && !empty($value)) {
180 $user->password = hash_internal_user_password($value);
182 else if ($name == "username") {
183 $user->username = addslashes(moodle_strtolower($value));
185 // normal entry
186 else {
187 $user->{$name} = addslashes($value);
190 $user->confirmed = 1;
191 $user->timemodified = time();
192 $linenum++;
193 $username = $user->username;
194 $addcourse[0] = isset($user->course1) ? $user->course1 : NULL;
195 $addcourse[1] = isset($user->course2) ? $user->course2 : NULL;
196 $addcourse[2] = isset($user->course3) ? $user->course3 : NULL;
197 $addcourse[3] = isset($user->course4) ? $user->course4 : NULL;
198 $addcourse[4] = isset($user->course5) ? $user->course5 : NULL;
199 $addgroup[0] = isset($user->group1) ? $user->group1 : NULL;
200 $addgroup[1] = isset($user->group2) ? $user->group2 : NULL;
201 $addgroup[2] = isset($user->group3) ? $user->group3 : NULL;
202 $addgroup[3] = isset($user->group4) ? $user->group4 : NULL;
203 $addgroup[4] = isset($user->group5) ? $user->group5 : NULL;
204 $addtype[0] = isset($user->type1) ? $user->type1 : NULL;
205 $addtype[1] = isset($user->type2) ? $user->type2 : NULL;
206 $addtype[2] = isset($user->type3) ? $user->type3 : NULL;
207 $addtype[3] = isset($user->type4) ? $user->type4 : NULL;
208 $addtype[4] = isset($user->type5) ? $user->type5 : NULL;
209 $addrole[0] = isset($user->role1) ? $user->role1 : NULL;
210 $addrole[1] = isset($user->role2) ? $user->role2 : NULL;
211 $addrole[2] = isset($user->role3) ? $user->role3 : NULL;
212 $addrole[3] = isset($user->role4) ? $user->role4 : NULL;
213 $addrole[4] = isset($user->role5) ? $user->role5 : NULL;
215 for ($i=0; $i<5; $i++) {
216 $course[$i]=NULL;
218 foreach ($courses as $eachcourse) {
219 for ($i=0; $i<5; $i++) {
220 if ($eachcourse->shortname == $addcourse[$i]) {
221 $course[$i] = $eachcourse;
226 // before insert/update, check whether we should be updating
227 // an old record instead
228 if ($allowrenames && !empty($user->oldusername) ) {
229 $user->oldusername = moodle_strtolower($user->oldusername);
230 if ($olduser = get_record('user', 'username', $user->oldusername, 'mnethostid', $user->mnethostid)) {
231 if (set_field('user', 'username', $user->username, 'username', $user->oldusername)) {
232 notify(get_string('userrenamed', 'admin') . " : $user->oldusername $user->username");
233 $renames++;
234 } else {
235 notify(get_string('usernotrenamedexists', 'error') . " : $user->oldusername $user->username");
236 $renameerrors++;
237 continue;
239 } else {
240 notify(get_string('usernotrenamedmissing', 'error') . " : $user->oldusername $user->username");
241 $renameerrors++;
242 continue;
246 if ($olduser = get_record("user", "username", $username, "mnethostid", $user->mnethostid)) {
247 if ($updateaccounts) {
248 // Record is being updated
249 $user->id = $olduser->id;
250 if (update_record('user', $user)) {
251 notify("$user->id , $user->username ".get_string('useraccountupdated', 'admin'));
252 $usersupdated++;
253 } else {
254 notify(get_string('usernotupdatederror', 'error', $username));
255 $userserrors++;
256 continue;
258 } else {
259 //Record not added - user is already registered
260 //In this case, output userid from previous registration
261 //This can be used to obtain a list of userids for existing users
262 notify("$olduser->id ".get_string('usernotaddedregistered', 'error', $username));
263 $userserrors++;
266 } else { // new user
267 if ($user->id = insert_record("user", $user)) {
268 notify("$struser: $user->id = $user->username");
269 $usersnew++;
270 if (empty($user->password) && $createpassword) {
271 // passwords will be created and sent out on cron
272 insert_record('user_preferences', array( 'userid' => $user->id,
273 'name' => 'create_password',
274 'value' => 1));
275 insert_record('user_preferences', array( 'userid' => $user->id,
276 'name' => 'auth_forcepasswordchange',
277 'value' => 1));
279 } else {
280 // Record not added -- possibly some other error
281 notify(get_string('usernotaddederror', 'error', $username));
282 $userserrors++;
283 continue;
286 for ($i=0; $i<5; $i++) {
287 if ($addcourse[$i] && !$course[$i]) {
288 notify(get_string('unknowncourse', 'error', $addcourse[$i]));
291 for ($i=0; $i<5; $i++) {
292 $groupid[$i] = 0;
293 if ($addgroup[$i]) {
294 if (!$course[$i]) {
295 notify(get_string('coursegroupunknown','error',$addgroup[$i]));
296 } else {
297 if ($gid = groups_get_group_by_name($course[$i]->id, $addgroup[$i])) {
298 $groupid[$i] = $gid;
299 } else {
300 notify(get_string('groupunknown','error',$addgroup[$i]));
305 for ($i=0; $i<5; $i++) { /// Enrol into courses if necessary
306 if ($course[$i]) {
307 if (isset($addrole[$i])) {
308 $coursecontext = get_context_instance(CONTEXT_COURSE, $course[$i]->id);
309 if (!user_can_assign($coursecontext, $addrole[$i])) {
310 notify('--> Can not assign role in course'); //TODO: localize
312 $ret = role_assign($addrole[$i], $user->id, 0, $coursecontext->id);
313 } else if (isset($addtype[$i])) {
314 switch ($addtype[$i]) {
315 case 2: // teacher
316 $ret = add_teacher($user->id, $course[$i]->id, 1);
317 break;
319 case 3: // non-editing teacher
320 $ret = add_teacher($user->id, $course[$i]->id, 0);
321 break;
323 default: // student
324 $ret = enrol_student($user->id, $course[$i]->id);
325 break;
327 } else {
328 $ret = enrol_student($user->id, $course[$i]->id);
330 if ($ret) { // OK
331 notify('-->'. get_string('enrolledincourse', '', $addcourse[$i]));
332 } else {
333 notify('-->'.get_string('enrolledincoursenot', '', $addcourse[$i]));
337 for ($i=0; $i<5; $i++) { // Add user to groups if necessary
338 if ($course[$i] && $groupid[$i]) {
339 $coursecontext = get_context_instance(CONTEXT_COURSE, $course[$i]->id);
340 if (count(get_user_roles($coursecontext, $user->id))) {
341 if (add_user_to_group($groupid[$i], $user->id)) {
342 notify('-->' . get_string('addedtogroup','',$addgroup[$i]));
343 } else {
344 notify('-->' . get_string('addedtogroupnot','',$addgroup[$i]));
346 } else {
347 notify('-->' . get_string('addedtogroupnotenrolled','',$addgroup[$i]));
352 unset ($user);
355 fclose($fp);
356 notify("$strusersnew: $usersnew");
357 notify(get_string('usersupdated', 'admin') . ": $usersupdated");
358 notify(get_string('errors', 'admin') . ": $userserrors");
359 if ($allowrenames) {
360 notify(get_string('usersrenamed', 'admin') . ": $renames");
361 notify(get_string('renameerrors', 'admin') . ": $renameerrors");
363 echo '<hr />';
366 /// Print the form
367 print_heading_with_help(get_string('uploadusers'), 'uploadusers');
369 $mform->display();
371 admin_externalpage_print_footer();
375 function my_file_get_contents($filename, $use_include_path = 0) {
376 /// Returns the file as one big long string
378 $data = "";
379 $file = @fopen($filename, "rb", $use_include_path);
380 if ($file) {
381 while (!feof($file)) {
382 $data .= fread($file, 1024);
384 fclose($file);
386 return $data;