weekly release 2.5dev
[moodle.git] / admin / tool / uploaduser / index.php
CommitLineData
9e492db0 1<?php
8bdb31ed
PS
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
0a6150ca 16
8bdb31ed
PS
17/**
18 * Bulk user registration script from a comma separated file
19 *
ce15d56d
PS
20 * @package tool
21 * @subpackage uploaduser
8bdb31ed
PS
22 * @copyright 2004 onwards Martin Dougiamas (http://dougiamas.com)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
0a6150ca 25
ce15d56d 26require('../../../config.php');
cc891abe 27require_once($CFG->libdir.'/adminlib.php');
e4e38544 28require_once($CFG->libdir.'/csvlib.class.php');
29require_once($CFG->dirroot.'/user/profile/lib.php');
59186c92 30require_once($CFG->dirroot.'/group/lib.php');
92b59a56 31require_once($CFG->dirroot.'/cohort/lib.php');
ce15d56d
PS
32require_once('locallib.php');
33require_once('user_form.php');
1ae083e4 34
e4e38544 35$iid = optional_param('iid', '', PARAM_INT);
df7ecfe4 36$previewrows = optional_param('previewrows', 10, PARAM_INT);
066bfbfe 37
8bdb31ed
PS
38@set_time_limit(60*60); // 1 hour should be enough
39raise_memory_limit(MEMORY_HUGE);
0a6150ca 40
ebff4779 41require_login();
ce15d56d 42admin_externalpage_setup('tooluploaduser');
bf006d2c 43require_capability('moodle/site:uploadusers', context_system::instance());
0a6150ca 44
ce15d56d 45$struserrenamed = get_string('userrenamed', 'tool_uploaduser');
e4e38544 46$strusernotrenamedexists = get_string('usernotrenamedexists', 'error');
47$strusernotrenamedmissing = get_string('usernotrenamedmissing', 'error');
48$strusernotrenamedoff = get_string('usernotrenamedoff', 'error');
49$strusernotrenamedadmin = get_string('usernotrenamedadmin', 'error');
50
ce15d56d 51$struserupdated = get_string('useraccountupdated', 'tool_uploaduser');
e4e38544 52$strusernotupdated = get_string('usernotupdatederror', 'error');
53$strusernotupdatednotexists = get_string('usernotupdatednotexists', 'error');
54$strusernotupdatedadmin = get_string('usernotupdatedadmin', 'error');
55
ce15d56d 56$struseruptodate = get_string('useraccountuptodate', 'tool_uploaduser');
8bdb31ed 57
e4e38544 58$struseradded = get_string('newuser');
59$strusernotadded = get_string('usernotaddedregistered', 'error');
60$strusernotaddederror = get_string('usernotaddederror', 'error');
61
ce15d56d 62$struserdeleted = get_string('userdeleted', 'tool_uploaduser');
e4e38544 63$strusernotdeletederror = get_string('usernotdeletederror', 'error');
64$strusernotdeletedmissing = get_string('usernotdeletedmissing', 'error');
65$strusernotdeletedoff = get_string('usernotdeletedoff', 'error');
66$strusernotdeletedadmin = get_string('usernotdeletedadmin', 'error');
67
68$strcannotassignrole = get_string('cannotassignrole', 'error');
e4e38544 69
70$struserauthunsupported = get_string('userauthunsupported', 'error');
3fe2cfb5 71$stremailduplicate = get_string('useremailduplicate', 'error');
e4e38544 72
3f12c146 73$strinvalidpasswordpolicy = get_string('invalidpasswordpolicy', 'error');
e4e38544 74$errorstr = get_string('error');
ca23a9c9 75
08157bfe
PS
76$stryes = get_string('yes');
77$strno = get_string('no');
78$stryesnooptions = array(0=>$strno, 1=>$stryes);
79
ce15d56d 80$returnurl = new moodle_url('/admin/tool/uploaduser/index.php');
8bdb31ed 81$bulknurl = new moodle_url('/admin/user/user_bulk.php');
e4e38544 82
2a6dcb72
PS
83$today = time();
84$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
85
e4e38544 86// array of all valid fields for validation
6dbcacee 87$STD_FIELDS = array('id', 'firstname', 'lastname', 'username', 'email',
8bdb31ed 88 'city', 'country', 'lang', 'timezone', 'mailformat',
a80b5a0c 89 'maildisplay', 'maildigest', 'htmleditor', 'autosubscribe',
8bdb31ed 90 'institution', 'department', 'idnumber', 'skype',
6dbcacee 91 'msn', 'aim', 'yahoo', 'icq', 'phone1', 'phone2', 'address',
8bdb31ed
PS
92 'url', 'description', 'descriptionformat', 'password',
93 'auth', // watch out when changing auth type or using external auth plugins!
94 'oldusername', // use when renaming users - this is the original username
08157bfe 95 'suspended', // 1 means suspend user account, 0 means activate user account, nothing means keep as is for existing users
8bdb31ed 96 'deleted', // 1 means delete user
9dcae46d 97 'mnethostid', // Can not be used for adding, updating or deleting of users - only for enrolments, groups, cohorts and suspending.
8bdb31ed 98 );
e4e38544 99
100$PRF_FIELDS = array();
101
1d8bf5f0 102if ($prof_fields = $DB->get_records('user_info_field')) {
e4e38544 103 foreach ($prof_fields as $prof_field) {
104 $PRF_FIELDS[] = 'profile_field_'.$prof_field->shortname;
105 }
e4e38544 106}
8bdb31ed 107unset($prof_fields);
e4e38544 108
109if (empty($iid)) {
8bdb31ed 110 $mform1 = new admin_uploaduser_form1();
0a6150ca 111
8bdb31ed 112 if ($formdata = $mform1->get_data()) {
e4e38544 113 $iid = csv_import_reader::get_new_iid('uploaduser');
114 $cir = new csv_import_reader($iid, 'uploaduser');
df7ecfe4 115
8bdb31ed
PS
116 $content = $mform1->get_file_content('userfile');
117
118 $readcount = $cir->load_csv_content($content, $formdata->encoding, $formdata->delimiter_name);
e4e38544 119 unset($content);
df7ecfe4 120
e4e38544 121 if ($readcount === false) {
bd8ee7c1 122 print_error('csvloaderror', '', $returnurl);
e4e38544 123 } else if ($readcount == 0) {
5a2a5331 124 print_error('csvemptyfile', 'error', $returnurl);
ed22a01b 125 }
8bdb31ed
PS
126 // test if columns ok
127 $filecolumns = uu_validate_user_upload_columns($cir, $STD_FIELDS, $PRF_FIELDS, $returnurl);
e4e38544 128 // continue to form2
df7ecfe4 129
130 } else {
61ef8f9f 131 echo $OUTPUT->header();
9e492db0 132
ce15d56d 133 echo $OUTPUT->heading_with_help(get_string('uploadusers', 'tool_uploaduser'), 'uploadusers', 'tool_uploaduser');
9e492db0 134
8bdb31ed 135 $mform1->display();
73d6f52f 136 echo $OUTPUT->footer();
df7ecfe4 137 die;
138 }
e4e38544 139} else {
140 $cir = new csv_import_reader($iid, 'uploaduser');
8bdb31ed 141 $filecolumns = uu_validate_user_upload_columns($cir, $STD_FIELDS, $PRF_FIELDS, $returnurl);
df7ecfe4 142}
143
8bdb31ed 144$mform2 = new admin_uploaduser_form2(null, array('columns'=>$filecolumns, 'data'=>array('iid'=>$iid, 'previewrows'=>$previewrows)));
df7ecfe4 145
146// If a file has been uploaded, then process it
8bdb31ed 147if ($formdata = $mform2->is_cancelled()) {
e4e38544 148 $cir->cleanup(true);
149 redirect($returnurl);
df7ecfe4 150
8bdb31ed 151} else if ($formdata = $mform2->get_data()) {
df7ecfe4 152 // Print the header
61ef8f9f 153 echo $OUTPUT->header();
ce15d56d 154 echo $OUTPUT->heading(get_string('uploadusersresult', 'tool_uploaduser'));
e4e38544 155
156 $optype = $formdata->uutype;
157
0c4807ab 158 $updatetype = isset($formdata->uuupdatetype) ? $formdata->uuupdatetype : 0;
8bdb31ed
PS
159 $createpasswords = (!empty($formdata->uupasswordnew) and $optype != UU_USER_UPDATE);
160 $updatepasswords = (!empty($formdata->uupasswordold) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC and ($updatetype == UU_UPDATE_FILEOVERRIDE or $updatetype == UU_UPDATE_ALLOVERRIDE));
161 $allowrenames = (!empty($formdata->uuallowrenames) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC);
162 $allowdeletes = (!empty($formdata->uuallowdeletes) and $optype != UU_USER_ADDNEW and $optype != UU_USER_ADDINC);
08157bfe 163 $allowsuspends = (!empty($formdata->uuallowsuspends));
0c4807ab 164 $bulk = $formdata->uubulk;
165 $noemailduplicates = $formdata->uunoemailduplicates;
8bdb31ed
PS
166 $standardusernames = $formdata->uustandardusernames;
167 $resetpasswords = isset($formdata->uuforcepasswordchange) ? $formdata->uuforcepasswordchange : UU_PWRESET_NONE;
e4e38544 168
169 // verification moved to two places: after upload and into form2
8bdb31ed
PS
170 $usersnew = 0;
171 $usersupdated = 0;
172 $usersuptodate = 0; //not printed yet anywhere
173 $userserrors = 0;
174 $deletes = 0;
175 $deleteerrors = 0;
176 $renames = 0;
177 $renameerrors = 0;
178 $usersskipped = 0;
d6bb2d2f 179 $weakpasswords = 0;
feecd4d6 180
e4e38544 181 // caches
8bdb31ed 182 $ccache = array(); // course cache - do not fetch all courses here, we will not probably use them all anyway!
92b59a56 183 $cohorts = array();
8bdb31ed
PS
184 $rolecache = uu_allowed_roles_cache(); // roles lookup cache
185 $manualcache = array(); // cache of used manual enrol plugins in each course
186 $supportedauths = uu_supported_auths(); // officially supported plugins that are enabled
e4e38544 187
df997f84
PS
188 // we use only manual enrol plugin here, if it is disabled no enrol is done
189 if (enrol_is_enabled('manual')) {
190 $manual = enrol_get_plugin('manual');
191 } else {
192 $manual = NULL;
e4e38544 193 }
df7ecfe4 194
b4bd91ce 195 // clear bulk selection
e4e38544 196 if ($bulk) {
cd1edf9e 197 $SESSION->bulk_users = array();
e4e38544 198 }
df7ecfe4 199
e4e38544 200 // init csv import helper
201 $cir->init();
202 $linenum = 1; //column header is first line
df7ecfe4 203
e4e38544 204 // init upload progress tracker
205 $upt = new uu_progress_tracker();
8bdb31ed 206 $upt->start(); // start table
a2ce7344 207
e4e38544 208 while ($line = $cir->next()) {
209 $upt->flush();
210 $linenum++;
211
212 $upt->track('line', $linenum);
213
a226a972 214 $user = new stdClass();
8bdb31ed 215
e4e38544 216 // add fields to user object
8bdb31ed
PS
217 foreach ($line as $keynum => $value) {
218 if (!isset($filecolumns[$keynum])) {
219 // this should not happen
220 continue;
221 }
222 $key = $filecolumns[$keynum];
223 if (strpos($key, 'profile_field_') === 0) {
224 //NOTE: bloody mega hack alert!!
225 if (isset($USER->$key) and is_array($USER->$key)) {
226 // this must be some hacky field that is abusing arrays to store content and format
227 $user->$key = array();
228 $user->$key['text'] = $value;
229 $user->$key['format'] = FORMAT_MOODLE;
230 } else {
231 $user->$key = $value;
e4e38544 232 }
c3231d1d 233 } else {
8bdb31ed 234 $user->$key = $value;
a7db355a 235 }
e4e38544 236
8bdb31ed
PS
237 if (in_array($key, $upt->columns)) {
238 // default value in progress tracking table, can be changed later
239 $upt->track($key, s($value), 'normal');
e4e38544 240 }
8bdb31ed
PS
241 }
242 if (!isset($user->username)) {
ce8df92d 243 // prevent warnings below
8bdb31ed
PS
244 $user->username = '';
245 }
e4e38544 246
8bdb31ed
PS
247 if ($optype == UU_USER_ADDNEW or $optype == UU_USER_ADDINC) {
248 // user creation is a special case - the username may be constructed from templates using firstname and lastname
249 // better never try this in mixed update types
e4e38544 250 $error = false;
e4e38544 251 if (!isset($user->firstname) or $user->firstname === '') {
252 $upt->track('status', get_string('missingfield', 'error', 'firstname'), 'error');
253 $upt->track('firstname', $errorstr, 'error');
254 $error = true;
255 }
256 if (!isset($user->lastname) or $user->lastname === '') {
257 $upt->track('status', get_string('missingfield', 'error', 'lastname'), 'error');
258 $upt->track('lastname', $errorstr, 'error');
259 $error = true;
260 }
261 if ($error) {
262 $userserrors++;
263 continue;
264 }
265 // we require username too - we might use template for it though
8bdb31ed
PS
266 if (empty($user->username) and !empty($formdata->username)) {
267 $user->username = uu_process_template($formdata->username, $user);
268 $upt->track('username', s($user->username));
e4e38544 269 }
a7db355a 270 }
e4e38544 271
272 // normalize username
8bdb31ed
PS
273 $originalusername = $user->username;
274 if ($standardusernames) {
275 $user->username = clean_param($user->username, PARAM_USERNAME);
276 }
07ed083e 277
8bdb31ed 278 // make sure we really have username
e4e38544 279 if (empty($user->username)) {
280 $upt->track('status', get_string('missingfield', 'error', 'username'), 'error');
281 $upt->track('username', $errorstr, 'error');
282 $userserrors++;
283 continue;
8bdb31ed
PS
284 } else if ($user->username === 'guest') {
285 $upt->track('status', get_string('guestnoeditprofileother', 'error'), 'error');
286 $userserrors++;
287 continue;
e4e38544 288 }
9dcae46d 289
7bf99ee5
AA
290 if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
291 $upt->track('status', get_string('invalidusername', 'error', 'username'), 'error');
292 $upt->track('username', $errorstr, 'error');
293 $userserrors++;
294 }
397ccf13 295
9dcae46d
PS
296 if (empty($user->mnethostid)) {
297 $user->mnethostid = $CFG->mnet_localhost_id;
298 }
299
300 if ($existinguser = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
e4e38544 301 $upt->track('id', $existinguser->id, 'normal', false);
302 }
303
9dcae46d
PS
304 if ($user->mnethostid == $CFG->mnet_localhost_id) {
305 $remoteuser = false;
306
307 // Find out if username incrementing required.
308 if ($existinguser and $optype == UU_USER_ADDINC) {
309 $user->username = uu_increment_username($user->username);
310 $existinguser = false;
311 }
312
313 } else {
314 if (!$existinguser or $optype == UU_USER_ADDINC) {
315 $upt->track('status', get_string('errormnetadd', 'tool_uploaduser'), 'error');
316 $userserrors++;
317 continue;
318 }
319
320 $remoteuser = true;
321
322 // Make sure there are no changes of existing fields except the suspended status.
323 foreach ((array)$existinguser as $k => $v) {
324 if ($k === 'suspended') {
325 continue;
326 }
327 if (property_exists($user, $k)) {
328 $user->$k = $v;
329 }
330 if (in_array($k, $upt->columns)) {
331 if ($k === 'password' or $k === 'oldusername' or $k === 'deleted') {
332 $upt->track($k, '', 'normal', false);
333 } else {
334 $upt->track($k, s($v), 'normal', false);
335 }
336 }
337 }
338 unset($user->oldusername);
339 unset($user->password);
340 $user->auth = $existinguser->auth;
e4e38544 341 }
342
8bdb31ed
PS
343 // notify about nay username changes
344 if ($originalusername !== $user->username) {
345 $upt->track('username', '', 'normal', false); // clear previous
346 $upt->track('username', s($originalusername).'-->'.s($user->username), 'info');
347 } else {
348 $upt->track('username', s($user->username), 'normal', false);
349 }
350
e4e38544 351 // add default values for remaining fields
8bdb31ed 352 $formdefaults = array();
e4e38544 353 foreach ($STD_FIELDS as $field) {
354 if (isset($user->$field)) {
355 continue;
356 }
357 // all validation moved to form2
358 if (isset($formdata->$field)) {
359 // process templates
8bdb31ed
PS
360 $user->$field = uu_process_template($formdata->$field, $user);
361 $formdefaults[$field] = true;
43070e61
PS
362 if (in_array($field, $upt->columns)) {
363 $upt->track($field, s($user->$field), 'normal');
364 }
e4e38544 365 }
366 }
367 foreach ($PRF_FIELDS as $field) {
368 if (isset($user->$field)) {
369 continue;
370 }
371 if (isset($formdata->$field)) {
372 // process templates
8bdb31ed
PS
373 $user->$field = uu_process_template($formdata->$field, $user);
374 $formdefaults[$field] = true;
e4e38544 375 }
376 }
377
378 // delete user
379 if (!empty($user->deleted)) {
9dcae46d 380 if (!$allowdeletes or $remoteuser) {
e4e38544 381 $usersskipped++;
382 $upt->track('status', $strusernotdeletedoff, 'warning');
383 continue;
384 }
385 if ($existinguser) {
4f0c2d00 386 if (is_siteadmin($existinguser->id)) {
e4e38544 387 $upt->track('status', $strusernotdeletedadmin, 'error');
388 $deleteerrors++;
389 continue;
390 }
391 if (delete_user($existinguser)) {
392 $upt->track('status', $struserdeleted);
393 $deletes++;
394 } else {
395 $upt->track('status', $strusernotdeletederror, 'error');
396 $deleteerrors++;
6b09974b 397 }
e4e38544 398 } else {
399 $upt->track('status', $strusernotdeletedmissing, 'error');
400 $deleteerrors++;
401 }
402 continue;
403 }
404 // we do not need the deleted flag anymore
405 unset($user->deleted);
406
407 // renaming requested?
408 if (!empty($user->oldusername) ) {
e4e38544 409 if (!$allowrenames) {
410 $usersskipped++;
411 $upt->track('status', $strusernotrenamedoff, 'warning');
412 continue;
413 }
414
415 if ($existinguser) {
416 $upt->track('status', $strusernotrenamedexists, 'error');
417 $renameerrors++;
418 continue;
16a1fed4 419 }
ed22a01b 420
8bdb31ed
PS
421 if ($user->username === 'guest') {
422 $upt->track('status', get_string('guestnoeditprofileother', 'error'), 'error');
423 $renameerrors++;
424 continue;
425 }
426
427 if ($standardusernames) {
428 $oldusername = clean_param($user->oldusername, PARAM_USERNAME);
429 } else {
430 $oldusername = $user->oldusername;
431 }
432
433 // no guessing when looking for old username, it must be exact match
434 if ($olduser = $DB->get_record('user', array('username'=>$oldusername, 'mnethostid'=>$CFG->mnet_localhost_id))) {
e4e38544 435 $upt->track('id', $olduser->id, 'normal', false);
4f0c2d00 436 if (is_siteadmin($olduser->id)) {
e4e38544 437 $upt->track('status', $strusernotrenamedadmin, 'error');
438 $renameerrors++;
a7db355a 439 continue;
0063abee 440 }
df997f84
PS
441 $DB->set_field('user', 'username', $user->username, array('id'=>$olduser->id));
442 $upt->track('username', '', 'normal', false); // clear previous
8bdb31ed 443 $upt->track('username', s($oldusername).'-->'.s($user->username), 'info');
df997f84
PS
444 $upt->track('status', $struserrenamed);
445 $renames++;
e4e38544 446 } else {
447 $upt->track('status', $strusernotrenamedmissing, 'error');
448 $renameerrors++;
449 continue;
450 }
451 $existinguser = $olduser;
452 $existinguser->username = $user->username;
453 }
454
455 // can we process with update or insert?
456 $skip = false;
457 switch ($optype) {
8bdb31ed 458 case UU_USER_ADDNEW:
e4e38544 459 if ($existinguser) {
460 $usersskipped++;
461 $upt->track('status', $strusernotadded, 'warning');
3fe2cfb5 462 $skip = true;
e4e38544 463 }
464 break;
465
8bdb31ed 466 case UU_USER_ADDINC:
e4e38544 467 if ($existinguser) {
468 //this should not happen!
469 $upt->track('status', $strusernotaddederror, 'error');
470 $userserrors++;
8bdb31ed 471 $skip = true;
e4e38544 472 }
473 break;
474
8bdb31ed 475 case UU_USER_ADD_UPDATE:
e4e38544 476 break;
477
8bdb31ed 478 case UU_USER_UPDATE:
e4e38544 479 if (!$existinguser) {
480 $usersskipped++;
481 $upt->track('status', $strusernotupdatednotexists, 'warning');
482 $skip = true;
483 }
484 break;
8bdb31ed
PS
485
486 default:
487 // unknown type
488 $skip = true;
e4e38544 489 }
490
491 if ($skip) {
492 continue;
493 }
494
495 if ($existinguser) {
496 $user->id = $existinguser->id;
497
8bdb31ed 498 $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$existinguser->id)), s($existinguser->username)), 'normal', false);
08157bfe 499 $upt->track('suspended', $stryesnooptions[$existinguser->suspended] , 'normal', false);
8bdb31ed 500
4f0c2d00 501 if (is_siteadmin($user->id)) {
e4e38544 502 $upt->track('status', $strusernotupdatedadmin, 'error');
503 $userserrors++;
504 continue;
505 }
506
8bdb31ed
PS
507 $existinguser->timemodified = time();
508 // do NOT mess with timecreated or firstaccess here!
509
510 //load existing profile data
511 profile_load_data($existinguser);
3fe2cfb5 512
8bdb31ed 513 $upt->track('auth', $existinguser->auth, 'normal', false);
e4e38544 514
8bdb31ed 515 $doupdate = false;
08157bfe 516 $dologout = false;
8bdb31ed 517
9dcae46d 518 if ($updatetype != UU_UPDATE_NOCHANGES and !$remoteuser) {
8bdb31ed
PS
519 if (!empty($user->auth) and $user->auth !== $existinguser->auth) {
520 $upt->track('auth', s($existinguser->auth).'-->'.s($user->auth), 'info', false);
521 $existinguser->auth = $user->auth;
522 if (!isset($supportedauths[$user->auth])) {
523 $upt->track('auth', $struserauthunsupported, 'warning');
524 }
df833016 525 $doupdate = true;
08157bfe
PS
526 if ($existinguser->auth === 'nologin') {
527 $dologout = true;
528 }
e4e38544 529 }
8bdb31ed
PS
530 $allcolumns = array_merge($STD_FIELDS, $PRF_FIELDS);
531 foreach ($allcolumns as $column) {
08157bfe 532 if ($column === 'username' or $column === 'password' or $column === 'auth' or $column === 'suspended') {
8bdb31ed 533 // these can not be changed here
e4e38544 534 continue;
535 }
8bdb31ed
PS
536 if (!property_exists($user, $column) or !property_exists($existinguser, $column)) {
537 // this should never happen
538 continue;
539 }
540 if ($updatetype == UU_UPDATE_MISSING) {
541 if (!is_null($existinguser->$column) and $existinguser->$column !== '') {
e4e38544 542 continue;
a7db355a 543 }
8bdb31ed
PS
544 } else if ($updatetype == UU_UPDATE_ALLOVERRIDE) {
545 // we override everything
3f12c146 546
8bdb31ed
PS
547 } else if ($updatetype == UU_UPDATE_FILEOVERRIDE) {
548 if (!empty($formdefaults[$column])) {
549 // do not override with form defaults
550 continue;
551 }
552 }
553 if ($existinguser->$column !== $user->$column) {
554 if ($column === 'email') {
555 if ($DB->record_exists('user', array('email'=>$user->email))) {
556 if ($noemailduplicates) {
557 $upt->track('email', $stremailduplicate, 'error');
558 $upt->track('status', $strusernotupdated, 'error');
559 $userserrors++;
560 continue 2;
561 } else {
562 $upt->track('email', $stremailduplicate, 'warning');
3f12c146
RW
563 }
564 }
8bdb31ed
PS
565 if (!validate_email($user->email)) {
566 $upt->track('email', get_string('invalidemail'), 'warning');
e4e38544 567 }
8bdb31ed 568 }
3f12c146 569
4d3cd148
PS
570 if ($column === 'lang') {
571 if (empty($user->lang)) {
572 // Do not change to not-set value.
573 continue;
574 } else if (clean_param($user->lang, PARAM_LANG) === '') {
575 $upt->track('status', get_string('cannotfindlang', 'error', $user->lang), 'warning');
576 continue;
577 }
578 }
579
8bdb31ed
PS
580 if (in_array($column, $upt->columns)) {
581 $upt->track($column, s($existinguser->$column).'-->'.s($user->$column), 'info', false);
a7db355a 582 }
8bdb31ed
PS
583 $existinguser->$column = $user->$column;
584 $doupdate = true;
6b09974b 585 }
a7db355a 586 }
8bdb31ed 587 }
ed22a01b 588
8bdb31ed 589 try {
3f12c146 590 $auth = get_auth_plugin($existinguser->auth);
8bdb31ed
PS
591 } catch (Exception $e) {
592 $upt->track('auth', get_string('userautherror', 'error', s($existinguser->auth)), 'error');
593 $upt->track('status', $strusernotupdated, 'error');
594 $userserrors++;
595 continue;
596 }
597 $isinternalauth = $auth->is_internal();
3f12c146 598
08157bfe
PS
599 // deal with suspending and activating of accounts
600 if ($allowsuspends and isset($user->suspended) and $user->suspended !== '') {
601 $user->suspended = $user->suspended ? 1 : 0;
602 if ($existinguser->suspended != $user->suspended) {
603 $upt->track('suspended', '', 'normal', false);
604 $upt->track('suspended', $stryesnooptions[$existinguser->suspended].'-->'.$stryesnooptions[$user->suspended], 'info', false);
605 $existinguser->suspended = $user->suspended;
606 $doupdate = true;
607 if ($existinguser->suspended) {
608 $dologout = true;
609 }
610 }
611 }
612
8bdb31ed
PS
613 // changing of passwords is a special case
614 // do not force password changes for external auth plugins!
615 $oldpw = $existinguser->password;
9dcae46d
PS
616
617 if ($remoteuser) {
618 // Do not mess with passwords of remote users.
619
620 } else if (!$isinternalauth) {
8bdb31ed
PS
621 $existinguser->password = 'not cached';
622 $upt->track('password', '-', 'normal', false);
623 // clean up prefs
624 unset_user_preference('create_password', $existinguser);
625 unset_user_preference('auth_forcepasswordchange', $existinguser);
626
627 } else if (!empty($user->password)) {
628 if ($updatepasswords) {
629 $errmsg = null;
faceca91 630 $weak = !check_password_policy($user->password, $errmsg);
8bdb31ed
PS
631 if ($resetpasswords == UU_PWRESET_ALL or ($resetpasswords == UU_PWRESET_WEAK and $weak)) {
632 if ($weak) {
633 $weakpasswords++;
634 $upt->track('password', $strinvalidpasswordpolicy, 'warning');
635 }
636 set_user_preference('auth_forcepasswordchange', 1, $existinguser);
637 } else {
638 unset_user_preference('auth_forcepasswordchange', $existinguser);
639 }
640 unset_user_preference('create_password', $existinguser); // no need to create password any more
641 $existinguser->password = hash_internal_user_password($user->password);
2197b642 642 $upt->track('password', $user->password, 'normal', false);
3f12c146 643 } else {
8bdb31ed
PS
644 // do not print password when not changed
645 $upt->track('password', '', 'normal', false);
3f12c146 646 }
8bdb31ed 647 }
3f12c146 648
8bdb31ed
PS
649 if ($doupdate or $existinguser->password !== $oldpw) {
650 // we want only users that were really updated
3f12c146 651
df997f84 652 $DB->update_record('user', $existinguser);
3f12c146 653
df997f84
PS
654 $upt->track('status', $struserupdated);
655 $usersupdated++;
9dcae46d
PS
656
657 if (!$remoteuser) {
658 // pre-process custom profile menu fields data from csv file
659 $existinguser = uu_pre_process_custom_profile_data($existinguser);
660 // save custom profile fields data from csv file
661 profile_save_data($existinguser);
662 }
e6f74ba3
PS
663
664 events_trigger('user_updated', $existinguser);
e4e38544 665
8bdb31ed
PS
666 if ($bulk == UU_BULK_UPDATED or $bulk == UU_BULK_ALL) {
667 if (!in_array($user->id, $SESSION->bulk_users)) {
668 $SESSION->bulk_users[] = $user->id;
669 }
670 }
671
672 } else {
673 // no user information changed
674 $upt->track('status', $struseruptodate);
675 $usersuptodate++;
676
677 if ($bulk == UU_BULK_ALL) {
678 if (!in_array($user->id, $SESSION->bulk_users)) {
679 $SESSION->bulk_users[] = $user->id;
680 }
ed22a01b 681 }
066bfbfe 682 }
ed22a01b 683
08157bfe
PS
684 if ($dologout) {
685 session_kill_user($existinguser->id);
686 }
687
e4e38544 688 } else {
8bdb31ed
PS
689 // save the new user to the database
690 $user->confirmed = 1;
a7db355a 691 $user->timemodified = time();
8bdb31ed
PS
692 $user->timecreated = time();
693 $user->mnethostid = $CFG->mnet_localhost_id; // we support ONLY local accounts here, sorry
066bfbfe 694
08157bfe
PS
695 if (!isset($user->suspended) or $user->suspended === '') {
696 $user->suspended = 0;
697 } else {
698 $user->suspended = $user->suspended ? 1 : 0;
699 }
700 $upt->track('suspended', $stryesnooptions[$user->suspended], 'normal', false);
701
8bdb31ed 702 if (empty($user->auth)) {
3f12c146
RW
703 $user->auth = 'manual';
704 }
8bdb31ed 705 $upt->track('auth', $user->auth, 'normal', false);
3f12c146 706
8bdb31ed
PS
707 // do not insert record if new auth plugin does not exist!
708 try {
709 $auth = get_auth_plugin($user->auth);
710 } catch (Exception $e) {
711 $upt->track('auth', get_string('userautherror', 'error', s($user->auth)), 'error');
712 $upt->track('status', $strusernotaddederror, 'error');
713 $userserrors++;
714 continue;
e4e38544 715 }
8bdb31ed
PS
716 if (!isset($supportedauths[$user->auth])) {
717 $upt->track('auth', $struserauthunsupported, 'warning');
066bfbfe 718 }
a2ce7344 719
8bdb31ed
PS
720 $isinternalauth = $auth->is_internal();
721
43070e61
PS
722 if (empty($user->email)) {
723 $upt->track('email', get_string('invalidemail'), 'error');
724 $upt->track('status', $strusernotaddederror, 'error');
725 $userserrors++;
726 continue;
727
728 } else if ($DB->record_exists('user', array('email'=>$user->email))) {
0c4807ab 729 if ($noemailduplicates) {
730 $upt->track('email', $stremailduplicate, 'error');
731 $upt->track('status', $strusernotaddederror, 'error');
732 $userserrors++;
733 continue;
734 } else {
735 $upt->track('email', $stremailduplicate, 'warning');
736 }
737 }
8bdb31ed
PS
738 if (!validate_email($user->email)) {
739 $upt->track('email', get_string('invalidemail'), 'warning');
3f12c146 740 }
0c4807ab 741
4d3cd148
PS
742 if (empty($user->lang)) {
743 $user->lang = '';
744 } else if (clean_param($user->lang, PARAM_LANG) === '') {
745 $upt->track('status', get_string('cannotfindlang', 'error', $user->lang), 'warning');
746 $user->lang = '';
747 }
748
8bdb31ed
PS
749 $forcechangepassword = false;
750
751 if ($isinternalauth) {
752 if (empty($user->password)) {
753 if ($createpasswords) {
754 $user->password = 'to be generated';
755 $upt->track('password', '', 'normal', false);
ce15d56d 756 $upt->track('password', get_string('uupasswordcron', 'tool_uploaduser'), 'warning', false);
8bdb31ed
PS
757 } else {
758 $upt->track('password', '', 'normal', false);
759 $upt->track('password', get_string('missingfield', 'error', 'password'), 'error');
760 $upt->track('status', $strusernotaddederror, 'error');
761 $userserrors++;
762 continue;
763 }
3f12c146 764 } else {
8bdb31ed 765 $errmsg = null;
faceca91 766 $weak = !check_password_policy($user->password, $errmsg);
8bdb31ed
PS
767 if ($resetpasswords == UU_PWRESET_ALL or ($resetpasswords == UU_PWRESET_WEAK and $weak)) {
768 if ($weak) {
769 $weakpasswords++;
770 $upt->track('password', $strinvalidpasswordpolicy, 'warning');
771 }
772 $forcechangepassword = true;
773 }
774 $user->password = hash_internal_user_password($user->password);
3f12c146 775 }
8bdb31ed
PS
776 } else {
777 $user->password = 'not cached';
778 $upt->track('password', '-', 'normal', false);
df997f84
PS
779 }
780
8bdb31ed
PS
781 // create user - insert_record ignores any extra properties
782 $user->id = $DB->insert_record('user', $user);
783 $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false);
784
d6aea4cc 785 // pre-process custom profile menu fields data from csv file
bd8dc9ba 786 $user = uu_pre_process_custom_profile_data($user);
e4e38544 787 // save custom profile fields data
788 profile_save_data($user);
789
8bdb31ed
PS
790 if ($forcechangepassword) {
791 set_user_preference('auth_forcepasswordchange', 1, $user);
792 }
793 if ($user->password === 'to be generated') {
794 set_user_preference('create_password', 1, $user);
795 }
796
797 $upt->track('status', $struseradded);
798 $upt->track('id', $user->id, 'normal', false);
799 $usersnew++;
800
2304f629 801 // make sure user context exists
bf006d2c 802 context_user::instance($user->id);
2304f629 803
e6f74ba3
PS
804 events_trigger('user_created', $user);
805
8bdb31ed 806 if ($bulk == UU_BULK_NEW or $bulk == UU_BULK_ALL) {
cd1edf9e 807 if (!in_array($user->id, $SESSION->bulk_users)) {
808 $SESSION->bulk_users[] = $user->id;
066bfbfe 809 }
066bfbfe 810 }
e4e38544 811 }
812
92b59a56
PS
813
814 // add to cohort first, it might trigger enrolments indirectly - do NOT create cohorts here!
815 foreach ($filecolumns as $column) {
816 if (!preg_match('/^cohort\d+$/', $column)) {
817 continue;
818 }
819
820 if (!empty($user->$column)) {
821 $addcohort = $user->$column;
822 if (!isset($cohorts[$addcohort])) {
823 if (is_number($addcohort)) {
824 // only non-numeric idnumbers!
825 $cohort = $DB->get_record('cohort', array('id'=>$addcohort));
826 } else {
827 $cohort = $DB->get_record('cohort', array('idnumber'=>$addcohort));
828 }
829
830 if (empty($cohort)) {
831 $cohorts[$addcohort] = get_string('unknowncohort', 'core_cohort', s($addcohort));
832 } else if (!empty($cohort->component)) {
833 // cohorts synchronised with external sources must not be modified!
834 $cohorts[$addcohort] = get_string('external', 'core_cohort');
835 } else {
836 $cohorts[$addcohort] = $cohort;
837 }
838 }
839
840 if (is_object($cohorts[$addcohort])) {
841 $cohort = $cohorts[$addcohort];
842 if (!$DB->record_exists('cohort_members', array('cohortid'=>$cohort->id, 'userid'=>$user->id))) {
843 cohort_add_member($cohort->id, $user->id);
844 // we might add special column later, for now let's abuse enrolments
845 $upt->track('enrolments', get_string('useradded', 'core_cohort', s($cohort->name)));
846 }
847 } else {
848 // error message
849 $upt->track('enrolments', $cohorts[$addcohort], 'error');
850 }
851 }
852 }
853
854
2686b6c3 855 // find course enrolments, groups, roles/types and enrol periods
8bdb31ed
PS
856 // this is again a special case, we always do this for any updated or created users
857 foreach ($filecolumns as $column) {
e4e38544 858 if (!preg_match('/^course\d+$/', $column)) {
859 continue;
860 }
861 $i = substr($column, 6);
6b09974b 862
df997f84
PS
863 if (empty($user->{'course'.$i})) {
864 continue;
865 }
e4e38544 866 $shortname = $user->{'course'.$i};
867 if (!array_key_exists($shortname, $ccache)) {
df997f84 868 if (!$course = $DB->get_record('course', array('shortname'=>$shortname), 'id, shortname')) {
8bdb31ed 869 $upt->track('enrolments', get_string('unknowncourse', 'error', s($shortname)), 'error');
a7db355a 870 continue;
066bfbfe 871 }
e4e38544 872 $ccache[$shortname] = $course;
873 $ccache[$shortname]->groups = null;
874 }
875 $courseid = $ccache[$shortname]->id;
bf006d2c 876 $coursecontext = context_course::instance($courseid);
df997f84 877 if (!isset($manualcache[$courseid])) {
4cb02426
PS
878 $manualcache[$courseid] = false;
879 if ($manual) {
880 if ($instances = enrol_get_instances($courseid, false)) {
881 foreach ($instances as $instance) {
882 if ($instance->enrol === 'manual') {
883 $manualcache[$courseid] = $instance;
884 break;
885 }
886 }
887 }
e4e38544 888 }
df997f84 889 }
e4e38544 890
df997f84
PS
891 if ($manual and $manualcache[$courseid]) {
892
893 // find role
894 $rid = false;
895 if (!empty($user->{'role'.$i})) {
896 $addrole = $user->{'role'.$i};
897 if (array_key_exists($addrole, $rolecache)) {
898 $rid = $rolecache[$addrole]->id;
e4e38544 899 } else {
8bdb31ed 900 $upt->track('enrolments', get_string('unknownrole', 'error', s($addrole)), 'error');
df997f84 901 continue;
a7db355a 902 }
e4e38544 903
df997f84
PS
904 } else if (!empty($user->{'type'.$i})) {
905 // if no role, then find "old" enrolment type
906 $addtype = $user->{'type'.$i};
907 if ($addtype < 1 or $addtype > 3) {
908 $upt->track('enrolments', $strerror.': typeN = 1|2|3', 'error');
909 continue;
910 } else if (empty($formdata->{'uulegacy'.$addtype})) {
911 continue;
912 } else {
913 $rid = $formdata->{'uulegacy'.$addtype};
914 }
e4e38544 915 } else {
df997f84
PS
916 // no role specified, use the default from manual enrol plugin
917 $rid = $manualcache[$courseid]->roleid;
a7db355a 918 }
2686b6c3 919
df997f84
PS
920 if ($rid) {
921 // find duration
df997f84
PS
922 $timeend = 0;
923 if (!empty($user->{'enrolperiod'.$i})) {
8bdb31ed 924 $duration = (int)$user->{'enrolperiod'.$i} * 60*60*24; // convert days to seconds
df997f84 925 if ($duration > 0) { // sanity check
8bdb31ed 926 $timeend = $today + $duration;
df997f84 927 }
b1d76077
AO
928 } else if ($manualcache[$courseid]->enrolperiod > 0) {
929 $timeend = $today + $manualcache[$courseid]->enrolperiod;
df997f84 930 }
2686b6c3 931
02c97e65 932 $manual->enrol_user($manualcache[$courseid], $user->id, $rid, $today, $timeend);
df997f84 933
a226a972 934 $a = new stdClass();
df997f84
PS
935 $a->course = $shortname;
936 $a->role = $rolecache[$rid]->name;
937 $upt->track('enrolments', get_string('enrolledincourserole', 'enrol_manual', $a));
066bfbfe 938 }
e4e38544 939 }
6b09974b 940
e4e38544 941 // find group to add to
942 if (!empty($user->{'group'.$i})) {
943 // make sure user is enrolled into course before adding into groups
4f0c2d00 944 if (!is_enrolled($coursecontext, $user->id)) {
d85f2634 945 $upt->track('enrolments', get_string('addedtogroupnotenrolled', '', $user->{'group'.$i}), 'error');
e4e38544 946 continue;
947 }
948 //build group cache
949 if (is_null($ccache[$shortname]->groups)) {
950 $ccache[$shortname]->groups = array();
35987665 951 if ($groups = groups_get_all_groups($courseid)) {
e4e38544 952 foreach ($groups as $gid=>$group) {
a226a972 953 $ccache[$shortname]->groups[$gid] = new stdClass();
e4e38544 954 $ccache[$shortname]->groups[$gid]->id = $gid;
955 $ccache[$shortname]->groups[$gid]->name = $group->name;
956 if (!is_numeric($group->name)) { // only non-numeric names are supported!!!
8bdb31ed
PS
957 $ccache[$shortname]->groups[$group->name] = new stdClass();
958 $ccache[$shortname]->groups[$group->name]->id = $gid;
959 $ccache[$shortname]->groups[$group->name]->name = $group->name;
a7db355a 960 }
a5702569 961 }
0063abee 962 }
6b09974b 963 }
e4e38544 964 // group exists?
965 $addgroup = $user->{'group'.$i};
966 if (!array_key_exists($addgroup, $ccache[$shortname]->groups)) {
b225cf36 967 // if group doesn't exist, create it
a226a972 968 $newgroupdata = new stdClass();
b225cf36 969 $newgroupdata->name = $addgroup;
970 $newgroupdata->courseid = $ccache[$shortname]->id;
e95bf5b5
PS
971 $newgroupdata->description = '';
972 $gid = groups_create_group($newgroupdata);
973 if ($gid){
974 $ccache[$shortname]->groups[$addgroup] = new stdClass();
975 $ccache[$shortname]->groups[$addgroup]->id = $gid;
b225cf36 976 $ccache[$shortname]->groups[$addgroup]->name = $newgroupdata->name;
977 } else {
8bdb31ed 978 $upt->track('enrolments', get_string('unknowngroup', 'error', s($addgroup)), 'error');
b225cf36 979 continue;
980 }
e4e38544 981 }
982 $gid = $ccache[$shortname]->groups[$addgroup]->id;
983 $gname = $ccache[$shortname]->groups[$addgroup]->name;
984
9c000a99 985 try {
986 if (groups_add_member($gid, $user->id)) {
8bdb31ed 987 $upt->track('enrolments', get_string('addedtogroup', '', s($gname)));
df997f84 988 } else {
8bdb31ed 989 $upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error');
9c000a99 990 }
991 } catch (moodle_exception $e) {
8bdb31ed 992 $upt->track('enrolments', get_string('addedtogroupnot', '', s($gname)), 'error');
e4e38544 993 continue;
994 }
a5702569 995 }
066bfbfe 996 }
997 }
e4e38544 998 $upt->close(); // close table
999
1000 $cir->close();
1001 $cir->cleanup(true);
1002
20486a5a 1003 echo $OUTPUT->box_start('boxwidthnarrow boxaligncenter generalbox', 'uploadresults');
e4e38544 1004 echo '<p>';
8bdb31ed 1005 if ($optype != UU_USER_UPDATE) {
ce15d56d 1006 echo get_string('userscreated', 'tool_uploaduser').': '.$usersnew.'<br />';
e4e38544 1007 }
8bdb31ed 1008 if ($optype == UU_USER_UPDATE or $optype == UU_USER_ADD_UPDATE) {
ce15d56d 1009 echo get_string('usersupdated', 'tool_uploaduser').': '.$usersupdated.'<br />';
e4e38544 1010 }
1011 if ($allowdeletes) {
ce15d56d
PS
1012 echo get_string('usersdeleted', 'tool_uploaduser').': '.$deletes.'<br />';
1013 echo get_string('deleteerrors', 'tool_uploaduser').': '.$deleteerrors.'<br />';
e4e38544 1014 }
1015 if ($allowrenames) {
ce15d56d
PS
1016 echo get_string('usersrenamed', 'tool_uploaduser').': '.$renames.'<br />';
1017 echo get_string('renameerrors', 'tool_uploaduser').': '.$renameerrors.'<br />';
e4e38544 1018 }
1019 if ($usersskipped) {
ce15d56d 1020 echo get_string('usersskipped', 'tool_uploaduser').': '.$usersskipped.'<br />';
e4e38544 1021 }
ce15d56d
PS
1022 echo get_string('usersweakpassword', 'tool_uploaduser').': '.$weakpasswords.'<br />';
1023 echo get_string('errors', 'tool_uploaduser').': '.$userserrors.'</p>';
20486a5a 1024 echo $OUTPUT->box_end();
e4e38544 1025
1026 if ($bulk) {
8fbce1c8 1027 echo $OUTPUT->continue_button($bulknurl);
e4e38544 1028 } else {
8fbce1c8 1029 echo $OUTPUT->continue_button($returnurl);
e4e38544 1030 }
73d6f52f 1031 echo $OUTPUT->footer();
df7ecfe4 1032 die;
6b09974b 1033}
0a6150ca 1034
df7ecfe4 1035// Print the header
61ef8f9f 1036echo $OUTPUT->header();
df7ecfe4 1037
ce15d56d 1038echo $OUTPUT->heading(get_string('uploaduserspreview', 'tool_uploaduser'));
df7ecfe4 1039
8bdb31ed
PS
1040// NOTE: this is JUST csv processing preview, we must not prevent import from here if there is something in the file!!
1041// this was intended for validation of csv formatting and encoding, not filtering the data!!!!
1042// we definitely must not process the whole file!
1043
1044// preview table data
1045$data = array();
e4e38544 1046$cir->init();
8bdb31ed 1047$linenum = 1; //column header is first line
1b4d2d56 1048$noerror = true; // Keep status of any error.
8bdb31ed
PS
1049while ($linenum <= $previewrows and $fields = $cir->next()) {
1050 $linenum++;
3fe2cfb5 1051 $rowcols = array();
8bdb31ed
PS
1052 $rowcols['line'] = $linenum;
1053 foreach($fields as $key => $field) {
1054 $rowcols[$filecolumns[$key]] = s($field);
3fe2cfb5 1055 }
8bdb31ed 1056 $rowcols['status'] = array();
3fe2cfb5 1057
8bdb31ed
PS
1058 if (isset($rowcols['username'])) {
1059 $stdusername = clean_param($rowcols['username'], PARAM_USERNAME);
1060 if ($rowcols['username'] !== $stdusername) {
1061 $rowcols['status'][] = get_string('invalidusernameupload');
3fe2cfb5 1062 }
8bdb31ed
PS
1063 if ($userid = $DB->get_field('user', 'id', array('username'=>$stdusername, 'mnethostid'=>$CFG->mnet_localhost_id))) {
1064 $rowcols['username'] = html_writer::link(new moodle_url('/user/profile.php', array('id'=>$userid)), $rowcols['username']);
e4e38544 1065 }
8bdb31ed
PS
1066 } else {
1067 $rowcols['status'][] = get_string('missingusername');
df7ecfe4 1068 }
07ed083e 1069
43070e61
PS
1070 if (isset($rowcols['email'])) {
1071 if (!validate_email($rowcols['email'])) {
1072 $rowcols['status'][] = get_string('invalidemail');
1073 }
1074 if ($DB->record_exists('user', array('email'=>$rowcols['email']))) {
1075 $rowcols['status'][] = $stremailduplicate;
1076 }
07ed083e 1077 }
fd9672ac
RW
1078
1079 if (isset($rowcols['city'])) {
1080 $rowcols['city'] = trim($rowcols['city']);
1081 if (empty($rowcols['city'])) {
1082 $rowcols['status'][] = get_string('fieldrequired', 'error', 'city');
1083 }
1084 }
1b4d2d56
RT
1085 // Check if rowcols have custom profile field with correct data and update error state.
1086 $noerror = uu_check_custom_profile_data($rowcols) && $noerror;
8bdb31ed
PS
1087 $rowcols['status'] = implode('<br />', $rowcols['status']);
1088 $data[] = $rowcols;
07ed083e 1089}
8bdb31ed
PS
1090if ($fields = $cir->next()) {
1091 $data[] = array_fill(0, count($fields) + 2, '...');
07ed083e 1092}
8bdb31ed 1093$cir->close();
3fe2cfb5
RW
1094
1095$table = new html_table();
1096$table->id = "uupreview";
16be8974 1097$table->attributes['class'] = 'generaltable';
3fe2cfb5 1098$table->tablealign = 'center';
ce15d56d 1099$table->summary = get_string('uploaduserspreview', 'tool_uploaduser');
3fe2cfb5 1100$table->head = array();
8bdb31ed 1101$table->data = $data;
3fe2cfb5 1102
ce15d56d 1103$table->head[] = get_string('uucsvline', 'tool_uploaduser');
8bdb31ed
PS
1104foreach ($filecolumns as $column) {
1105 $table->head[] = $column;
07ed083e 1106}
8bdb31ed 1107$table->head[] = get_string('status');
07ed083e 1108
3f12c146 1109echo html_writer::tag('div', html_writer::table($table), array('class'=>'flexible-wrap'));
3fe2cfb5 1110
1b4d2d56
RT
1111// Print the form if valid values are available
1112if ($noerror) {
1113 $mform2->display();
1114}
73d6f52f 1115echo $OUTPUT->footer();
df7ecfe4 1116die;
1117