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