1 | <?php |
---|
2 | |
---|
3 | require_once('../config.php'); |
---|
4 | require_once($CFG->libdir.'/adminlib.php'); |
---|
5 | require_once($CFG->libdir.'/authlib.php'); |
---|
6 | require_once($CFG->dirroot.'/user/filters/lib.php'); |
---|
7 | require_once($CFG->dirroot.'/user/lib.php'); |
---|
8 | |
---|
9 | $delete = optional_param('delete', 0, PARAM_INT); |
---|
10 | $confirm = optional_param('confirm', '', PARAM_ALPHANUM); //md5 confirmation hash |
---|
11 | $confirmuser = optional_param('confirmuser', 0, PARAM_INT); |
---|
12 | $sort = optional_param('sort', 'name', PARAM_ALPHANUM); |
---|
13 | $dir = optional_param('dir', 'ASC', PARAM_ALPHA); |
---|
14 | $page = optional_param('page', 0, PARAM_INT); |
---|
15 | $perpage = optional_param('perpage', 30, PARAM_INT); // how many per page |
---|
16 | $ru = optional_param('ru', '2', PARAM_INT); // show remote users |
---|
17 | $lu = optional_param('lu', '2', PARAM_INT); // show local users |
---|
18 | $acl = optional_param('acl', '0', PARAM_INT); // id of user to tweak mnet ACL (requires $access) |
---|
19 | $suspend = optional_param('suspend', 0, PARAM_INT); |
---|
20 | $unsuspend = optional_param('unsuspend', 0, PARAM_INT); |
---|
21 | $unlock = optional_param('unlock', 0, PARAM_INT); |
---|
22 | |
---|
23 | admin_externalpage_setup('editusers'); |
---|
24 | |
---|
25 | $sitecontext = context_system::instance(); |
---|
26 | $site = get_site(); |
---|
27 | |
---|
28 | if (!has_capability('moodle/user:update', $sitecontext) and !has_capability('moodle/user:delete', $sitecontext)) { |
---|
29 | print_error('nopermissions', 'error', '', 'edit/delete users'); |
---|
30 | } |
---|
31 | |
---|
32 | $stredit = get_string('edit'); |
---|
33 | $strdelete = get_string('delete'); |
---|
34 | $strdeletecheck = get_string('deletecheck'); |
---|
35 | $strshowallusers = get_string('showallusers'); |
---|
36 | $strsuspend = get_string('suspenduser', 'admin'); |
---|
37 | $strunsuspend = get_string('unsuspenduser', 'admin'); |
---|
38 | $strunlock = get_string('unlockaccount', 'admin'); |
---|
39 | $strconfirm = get_string('confirm'); |
---|
40 | |
---|
41 | if (empty($CFG->loginhttps)) { |
---|
42 | $securewwwroot = $CFG->wwwroot; |
---|
43 | } else { |
---|
44 | $securewwwroot = str_replace('http:','https:',$CFG->wwwroot); |
---|
45 | } |
---|
46 | |
---|
47 | $returnurl = new moodle_url('/admin/user.php', array('sort' => $sort, 'dir' => $dir, 'perpage' => $perpage, 'page'=>$page)); |
---|
48 | |
---|
49 | // The $user variable is also used outside of these if statements. |
---|
50 | $user = null; |
---|
51 | if ($confirmuser and confirm_sesskey()) { |
---|
52 | require_capability('moodle/user:update', $sitecontext); |
---|
53 | if (!$user = $DB->get_record('user', array('id'=>$confirmuser, 'mnethostid'=>$CFG->mnet_localhost_id))) { |
---|
54 | print_error('nousers'); |
---|
55 | } |
---|
56 | |
---|
57 | $auth = get_auth_plugin($user->auth); |
---|
58 | |
---|
59 | $result = $auth->user_confirm($user->username, $user->secret); |
---|
60 | |
---|
61 | if ($result == AUTH_CONFIRM_OK or $result == AUTH_CONFIRM_ALREADY) { |
---|
62 | redirect($returnurl); |
---|
63 | } else { |
---|
64 | echo $OUTPUT->header(); |
---|
65 | redirect($returnurl, get_string('usernotconfirmed', '', fullname($user, true))); |
---|
66 | } |
---|
67 | |
---|
68 | } else if ($delete and confirm_sesskey()) { // Delete a selected user, after confirmation |
---|
69 | require_capability('moodle/user:delete', $sitecontext); |
---|
70 | |
---|
71 | $user = $DB->get_record('user', array('id'=>$delete, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST); |
---|
72 | |
---|
73 | if (is_siteadmin($user->id)) { |
---|
74 | print_error('useradminodelete', 'error'); |
---|
75 | } |
---|
76 | |
---|
77 | if ($confirm != md5($delete)) { |
---|
78 | echo $OUTPUT->header(); |
---|
79 | $fullname = fullname($user, true); |
---|
80 | echo $OUTPUT->heading(get_string('deleteuser', 'admin')); |
---|
81 | $optionsyes = array('delete'=>$delete, 'confirm'=>md5($delete), 'sesskey'=>sesskey()); |
---|
82 | echo $OUTPUT->confirm(get_string('deletecheckfull', '', "'$fullname'"), new moodle_url($returnurl, $optionsyes), $returnurl); |
---|
83 | echo $OUTPUT->footer(); |
---|
84 | die; |
---|
85 | } else if (data_submitted() and !$user->deleted) { |
---|
86 | if (delete_user($user)) { |
---|
87 | \core\session\manager::gc(); // Remove stale sessions. |
---|
88 | redirect($returnurl); |
---|
89 | } else { |
---|
90 | \core\session\manager::gc(); // Remove stale sessions. |
---|
91 | echo $OUTPUT->header(); |
---|
92 | echo $OUTPUT->notification($returnurl, get_string('deletednot', '', fullname($user, true))); |
---|
93 | } |
---|
94 | } |
---|
95 | } else if ($acl and confirm_sesskey()) { |
---|
96 | if (!has_capability('moodle/user:update', $sitecontext)) { |
---|
97 | print_error('nopermissions', 'error', '', 'modify the NMET access control list'); |
---|
98 | } |
---|
99 | if (!$user = $DB->get_record('user', array('id'=>$acl))) { |
---|
100 | print_error('nousers', 'error'); |
---|
101 | } |
---|
102 | if (!is_mnet_remote_user($user)) { |
---|
103 | print_error('usermustbemnet', 'error'); |
---|
104 | } |
---|
105 | $accessctrl = strtolower(required_param('accessctrl', PARAM_ALPHA)); |
---|
106 | if ($accessctrl != 'allow' and $accessctrl != 'deny') { |
---|
107 | print_error('invalidaccessparameter', 'error'); |
---|
108 | } |
---|
109 | $aclrecord = $DB->get_record('mnet_sso_access_control', array('username'=>$user->username, 'mnet_host_id'=>$user->mnethostid)); |
---|
110 | if (empty($aclrecord)) { |
---|
111 | $aclrecord = new stdClass(); |
---|
112 | $aclrecord->mnet_host_id = $user->mnethostid; |
---|
113 | $aclrecord->username = $user->username; |
---|
114 | $aclrecord->accessctrl = $accessctrl; |
---|
115 | $DB->insert_record('mnet_sso_access_control', $aclrecord); |
---|
116 | } else { |
---|
117 | $aclrecord->accessctrl = $accessctrl; |
---|
118 | $DB->update_record('mnet_sso_access_control', $aclrecord); |
---|
119 | } |
---|
120 | $mnethosts = $DB->get_records('mnet_host', null, 'id', 'id,wwwroot,name'); |
---|
121 | redirect($returnurl); |
---|
122 | |
---|
123 | } else if ($suspend and confirm_sesskey()) { |
---|
124 | require_capability('moodle/user:update', $sitecontext); |
---|
125 | |
---|
126 | if ($user = $DB->get_record('user', array('id'=>$suspend, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) { |
---|
127 | if (!is_siteadmin($user) and $USER->id != $user->id and $user->suspended != 1) { |
---|
128 | $user->suspended = 1; |
---|
129 | // Force logout. |
---|
130 | \core\session\manager::kill_user_sessions($user->id); |
---|
131 | user_update_user($user, false); |
---|
132 | } |
---|
133 | } |
---|
134 | redirect($returnurl); |
---|
135 | |
---|
136 | } else if ($unsuspend and confirm_sesskey()) { |
---|
137 | require_capability('moodle/user:update', $sitecontext); |
---|
138 | |
---|
139 | if ($user = $DB->get_record('user', array('id'=>$unsuspend, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) { |
---|
140 | if ($user->suspended != 0) { |
---|
141 | $user->suspended = 0; |
---|
142 | user_update_user($user, false); |
---|
143 | } |
---|
144 | } |
---|
145 | redirect($returnurl); |
---|
146 | |
---|
147 | } else if ($unlock and confirm_sesskey()) { |
---|
148 | require_capability('moodle/user:update', $sitecontext); |
---|
149 | |
---|
150 | if ($user = $DB->get_record('user', array('id'=>$unlock, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) { |
---|
151 | login_unlock_account($user); |
---|
152 | } |
---|
153 | redirect($returnurl); |
---|
154 | } |
---|
155 | |
---|
156 | // create the user filter form |
---|
157 | $ufiltering = new user_filtering(); |
---|
158 | echo $OUTPUT->header(); |
---|
159 | |
---|
160 | // Carry on with the user listing |
---|
161 | $context = context_system::instance(); |
---|
162 | $extracolumns = get_extra_user_fields($context); |
---|
163 | // Get all user name fields as an array. |
---|
164 | $allusernamefields = get_all_user_name_fields(false, null, null, null, true); |
---|
165 | $columns = array_merge($allusernamefields, $extracolumns, array('city', 'country', 'lastaccess')); |
---|
166 | |
---|
167 | foreach ($columns as $column) { |
---|
168 | $string[$column] = get_user_field_name($column); |
---|
169 | if ($sort != $column) { |
---|
170 | $columnicon = ""; |
---|
171 | if ($column == "lastaccess") { |
---|
172 | $columndir = "DESC"; |
---|
173 | } else { |
---|
174 | $columndir = "ASC"; |
---|
175 | } |
---|
176 | } else { |
---|
177 | $columndir = $dir == "ASC" ? "DESC":"ASC"; |
---|
178 | if ($column == "lastaccess") { |
---|
179 | $columnicon = ($dir == "ASC") ? "sort_desc" : "sort_asc"; |
---|
180 | } else { |
---|
181 | $columnicon = ($dir == "ASC") ? "sort_asc" : "sort_desc"; |
---|
182 | } |
---|
183 | $columnicon = "<img class='iconsort' src=\"" . $OUTPUT->pix_url('t/' . $columnicon) . "\" alt=\"\" />"; |
---|
184 | |
---|
185 | } |
---|
186 | $$column = "<a href=\"user.php?sort=$column&dir=$columndir\">".$string[$column]."</a>$columnicon"; |
---|
187 | } |
---|
188 | |
---|
189 | // We need to check that alternativefullnameformat is not set to '' or language. |
---|
190 | // We don't need to check the fullnamedisplay setting here as the fullname function call further down has |
---|
191 | // the override parameter set to true. |
---|
192 | $fullnamesetting = $CFG->alternativefullnameformat; |
---|
193 | // If we are using language or it is empty, then retrieve all of the user's names. |
---|
194 | if ($fullnamesetting == 'language' || empty($fullnamesetting)) { |
---|
195 | $fullnamesetting = implode(' ', $allusernamefields); |
---|
196 | } |
---|
197 | |
---|
198 | // Order in string will ensure that the name columns are in the correct order. |
---|
199 | $usernames = order_in_string($allusernamefields, $fullnamesetting); |
---|
200 | $fullnamedisplay = array(); |
---|
201 | foreach ($usernames as $name) { |
---|
202 | // Use the link from $$column for sorting on the user's name. |
---|
203 | $fullnamedisplay[] = ${$name}; |
---|
204 | } |
---|
205 | // All of the names are in one column. Put them into a string and separate them with a /. |
---|
206 | $fullnamedisplay = implode(' / ', $fullnamedisplay); |
---|
207 | // If $sort = name then it is the default for the setting and we should use the first name to sort by. |
---|
208 | if ($sort == "name") { |
---|
209 | // Use the first item in the array. |
---|
210 | $sort = reset($usernames); |
---|
211 | } |
---|
212 | |
---|
213 | list($extrasql, $params) = $ufiltering->get_sql_filter(); |
---|
214 | $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '', |
---|
215 | $extrasql, $params, $context); |
---|
216 | $usercount = get_users(false); |
---|
217 | $usersearchcount = get_users(false, '', false, null, "", '', '', '', '', '*', $extrasql, $params); |
---|
218 | |
---|
219 | if ($extrasql !== '') { |
---|
220 | echo $OUTPUT->heading("$usersearchcount / $usercount ".get_string('users')); |
---|
221 | $usercount = $usersearchcount; |
---|
222 | } else { |
---|
223 | echo $OUTPUT->heading("$usercount ".get_string('users')); |
---|
224 | } |
---|
225 | |
---|
226 | $strall = get_string('all'); |
---|
227 | |
---|
228 | $baseurl = new moodle_url('/admin/user.php', array('sort' => $sort, 'dir' => $dir, 'perpage' => $perpage)); |
---|
229 | echo $OUTPUT->paging_bar($usercount, $page, $perpage, $baseurl); |
---|
230 | |
---|
231 | flush(); |
---|
232 | |
---|
233 | |
---|
234 | if (!$users) { |
---|
235 | $match = array(); |
---|
236 | echo $OUTPUT->heading(get_string('nousersfound')); |
---|
237 | |
---|
238 | $table = NULL; |
---|
239 | |
---|
240 | } else { |
---|
241 | |
---|
242 | $countries = get_string_manager()->get_list_of_countries(false); |
---|
243 | if (empty($mnethosts)) { |
---|
244 | $mnethosts = $DB->get_records('mnet_host', null, 'id', 'id,wwwroot,name'); |
---|
245 | } |
---|
246 | |
---|
247 | foreach ($users as $key => $user) { |
---|
248 | if (isset($countries[$user->country])) { |
---|
249 | $users[$key]->country = $countries[$user->country]; |
---|
250 | } |
---|
251 | } |
---|
252 | if ($sort == "country") { // Need to resort by full country name, not code |
---|
253 | foreach ($users as $user) { |
---|
254 | $susers[$user->id] = $user->country; |
---|
255 | } |
---|
256 | asort($susers); |
---|
257 | foreach ($susers as $key => $value) { |
---|
258 | $nusers[] = $users[$key]; |
---|
259 | } |
---|
260 | $users = $nusers; |
---|
261 | } |
---|
262 | |
---|
263 | $table = new html_table(); |
---|
264 | $table->head = array (); |
---|
265 | $table->colclasses = array(); |
---|
266 | $table->head[] = $fullnamedisplay; |
---|
267 | $table->attributes['class'] = 'admintable generaltable'; |
---|
268 | foreach ($extracolumns as $field) { |
---|
269 | $table->head[] = ${$field}; |
---|
270 | } |
---|
271 | $table->head[] = $city; |
---|
272 | $table->head[] = $country; |
---|
273 | $table->head[] = $lastaccess; |
---|
274 | $table->head[] = get_string('edit'); |
---|
275 | $table->colclasses[] = 'centeralign'; |
---|
276 | $table->head[] = ""; |
---|
277 | $table->colclasses[] = 'centeralign'; |
---|
278 | |
---|
279 | $table->id = "users"; |
---|
280 | foreach ($users as $user) { |
---|
281 | $buttons = array(); |
---|
282 | $lastcolumn = ''; |
---|
283 | |
---|
284 | // delete button |
---|
285 | if (has_capability('moodle/user:delete', $sitecontext)) { |
---|
286 | if (is_mnet_remote_user($user) or $user->id == $USER->id or is_siteadmin($user)) { |
---|
287 | // no deleting of self, mnet accounts or admins allowed |
---|
288 | } else { |
---|
289 | $buttons[] = html_writer::link(new moodle_url($returnurl, array('delete'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/delete'), 'alt'=>$strdelete, 'class'=>'iconsmall')), array('title'=>$strdelete)); |
---|
290 | } |
---|
291 | } |
---|
292 | |
---|
293 | // suspend button |
---|
294 | if (has_capability('moodle/user:update', $sitecontext)) { |
---|
295 | if (is_mnet_remote_user($user)) { |
---|
296 | // mnet users have special access control, they can not be deleted the standard way or suspended |
---|
297 | $accessctrl = 'allow'; |
---|
298 | if ($acl = $DB->get_record('mnet_sso_access_control', array('username'=>$user->username, 'mnet_host_id'=>$user->mnethostid))) { |
---|
299 | $accessctrl = $acl->accessctrl; |
---|
300 | } |
---|
301 | $changeaccessto = ($accessctrl == 'deny' ? 'allow' : 'deny'); |
---|
302 | $buttons[] = " (<a href=\"?acl={$user->id}&accessctrl=$changeaccessto&sesskey=".sesskey()."\">".get_string($changeaccessto, 'mnet') . " access</a>)"; |
---|
303 | |
---|
304 | } else { |
---|
305 | if ($user->suspended) { |
---|
306 | $buttons[] = html_writer::link(new moodle_url($returnurl, array('unsuspend'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/show'), 'alt'=>$strunsuspend, 'class'=>'iconsmall')), array('title'=>$strunsuspend)); |
---|
307 | } else { |
---|
308 | if ($user->id == $USER->id or is_siteadmin($user)) { |
---|
309 | // no suspending of admins or self! |
---|
310 | } else { |
---|
311 | $buttons[] = html_writer::link(new moodle_url($returnurl, array('suspend'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/hide'), 'alt'=>$strsuspend, 'class'=>'iconsmall')), array('title'=>$strsuspend)); |
---|
312 | } |
---|
313 | } |
---|
314 | |
---|
315 | if (login_is_lockedout($user)) { |
---|
316 | $buttons[] = html_writer::link(new moodle_url($returnurl, array('unlock'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/unlock'), 'alt'=>$strunlock, 'class'=>'iconsmall')), array('title'=>$strunlock)); |
---|
317 | } |
---|
318 | } |
---|
319 | } |
---|
320 | |
---|
321 | // edit button |
---|
322 | if (has_capability('moodle/user:update', $sitecontext)) { |
---|
323 | // prevent editing of admins by non-admins |
---|
324 | if (is_siteadmin($USER) or !is_siteadmin($user)) { |
---|
325 | $buttons[] = html_writer::link(new moodle_url($securewwwroot.'/user/editadvanced.php', array('id'=>$user->id, 'course'=>$site->id)), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/edit'), 'alt'=>$stredit, 'class'=>'iconsmall')), array('title'=>$stredit)); |
---|
326 | } |
---|
327 | } |
---|
328 | |
---|
329 | // the last column - confirm or mnet info |
---|
330 | if (is_mnet_remote_user($user)) { |
---|
331 | // all mnet users are confirmed, let's print just the name of the host there |
---|
332 | if (isset($mnethosts[$user->mnethostid])) { |
---|
333 | $lastcolumn = get_string($accessctrl, 'mnet').': '.$mnethosts[$user->mnethostid]->name; |
---|
334 | } else { |
---|
335 | $lastcolumn = get_string($accessctrl, 'mnet'); |
---|
336 | } |
---|
337 | |
---|
338 | } else if ($user->confirmed == 0) { |
---|
339 | if (has_capability('moodle/user:update', $sitecontext)) { |
---|
340 | $lastcolumn = html_writer::link(new moodle_url($returnurl, array('confirmuser'=>$user->id, 'sesskey'=>sesskey())), $strconfirm); |
---|
341 | } else { |
---|
342 | $lastcolumn = "<span class=\"dimmed_text\">".get_string('confirm')."</span>"; |
---|
343 | } |
---|
344 | } |
---|
345 | |
---|
346 | if ($user->lastaccess) { |
---|
347 | $strlastaccess = format_time(time() - $user->lastaccess); |
---|
348 | } else { |
---|
349 | $strlastaccess = get_string('never'); |
---|
350 | } |
---|
351 | $fullname = fullname($user, true); |
---|
352 | |
---|
353 | $row = array (); |
---|
354 | $row[] = "<a href=\"../user/view.php?id=$user->id&course=$site->id\">$fullname</a>"; |
---|
355 | foreach ($extracolumns as $field) { |
---|
356 | $row[] = $user->{$field}; |
---|
357 | } |
---|
358 | $row[] = $user->city; |
---|
359 | $row[] = $user->country; |
---|
360 | $row[] = $strlastaccess; |
---|
361 | if ($user->suspended) { |
---|
362 | foreach ($row as $k=>$v) { |
---|
363 | $row[$k] = html_writer::tag('span', $v, array('class'=>'usersuspended')); |
---|
364 | } |
---|
365 | } |
---|
366 | $row[] = implode(' ', $buttons); |
---|
367 | $row[] = $lastcolumn; |
---|
368 | $table->data[] = $row; |
---|
369 | } |
---|
370 | } |
---|
371 | |
---|
372 | // add filters |
---|
373 | $ufiltering->display_add(); |
---|
374 | $ufiltering->display_active(); |
---|
375 | |
---|
376 | if (!empty($table)) { |
---|
377 | echo html_writer::start_tag('div', array('class'=>'no-overflow')); |
---|
378 | echo html_writer::table($table); |
---|
379 | echo html_writer::end_tag('div'); |
---|
380 | echo $OUTPUT->paging_bar($usercount, $page, $perpage, $baseurl); |
---|
381 | } |
---|
382 | if (has_capability('moodle/user:create', $sitecontext)) { |
---|
383 | $url = new moodle_url($securewwwroot . '/user/editadvanced.php', array('id' => -1)); |
---|
384 | echo $OUTPUT->single_button($url, get_string('addnewuser'), 'get'); |
---|
385 | } |
---|
386 | |
---|
387 | echo $OUTPUT->footer(); |
---|