edit.php 37.5 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/usersearch');
15
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
16
define('TITLE', get_string('accountsettings', 'admin'));
17
18
19
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
require_once('pieforms/pieform.php');
20
require_once('activity.php');
21
require_once(get_config('docroot') . 'lib/antispam.php');
22
23

$id = param_integer('id');
24
25
$user = new User;
$user->find_by_id($id);
26
$authobj = AuthFactory::create($user->authinstance);
27

28
if (!$USER->is_admin_for_user($user)) {
29
    $SESSION->add_error_msg(get_string('youcannotadministerthisuser', 'admin'));
30
    redirect(profile_url($user));
31
}
32

33
34
35
36
37
38
39
if ($user->deleted) {
    $smarty = smarty();
    $smarty->assign('PAGEHEADING', TITLE . ': ' . display_name($user));
    $smarty->assign('message', get_string('thisuserdeleted', 'admin'));
    $smarty->display('message.tpl');
    exit;
}
40
41

// Site-wide account settings
42
$currentdate = getdate();
Richard Mansfield's avatar
Richard Mansfield committed
43
$elements = array();
44
45
46
47
48
$elements['id'] = array(
    'type'    => 'hidden',
    'rules'   => array('integer' => true),
    'value'   => $id,
);
49

50
51
52
53
54
55
if (method_exists($authobj, 'change_username')) {
    $elements['username'] = array(
        'type'         => 'text',
        'title'        => get_string('changeusername', 'admin'),
        'description'  => get_string('changeusernamedescription', 'admin'),
        'defaultvalue' => $user->username,
56
57
58
        'rules' => array(
            'maxlength' => 236,
         ),
59
60
61
    );
}

62
63
64
if (method_exists($authobj, 'change_password')) {
    // Only show the password options if the plugin allows for the functionality
    $elements['password'] = array(
65
        'type'         => 'password',
66
67
68
69
70
        'title'        => get_string('resetpassword','admin'),
        'description'  => get_string('resetpassworddescription','admin'),
    );

    $elements['passwordchange'] = array(
71
        'type'         => 'switchbox',
72
73
74
75
76
        'title'        => get_string('forcepasswordchange','admin'),
        'description'  => get_string('forcepasswordchangedescription','admin'),
        'defaultvalue' => $user->passwordchange,
    );
}
77
78
if ($USER->get('admin')) {
    $elements['staff'] = array(
79
        'type'         => 'switchbox',
80
81
        'title'        => get_string('sitestaff','admin'),
        'defaultvalue' => $user->staff,
82
        'help'         => true,
83
84
    );
    $elements['admin'] = array(
85
        'type'         => 'switchbox',
86
87
        'title'        => get_string('siteadmin','admin'),
        'defaultvalue' => $user->admin,
88
        'help'         => true,
89
90
    );
}
91
92
93
94
95
96
97
98
99
100
$elements['email'] = array(
    'type'         => 'text',
    'title'        => get_string('primaryemail','admin'),
    'defaultvalue' => $user->email,
    'help'         => true,
    'rules'        => array(
        'required' => true,
        'email'    => true,
    ),
);
101
$elements['maildisabled'] = array(
102
    'type' => 'switchbox',
103
    'defaultvalue' => get_account_preference($user->id, 'maildisabled'),
104
    'title' => get_string('disableemail', 'admin'),
105
106
    'help' => true,
);
107
108
$elements['expiry'] = array(
    'type'         => 'date',
109
    'class'        => 'form-condensed',
110
111
112
113
114
115
    'title'        => get_string('accountexpiry', 'admin'),
    'description'  => get_string('accountexpirydescription', 'admin'),
    'minyear'      => $currentdate['year'] - 2,
    'maxyear'      => $currentdate['year'] + 20,
    'defaultvalue' => $user->expiry
);
116
$quotaused = get_string('quotaused', 'admin') . ': ' . display_size($user->quotaused);
117
118
119
if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
    $elements['quota'] = array(
        'type'         => 'bytes',
120
        'title'        => get_string('filequota1','admin'),
121
        'description'  => get_string('filequotadescription','admin') . '<br>' . $quotaused,
122
123
        'rules'        => array('integer' => true,
                                'minvalue' => 1),
124
        'class'        => 'form-inline',
125
126
127
128
129
130
131
        'defaultvalue' => $user->quota,
    );
}
else {
    $elements['quota'] = array(
        'type'         => 'text',
        'disabled'     => true,
132
        'title'        => get_string('filequota1', 'admin'),
133
        'description'  => get_string('filequotadescription', 'admin') . '<br>' . $quotaused,
134
        'class'        => 'form-inline',
135
136
137
        'value'        => display_size($user->quota),
    );
}
138

139
140
141
142
143
144
// Probation points
if (is_using_probation($user->id)) {
    $elements['probationpoints'] = array(
        'type' => 'select',
        'title' => get_string('probationtitle', 'admin'),
        'help' => true,
145
146
        'options' => probation_form_options(),
        'defaultvalue' => ensure_valid_probation_points($user->probation),
147
148
149
    );
}

150
151
152
153
$authinstances = auth_get_auth_instances();
if (count($authinstances) > 1) {
    $options = array();

154
155
156
    // NOTE: This is a little broken at the moment. The "username in the remote
    // system" setting is only actively used by the XMLRPC authentication
    // plugin, and thus only makes sense when the user is authenticating in
157
158
    // this manner.
    //
159
160
    // We hope to one day make it possible for users to get into accounts via
    // multiple methods, at which time we can tie the username-in-remote-system
161
    // setting to the XMLRPC plugin only, making the UI a bit more consistent
162
    $external = false;
163
    $externalauthjs = array();
164
    foreach ($authinstances as $authinstance) {
165
166
167
168
        // If a user has a "No Institution" auth method (institution "mahara", id = 1) and he belongs to an Institution,
        // his Institution Admin will be able to change his auth method away to one of the Institution's auth methods
        // that's the second part of the "if"
        if ($USER->can_edit_institution($authinstance->name) || ($authinstance->id == 1 && $user->authinstance == 1)) {
169
            $options[$authinstance->id] = $authinstance->displayname . ': ' . $authinstance->instancename;
170
171
            $authobj = AuthFactory::create($authinstance->id);
            if ($authobj->needs_remote_username()) {
172
                $externalauthjs[] = $authinstance->id;
173
174
                $external = true;
            }
175
        }
176
177
    }

178
179
    if (isset($options[$user->authinstance])) {
        $elements['authinstance'] = array(
180
181
            'type'         => 'select',
            'title'        => get_string('authenticatedby', 'admin'),
182
            'description'  => get_string('authenticatedbydescription', 'admin'),
183
            'options'      => $options,
184
            'defaultvalue' => $user->authinstance,
185
            'help'         => true,
186
        );
187
188
189
190
191
192
193
        $un = get_field('auth_remote_user', 'remoteusername', 'authinstance', $user->authinstance, 'localusr', $user->id);
        $elements['remoteusername'] = array(
            'type'         => 'text',
            'title'        => get_string('remoteusername', 'admin'),
            'description'  => get_string('remoteusernamedescription1', 'admin', hsc(get_config('sitename'))),
            'help'         => true,
        );
194
195
196
        if ($un) {
            $elements['remoteusername']['defaultvalue'] = $un;
        }
197
    }
198
    $remoteusernames = json_encode(get_records_menu('auth_remote_user', 'localusr', $id));
199
    $js = "<script type='application/javascript'>
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
          var externalauths = ['" . implode("','", $externalauthjs) . "'];
          var remoteusernames = " . $remoteusernames . ";
          jQuery(document).ready(function() {
          // set up initial display
          var authinstanceid = jQuery('#edituser_site_authinstance :selected').val();
          is_external(authinstanceid);

          // update display as auth method dropdown changes
          jQuery('#edituser_site_authinstance').change(function() {
              authinstanceid = jQuery('#edituser_site_authinstance :selected').val();
              is_external(authinstanceid);
          });

          function is_external(id) {
              if (jQuery.inArray(authinstanceid,externalauths) != -1) {
                  // is external option so show external auth field and help text rows
216
217
                  jQuery('#edituser_site_remoteusername_container').css('display','block');
                  jQuery('#edituser_site_remoteusername_container').next('div').css('display','block');
218
219
220
221
                  if (remoteusernames[id]) {
                      // if value exists in auth_remote_user display it
                      jQuery('#edituser_site_remoteusername').val(remoteusernames[id]);
                  }
222
223
224
                  else {
                      jQuery('#edituser_site_remoteusername').val('');
                  }
225
226
227
228
              }
              else {
                  // is internal option so hide external auth field and help text rows
                  jQuery('#edituser_site_remoteusername_container').css('display','none');
229
                  jQuery('#edituser_site_remoteusername_container').next('div').css('display','none');
230
231
232
233
234
235
236
              }
          }
      });
      </script>";

    $elements['externalauthjs'] = array(
        'type'         => 'html',
237
        'class'        => 'hidden',
238
239
        'value'        => $js,
    );
240
241
}

242
$tags = get_column_sql('SELECT tag FROM {usr_tag} WHERE usr = ? AND NOT tag ' . db_ilike() . " 'lastinstitution:%'", array($user->id));
Hugh Davenport's avatar
Hugh Davenport committed
243
244
245
246
247
248
249
250
251

$elements['tags'] = array(
    'defaultvalue' => $tags,
    'type'         => 'tags',
    'title'        => get_string('tags'),
    'description'  => get_string('tagsdesc'),
    'help'         => true,
);

252
253
$elements['submit'] = array(
    'type'  => 'submit',
254
    'class' => 'btn-primary',
255
256
257
    'value' => get_string('savechanges','admin'),
);

Richard Mansfield's avatar
Richard Mansfield committed
258
259
$siteform = pieform(array(
    'name'       => 'edituser_site',
Pat Kira's avatar
Pat Kira committed
260
    'renderer'   => 'div',
261
262
    'plugintype' => 'core',
    'pluginname' => 'admin',
263
    'class' => 'form-group-nested',
264
265
266
    'elements'   => $elements,
));

267
268
function edituser_site_validate(Pieform $form, $values) {
    global $USER, $SESSION;
269
270
271
    if (!$user = get_record('usr', 'id', $values['id'])) {
        return false;
    }
272
273
274
275
276
277
278
    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)));
            $SESSION->add_error_msg(get_string('maxquotaexceeded', 'artefact.file', display_size($maxquota)));
        }
279
    }
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
    $userobj = new User();
    $userobj = $userobj->find_by_id($user->id);

    if (isset($values['username']) && !empty($values['username']) && $values['username'] != $userobj->username) {

        if (!isset($values['authinstance'])) {
            $authobj = AuthFactory::create($userobj->authinstance);
        }
        else {
            $authobj = AuthFactory::create($values['authinstance']);
        }

        if (method_exists($authobj, 'change_username')) {

            if (method_exists($authobj, 'is_username_valid_admin')) {
                if (!$authobj->is_username_valid_admin($values['username'])) {
                    $form->set_error('username', get_string('usernameinvalidadminform', 'auth.internal'));
                }
            }
            else if (method_exists($authobj, 'is_username_valid')) {
                if (!$authobj->is_username_valid($values['username'])) {
                    $form->set_error('username', get_string('usernameinvalidform', 'auth.internal'));
                }
            }

306
            if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', array(strtolower($values['username'])))) {
307
308
309
310
311
312
313
314
                $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal'));
            }
        }
        else {
            $form->set_error('username', get_string('usernamechangenotallowed', 'admin'));
        }
    }

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Check that the external username isn't already in use by someone else
    if (isset($values['authinstance']) && isset($values['remoteusername'])) {
        // there are 4 cases for changes on the page
        // 1) ai and remoteuser have changed
        // 2) just ai has changed
        // 3) just remoteuser has changed
        // 4) the ai changes and the remoteuser is wiped - this is a delete of the old ai-remoteuser

        // determine the current remoteuser
        $current_remotename = get_field('auth_remote_user', 'remoteusername',
                                        'authinstance', $user->authinstance, 'localusr', $user->id);
        if (!$current_remotename) {
            $current_remotename = $user->username;
        }
        // what should the new remoteuser be
        $new_remoteuser = get_field('auth_remote_user', 'remoteusername',
                                    'authinstance', $values['authinstance'], 'localusr', $user->id);
        if (!$new_remoteuser) {
            $new_remoteuser = $user->username;
        }
        if (strlen(trim($values['remoteusername'])) > 0) {
            // value changed on page - use it
            if ($values['remoteusername'] != $current_remotename) {
                $new_remoteuser = $values['remoteusername'];
            }
        }

        // what really counts is who owns the target remoteuser slot
        $target_owner = get_field('auth_remote_user', 'localusr',
                                  'authinstance', $values['authinstance'], 'remoteusername', $new_remoteuser);
        // target remoteuser is owned by someone else
        if ($target_owner && $target_owner != $user->id) {
            $usedbyuser = get_field('usr', 'username', 'id', $target_owner);
            $SESSION->add_error_msg(get_string('duplicateremoteusername', 'auth', $usedbyuser));
            $form->set_error('remoteusername', get_string('duplicateremoteusernameformerror', 'auth'));
        }
351
    }
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

    // Check if the new primary email address is valid
    if (isset($values['email']) &&
        ($values['email'] !== $user->email)) {
        $email = sanitize_email($values['email']);
        if (!$form->get_error('email')) {
            if (!$form->get_error('email') && empty($email)) {
                $form->set_error('email', get_string('invalidemailaddress', 'artefact.internal'));
            }

            if (record_exists_sql('
                    SELECT id
                    FROM {usr}
                    WHERE deleted != 1 AND email = ? AND id != ?', array($email, $user->id))
                || record_exists_sql('
                    SELECT owner
                    FROM {artefact_internal_profile_email}
                    WHERE email = ? AND owner != ?', array($email, $user->id))) {
                $form->set_error('email', get_string('emailalreadytakenbyothers', 'auth.internal'));
            }
        }
    }
374
}
375

Richard Mansfield's avatar
Richard Mansfield committed
376
function edituser_site_submit(Pieform $form, $values) {
377
    global $USER, $authobj, $SESSION;
378

379
380
381
382
    if (!$user = get_record('usr', 'id', $values['id'])) {
        return false;
    }

383
384
    if (is_using_probation()) {
        // Value should be between 0 and 10 inclusive
385
        $user->probation = ensure_valid_probation_points($values['probationpoints']);
386
387
    }

388
389
    if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) {
        $user->quota = $values['quota'];
390
391
392
393
394
        // check if the user has gone over the quota notify limit
        $quotanotifylimit = get_config_plugin('artefact', 'file', 'quotanotifylimit');
        if ($quotanotifylimit <= 0 || $quotanotifylimit >= 100) {
            $quotanotifylimit = 100;
        }
395
        $user->quotausedpercent = empty($user->quota) ? 0 : ($user->quotaused / $user->quota) * 100;
396
397
398
399
400
401
402
403
404
405
406
407
408
409
        $overlimit = false;
        if ($quotanotifylimit <= $user->quotausedpercent) {
            $overlimit = true;
        }
        $notified = get_field('usr_account_preference', 'value', 'field', 'quota_exceeded_notified', 'usr', $user->id);
        if ($overlimit && '1' !== $notified) {
            require_once(get_config('docroot') . 'artefact/file/lib.php');
            ArtefactTypeFile::notify_users_threshold_exceeded(array($user), false);
            // no need to email admin as we can alert them right now
            $SESSION->add_error_msg(get_string('useroverquotathreshold', 'artefact.file', display_name($user)));
        }
        else if ($notified && !$overlimit) {
            set_account_preference($user->id, 'quota_exceeded_notified', false);
        }
410
    }
411

412
413
414
415
416
417
418
419
420
    $unexpire = $user->expiry && strtotime($user->expiry) < time() && (empty($values['expiry']) || $values['expiry'] > time());
    $newexpiry = db_format_timestamp($values['expiry']);
    if ($user->expiry != $newexpiry) {
        $user->expiry = $newexpiry;
        if ($unexpire) {
            $user->expirymailsent = 0;
            $user->lastaccess = db_format_timestamp(time());
        }
    }
421
422
423
424
425

    // Try to kick the user from any active login sessions, before saving data.
    require_once(get_config('docroot') . 'auth/session.php');
    remove_user_sessions($user->id);

426
427
428
    if ($USER->get('admin')) {  // Not editable by institutional admins
        $user->staff = (int) ($values['staff'] == 'on');
        $user->admin = (int) ($values['admin'] == 'on');
429
430
431
        if ($user->admin) {
            activity_add_admin_defaults(array($user->id));
        }
432
433
    }

434
435
436
437
    if ($values['maildisabled'] == 0 && get_account_preference($user->id, 'maildisabled') == 1) {
        // Reset the sent and bounce counts otherwise mail will be disabled
        // on the next send attempt
        $u = new StdClass;
438
439
        $u->email = $user->email;
        $u->id = $user->id;
440
441
442
443
444
        update_bounce_count($u,true);
        update_send_count($u,true);
    }
    set_account_preference($user->id, 'maildisabled', $values['maildisabled']);

445
446
447
448
449
    // process the change of the authinstance and or the remoteuser
    if (isset($values['authinstance']) && isset($values['remoteusername'])) {
        // Authinstance can be changed by institutional admins if both the
        // old and new authinstances belong to the admin's institutions
        $authinst = get_records_select_assoc('auth_instance', 'id = ? OR id = ?',
450
                                             array($values['authinstance'], $user->authinstance));
451
452
453
        // But don't bother if the auth instance doesn't take a remote username
        $authobj = AuthFactory::create($values['authinstance']);
        if (
454
455
456
457
458
459
            $USER->get('admin')
            || (
                $USER->is_institutional_admin($authinst[$values['authinstance']]->institution)
                && (
                    $USER->is_institutional_admin($authinst[$user->authinstance]->institution)
                    || $user->authinstance == 1
460
                )
461
            )
462
        ) {
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
            if ($authobj->needs_remote_username()) {
                // determine the current remoteuser
                $current_remotename = get_field('auth_remote_user', 'remoteusername',
                                                'authinstance', $user->authinstance, 'localusr', $user->id);
                if (!$current_remotename) {
                    $current_remotename = $user->username;
                }
                // if the remoteuser is empty
                if (strlen(trim($values['remoteusername'])) == 0) {
                    delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'localusr', $user->id);
                }
                // what should the new remoteuser be
                $new_remoteuser = get_field('auth_remote_user', 'remoteusername',
                                            'authinstance', $values['authinstance'], 'localusr', $user->id);
                // save the remotename for the target existence check
                $target_remotename = $new_remoteuser;
                if (!$new_remoteuser) {
                    $new_remoteuser = $user->username;
                }
                if (strlen(trim($values['remoteusername'])) > 0) {
                    // value changed on page - use it
                    if ($values['remoteusername'] != $current_remotename) {
                        $new_remoteuser = $values['remoteusername'];
                    }
                }
                // only update remote name if the input actually changed on the page  or it doesn't yet exist
                if ($current_remotename != $new_remoteuser || !$target_remotename) {
                    // only remove the ones related to this traget authinstance as we now allow multiple
                    // for dual login mechanisms
                    delete_records('auth_remote_user', 'authinstance', $values['authinstance'], 'localusr', $user->id);
                    insert_record('auth_remote_user', (object) array(
                        'authinstance'   => $values['authinstance'],
                        'remoteusername' => $new_remoteuser,
                        'localusr'       => $user->id,
                    ));
498
                }
499
            }
500
            // update the ai on the user master
501
            $user->authinstance = $values['authinstance'];
502
503
504
505
506

            // update the global $authobj to match the new authinstance
            // this is used by the password/username change methods
            // if either/both has been requested at the same time
            $authobj = AuthFactory::create($user->authinstance);
507
        }
508
    }
509

510
511
    // Only change the pw if the new auth instance allows for it
    if (method_exists($authobj, 'change_password')) {
512
        $user->passwordchange = (int) (isset($values['passwordchange']) && $values['passwordchange'] == 'on' ? 1 : 0);
513
514
515
516
517

        if (isset($values['password']) && $values['password'] !== '') {
            $userobj = new User();
            $userobj = $userobj->find_by_id($user->id);

518
519
            $user->password = $authobj->change_password($userobj, $values['password']);
            $user->salt = $userobj->salt;
520
521
522
523
524
525
526
527
528

            unset($userobj);
        }
    } else {
        // inform the user that the chosen auth instance doesn't allow password changes
        // but only if they tried changing it
        if (isset($values['password']) && $values['password'] !== '') {
            $SESSION->add_error_msg(get_string('passwordchangenotallowed', 'admin'));

529
530
531
532
            // Set empty pw with salt
            $user->password = '';
            $user->salt = auth_get_random_salt();
        }
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
    }

    if (isset($values['username']) && $values['username'] !== '') {
        $userobj = new User();
        $userobj = $userobj->find_by_id($user->id);

        if ($userobj->username != $values['username']) {
            // Only change the username if the auth instance allows for it
            if (method_exists($authobj, 'change_username')) {
                // check the existence of the chosen username
                try {
                    if ($authobj->user_exists($values['username'])) {
                        // set an error message if it is already in use
                        $SESSION->add_error_msg(get_string('usernameexists', 'account'));
                    }
                } catch (AuthUnknownUserException $e) {
                    // update the username otherwise
                    $user->username = $authobj->change_username($userobj, $values['username']);
                }
            } else {
                // inform the user that the chosen auth instance doesn't allow username changes
                $SESSION->add_error_msg(get_string('usernamechangenotallowed', 'admin'));
            }
        }
557

558
        unset($userobj);
559
    }
560

Hugh Davenport's avatar
Hugh Davenport committed
561
    db_begin();
562
563
    update_record('usr', $user);

564
565
566
    // Update user's primary email address
    set_user_primary_email($user->id, $values['email']);

Hugh Davenport's avatar
Hugh Davenport committed
567
568
    delete_records('usr_tag', 'usr', $user->id);
    if (is_array($values['tags'])) {
569
        $values['tags'] = check_case_sensitive($values['tags'], 'usr_tag');
Hugh Davenport's avatar
Hugh Davenport committed
570
571
572
573
574
575
576
577
578
579
580
581
582
583
        foreach(array_unique($values['tags']) as $tag) {
            if (empty($tag)) {
                continue;
            }
            insert_record(
                'usr_tag',
                (object) array(
                    'usr' => $user->id,
                    'tag' => strtolower($tag),
                )
            );
        }
    }
    db_commit();
584

585
    $SESSION->add_ok_msg(get_string('usersitesettingschanged', 'admin'));
586
587
588
589
    redirect('/admin/users/edit.php?id='.$user->id);
}


590
591
592
593
594
595
596
597
598
599
600
601
602
603
// Suspension/deletion controls
$suspended = $user->get('suspendedcusr');
if (empty($suspended)) {
    $suspendform = pieform(array(
        'name'       => 'edituser_suspend',
        'plugintype' => 'core',
        'pluginname' => 'admin',
        'elements'   => array(
            'id' => array(
                 'type'    => 'hidden',
                 'value'   => $id,
            ),
            'reason' => array(
                'type'        => 'textarea',
604
                'class'       => 'under-label',
605
                'rows'        => 5,
606
                'cols'        => 28,
607
608
609
610
611
                'title'       => get_string('reason'),
                'description' => get_string('suspendedreasondescription', 'admin'),
            ),
            'submit' => array(
                'type'  => 'submit',
612
                'class' => 'btn-default',
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
                'value' => get_string('suspenduser','admin'),
            ),
        )
    ));
}
else {
    $suspendformdef = array(
        'name'       => 'edituser_unsuspend',
        'plugintype' => 'core',
        'pluginname' => 'admin',
        'renderer'   => 'oneline',
        'elements'   => array(
            'id' => array(
                 'type'    => 'hidden',
                 'value'   => $id,
            ),
            'submit' => array(
                'type'  => 'submit',
631
                'class' => 'btn-default',
632
633
634
635
636
                'value' => get_string('unsuspenduser','admin'),
            ),
        )
    );

637
638
    // Create two forms for unsuspension - one in the suspend message and the
    // other where the 'suspend' button normally goes. This keeps the HTML IDs
639
640
641
642
643
644
645
    // unique
    $suspendform  = pieform($suspendformdef);
    $suspendformdef['name'] = 'edituser_suspend2';
    $suspendformdef['successcallback'] = 'edituser_unsuspend_submit';
    $suspendform2 = pieform($suspendformdef);

    $suspender = display_name(get_record('usr', 'id', $suspended));
646
    $suspendedtime = format_date($user->get('suspendedctime'), 'strftimedate');
647
648
649
}

function edituser_suspend_submit(Pieform $form, $values) {
650
651
652
653
654
655
656
657
658
    global $SESSION, $USER, $user;
    if (!$USER->get('admin') && ($user->get('admin') || $user->get('staff'))) {
        $SESSION->add_error_msg(get_string('errorwhilesuspending', 'admin'));
    }
    else {
        suspend_user($user->get('id'), $values['reason']);
        $SESSION->add_ok_msg(get_string('usersuspended', 'admin'));
    }
    redirect('/admin/users/edit.php?id=' . $user->get('id'));
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
}

function edituser_unsuspend_submit(Pieform $form, $values) {
    global $SESSION;
    unsuspend_user($values['id']);
    $SESSION->add_ok_msg(get_string('userunsuspended', 'admin'));
    redirect('/admin/users/edit.php?id=' . $values['id']);
}

$deleteform = pieform(array(
    'name' => 'edituser_delete',
    'plugintype' => 'core',
    'pluginname' => 'admin',
    'renderer' => 'oneline',
    'elements'   => array(
        'id' => array(
            'type' => 'hidden',
            'value' => $id,
        ),
        'submit' => array(
679
680
            'type' => 'button',
            'usebuttontag' => true,
681
            'class' => 'btn-default',
682
            'value'          => '<span class="icon icon-trash icon-lg text-danger left"></span><span>'. get_string('deleteuser', 'admin') . '</span>',
683
684
685
686
687
            'confirm' => get_string('confirmdeleteuser', 'admin'),
        ),
    ),
));

688
689
690
691
692
693
function edituser_delete_validate(Pieform $form, $values) {
    global $USER, $SESSION;
    if (!$USER->get('admin')) {
        $form->set_error('submit', get_string('deletefailed', 'admin'));
        $SESSION->add_error_msg(get_string('deletefailed', 'admin'));
    }
694
695
696
697
698
699
    // Check to see if there are any pending archives in the export_queue for this user.
    // We can't delete them if there are.
    if ($results = count_records('export_queue', 'usr', $values['id'])) {
        $form->set_error('submit', get_string('deletefailed', 'admin'));
        $SESSION->add_error_msg(get_string('exportqueuenotempty', 'export'));
    }
700
701
}

702
function edituser_delete_submit(Pieform $form, $values) {
703
704
705
706
707
    global $SESSION, $USER;
    if ($USER->get('admin')) {
        delete_user($values['id']);
        $SESSION->add_ok_msg(get_string('userdeletedsuccessfully', 'admin'));
    }
708
709
710
    redirect('/admin/users/search.php');
}

Richard Mansfield's avatar
Richard Mansfield committed
711

712
// Institution settings form
Richard Mansfield's avatar
Richard Mansfield committed
713
714
715
716
717
718
719
$elements = array(
    'id' => array(
         'type'    => 'hidden',
         'value'   => $id,
     ),
);

720
721
722
723
724
725
726
727
728
729
730
function is_institute_admin($institution) {
    return $institution->admin;
}

$institutions = $user->get('institutions');
if ( !$USER->get('admin') ) { // for institution admins
    $admin_institutions = $USER->get('institutions');
    $admin_institutions = array_filter($admin_institutions, "is_institute_admin");
    $institutions = array_intersect_key($institutions, $admin_institutions);
}

731
$allinstitutions = get_records_assoc('institution', '', '', 'displayname', 'name, displayname');
732
733
$institutionloop = 0;
$institutionlength = count($institutions);
734
foreach ($institutions as $i) {
735
736
    $elements[$i->institution.'_settings'] = array(
        'type' => 'fieldset',
737
738
739
        'legend' => get_string('institutionsettings', 'admin').' - '.$i->displayname,
        'collapsible'  => true,
        'collapsed'    => true,
740
741
742
        'elements' => array(
            $i->institution.'_expiry' => array(
                'type'         => 'date',
743
744
                'title'        => get_string('membershipexpiry', 'admin'),
                'description'  => get_string('membershipexpirydescription', 'admin'),
745
                'class'        => 'form-condensed',
746
747
                'minyear'      => $currentdate['year'],
                'maxyear'      => $currentdate['year'] + 20,
748
                'defaultvalue' => $i->membership_expiry
749
750
751
            ),
            $i->institution.'_studentid' => array(
                'type'         => 'text',
752
753
                'title'        => get_string('studentid', 'admin'),
                'description'  => get_string('institutionstudentiddescription', 'admin'),
754
755
                'defaultvalue' => $i->studentid,
            ),
756
            $i->institution.'_staff' => array(
757
                'type'         => 'switchbox',
758
759
                'title'        => get_string('institutionstaff','admin'),
                'defaultvalue' => $i->staff,
760
            ),
761
            $i->institution.'_admin' => array(
762
                'type'         => 'switchbox',
763
                'title'        => get_string('institutionadmin','admin'),
764
                'description'  => get_string('institutionadmindescription1','admin'),
765
766
767
768
769
                'defaultvalue' => $i->admin,
            ),
            $i->institution.'_submit' => array(
                'type'  => 'submit',
                'value' => get_string('update'),
770
                'class' => 'btn-primary'
771
            ),
772
773
            $i->institution.'_remove' => array(
                'type'  => 'submit',
774
                'class' => 'btn-default',
775
776
                'value' => get_string('removeuserfrominstitution', 'admin'),
                'confirm' => get_string('confirmremoveuserfrominstitution', 'admin'),
777
778
            )
        )
Richard Mansfield's avatar
Richard Mansfield committed
779
    );
780
    if ($institutionloop == $institutionlength - 1) {
781
        $elements[$i->institution.'_settings']['class'] = 'last';
782
783
    }
    $institutionloop++;
Richard Mansfield's avatar
Richard Mansfield committed
784
}
785

786
// Only site admins can add institutions; institutional admins must invite
787
if ($USER->get('admin')
788
789
790
791
792
793
794
795
    && (get_config('usersallowedmultipleinstitutions') || count($user->institutions) == 0)) {
    $options = array();
    foreach ($allinstitutions as $i) {
        if (!$user->in_institution($i->name) && $i->name != 'mahara') {
            $options[$i->name] = $i->displayname;
        }
    }
    if (!empty($options)) {
796
797
        $elements['addinstitutionheader'] = array(
            'type'  => 'markup',
798
            'value' => '<h4>' . get_string('addusertoinstitution', 'admin') . '</h4>',
799
        );
800
801
        $elements['addinstitution'] = array(
            'type'         => 'select',
802
            'title'        => get_string('institution'),
803
804
805
806
            'options'      => $options,
        );
        $elements['add'] = array(
            'type'  => 'submit',
807
            'class' => 'btn-primary',
808
            'value' => get_string('addusertoinstitution', 'admin'),
809
810
811
812
        );
    }
}

Richard Mansfield's avatar
Richard Mansfield committed
813
814
$institutionform = pieform(array(
    'name'       => 'edituser_institution',
Pat Kira's avatar
Pat Kira committed
815
    'renderer'   => 'div',
Richard Mansfield's avatar
Richard Mansfield committed
816
817
818
819
820
    'plugintype' => 'core',
    'pluginname' => 'admin',
    'elements'   => $elements,
));

821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
function edituser_institution_validate(Pieform $form, $values) {
    $user = new User;
    if (!$user->find_by_id($values['id'])) {
        return false;
    }
    global $USER;

    $userinstitutions = $user->get('institutions');
    if (isset($values['add']) && $USER->get('admin')
        && (empty($userinstitutions) || get_config('usersallowedmultipleinstitutions'))) {
        // check if the institution is full
        require_once(get_config('docroot') . 'lib/institution.php');
        $institution = new Institution($values['addinstitution']);
        if ($institution->isFull()) {
            $institution->send_admin_institution_is_full_message();
            $form->set_error(null,get_string('institutionmaxusersexceeded', 'admin'));
        }
    }
}

Richard Mansfield's avatar
Richard Mansfield committed
841
function edituser_institution_submit(Pieform $form, $values) {
842
843
    $user = new User;
    if (!$user->find_by_id($values['id'])) {
Richard Mansfield's avatar
Richard Mansfield committed
844
845
        return false;
    }
846
    $userinstitutions = $user->get('institutions');
Richard Mansfield's avatar
Richard Mansfield committed
847

848
    global $USER, $SESSION;
849
    foreach ($userinstitutions as $i) {
Richard Mansfield's avatar
Richard Mansfield committed
850
        if ($USER->can_edit_institution($i->institution)) {
851
852
853
854
            if (isset($values[$i->institution.'_submit'])) {
                $newuser = (object) array(
                    'usr'         => $user->id,
                    'institution' => $i->institution,
855
                    'ctime'       => db_format_timestamp($i->ctime),
856
                    'studentid'   => $values[$i->institution . '_studentid'],
857
                    'staff'       => (int) ($values[$i->institution . '_staff'] == 'on'),
858
859
860
861
862
863
864
865
                    'admin'       => (int) ($values[$i->institution . '_admin'] == 'on'),
                );
                if ($values[$i->institution . '_expiry']) {
                    $newuser->expiry = db_format_timestamp($values[$i->institution . '_expiry']);
                }
                db_begin();
                delete_records('usr_institution', 'usr', $user->id, 'institution', $i->institution);
                insert_record('usr_institution', $newuser);
866
867
868
                if ($newuser->admin) {
                    activity_add_admin_defaults(array($user->id));
                }
869
870
                handle_event('updateuser', $user->id);
                db_commit();
871
                $SESSION->add_ok_msg(get_string('userinstitutionupdated', 'admin', $i->displayname));
872
                break;
873
874
            }
            else if (isset($values[$i->institution.'_remove'])) {
875
876
                if ($user->id == $USER->id) {
                    $USER->leave_institution($i->institution);
877
878
                }
                else {
879
880
                    $user->leave_institution($i->institution);
                }
881
                $SESSION->add_ok_msg(get_string('userinstitutionremoved', 'admin', $i->displayname));
882
883
884
885
                // Institutional admins can no longer access this page
                // if they remove the user from the institution, so
                // send them back to user search.
                if (!$USER->get('admin')) {
886
887
888
                    if (!$USER->is_institutional_admin()) {
                        redirect(get_config('wwwroot'));
                    }
889
890
891
892
893
                    redirect('/admin/users/search.php');
                }
                break;
            }
        }
894
895
    }

896
897
    if (isset($values['add']) && $USER->get('admin')
        && (empty($userinstitutions) || get_config('usersallowedmultipleinstitutions'))) {
898
899
900
        if ($user->id == $USER->id) {
            $USER->join_institution($values['addinstitution']);
            $USER->commit();
901
            $userinstitutions = $USER->get('institutions');
902
903
904
        }
        else {
            $user->join_institution($values['addinstitution']);
905
            $userinstitutions = $user->get('institutions');
906
        }
907
        $SESSION->add_ok_msg(get_string('userinstitutionjoined', 'admin', $userinstitutions[$values['addinstitution']]->displayname));
Richard Mansfield's avatar
Richard Mansfield committed
908
909
910
911
    }

    redirect('/admin/users/edit.php?id='.$user->id);
}
912
913
914

$smarty = smarty();
$smarty->assign('user', $user);
915
916
$smarty->assign('suspended', $suspended);
if ($suspended) {
917
    $smarty->assign('suspendedby', get_string('suspendedinfo', 'admin', $suspender, $suspendedtime));
918
}
919
$smarty->assign('suspendform', $suspendform);
920
921
922
923
if (isset($suspendform2)) {
    $smarty->assign('suspendform2', $suspendform2);
}
$smarty->assign('deleteform', $deleteform);
Richard Mansfield's avatar
Richard Mansfield committed
924
$smarty->assign('siteform', $siteform);
925
$smarty->assign('institutions', count($allinstitutions) > 1);
Richard Mansfield's avatar
Richard Mansfield committed
926
$smarty->assign('institutionform', $institutionform);
Richard Mansfield's avatar
Richard Mansfield committed
927

928
$smarty->assign('loginas', $id != $USER->get('id') && is_null($USER->get('parentuser')));
929
$smarty->assign('PAGEHEADING', TITLE . ': ' . display_name($user));
930
931
932
933
934
935
936
937
938

# Only allow deletion and suspension of a user if the viewed user is not
# the current user; or if they are the current user, they're not the only
# admin
if ($id != $USER->get('id') || count_records('usr', 'admin', 1, 'deleted', 0) > 1) {
    $smarty->assign('suspendable', ($USER->get('admin') || !$user->get('admin') && !$user->get('staff')));
    $smarty->assign('deletable', $USER->get('admin'));
}

939
$smarty->display('admin/users/edit.tpl');