fixes delete description record
[moodle.git] / admin / uploaduser.php
CommitLineData
df7ecfe4 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');
0a5dffcc 8require_once('uploaduser_form.php');
1ae083e4 9
df7ecfe4 10$uplid = optional_param('uplid', '', PARAM_FILE);
11$previewrows = optional_param('previewrows', 10, PARAM_INT);
12$separator = optional_param('separator', 'comma', PARAM_ALPHA);
13
14if (!defined('UP_LINE_MAX_SIZE')) {
15 define('UP_LINE_MAX_SIZE', 4096);
16}
066bfbfe 17
df7ecfe4 18@set_time_limit(3600); // 1 hour should be enough
19@raise_memory_limit('256M');
20if (function_exists('apache_child_terminate')) {
21 // if we are running from Apache, give httpd a hint that
22 // it can recycle the process after it's done. Apache's
23 // memory management is truly awful but we can help it.
24 @apache_child_terminate();
25}
0a6150ca 26
066bfbfe 27admin_externalpage_setup('uploadusers');
1ae083e4 28require_capability('moodle/site:uploadusers', get_context_instance(CONTEXT_SYSTEM));
0a6150ca 29
1c0ccfd6 30$textlib = textlib_get_instance();
ca23a9c9 31
066bfbfe 32$struserrenamed = get_string('userrenamed', 'admin');
33$strusernotrenamedexists = get_string('usernotrenamedexists', 'error');
34$strusernotrenamedmissing = get_string('usernotrenamedmissing', 'error');
6b09974b 35
066bfbfe 36$struserupdated = get_string('useraccountupdated', 'admin');
37$strusernotupdated = get_string('usernotupdatederror', 'error');
6b09974b 38
066bfbfe 39$struseradded = get_string('newuser');
a7db355a 40$strusernotadded = get_string('usernotaddedregistered', 'error');
066bfbfe 41$strusernotaddederror = get_string('usernotaddederror', 'error');
a7db355a 42
43$struserdeleted = get_string('userdeleted', 'admin');
44$strusernotdeletederror = get_string('usernotdeletederror', 'error');
45$strusernotdeletedmissing = get_string('usernotdeletedmissing', 'error');
46
066bfbfe 47$strcannotassignrole = get_string('cannotassignrole', 'error');
48$strduplicateusername = get_string('duplicateusername', 'error');
49$strindent = '-->';
a5702569 50
df7ecfe4 51$return = $CFG->wwwroot.'/'.$CFG->admin.'/uploaduser.php';
a5702569 52
df7ecfe4 53// make arrays of valid fields for error checking
54// the value associated to each field is: 0 = optional field, 1 = field required either in default values or in data file
55$fields = array(
56 'firstname' => 1,
57 'lastname' => 1,
58 'username' => 1,
59 'email' => 1,
60 'city' => 1,
61 'country' => 1,
62 'lang' => 1,
63 'auth' => 1,
64 'timezone' => 1,
65 'mailformat' => 1,
66 'maildisplay' => 1,
67 'htmleditor' => 0,
68 'ajax' => 0,
69 'autosubscribe' => 1,
70 'mnethostid' => 0,
71 'institution' => 0,
72 'department' => 0,
73 'idnumber' => 0,
74 'icq' => 0,
75 'phone1' => 0,
76 'phone2' => 0,
77 'address' => 0,
78 'url' => 0,
79 'description' => 0,
80 'icq' => 0,
81 'oldusername' => 0,
82 'emailstop' => 1,
83 'deleted' => 0,
84 'password' => 0, // changed later
85);
0a6150ca 86
df7ecfe4 87if (empty($uplid)) {
88 $mform = new admin_uploaduser_form1();
0a6150ca 89
df7ecfe4 90 if ($formdata = $mform->get_data()) {
91 if (!$filename = make_upload_directory('temp/uploaduser/'.$USER->id, true)) {
92 error('Can not create temporary upload directory!', $return);
93 }
94 // use current (non-conflicting) time stamp
95 $uplid = time();
96 while (file_exists($filename.'/'.$uplid)) {
97 $uplid--;
98 }
99 $filename = $filename.'/'.$uplid;
ed22a01b 100
df7ecfe4 101 $text = $mform->get_file_content('userfile');
102 // convert to utf-8 encoding
103 $text = $textlib->convert($text, $formdata->encoding, 'utf-8');
104 // remove Unicode BOM from first line
105 $text = $textlib->trim_utf8_bom($text);
106 // Fix mac/dos newlines
107 $text = preg_replace('!\r\n?!', "\n", $text);
108 //remove empty lines at the beginning and end
109 $text = trim($text);
ed22a01b 110
df7ecfe4 111 // verify each line has the same number of separators - this detects major breakage in files
112 $line = strtok($text, "\n");
113 if ($line === false) {
114 error('Empty file', $return); //TODO: localize
115 }
116
117 // test headers
118 $csv_delimiter = get_upload_csv_delimiter($separator);
119 $col_count = substr_count($line, $csv_delimiter);
120 if ($col_count < 2) {
121 error('Not enough columns, please verify the separator setting!', $return); //TODO: localize
066bfbfe 122 }
df7ecfe4 123
ed22a01b 124 $line = explode($csv_delimiter, $line);
ed22a01b 125 foreach ($line as $key => $value) {
126 $value = trim($value); // remove whitespace
df7ecfe4 127 if (!array_key_exists($value, $fields) && // if not a standard field and not an enrolment field, then we have an error
ed22a01b 128 !preg_match('/^course\d+$/', $value) && !preg_match('/^group\d+$/', $value) &&
129 !preg_match('/^type\d+$/', $value) && !preg_match('/^role\d+$/', $value)) {
df7ecfe4 130 error(get_string('invalidfieldname', 'error', $value), $return);
131 }
132 }
133
134 $line = strtok("\n");
135 if ($line === false) {
136 error('Only one row present, can not continue!', $return); //TODO: localize
137 }
138
139 while ($line !== false) {
140 if (substr_count($line, $csv_delimiter) !== $col_count) {
141 error('Incorrect file format - number of columns is not constant!', $return); //TODO: localize
ed22a01b 142 }
df7ecfe4 143 $line = strtok("\n");
ed22a01b 144 }
df7ecfe4 145
146 // store file
147 $fp = fopen($filename, "w");
148 fwrite($fp,$text);
149 fclose($fp);
150 // continue to second form
151
152 } else {
153 admin_externalpage_print_header();
154 print_heading_with_help(get_string('uploadusers'), 'uploadusers2');
155 $mform->display();
156 admin_externalpage_print_footer();
157 die;
158 }
159}
160
161$mform = new admin_uploaduser_form2();
162// set initial date from form1
163$mform->set_data(array('separator'=>$separator, 'uplid'=>$uplid, 'previewrows'=>$previewrows));
164
165// If a file has been uploaded, then process it
166if ($formdata = $mform->is_cancelled()) {
167 user_upload_cleanup($uplid);
168 redirect($return);
169
170} else if ($formdata = $mform->get_data()) {
171 // Print the header
172 admin_externalpage_print_header();
173 print_heading(get_string('uploadusers'));
174
175 $createpassword = $formdata->createpassword;
176 $updateaccounts = $formdata->updateaccounts;
177 $allowrenames = $formdata->allowrenames;
178 $skipduplicates = $formdata->duplicatehandling;
179
180 $fields['password'] = !$createpassword;
181
182 $filename = $CFG->dataroot.'/temp/uploaduser/'.$USER->id.'/'.$uplid;
183 if (!file_exists($filename)) {
184 user_upload_cleanup($uplid);
185 error('Error reading temporary file!', $return); //TODO: localize
186 }
187 if (!$fp = fopen($filename, "r")) {
188 user_upload_cleanup($uplid);
189 error('Error reading temporary file!', $return); //TODO: localize
190 }
191
192 $csv_delimiter = get_upload_csv_delimiter($separator);
193 $csv_encode = get_upload_csv_encode($csv_delimiter);
194
195 // find header row
196 $headers = array();
197 $linenum = 1;
198 $line = explode($csv_delimiter, fgets($fp, UP_LINE_MAX_SIZE));
199
200 // prepare headers
201 foreach ($line as $key => $value) {
202 $headers[$key] = trim($value);
6b09974b 203 }
a2ce7344 204
a7db355a 205 // check that required fields are present or a default value for them exists
206 $headersOk = true;
207 // disable the check if we also have deleting information (ie. deleted column)
208 if (!in_array('deleted', $headers)) {
209 foreach ($fields as $key => $required) {
ed22a01b 210 if($required && !in_array($key, $headers) && (!isset($formdata->$key) || $formdata->$key==='')) {
a7db355a 211 notify(get_string('missingfield', 'error', $key));
212 $headersOk = false;
213 }
214 }
066bfbfe 215 }
ed22a01b 216 if ($headersOk) {
a7db355a 217 $usersnew = 0;
218 $usersupdated = 0;
219 $userserrors = 0;
220 $usersdeleted = 0;
221 $renames = 0;
222 $renameerrors = 0;
223 $deleteerrors = 0;
224 $newusernames = array();
225 // We'll need courses a lot, so fetch it early and keep it in memory, indexed by their shortname
226 $tmp =& get_courses('all','','id,shortname,visible');
227 $courses = array();
228 foreach ($tmp as $c) {
229 $courses[$c->shortname] = $c;
230 }
231 unset($tmp);
066bfbfe 232
a7db355a 233 echo '<p id="results">';
df7ecfe4 234 while (!feof($fp)) {
ed22a01b 235 $linenum++;
df7ecfe4 236 $line = explode($csv_delimiter, fgets($fp, UP_LINE_MAX_SIZE));
a7db355a 237 $errors = '';
238 $user = new object();
239 // by default, use the local mnet id (this may be changed in the file)
240 $user->mnethostid = $CFG->mnet_localhost_id;
a7db355a 241 // add fields to user object
242 foreach ($line as $key => $value) {
243 if($value !== '') {
244 $key = $headers[$key];
245 //decode encoded commas
246 $value = str_replace($csv_encode,$csv_delimiter,trim($value));
247 // special fields: password and username
248 if ($key == 'password' && !empty($value)) {
249 $user->$key = hash_internal_user_password($value);
250 } else if($key == 'username') {
251 $value = $textlib->strtolower(addslashes($value));
252 if(empty($CFG->extendedusernamechars)) {
253 $value = eregi_replace('[^(-\.[:alnum:])]', '', $value);
254 }
255 @$newusernames[$value]++;
256 $user->$key = $value;
257 } else {
258 $user->$key = addslashes($value);
259 }
6b09974b 260 }
16a1fed4 261 }
ed22a01b 262
a7db355a 263 // add default values for remaining fields
264 foreach ($fields as $key => $required) {
265 if(isset($user->$key)) {
266 continue;
0063abee 267 }
a7db355a 268 if(!isset($formdata->$key) || $formdata->$key==='') { // no default value was submited
269 // if the field is required, give an error only if we are adding the user or deleting a user with unkown username
ed22a01b 270 if($required && (empty($user->deleted) || $key == 'username')) {
a7db355a 271 $errors .= get_string('missingfield', 'error', $key) . ' ';
6b09974b 272 }
a7db355a 273 continue;
274 }
275 // process templates
276 $template = $formdata->$key;
277 $templatelen = strlen($template);
278 $value = '';
279 for ($i = 0 ; $i < $templatelen; ++$i) {
280 if($template[$i] == '%') {
281 $case = 0; // 1=lowercase, 2=uppercase
282 $len = 0; // number of characters to keep
283 $info = null; // data to process
284 for($j = $i + 1; is_null($info) && $j < $templatelen; ++$j) {
285 $car = $template[$j];
286 if ($car >= '0' && $car <= '9') {
287 $len = $len * 10 + (int)$car;
288 } else if($car == '-') {
289 $case = 1;
ed22a01b 290 } else if($car == '+') {
a7db355a 291 $case = 2;
292 } else if($car == 'f') { // first name
293 $info = @$user->firstname;
294 } else if($car == 'l') { // last name
295 $info = @$user->lastname;
296 } else if($car == 'u') { // username
297 $info = @$user->username;
298 } else if($car == '%' && $j == $i+1) {
299 $info = '%';
300 } else { // invalid character
301 $info = '';
302 }
303 }
304 if($info==='' || is_null($info)) { // invalid template
305 continue;
306 }
307 $i = $j - 1;
308 // change case
ed22a01b 309 if($case == 1) {
a7db355a 310 $info = $textlib->strtolower($info);
311 } else if($case == 2) {
312 $info = $textlib->strtoupper($info);
313 }
314 if($len) { // truncate data
315 $info = $textlib->substr($info, 0, $len);
316 }
317 $value .= $info;
318 } else {
319 $value .= $template[$i];
6b09974b 320 }
a7db355a 321 }
ed22a01b 322
a7db355a 323 if($key == 'username') {
324 $value = $textlib->strtolower($value);
325 if(empty($CFG->extendedusernamechars)) {
326 $value = eregi_replace('[^(-\.[:alnum:])]', '', $value);
6740dd64 327 }
a7db355a 328 @$newusernames[$value]++;
329 // check for new username duplicates
330 if($newusernames[$value] > 1) {
331 if($skipduplicates) {
332 $errors .= $strduplicateusername . ' (' . stripslashes($value) . '). ';
333 continue;
334 } else {
335 $value .= $newusernames[$value];
336 }
066bfbfe 337 }
066bfbfe 338 }
a7db355a 339 $user->$key = $value;
066bfbfe 340 }
a7db355a 341 if($errors) {
342 notify(get_string('erroronline', 'error', $linenum). ': ' . $errors);
343 ++$userserrors;
344 continue;
345 }
346
ed22a01b 347 // delete user
a7db355a 348 if(@$user->deleted) {
349 $info = ': ' . stripslashes($user->username) . '. ';
350 if($user =& get_record('user', 'username', $user->username, 'mnethostid', $user->mnethostid)) {
351 $user->timemodified = time();
352 $user->username = addslashes($user->email . $user->timemodified); // Remember it just in case
353 $user->deleted = 1;
354 $user->email = ''; // Clear this field to free it up
355 $user->idnumber = ''; // Clear this field to free it up
356 if (update_record('user', $user)) {
357 // not sure if this is needed. unenrol_student($user->id); // From all courses
358 delete_records('role_assignments', 'userid', $user->id); // unassign all roles
359 // remove all context assigned on this user?
360 echo $struserdeleted . $info . '<br />';
361 ++$usersdeleted;
066bfbfe 362 } else {
a7db355a 363 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotdeletederror . $info);
364 ++$deleteerrors;
a2ce7344 365 }
a7db355a 366 } else {
367 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotdeletedmissing . $info);
368 ++$deleteerrors;
ed22a01b 369 }
a7db355a 370 continue;
066bfbfe 371 }
ed22a01b 372
a7db355a 373 // save the user to the database
374 $user->confirmed = 1;
375 $user->timemodified = time();
066bfbfe 376
a7db355a 377 // before insert/update, check whether we should be updating an old record instead
378 if ($allowrenames && !empty($user->oldusername) ) {
379 $user->oldusername = $textlib->strtolower($user->oldusername);
380 $info = ': ' . stripslashes($user->oldusername) . '-->' . stripslashes($user->username) . '. ';
381 if ($olduser =& get_record('user', 'username', $user->oldusername, 'mnethostid', $user->mnethostid)) {
382 if (set_field('user', 'username', $user->username, 'id', $olduser->id)) {
383 echo $struserrenamed . $info;
384 $renames++;
385 } else {
386 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotrenamedexists . $info);
387 $renameerrors++;
388 continue;
389 }
066bfbfe 390 } else {
a7db355a 391 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotrenamedmissing . $info);
066bfbfe 392 $renameerrors++;
393 continue;
394 }
066bfbfe 395 }
a2ce7344 396
a7db355a 397 // save the information
398 if ($olduser =& get_record('user', 'username', $user->username, 'mnethostid', $user->mnethostid)) {
399 $user->id = $olduser->id;
400 $info = ': ' . stripslashes($user->username) .' (ID = ' . $user->id . ')';
401 if ($updateaccounts) {
402 // Record is being updated
403 if (update_record('user', $user)) {
404 echo $struserupdated . $info . '<br />';
405 $usersupdated++;
406 } else {
407 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotupdated . $info);
408 $userserrors++;
409 continue;
410 }
066bfbfe 411 } else {
a7db355a 412 //Record not added - user is already registered
413 //In this case, output userid from previous registration
414 //This can be used to obtain a list of userids for existing users
415 echo $strusernotadded . $info . '<br />';
066bfbfe 416 $userserrors++;
066bfbfe 417 }
a7db355a 418 } else { // new user
419 if ($user->id = insert_record('user', $user)) {
420 $info = ': ' . stripslashes($user->username) .' (ID = ' . $user->id . ')';
421 echo $struseradded . $info . '<br />';
422 $usersnew++;
423 if (empty($user->password) && $createpassword) {
424 // passwords will be created and sent out on cron
ed22a01b 425 set_user_preference('create_password', 1, $user->id);
426 set_user_preference('auth_forcepasswordchange', 1, $user->id);
a7db355a 427 }
428 } else {
429 // Record not added -- possibly some other error
430 notify(get_string('erroronline', 'error', $linenum). ': ' . $strusernotaddederror . ': ' . stripslashes($user->username));
431 $userserrors++;
432 continue;
066bfbfe 433 }
066bfbfe 434 }
6b09974b 435
a7db355a 436 // find course enrolments, groups and roles/types
437 for($ncourses = 1; $addcourse = @$user->{'course' . $ncourses}; ++$ncourses) {
438 // find course
439 if(!$course = @$courses[$addcourse]) {
440 notify(get_string('erroronline', 'error', $linenum). ': ' . get_string('unknowncourse', 'error', $addcourse));
441 continue;
066bfbfe 442 }
a7db355a 443 // find role
444 if ($addrole = @$user->{'role' . $ncourses}) {
445 $coursecontext =& get_context_instance(CONTEXT_COURSE, $course->id);
446 if (!$ok = role_assign($addrole, $user->id, 0, $coursecontext->id)) {
447 echo $strindent . $strcannotassignrole . '<br >';
448 }
449 } else {
450 // if no role, then find "old" enrolment type
451 switch ($addtype = @$user->{'type' . $ncourses}) {
452 case 2: // teacher
453 $ok = add_teacher($user->id, $course->id, 1);
454 break;
455 case 3: // non-editing teacher
456 $ok = add_teacher($user->id, $course->id, 0);
457 break;
458 case 1: // student
ed22a01b 459 default:
a7db355a 460 $ok = enrol_student($user->id, $course->id);
461 break;
462 }
463 }
464 if ($ok) { // OK
465 echo $strindent . get_string('enrolledincourse', '', $addcourse) . '<br />';
466 } else {
467 notify(get_string('erroronline', 'error', $linenum). ': ' . get_string('enrolledincoursenot', '', $addcourse));
066bfbfe 468 }
6b09974b 469
a7db355a 470 // find group to add to
471 if ($addgroup = @$user->{'group' . $ncourses}) {
472 if ($gid =& groups_get_group_by_name($course->id, $addgroup)) {
473 $coursecontext =& get_context_instance(CONTEXT_COURSE, $course->id);
474 if (count(get_user_roles($coursecontext, $user->id))) {
475 if (groups_add_member($gid, $user->id)) {
476 echo $strindent . get_string('addedtogroup','',$addgroup) . '<br />';
477 } else {
478 notify(get_string('erroronline', 'error', $linenum). ': ' . get_string('addedtogroupnot','',$addgroup));
479 }
066bfbfe 480 } else {
a7db355a 481 notify(get_string('erroronline', 'error', $linenum). ': ' . get_string('addedtogroupnotenrolled','',$addgroup));
a5702569 482 }
066bfbfe 483 } else {
a7db355a 484 notify(get_string('erroronline', 'error', $linenum). ': ' . get_string('groupunknown','error',$addgroup));
0063abee 485 }
6b09974b 486 }
a5702569 487 }
066bfbfe 488 }
a7db355a 489 echo '</p>';
490 notify(get_string('userscreated', 'admin') . ': ' . $usersnew);
491 notify(get_string('usersupdated', 'admin') . ': ' . $usersupdated);
492 notify(get_string('usersdeleted', 'admin') . ': ' . $usersdeleted);
493 notify(get_string('deleteerrors', 'admin') . ': ' . $deleteerrors);
494 if ($allowrenames) {
495 notify(get_string('usersrenamed', 'admin') . ': ' . $renames);
496 notify(get_string('renameerrors', 'admin') . ': ' . $renameerrors);
497 }
498 notify(get_string('errors', 'admin') . ': ' . $userserrors);
066bfbfe 499 }
df7ecfe4 500 fclose($fp);
501 user_upload_cleanup($uplid);
066bfbfe 502 echo '<hr />';
df7ecfe4 503 print_continue($return);
504 admin_externalpage_print_footer();
505 die;
6b09974b 506}
0a6150ca 507
df7ecfe4 508// Print the header
509admin_externalpage_print_header();
510
a5702569 511/// Print the form
d526725b 512print_heading_with_help(get_string('uploadusers'), 'uploadusers2');
df7ecfe4 513
514/// Print csv file preview
515$filename = $CFG->dataroot.'/temp/uploaduser/'.$USER->id.'/'.$uplid;
516if (!file_exists($filename)) {
517 error('Error reading temporary file!', $return); //TODO: localize
518}
519if (!$fp = fopen($filename, "r")) {
520 error('Error reading temporary file!', $return); //TODO: localize
521}
522
523$csv_delimiter = get_upload_csv_delimiter($separator);
524$csv_encode = get_upload_csv_encode($csv_delimiter);
525
526$header = explode($csv_delimiter, fgets($fp, UP_LINE_MAX_SIZE));
527
528$width = count($header);
529$columncount = 0;
530$rowcount = 0;
531echo '<table class="flexible boxaligncenter generaltable">';
532echo '<tr class="heading r'.$rowcount++.'">';
533foreach ($header as $h) {
534 echo '<th class="header c'.$columncount++.'">'.trim($h).'</th>';
535}
536echo '</tr>';
537
538while (!feof($fp) and $rowcount <= $previewrows+1) {
539 $columncount = 0;
540 $fields = explode($csv_delimiter, fgets($fp, UP_LINE_MAX_SIZE));
541 echo '<tr class="r'.$rowcount++.'">';
542 foreach ($fields as $field) {
543 echo '<td class=" c'.$columncount++.'">'.trim(str_replace($csv_encode, $csv_delimiter, $field)).'</td>';;
544 }
545 echo '</tr>';
546}
547if ($rowcount > $previewrows+1) {
548 echo '<tr class="r'.$rowcount++.'">';
549 foreach ($fields as $field) {
550 echo '<td class=" c'.$columncount++.'">...</td>';;
551 }
552}
553echo '</table>';
554fclose($fp);
555
0a5dffcc 556$mform->display();
1ae083e4 557admin_externalpage_print_footer();
df7ecfe4 558die;
559
560/////////////////////////
561/// Utility functions ///
562/////////////////////////
563
564function user_upload_cleanup($uplid) {
565 global $USER, $CFG;
566 if (empty($uplid)) {
567 return;
568 }
569 $filename = $CFG->dataroot.'/temp/uploaduser/'.$USER->id.'/'.$uplid;
570 if (file_exists($filename)) {
571 @unlink($filename);
572 }
573}
574
575function get_uf_headers($uplid, $separator) {
576 global $USER, $CFG;
577
578 $filename = $CFG->dataroot.'/temp/uploaduser/'.$USER->id.'/'.$uplid;
579 if (!file_exists($filename)) {
580 return false;
581 }
582 $fp = fopen($filename, "r");
583 $line = fgets($fp, 2048);
584 fclose($fp);
585 if ($line === false) {
586 return false;
587 }
588
589 $csv_delimiter = get_upload_csv_delimiter($separator);
590 $headers = explode($csv_delimiter, $line);
591 foreach($headers as $key=>$val) {
592 $headers[$key] = trim($val);
593 }
594 return $headers;
595}
596
597function get_upload_csv_delimiter($separator) {
598 global $CFG;
599
600 switch ($separator) {
601 case 'semicolon' : return ';';
602 case 'colon' : return ':';
603 case 'tab' : return "\t";
604 case 'cfg' : return isset($CFG->CSV_DELIMITER) ? $CFG->CSV_DELIMITER : ',';
605 default : return ',';
606 }
607}
608
609function get_upload_csv_encode($delimiter) {
610//Note: commas within a field should be encoded as &#44 (for comma separated csv files)
611//Note: semicolon within a field should be encoded as &#59 (for semicolon separated csv files)
612 global $CFG;
613 return '&#' . (isset($CFG->CSV_ENCODE) ? $CFG->CSV_ENCODE : ord($delimiter));
614}
0a6150ca 615?>