bulk.php 12.4 KB
Newer Older
1
2
3
4
5
6
<?php
/**
 *
 * @package    mahara
 * @subpackage admin
 * @author     Richard Mansfield
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
13
 *
 */

define('INTERNAL', 1);
define('INSTITUTIONALADMIN', 1);
14
15
define('MENUITEM', 'configusers/usersearch');
define('SECTION_PAGE', 'bulkedit');
16
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
17
require_once(get_config('docroot') . 'lib/antispam.php');
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

define('TITLE', get_string('bulkactions', 'admin'));

$userids = array_map('intval', param_variable('users'));

$ph = $userids;
$institutionsql = '';

if (!$USER->get('admin')) {
    // Filter the users by the admin's institutions
    $institutions = array_values($USER->get('admininstitutions'));
    $ph = array_merge($ph, $institutions);
    $institutionsql = '
            AND id IN (
                SELECT usr FROM {usr_institution} WHERE institution IN (' . join(',', array_fill(0, count($institutions), '?')) . ')
            )';
}

$users = get_records_sql_assoc('
    SELECT
        u.id, u.username, u.email, u.firstname, u.lastname, u.suspendedcusr, u.authinstance, u.studentid,
39
40
        u.preferredname, CHAR_LENGTH(u.password) AS haspassword, aru.remoteusername AS remoteuser, u.lastlogin,
        u.probation
41
42
43
44
45
46
47
48
    FROM {usr} u
        LEFT JOIN {auth_remote_user} aru ON u.id = aru.localusr AND u.authinstance = aru.authinstance
    WHERE id IN (' . join(',', array_fill(0, count($userids), '?')) . ')
        AND deleted = 0' . $institutionsql . '
    ORDER BY username',
    $ph
);

49
50
51
52
if (empty($users)) {
    // None of the userids are valid
    throw new InvalidArgumentException("Trying to access invalid user(s)");
}
53
54
55
56
57
58
59
// Display the number of users filtered out due to institution permissions.  This is not an
// exception, because the logged in user might be an admin in one institution, and staff in
// another.
if ($uneditableusers = count($userids) - count($users)) {
    $SESSION->add_info_msg(get_string('uneditableusers', 'admin', $uneditableusers));
}

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
$userids = array_keys($users);

// Hidden drop-down to submit the list of users back to this page.
// Used in all three forms
$userelement = array(
    'type'     => 'select',
    'class'    => 'hidden',
    'multiple' => 'true',
    'options'  => array_combine($userids, $userids),
    'value'    => $userids,
);

// Change authinstance
if ($USER->get('admin')) {
    $authinstances = auth_get_auth_instances();
}
else {
    $admininstitutions = $USER->get('admininstitutions');
    $authinstances = auth_get_auth_instances_for_institutions($admininstitutions);
}

$options = array();
$default = null;
foreach ($authinstances as $authinstance) {
    $options[$authinstance->id] = $authinstance->displayname. ': '.$authinstance->instancename;
    if (!$default && $authinstance->name == 'mahara') {
        $default = $authinstance->id;
    }
}

90
91
92
// Suspend users
$suspendform = pieform(array(
    'name'     => 'suspend',
Naomi Guyer's avatar
Naomi Guyer committed
93
94
    'class'    => 'bulkactionform form-inline form-as-button',
    'renderer' => 'div',
95
96
    'elements' => array(
        'users' => $userelement,
Naomi Guyer's avatar
Naomi Guyer committed
97
98
99
100
101
102
103
104
105
106
107
108
        'suspendgroup' => array(
            'type' => 'fieldset',
            'class' => 'input-group',
            'elements' => array (
                'reason' => array(
                    'type'        => 'text',
                    'class'       => 'input-small',
                    'title'       => get_string('suspendedreason', 'admin') . ': ',
                ),
                'suspend' => array(
                    'type'        => 'button',
                    'usebuttontag' => true,
109
                    'class'       => 'btn-default input-group-btn no-label',
Naomi Guyer's avatar
Naomi Guyer committed
110
111
112
113
                    'value'       => get_string('Suspend', 'admin'),
                )
            )
        )
114
115
116
117
    ),
));

// Change authentication method
118
119
120
121
$changeauthform = null;
if (count($options) > 1) {
    $changeauthform = pieform(array(
        'name'           => 'changeauth',
Naomi Guyer's avatar
Naomi Guyer committed
122
123
        'class'          => 'bulkactionform form-inline form-as-button',
        'renderer'       => 'div',
124
125
126
        'dieaftersubmit' => false,
        'elements'       => array(
            'users' => $userelement,
Naomi Guyer's avatar
Naomi Guyer committed
127
128
129
130
131
132
133
134
135
136
137
138
            'authgroup' => array(
                'type' => 'fieldset',
                'class' => 'input-group',
                'elements' => array (
                    'authinstance' => array(
                        'type'         => 'select',
                        'options'      => $options,
                        'defaultvalue' => $default,
                    ),
                    'changeauth' => array(
                        'type'        => 'button',
                        'usebuttontag' => true,
139
                        'class'       => 'btn-default input-group-btn',
Naomi Guyer's avatar
Naomi Guyer committed
140
141
142
143
                        'value'        => get_string('changeauthmethod', 'admin')
                    )
                )
            )
144
        ),
145
146
    ));
}
147

148
149
150
151
152
// Set probation points
$probationform = null;
if (is_using_probation()) {
    $probationform = pieform(array(
        'name' => 'probation',
Naomi Guyer's avatar
Naomi Guyer committed
153
154
        'class' => 'bulkactionform form-inline form-as-button',
        'renderer' => 'div',
155
156
        'elements' => array(
            'users' => $userelement,
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
            'spamgroup' => array(
                'type' => 'fieldset',
                'class' => 'input-group',
                'elements' => array (
                    'probationpoints' => array(
                        'type' => 'select',
                        'title' => get_string('probationbulksetspamprobation', 'admin') . ': ',
                        'options' => probation_form_options(),
                        'defaultvalue' => '0',
                    ),
                    'setprobation' => array(
                        'type' => 'button',
                        'usebuttontag' => true,
                        'class'       => 'btn-default input-group-btn no-label',
                        'confirm' => get_string('probationbulkconfirm', 'admin'),
                        'value' => get_string('probationbulkset', 'admin'),
                    )
                )
175
            )
176
        ),
177
178
    ));
}
179
180
181
182

// Delete users
$deleteform = pieform(array(
    'name'     => 'delete',
Naomi Guyer's avatar
Naomi Guyer committed
183
184
    'class'    => 'bulkactionform delete form-inline form-as-button',
    'renderer' => 'div',
185
186
187
    'elements' => array(
        'users' => $userelement,
        'delete' => array(
Naomi Guyer's avatar
Naomi Guyer committed
188
189
            'type'        => 'button',
            'usebuttontag' => true,
190
            'class'       => 'btn-default',
191
            'confirm'     => get_string('confirmdeleteusers', 'admin'),
192
            'value'       => '<span class="icon icon-lg icon-user-times left text-danger" role="presentation" aria-hidden="true"></span>' . get_string('deleteusers', 'admin'),
193
194
195
196
197
198
199
200
201
        ),
    ),
));

$smarty = smarty();
$smarty->assign('users', $users);
$smarty->assign('changeauthform', $changeauthform);
$smarty->assign('suspendform', $suspendform);
$smarty->assign('deleteform', $deleteform);
202
$smarty->assign('probationform', $probationform);
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
$smarty->display('admin/users/bulk.tpl');

function changeauth_validate(Pieform $form, $values) {
    global $userids, $SESSION;

    // Make sure all users are members of the institution that
    // this authinstance belongs to.
    $authobj = AuthFactory::create($values['authinstance']);

    if ($authobj->institution != 'mahara') {
        $ph = $userids;
        $ph[] = $authobj->institution;
        $institutionusers = count_records_sql('
            SELECT COUNT(usr)
            FROM {usr_institution}
            WHERE usr IN (' . join(',', array_fill(0, count($userids), '?')) . ') AND institution = ?',
            $ph
        );
        if ($institutionusers != count($userids)) {
            $SESSION->add_error_msg(get_string('someusersnotinauthinstanceinstitution', 'admin'));
            $form->set_error('authinstance', get_string('someusersnotinauthinstanceinstitution', 'admin'));
        }
    }
}

function changeauth_submit(Pieform $form, $values) {
229
    global $users, $SESSION, $authinstances, $USER;
230
231
232
233
234
235
236
237
238

    $newauth = AuthFactory::create($values['authinstance']);
    $needspassword = method_exists($newauth, 'change_password');

    $updated = 0;
    $needpassword = 0;

    db_begin();

239
240
241
242
243
244
    $newauthinst = get_records_select_assoc('auth_instance', 'id = ?', array($values['authinstance']));
    if ($USER->get('admin') || $USER->is_institutional_admin($newauthinst[$values['authinstance']]->institution)) {
        foreach ($users as $user) {
            if ($user->authinstance != $values['authinstance']) {
                // Authinstance can be changed by institutional admins if both the
                // old and new authinstances belong to the admin's institutions
Aaron Wells's avatar
Aaron Wells committed
245
246
                $authinst = get_field('auth_instance', 'institution', 'id', $user->authinstance);
                if ($USER->get('admin') || $USER->is_institutional_admin($authinst)) {
247
248
249
250
251
252
253
                    // determine the current remoteusername
                    $current_remotename = get_field('auth_remote_user', 'remoteusername',
                                                    'authinstance', $user->authinstance, 'localusr', $user->id);
                    if (!$current_remotename) {
                        $current_remotename = $user->username;
                    }
                    // remove row if new authinstance row already exists to avoid doubleups
Aaron Wells's avatar
Aaron Wells committed
254
                    delete_records('auth_remote_user', 'authinstance', $values['authinstance'], 'localusr', $user->id);
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
                    insert_record('auth_remote_user', (object) array(
                        'authinstance'   => $values['authinstance'],
                        'remoteusername' => $current_remotename,
                        'localusr'       => $user->id,
                    ));
                }

                if ($user->haspassword && !$needspassword) {
                    $user->password = '';
                }
                else if ($needspassword && !$user->haspassword) {
                    $needpassword++;
                }

                $user->authinstance = $values['authinstance'];
                update_record('usr', $user, 'id');
                $updated++;
272
273
274
275
276
277
278
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
            }
        }
    }

    db_commit();

    if ($needpassword) {
        // Inform the user that they may need to reset passwords
        $SESSION->add_info_msg(get_string('bulkchangeauthmethodresetpassword', 'admin', $needpassword));
    }
    $message = get_string('bulkchangeauthmethodsuccess', 'admin', $updated);
    $form->reply(PIEFORM_OK, array('message' => $message));
}

function suspend_submit(Pieform $form, $values) {
    global $users, $SESSION;

    $suspended = 0;

    db_begin();

    foreach ($users as $user) {
        if (!$user->suspendedcusr) {
            suspend_user($user->id, $values['reason']);
            $suspended++;
        }
    }

    db_commit();

    $SESSION->add_ok_msg(get_string('bulksuspenduserssuccess', 'admin', $suspended));
    redirect('/admin/users/suspended.php');
}

306
307
308
309
310
function delete_validate(Pieform $form, $values) {
    global $SESSION, $USER;
    $users = $values['users'];
    // Not allowed to bulk delete yourself
    if (is_array($users) && in_array($USER->get('id'), $users)) {
311
        $form->set_error(null, get_string('unabletodeleteself1', 'admin'));
312
313
    }
    // Not allowed to remove all site admins
314
315
    $siteadmins = count_records_sql("SELECT COUNT(\"admin\") FROM {usr}
                           WHERE id NOT IN (" . join(',', array_map('db_quote', $users)) . ") AND \"admin\" = 1", array());
316
    if (!$siteadmins) {
317
        $form->set_error(null, get_string('unabletodeletealladmins1', 'admin'));
318
319
320
    }
}

321
322
323
324
325
326
327
328
329
330
331
332
333
334
function delete_submit(Pieform $form, $values) {
    global $users, $editable, $SESSION;

    db_begin();

    foreach ($users as $user) {
        delete_user($user->id);
    }

    db_commit();

    $SESSION->add_ok_msg(get_string('bulkdeleteuserssuccess', 'admin', count($users)));
    redirect('/admin/users/search.php');
}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

function probation_submit(Pieform $form, $values) {
    global $SESSION, $users;

    $newpoints = ensure_valid_probation_points($values['probationpoints']);
    $paramlist = array($newpoints);

    $sql = '';
    foreach ($users as $user) {
        $paramlist[] = $user->id;
        $sql .= '?,';
    }
    // Drop the last comma
    $sql = substr($sql, 0, -1);

    execute_sql('update {usr} set probation = ? where id in (' . $sql . ')', $paramlist);

    $SESSION->add_ok_msg(get_string('bulkprobationpointssuccess', 'admin', count($users), $newpoints));
    redirect('/admin/users/search.php');
}