uploadcsv.php 24.4 KB
Newer Older
1 2 3 4 5
<?php
/**
 *
 * @package    mahara
 * @subpackage admin
6
 * @author     Catalyst IT Ltd
7 8
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
9 10 11 12
 *
 */

define('INTERNAL', 1);
13
define('INSTITUTIONALADMIN', 1);
14
define('MENUITEM', 'configusers/uploadcsv');
15
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
Martyn Smith's avatar
Martyn Smith committed
16
define('TITLE', get_string('uploadcsv', 'admin'));
17
require_once('pieforms/pieform.php');
18
require_once('institution.php');
19
require_once('phpmailer/class.phpmailer.php');
Nigel McNie's avatar
Nigel McNie committed
20
safe_require('artefact', 'internal');
21
raise_memory_limit("512M");
22

23 24 25
// Turn on autodetecting of line endings, so mac newlines (\r) will work
ini_set('auto_detect_line_endings', 1);

Nigel McNie's avatar
Nigel McNie committed
26
$FORMAT = array();
27
$specialcases = array('username', 'password', 'remoteuser');
28 29
// Don't upload social profiles for now. A user can have multiple profiles. Not sure how to put that in a csv.
$notallowed = array('socialprofile');
30
$ALLOWEDKEYS = array_keys(ArtefactTypeProfile::get_all_fields());
31
$ALLOWEDKEYS = array_diff($ALLOWEDKEYS, $notallowed);
32 33
$maildisabled = array_search('maildisabled', $ALLOWEDKEYS);
unset($ALLOWEDKEYS[$maildisabled]);
34 35
$ALLOWEDKEYS = array_merge($ALLOWEDKEYS, $specialcases);

36 37
$UPDATES         = array(); // During validation, remember which users already exist
$INSTITUTIONNAME = array(); // Mapping from institution id to display name
Nigel McNie's avatar
Nigel McNie committed
38

39 40 41 42 43 44
if ($USER->get('admin')) {
    $authinstances = auth_get_auth_instances();
} else {
    $admininstitutions = $USER->get('admininstitutions');
    $authinstances = auth_get_auth_instances_for_institutions($admininstitutions);
    if (empty($authinstances)) {
45
        $SESSION->add_info_msg(get_string('configureauthplugin', 'admin'));
46 47 48
        redirect(get_config('wwwroot').'admin/users/institutions.php?i='.key($admininstitutions).'&amp;edit=1');
    }
}
49

50
if (count($authinstances) > 0) {
51
    $options = array();
52 53

    foreach ($authinstances as $authinstance) {
Richard Mansfield's avatar
Richard Mansfield committed
54
        if ($USER->can_edit_institution($authinstance->name)) {
55
            $options[$authinstance->id] = $authinstance->displayname. ': '.$authinstance->instancename;
56
            $INSTITUTIONNAME[$authinstance->name] = $authinstance->displayname;
57
        }
58
    }
59 60 61 62 63 64 65
    if ($USER->get('admin')) {
        $definst = get_field('auth_instance', 'id', 'institution', 'mahara');
        $default = $definst ? $definst : key($options);
    }
    else {
        $default = key($options);
    }
66 67

    $authinstanceelement = array(
68 69
        'type' => 'select',
        'title' => get_string('institution'),
70 71
        'description' => get_string('uploadcsvinstitution', 'admin'),
        'options' => $options,
72
        'defaultvalue' => $default
73 74 75
    );
}

76 77
$prefs = (object) expected_account_preferences();

78 79
$form = array(
    'name' => 'uploadcsv',
80 81
    'plugintype' => 'core',
    'pluginname' => 'admin',
82
    'elements' => array(
83
        'authinstance' => $authinstanceelement,
84 85
        'quota' => array(
            'type' => 'bytes',
86
            'title' => get_string('filequota1', 'admin'),
87 88 89 90
            'description' => get_string('filequotadescription', 'admin'),
            'rules' => array('integer' => true, 'minvalue' => 0),
            'defaultvalue' => get_config_plugin('artefact', 'file', 'defaultquota'),
        ),
91 92 93 94
        'file' => array(
            'type' => 'file',
            'title' => get_string('csvfile', 'admin'),
            'description' => get_string('csvfiledescription', 'admin'),
95
            'accept' => '.csv, text/csv, application/csv, text/comma-separated-values',
96 97 98 99
            'rules' => array(
                'required' => true
            )
        ),
100 101 102 103 104 105 106 107 108 109 110 111
        'forcepasswordchange' => array(
            'type'         => 'checkbox',
            'title'        => get_string('forceuserstochangepassword', 'admin'),
            'description'  => get_string('forceuserstochangepassworddescription', 'admin'),
            'defaultvalue' => true,
        ),
        'emailusers' => array(
            'type' => 'checkbox',
            'title' => get_string('emailusersaboutnewaccount', 'admin'),
            'description' => get_string('emailusersaboutnewaccountdescription', 'admin'),
            'defaultvalue' => true,
        ),
112 113 114 115 116 117
        'updateusers' => array(
            'type' => 'checkbox',
            'title' => get_string('updateusers', 'admin'),
            'description' => get_string('updateusersdescription', 'admin'),
            'defaultvalue' => false,
        ),
118 119 120 121 122 123 124
        'accountprefs' => array(
            'type' => 'fieldset',
            'legend' => get_string('accountoptionsdesc', 'account'),
            'collapsible' => true,
            'collapsed' => true,
            'elements' => general_account_prefs_form_elements($prefs),
        ),
125 126
        'submit' => array(
            'type' => 'submit',
Nigel McNie's avatar
Nigel McNie committed
127
            'value' => get_string('uploadcsv', 'admin')
128 129 130 131
        )
    )
);

132 133 134 135
if ($maxcsvlines = get_config('maxusercsvlines')) {
    $form['elements']['file']['description'] .= ' ' . get_string('csvmaxusersdescription', 'admin', get_string('nusers', 'mahara', $maxcsvlines));
}

136 137
unset($prefs);

138 139 140 141
if (!($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride'))) {
    $form['elements']['quota'] = array(
        'type'         => 'text',
        'disabled'     => true,
142
        'title'        => get_string('filequota1', 'admin'),
143 144 145 146 147
        'description'  => get_string('filequotadescription', 'admin'),
        'value'        => display_size(get_config_plugin('artefact', 'file', 'defaultquota')),
    );
}

148 149 150 151 152
/**
 * The CSV file is parsed here so validation errors can be returned to the
 * user. The data from a successful parsing is stored in the <var>$CVSDATA</var>
 * array so it can be accessed by the submit function
 *
153 154
 * @param Pieform  $form   The form to validate
 * @param array    $values The values submitted
155
 */
156
function uploadcsv_validate(Pieform $form, $values) {
157
    global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER, $INSTITUTIONNAME, $UPDATES;
158 159 160 161 162 163 164

    // Don't even start attempting to parse if there are previous errors
    if ($form->has_errors()) {
        return;
    }

    if ($values['file']['size'] == 0) {
165
        $form->set_error('file', $form->i18n('rule', 'required', 'required', array()));
166 167 168
        return;
    }

169 170 171 172 173 174
    if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
        $maxquotaenabled = get_config_plugin('artefact', 'file', 'maxquotaenabled');
        $maxquota = get_config_plugin('artefact', 'file', 'maxquota');
        if ($maxquotaenabled && $values['quota'] > $maxquota) {
            $form->set_error('quota', get_string('maxquotaexceededform', 'artefact.file', display_size($maxquota)));
        }
175 176
    }

177
    require_once('csvfile.php');
178

179 180
    $authinstance = (int) $values['authinstance'];
    $institution = get_field('auth_instance', 'institution', 'id', $authinstance);
Richard Mansfield's avatar
Richard Mansfield committed
181
    if (!$USER->can_edit_institution($institution)) {
182 183 184
        $form->set_error('authinstance', get_string('notadminforinstitution', 'admin'));
        return;
    }
185

186 187
    $authobj = AuthFactory::create($authinstance);

188 189
    $csvusers = new CsvFile($values['file']['tmp_name']);
    $csvusers->set('allowedkeys', $ALLOWEDKEYS);
190

191 192 193
    // Now we know all of the field names are valid, we need to make
    // sure that the required fields are included
    $mandatoryfields = array(
194
        'username', 'email', 'firstname', 'lastname'
195
    );
196 197 198 199
    if (!$values['updateusers']) {
        $mandatoryfields[] = 'password';
    }

200 201
    $csvusers->set('mandatoryfields', $mandatoryfields);
    $csvdata = $csvusers->get_data();
202

203 204 205 206
    if (!empty($csvdata->errors['file'])) {
        $form->set_error('file', $csvdata->errors['file']);
        return;
    }
Nigel McNie's avatar
Nigel McNie committed
207

208 209
    $csverrors = new CSVErrors();

210 211
    $formatkeylookup = array_flip($csvdata->format);

212 213 214 215
    // First pass validates usernames & passwords in the file, and builds
    // up a list indexed by username.

    $emails = array();
216 217 218
    if (isset($formatkeylookup['remoteuser'])) {
        $remoteusers = array();
    }
219

220 221 222 223 224 225
    $maxcsvlines = get_config('maxusercsvlines');
    if ($maxcsvlines && $maxcsvlines < count($csvdata->data)) {
        $form->set_error('file', get_string('uploadcsverrortoomanyusers', 'admin', get_string('nusers', 'mahara', $maxcsvlines)));
        return;
    }

226
    foreach ($csvdata->data as $key => $line) {
227 228
        // If headers exists, increment i = key + 2 for actual line number
        $i = ($csvusers->get('headerExists')) ? ($key + 2) : ($key + 1);
229

230 231 232 233
        // Trim non-breaking spaces -- they get left in place by File_CSV
        foreach ($line as &$field) {
            $field = preg_replace('/^(\s|\xc2\xa0)*(.*?)(\s|\xc2\xa0)*$/', '$2', $field);
        }
234

235
        if (count($line) != count($csvdata->format)) {
236
            $csverrors->add($i, get_string('uploadcsverrorwrongnumberoffields', 'admin', $i));
237 238 239
            continue;
        }

240 241 242
        // We have a line with the correct number of fields, but should validate these fields
        // Note: This validation should really be methods on each profile class, that way
        // it can be used in the profile screen as well.
243

244
        $username = $line[$formatkeylookup['username']];
245
        $password = isset($formatkeylookup['password']) ? $line[$formatkeylookup['password']] : null;
246
        $email    = $line[$formatkeylookup['email']];
247 248 249
        if (isset($remoteusers)) {
            $remoteuser = strlen($line[$formatkeylookup['remoteuser']]) ? $line[$formatkeylookup['remoteuser']] : null;
        }
Nigel McNie's avatar
Nigel McNie committed
250

251 252
        if (method_exists($authobj, 'is_username_valid_admin')) {
            if (!$authobj->is_username_valid_admin($username)) {
253
                $csverrors->add($i, get_string('uploadcsverrorinvalidusername', 'admin', $i));
254 255 256 257
            }
        }
        else if (method_exists($authobj, 'is_username_valid')) {
            if (!$authobj->is_username_valid($username)) {
258
                $csverrors->add($i, get_string('uploadcsverrorinvalidusername', 'admin', $i));
259
            }
260
        }
261 262 263 264 265 266

        if (!$values['updateusers']) {
            // Note: only checks for valid form are done here, none of the checks
            // like whether the password is too easy. The user is going to have to
            // change their password on first login anyway.
            if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) {
267
                $csverrors->add($i, get_string('uploadcsverrorinvalidpassword', 'admin', $i));
268
            }
269
        }
270 271 272

        if (isset($emails[$email])) {
            // Duplicate email within this file.
273
            $csverrors->add($i, get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email));
274
        }
275 276 277
        else if (!PHPMailer::ValidateAddress($email)) {
            $csverrors->add($i, get_string('uploadcsverrorinvalidemail', 'admin', $i, $email));
        }
278 279 280
        else if (!$values['updateusers']) {
            // The email address must be new
            if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email, 'verified', 1)) {
281
                $csverrors->add($i, get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email));
282 283 284
            }
        }
        $emails[$email] = 1;
285

286 287
        if (isset($remoteusers) && $remoteuser) {
            if (isset($remoteusers[$remoteuser])) {
288
                $csverrors->add($i, get_string('uploadcsverrorduplicateremoteuser', 'admin', $i, $remoteuser));
289 290
            }
            else if (!$values['updateusers']) {
291 292 293 294 295
                if ($remoteuserowner = get_record_sql('
                    SELECT u.username
                    FROM {auth_remote_user} aru JOIN {usr} u ON aru.localusr = u.id
                    WHERE aru.remoteusername = ? AND aru.authinstance = ?',
                    array($remoteuser, $authinstance))) {
296
                    $csverrors->add($i, get_string('uploadcsverrorremoteusertaken', 'admin', $i, $remoteuser, $remoteuserowner->username));
297 298 299 300 301
                }
            }
            $remoteusers[$remoteuser] = true;
        }

302 303 304 305 306
        // If we didn't even get a username, we can't check for duplicates, so move on.
        if (strlen($username) < 1) {
            continue;
        }

307 308
        if (isset($usernames[strtolower($username)])) {
            // Duplicate username within this file.
309
            $csverrors->add($i, get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username));
310
        }
311
        else {
312
            if (!$values['updateusers'] && record_exists_select('usr', 'LOWER(username) = ?', array(strtolower($username)))) {
313
                $csverrors->add($i, get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username));
314 315 316 317 318 319 320 321
            }
            $usernames[strtolower($username)] = array(
                'username' => $username,
                'password' => $password,
                'email'    => $email,
                'lineno'   => $i,
                'raw'      => $line,
            );
322 323 324
            if (!empty($remoteuser) && !empty($remoteusers[$remoteuser])) {
                $usernames[strtolower($username)]['remoteuser'] = $remoteuser;
            }
325 326
        }
    }
Nigel McNie's avatar
Nigel McNie committed
327

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
    // If the admin is trying to overwrite existing users, identified by username,
    // this second pass performs some additional checks

    if ($values['updateusers']) {

        foreach ($usernames as $lowerusername => $data) {

            $line      = $data['lineno'];
            $username  = $data['username'];
            $password  = $data['password'];
            $email     = $data['email'];

            // If the user already exists, they must already be in this institution.
            $userinstitutions = get_records_sql_assoc("
                SELECT COALESCE(ui.institution, 'mahara') AS institution, u.id
                FROM {usr} u LEFT JOIN {usr_institution} ui ON u.id = ui.usr
                WHERE LOWER(u.username) = ?",
                array($lowerusername)
            );
            if ($userinstitutions) {
                if (!isset($userinstitutions[$institution])) {
                    if ($institution == 'mahara') {
                        $institutiondisplay = array();
                        foreach ($userinstitutions as $i) {
                            $institutiondisplay[] = $INSTITUTIONNAME[$i->institution];
                        }
                        $institutiondisplay = join(', ', $institutiondisplay);
                        $message = get_string('uploadcsverroruserinaninstitution', 'admin', $line, $username, $institutiondisplay);
                    }
                    else {
                        $message = get_string('uploadcsverrorusernotininstitution', 'admin', $line, $username, $INSTITUTIONNAME[$institution]);
                    }
360
                    $csverrors->add($line, $message);
361 362 363 364 365 366 367 368 369
                }
                else {
                    // Remember that this user is being updated
                    $UPDATES[$username] = 1;
                }
            }
            else {
                // New user, check the password
                if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) {
370
                    $csverrors->add($line, get_string('uploadcsverrorinvalidpassword', 'admin', $line));
371 372 373
                }
            }

374 375 376 377 378
            // Check if the email already exists and if it's owned by this user.  This query can return more
            // than one row when there are duplicate emails already on the site.  If that happens, things are
            // already a bit out of hand, and we'll just allow an update if this user is one of the users who
            // owns the email.
            $emailowned = get_records_sql_assoc('
379 380 381 382 383 384 385 386
                SELECT LOWER(u.username) AS lowerusername, ae.principal FROM {usr} u
                LEFT JOIN {artefact_internal_profile_email} ae ON u.id = ae.owner AND ae.verified = 1 AND ae.email = ?
                WHERE ae.owner IS NOT NULL OR u.email = ?',
                array($email, $email)
            );

            // If the email is owned by someone else, it could still be okay provided
            // that other user's email is also being changed in this csv file.
387 388 389 390 391 392 393 394 395 396 397 398 399
            if ($emailowned && !isset($emailowned[$lowerusername])) {
                foreach ($emailowned as $e) {
                    // Only primary emails can be set in uploadcsv, so it's an error when someone else
                    // owns the email as a secondary.
                    if (!$e->principal) {
                        $csverrors->add($line, get_string('uploadcsverroremailaddresstaken', 'admin', $line, $email));
                        break;
                    }
                    // It's also an error if the email owner is not being updated in this file
                    if (!isset($usernames[$e->lowerusername])) {
                        $csverrors->add($line, get_string('uploadcsverroremailaddresstaken', 'admin', $line, $email));
                        break;
                    }
400 401 402 403
                    // If the other user is being updated in this file, but isn't changing their
                    // email address, it's ok, we've already notified duplicate emails within the file.
                }
            }
404 405 406 407 408 409 410 411 412 413 414

            if (isset($remoteusers) && !empty($data['remoteuser'])) {
                $remoteuser = $data['remoteuser'];
                $remoteuserowner = get_field_sql('
                    SELECT LOWER(u.username)
                    FROM {usr} u JOIN {auth_remote_user} aru ON u.id = aru.localusr
                    WHERE aru.remoteusername = ? AND aru.authinstance = ?',
                    array($remoteuser, $authinstance)
                );
                if ($remoteuserowner && $remoteuserowner != $lowerusername && !isset($usernames[$remoteuserowner])) {
                    // The remote username is owned by some other user who is not being updated in this file
415
                    $csverrors->add($line, get_string('uploadcsverrorremoteusertaken', 'admin', $line, $remoteuser, $remoteuserowner));
416 417
                }
            }
418
        }
419
    }
420

421
    if ($errors = $csverrors->process()) {
422
        $form->set_error('file', clean_html($errors), false);
423 424 425
        return;
    }

426 427
    $FORMAT = $csvdata->format;
    $CSVDATA = $csvdata->data;
428 429 430 431 432 433
}

/**
 * Add the users to the system. Make sure that they have to change their
 * password on next login also.
 */
434
function uploadcsv_submit(Pieform $form, $values) {
435
    global $USER, $SESSION, $CSVDATA, $FORMAT, $UPDATES;
436

Nigel McNie's avatar
Nigel McNie committed
437
    $formatkeylookup = array_flip($FORMAT);
438

439
    $authinstance = (int) $values['authinstance'];
440 441
    $authrecord   = get_record('auth_instance', 'id', $authinstance);
    $authobj      = AuthFactory::create($authinstance);
442 443

    $institution = new Institution($authobj->institution);
444

Aaron Wells's avatar
Aaron Wells committed
445
    $maxusers = $institution->maxuseraccounts;
446 447 448 449 450 451 452 453 454 455
    if (!empty($maxusers)) {
        $members = count_records_sql('
            SELECT COUNT(*) FROM {usr} u INNER JOIN {usr_institution} i ON u.id = i.usr
            WHERE i.institution = ? AND u.deleted = 0', array($institution->name));
        if ($members + count($CSVDATA) > $maxusers) {
            $SESSION->add_error_msg(get_string('uploadcsvfailedusersexceedmaxallowed', 'admin'));
            redirect('/admin/users/uploadcsv.php');
        }
    }

456 457 458 459 460 461
    if ($values['updateusers']) {
        log_info('Updating users from the CSV file');
    }
    else {
        log_info('Inserting users from the CSV file');
    }
462 463
    db_begin();

464
    $addedusers = array();
465 466 467 468 469 470 471

    $cfgsendemail = get_config('sendemail');
    if (empty($values['emailusers'])) {
        // Temporarily disable email sent during user creation, e.g. institution membership
        $GLOBALS['CFG']->sendemail = false;
    }

472
    foreach ($CSVDATA as $record) {
473
        $user = new StdClass;
474 475 476 477 478 479 480 481 482 483 484
        foreach ($FORMAT as $field) {
            if ($field == 'username'  ||
                $field == 'firstname' ||
                $field == 'lastname'  ||
                $field == 'password'  ||
                $field == 'email'     ||
                $field == 'studentid' ||
                $field == 'preferredname') {
                $user->{$field} = $record[$formatkeylookup[$field]];
            }
        }
485
        $user->authinstance = $authinstance;
486 487 488
        if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
            $user->quota        = $values['quota'];
        }
489

490
        $profilefields = new StdClass;
Piers Harding's avatar
Piers Harding committed
491
        $remoteuser = null;
Nigel McNie's avatar
Nigel McNie committed
492 493 494 495
        foreach ($FORMAT as $field) {
            if ($field == 'username' || $field == 'password') {
                continue;
            }
Piers Harding's avatar
Piers Harding committed
496 497 498 499 500 501
            if ($field == 'remoteuser') {
                if (!empty($record[$formatkeylookup[$field]])) {
                    $remoteuser = $record[$formatkeylookup[$field]];
                }
                continue;
            }
502
            $profilefields->{$field} = $record[$formatkeylookup[$field]];
503
        }
Nigel McNie's avatar
Nigel McNie committed
504

505 506
        if (!$values['updateusers'] || !isset($UPDATES[$user->username])) {
            $user->passwordchange = (int)$values['forcepasswordchange'];
507

508
            $user->id = create_user($user, $profilefields, $institution, $authrecord, $remoteuser, $values, true);
509 510 511 512 513

            $addedusers[] = $user;
            log_debug('added user ' . $user->username);
        }
        else if (isset($UPDATES[$user->username])) {
514
            $updated = update_user($user, $profilefields, $remoteuser, $values, true, true);
515 516 517 518 519 520 521 522 523 524

            if (empty($updated)) {
                // Nothing changed for this user
                unset($UPDATES[$user->username]);
            }
            else {
                $UPDATES[$user->username] = $updated;
                log_debug('updated user ' . $user->username . ' (' . implode(', ', array_keys($updated)) . ')');
            }
        }
525
        set_time_limit(10);
526
    }
527
    db_commit();
528

529 530 531
    // Reenable email
    set_config('sendemail', $cfgsendemail);

Aaron Wells's avatar
Aaron Wells committed
532
    // Only send e-mail to users after we're sure they have been inserted
533 534 535 536 537
    // successfully
    $straccountcreatedtext = ($values['forcepasswordchange']) ? 'accountcreatedchangepasswordtext' : 'accountcreatedtext';
    $straccountcreatedhtml = ($values['forcepasswordchange']) ? 'accountcreatedchangepasswordhtml' : 'accountcreatedhtml';
    if ($values['emailusers'] && $addedusers) {
        foreach ($addedusers as $user) {
538 539
            $failedusers = array();
            try {
540 541 542
                email_user($user, null, get_string('accountcreated', 'mahara', get_config('sitename')),
                    get_string($straccountcreatedtext, 'mahara', $user->firstname, get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('sitename')),
                    get_string($straccountcreatedhtml, 'mahara', $user->firstname, get_config('wwwroot'), get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('wwwroot'), get_config('sitename'))
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
                );
            }
            catch (EmailException $e) {
                log_info($e->getMessage());
                $failedusers[] = $user;
            }
        }

        if ($failedusers) {
            $message = get_string('uploadcsvsomeuserscouldnotbeemailed', 'admin') . "\n<ul>\n";
            foreach ($failedusers as $user) {
                $message .= '<li>' . full_name($user) . ' &lt;' . hsc($user->email) . "&gt;</li>\n";
            }
            $message .= "</ul>\n";
            $SESSION->add_info_msg($message, false);
558 559 560
        }
    }

561
    log_info('Added ' . count($addedusers) . ' users, updated ' . count($UPDATES) . ' users.');
562

563 564 565 566 567 568 569 570 571 572
    $SESSION->add_ok_msg(get_string('csvfileprocessedsuccessfully', 'admin'));
    if ($UPDATES) {
        $updatemsg = smarty_core();
        $updatemsg->assign('added', count($addedusers));
        $updatemsg->assign('updates', $UPDATES);
        $SESSION->add_info_msg($updatemsg->fetch('admin/users/csvupdatemessage.tpl'), false);
    }
    else {
        $SESSION->add_ok_msg(get_string('numbernewusersadded', 'admin', count($addedusers)));
    }
573
    redirect('/admin/users/uploadcsv.php');
574 575
}

Nigel McNie's avatar
Nigel McNie committed
576 577
// Get a list of all profile fields, to inform the user on what fields they can
// put in their file.
Evonne Cheung's avatar
Evonne Cheung committed
578
$fields = "<ul class=fieldslist>\n";
579
foreach ($ALLOWEDKEYS as $type) {
Nigel McNie's avatar
Nigel McNie committed
580 581 582 583 584
    if ($type == 'firstname' || $type == 'lastname' || $type == 'email') {
        continue;
    }
    $fields .= '<li>' . hsc($type) . "</li>\n";
}
Evonne Cheung's avatar
Evonne Cheung committed
585
$fields .= "<div class=cl></div></ul>\n";
Nigel McNie's avatar
Nigel McNie committed
586

587
$uploadcsvpagedescription = get_string('uploadcsvpagedescription4', 'admin', $fields);
588

589 590
$form = pieform($form);

591
$smarty = smarty(array('adminuploadcsv'));
592
$smarty->assign('uploadcsvpagedescription', $uploadcsvpagedescription);
593
$smarty->assign('uploadcsvform', $form);
594
$smarty->assign('PAGEHEADING', TITLE);
595
$smarty->display('admin/users/uploadcsv.tpl');