Mercurial > hg > vamp-website
comparison forum/Sources/ManageMembers.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
75:72f59aa7e503 | 76:e3e11437ecea |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Simple Machines Forum (SMF) | |
5 * | |
6 * @package SMF | |
7 * @author Simple Machines http://www.simplemachines.org | |
8 * @copyright 2011 Simple Machines | |
9 * @license http://www.simplemachines.org/about/smf/license.php BSD | |
10 * | |
11 * @version 2.0 | |
12 */ | |
13 | |
14 if (!defined('SMF')) | |
15 die('Hacking attempt...'); | |
16 | |
17 /* Show a list of members or a selection of members. | |
18 | |
19 void ViewMembers() | |
20 - the main entrance point for the Manage Members screen. | |
21 - called by ?action=admin;area=viewmembers. | |
22 - requires the moderate_forum permission. | |
23 - loads the ManageMembers template and ManageMembers language file. | |
24 - calls a function based on the given sub-action. | |
25 | |
26 void ViewMemberlist() | |
27 - shows a list of members. | |
28 - called by ?action=admin;area=viewmembers;sa=all or ?action=admin;area=viewmembers;sa=query. | |
29 - requires the moderate_forum permission. | |
30 - uses the view_members sub template of the ManageMembers template. | |
31 - allows sorting on several columns. | |
32 - handles deletion of selected members. | |
33 - handles the search query sent by ?action=admin;area=viewmembers;sa=search. | |
34 | |
35 void SearchMembers() | |
36 - search the member list, using one or more criteria. | |
37 - called by ?action=admin;area=viewmembers;sa=search. | |
38 - requires the moderate_forum permission. | |
39 - uses the search_members sub template of the ManageMembers template. | |
40 - form is submitted to action=admin;area=viewmembers;sa=query. | |
41 | |
42 void MembersAwaitingActivation() | |
43 - show a list of members awaiting approval or activation. | |
44 - called by ?action=admin;area=viewmembers;sa=browse;type=approve or | |
45 ?action=admin;area=viewmembers;sa=browse;type=activate. | |
46 - requires the moderate_forum permission. | |
47 - uses the admin_browse sub template of the ManageMembers template. | |
48 - allows instant approval or activation of (a selection of) members. | |
49 - list can be sorted on different columns. | |
50 - form submits to ?action=admin;area=viewmembers;sa=approve. | |
51 | |
52 void AdminApprove() | |
53 - handles the approval, rejection, activation or deletion of members. | |
54 - called by ?action=admin;area=viewmembers;sa=approve. | |
55 - requires the moderate_forum permission. | |
56 - redirects to ?action=admin;area=viewmembers;sa=browse with the same parameters | |
57 as the calling page. | |
58 | |
59 int jeffsdatediff(int old) | |
60 - nifty function to calculate the number of days ago a given date was. | |
61 - requires a unix timestamp as input, returns an integer. | |
62 - in honour of Jeff Lewis, the original creator of...this function. | |
63 - the returned number of days is based on the forum time. | |
64 */ | |
65 | |
66 function ViewMembers() | |
67 { | |
68 global $txt, $scripturl, $context, $modSettings, $smcFunc; | |
69 | |
70 $subActions = array( | |
71 'all' => array('ViewMemberlist', 'moderate_forum'), | |
72 'approve' => array('AdminApprove', 'moderate_forum'), | |
73 'browse' => array('MembersAwaitingActivation', 'moderate_forum'), | |
74 'search' => array('SearchMembers', 'moderate_forum'), | |
75 'query' => array('ViewMemberlist', 'moderate_forum'), | |
76 ); | |
77 | |
78 // Default to sub action 'index' or 'settings' depending on permissions. | |
79 $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'all'; | |
80 | |
81 // We know the sub action, now we know what you're allowed to do. | |
82 isAllowedTo($subActions[$_REQUEST['sa']][1]); | |
83 | |
84 // Load the essentials. | |
85 loadLanguage('ManageMembers'); | |
86 loadTemplate('ManageMembers'); | |
87 | |
88 // Get counts on every type of activation - for sections and filtering alike. | |
89 $request = $smcFunc['db_query']('', ' | |
90 SELECT COUNT(*) AS total_members, is_activated | |
91 FROM {db_prefix}members | |
92 WHERE is_activated != {int:is_activated} | |
93 GROUP BY is_activated', | |
94 array( | |
95 'is_activated' => 1, | |
96 ) | |
97 ); | |
98 $context['activation_numbers'] = array(); | |
99 $context['awaiting_activation'] = 0; | |
100 $context['awaiting_approval'] = 0; | |
101 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
102 $context['activation_numbers'][$row['is_activated']] = $row['total_members']; | |
103 $smcFunc['db_free_result']($request); | |
104 | |
105 foreach ($context['activation_numbers'] as $activation_type => $total_members) | |
106 { | |
107 if (in_array($activation_type, array(0, 2))) | |
108 $context['awaiting_activation'] += $total_members; | |
109 elseif (in_array($activation_type, array(3, 4, 5))) | |
110 $context['awaiting_approval'] += $total_members; | |
111 } | |
112 | |
113 // For the page header... do we show activation? | |
114 $context['show_activate'] = (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1) || !empty($context['awaiting_activation']); | |
115 | |
116 // What about approval? | |
117 $context['show_approve'] = (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 2) || !empty($context['awaiting_approval']) || !empty($modSettings['approveAccountDeletion']); | |
118 | |
119 // Setup the admin tabs. | |
120 $context[$context['admin_menu_name']]['tab_data'] = array( | |
121 'title' => $txt['admin_members'], | |
122 'help' => 'view_members', | |
123 'description' => $txt['admin_members_list'], | |
124 'tabs' => array(), | |
125 ); | |
126 | |
127 $context['tabs'] = array( | |
128 'viewmembers' => array( | |
129 'label' => $txt['view_all_members'], | |
130 'description' => $txt['admin_members_list'], | |
131 'url' => $scripturl . '?action=admin;area=viewmembers;sa=all', | |
132 'is_selected' => $_REQUEST['sa'] == 'all', | |
133 ), | |
134 'search' => array( | |
135 'label' => $txt['mlist_search'], | |
136 'description' => $txt['admin_members_list'], | |
137 'url' => $scripturl . '?action=admin;area=viewmembers;sa=search', | |
138 'is_selected' => $_REQUEST['sa'] == 'search' || $_REQUEST['sa'] == 'query', | |
139 ), | |
140 'approve' => array( | |
141 'label' => sprintf($txt['admin_browse_awaiting_approval'], $context['awaiting_approval']), | |
142 'description' => $txt['admin_browse_approve_desc'], | |
143 'url' => $scripturl . '?action=admin;area=viewmembers;sa=browse;type=approve', | |
144 'is_selected' => false, | |
145 ), | |
146 'activate' => array( | |
147 'label' => sprintf($txt['admin_browse_awaiting_activate'], $context['awaiting_activation']), | |
148 'description' => $txt['admin_browse_activate_desc'], | |
149 'url' => $scripturl . '?action=admin;area=viewmembers;sa=browse;type=activate', | |
150 'is_selected' => false, | |
151 'is_last' => true, | |
152 ), | |
153 ); | |
154 | |
155 // Sort out the tabs for the ones which may not exist! | |
156 if (!$context['show_activate'] && ($_REQUEST['sa'] != 'browse' || $_REQUEST['type'] != 'activate')) | |
157 { | |
158 $context['tabs']['approve']['is_last'] = true; | |
159 unset($context['tabs']['activate']); | |
160 } | |
161 if (!$context['show_approve'] && ($_REQUEST['sa'] != 'browse' || $_REQUEST['type'] != 'approve')) | |
162 { | |
163 if (!$context['show_activate'] && ($_REQUEST['sa'] != 'browse' || $_REQUEST['type'] != 'activate')) | |
164 $context['tabs']['search']['is_last'] = true; | |
165 unset($context['tabs']['approve']); | |
166 } | |
167 | |
168 $subActions[$_REQUEST['sa']][0](); | |
169 } | |
170 | |
171 // View all members. | |
172 function ViewMemberlist() | |
173 { | |
174 global $txt, $scripturl, $context, $modSettings, $sourcedir, $smcFunc, $user_info; | |
175 | |
176 // Set the current sub action. | |
177 $context['sub_action'] = $_REQUEST['sa']; | |
178 | |
179 // Are we performing a delete? | |
180 if (isset($_POST['delete_members']) && !empty($_POST['delete']) && allowedTo('profile_remove_any')) | |
181 { | |
182 checkSession(); | |
183 | |
184 // Clean the input. | |
185 foreach ($_POST['delete'] as $key => $value) | |
186 { | |
187 $_POST['delete'][$key] = (int) $value; | |
188 // Don't delete yourself, idiot. | |
189 if ($value == $user_info['id']) | |
190 unset($_POST['delete'][$key]); | |
191 } | |
192 | |
193 if (!empty($_POST['delete'])) | |
194 { | |
195 // Delete all the selected members. | |
196 require_once($sourcedir . '/Subs-Members.php'); | |
197 deleteMembers($_POST['delete'], true); | |
198 } | |
199 } | |
200 | |
201 if ($context['sub_action'] == 'query' && !empty($_REQUEST['params']) && empty($_POST)) | |
202 $_POST += @unserialize(base64_decode($_REQUEST['params'])); | |
203 | |
204 // Check input after a member search has been submitted. | |
205 if ($context['sub_action'] == 'query') | |
206 { | |
207 // Retrieving the membergroups and postgroups. | |
208 $context['membergroups'] = array( | |
209 array( | |
210 'id' => 0, | |
211 'name' => $txt['membergroups_members'], | |
212 'can_be_additional' => false | |
213 ) | |
214 ); | |
215 $context['postgroups'] = array(); | |
216 | |
217 $request = $smcFunc['db_query']('', ' | |
218 SELECT id_group, group_name, min_posts | |
219 FROM {db_prefix}membergroups | |
220 WHERE id_group != {int:moderator_group} | |
221 ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', | |
222 array( | |
223 'moderator_group' => 3, | |
224 'newbie_group' => 4, | |
225 ) | |
226 ); | |
227 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
228 { | |
229 if ($row['min_posts'] == -1) | |
230 $context['membergroups'][] = array( | |
231 'id' => $row['id_group'], | |
232 'name' => $row['group_name'], | |
233 'can_be_additional' => true | |
234 ); | |
235 else | |
236 $context['postgroups'][] = array( | |
237 'id' => $row['id_group'], | |
238 'name' => $row['group_name'] | |
239 ); | |
240 } | |
241 $smcFunc['db_free_result']($request); | |
242 | |
243 // Some data about the form fields and how they are linked to the database. | |
244 $params = array( | |
245 'mem_id' => array( | |
246 'db_fields' => array('id_member'), | |
247 'type' => 'int', | |
248 'range' => true | |
249 ), | |
250 'age' => array( | |
251 'db_fields' => array('birthdate'), | |
252 'type' => 'age', | |
253 'range' => true | |
254 ), | |
255 'posts' => array( | |
256 'db_fields' => array('posts'), | |
257 'type' => 'int', | |
258 'range' => true | |
259 ), | |
260 'reg_date' => array( | |
261 'db_fields' => array('date_registered'), | |
262 'type' => 'date', | |
263 'range' => true | |
264 ), | |
265 'last_online' => array( | |
266 'db_fields' => array('last_login'), | |
267 'type' => 'date', | |
268 'range' => true | |
269 ), | |
270 'gender' => array( | |
271 'db_fields' => array('gender'), | |
272 'type' => 'checkbox', | |
273 'values' => array('0', '1', '2'), | |
274 ), | |
275 'activated' => array( | |
276 'db_fields' => array('CASE WHEN is_activated IN (1, 11) THEN 1 ELSE 0 END'), | |
277 'type' => 'checkbox', | |
278 'values' => array('0', '1'), | |
279 ), | |
280 'membername' => array( | |
281 'db_fields' => array('member_name', 'real_name'), | |
282 'type' => 'string' | |
283 ), | |
284 'email' => array( | |
285 'db_fields' => array('email_address'), | |
286 'type' => 'string' | |
287 ), | |
288 'website' => array( | |
289 'db_fields' => array('website_title', 'website_url'), | |
290 'type' => 'string' | |
291 ), | |
292 'location' => array( | |
293 'db_fields' => array('location'), | |
294 'type' => 'string' | |
295 ), | |
296 'ip' => array( | |
297 'db_fields' => array('member_ip'), | |
298 'type' => 'string' | |
299 ), | |
300 'messenger' => array( | |
301 'db_fields' => array('icq', 'aim', 'yim', 'msn'), | |
302 'type' => 'string' | |
303 ) | |
304 ); | |
305 $range_trans = array( | |
306 '--' => '<', | |
307 '-' => '<=', | |
308 '=' => '=', | |
309 '+' => '>=', | |
310 '++' => '>' | |
311 ); | |
312 | |
313 // !!! Validate a little more. | |
314 | |
315 // Loop through every field of the form. | |
316 $query_parts = array(); | |
317 $where_params = array(); | |
318 foreach ($params as $param_name => $param_info) | |
319 { | |
320 // Not filled in? | |
321 if (!isset($_POST[$param_name]) || $_POST[$param_name] === '') | |
322 continue; | |
323 | |
324 // Make sure numeric values are really numeric. | |
325 if (in_array($param_info['type'], array('int', 'age'))) | |
326 $_POST[$param_name] = (int) $_POST[$param_name]; | |
327 // Date values have to match the specified format. | |
328 elseif ($param_info['type'] == 'date') | |
329 { | |
330 // Check if this date format is valid. | |
331 if (preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $_POST[$param_name]) == 0) | |
332 continue; | |
333 | |
334 $_POST[$param_name] = strtotime($_POST[$param_name]); | |
335 } | |
336 | |
337 // Those values that are in some kind of range (<, <=, =, >=, >). | |
338 if (!empty($param_info['range'])) | |
339 { | |
340 // Default to '=', just in case... | |
341 if (empty($range_trans[$_POST['types'][$param_name]])) | |
342 $_POST['types'][$param_name] = '='; | |
343 | |
344 // Handle special case 'age'. | |
345 if ($param_info['type'] == 'age') | |
346 { | |
347 // All people that were born between $lowerlimit and $upperlimit are currently the specified age. | |
348 $datearray = getdate(forum_time()); | |
349 $upperlimit = sprintf('%04d-%02d-%02d', $datearray['year'] - $_POST[$param_name], $datearray['mon'], $datearray['mday']); | |
350 $lowerlimit = sprintf('%04d-%02d-%02d', $datearray['year'] - $_POST[$param_name] - 1, $datearray['mon'], $datearray['mday']); | |
351 if (in_array($_POST['types'][$param_name], array('-', '--', '='))) | |
352 { | |
353 $query_parts[] = ($param_info['db_fields'][0]) . ' > {string:' . $param_name . '_minlimit}'; | |
354 $where_params[$param_name . '_minlimit'] = ($_POST['types'][$param_name] == '--' ? $upperlimit : $lowerlimit); | |
355 } | |
356 if (in_array($_POST['types'][$param_name], array('+', '++', '='))) | |
357 { | |
358 $query_parts[] = ($param_info['db_fields'][0]) . ' <= {string:' . $param_name . '_pluslimit}'; | |
359 $where_params[$param_name . '_pluslimit'] = ($_POST['types'][$param_name] == '++' ? $lowerlimit : $upperlimit); | |
360 | |
361 // Make sure that members that didn't set their birth year are not queried. | |
362 $query_parts[] = ($param_info['db_fields'][0]) . ' > {date:dec_zero_date}'; | |
363 $where_params['dec_zero_date'] = '0004-12-31'; | |
364 } | |
365 } | |
366 // Special case - equals a date. | |
367 elseif ($param_info['type'] == 'date' && $_POST['types'][$param_name] == '=') | |
368 { | |
369 $query_parts[] = $param_info['db_fields'][0] . ' > ' . $_POST[$param_name] . ' AND ' . $param_info['db_fields'][0] . ' < ' . ($_POST[$param_name] + 86400); | |
370 } | |
371 else | |
372 $query_parts[] = $param_info['db_fields'][0] . ' ' . $range_trans[$_POST['types'][$param_name]] . ' ' . $_POST[$param_name]; | |
373 } | |
374 // Checkboxes. | |
375 elseif ($param_info['type'] == 'checkbox') | |
376 { | |
377 // Each checkbox or no checkbox at all is checked -> ignore. | |
378 if (!is_array($_POST[$param_name]) || count($_POST[$param_name]) == 0 || count($_POST[$param_name]) == count($param_info['values'])) | |
379 continue; | |
380 | |
381 $query_parts[] = ($param_info['db_fields'][0]) . ' IN ({array_string:' . $param_name . '_check})'; | |
382 $where_params[$param_name . '_check'] = $_POST[$param_name]; | |
383 } | |
384 else | |
385 { | |
386 // Replace the wildcard characters ('*' and '?') into MySQL ones. | |
387 $parameter = strtolower(strtr($smcFunc['htmlspecialchars']($_POST[$param_name], ENT_QUOTES), array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_'))); | |
388 | |
389 $query_parts[] = '(' . implode( ' LIKE {string:' . $param_name . '_normal} OR ', $param_info['db_fields']) . ' LIKE {string:' . $param_name . '_normal})'; | |
390 $where_params[$param_name . '_normal'] = '%' . $parameter . '%'; | |
391 } | |
392 } | |
393 | |
394 // Set up the membergroup query part. | |
395 $mg_query_parts = array(); | |
396 | |
397 // Primary membergroups, but only if at least was was not selected. | |
398 if (!empty($_POST['membergroups'][1]) && count($context['membergroups']) != count($_POST['membergroups'][1])) | |
399 { | |
400 $mg_query_parts[] = 'mem.id_group IN ({array_int:group_check})'; | |
401 $where_params['group_check'] = $_POST['membergroups'][1]; | |
402 } | |
403 | |
404 // Additional membergroups (these are only relevant if not all primary groups where selected!). | |
405 if (!empty($_POST['membergroups'][2]) && (empty($_POST['membergroups'][1]) || count($context['membergroups']) != count($_POST['membergroups'][1]))) | |
406 foreach ($_POST['membergroups'][2] as $mg) | |
407 { | |
408 $mg_query_parts[] = 'FIND_IN_SET({int:add_group_' . $mg . '}, mem.additional_groups) != 0'; | |
409 $where_params['add_group_' . $mg] = $mg; | |
410 } | |
411 | |
412 // Combine the one or two membergroup parts into one query part linked with an OR. | |
413 if (!empty($mg_query_parts)) | |
414 $query_parts[] = '(' . implode(' OR ', $mg_query_parts) . ')'; | |
415 | |
416 // Get all selected post count related membergroups. | |
417 if (!empty($_POST['postgroups']) && count($_POST['postgroups']) != count($context['postgroups'])) | |
418 { | |
419 $query_parts[] = 'id_post_group IN ({array_int:post_groups})'; | |
420 $where_params['post_groups'] = $_POST['postgroups']; | |
421 } | |
422 | |
423 // Construct the where part of the query. | |
424 $where = empty($query_parts) ? '1' : implode(' | |
425 AND ', $query_parts); | |
426 | |
427 $search_params = base64_encode(serialize($_POST)); | |
428 } | |
429 else | |
430 $search_params = null; | |
431 | |
432 // Construct the additional URL part with the query info in it. | |
433 $context['params_url'] = $context['sub_action'] == 'query' ? ';sa=query;params=' . $search_params : ''; | |
434 | |
435 // Get the title and sub template ready.. | |
436 $context['page_title'] = $txt['admin_members']; | |
437 | |
438 $listOptions = array( | |
439 'id' => 'member_list', | |
440 'items_per_page' => $modSettings['defaultMaxMembers'], | |
441 'base_href' => $scripturl . '?action=admin;area=viewmembers' . $context['params_url'], | |
442 'default_sort_col' => 'user_name', | |
443 'get_items' => array( | |
444 'file' => $sourcedir . '/Subs-Members.php', | |
445 'function' => 'list_getMembers', | |
446 'params' => array( | |
447 isset($where) ? $where : '1=1', | |
448 isset($where_params) ? $where_params : array(), | |
449 ), | |
450 ), | |
451 'get_count' => array( | |
452 'file' => $sourcedir . '/Subs-Members.php', | |
453 'function' => 'list_getNumMembers', | |
454 'params' => array( | |
455 isset($where) ? $where : '1=1', | |
456 isset($where_params) ? $where_params : array(), | |
457 ), | |
458 ), | |
459 'columns' => array( | |
460 'id_member' => array( | |
461 'header' => array( | |
462 'value' => $txt['member_id'], | |
463 ), | |
464 'data' => array( | |
465 'db' => 'id_member', | |
466 'class' => 'windowbg', | |
467 'style' => 'text-align: center;', | |
468 ), | |
469 'sort' => array( | |
470 'default' => 'id_member', | |
471 'reverse' => 'id_member DESC', | |
472 ), | |
473 ), | |
474 'user_name' => array( | |
475 'header' => array( | |
476 'value' => $txt['username'], | |
477 ), | |
478 'data' => array( | |
479 'sprintf' => array( | |
480 'format' => '<a href="' . strtr($scripturl, array('%' => '%%')) . '?action=profile;u=%1$d">%2$s</a>', | |
481 'params' => array( | |
482 'id_member' => false, | |
483 'member_name' => false, | |
484 ), | |
485 ), | |
486 ), | |
487 'sort' => array( | |
488 'default' => 'member_name', | |
489 'reverse' => 'member_name DESC', | |
490 ), | |
491 ), | |
492 'display_name' => array( | |
493 'header' => array( | |
494 'value' => $txt['display_name'], | |
495 ), | |
496 'data' => array( | |
497 'sprintf' => array( | |
498 'format' => '<a href="' . strtr($scripturl, array('%' => '%%')) . '?action=profile;u=%1$d">%2$s</a>', | |
499 'params' => array( | |
500 'id_member' => false, | |
501 'real_name' => false, | |
502 ), | |
503 ), | |
504 ), | |
505 'sort' => array( | |
506 'default' => 'real_name', | |
507 'reverse' => 'real_name DESC', | |
508 ), | |
509 ), | |
510 'email' => array( | |
511 'header' => array( | |
512 'value' => $txt['email_address'], | |
513 ), | |
514 'data' => array( | |
515 'sprintf' => array( | |
516 'format' => '<a href="mailto:%1$s">%1$s</a>', | |
517 'params' => array( | |
518 'email_address' => true, | |
519 ), | |
520 ), | |
521 'class' => 'windowbg', | |
522 ), | |
523 'sort' => array( | |
524 'default' => 'email_address', | |
525 'reverse' => 'email_address DESC', | |
526 ), | |
527 ), | |
528 'ip' => array( | |
529 'header' => array( | |
530 'value' => $txt['ip_address'], | |
531 ), | |
532 'data' => array( | |
533 'sprintf' => array( | |
534 'format' => '<a href="' . strtr($scripturl, array('%' => '%%')) . '?action=trackip;searchip=%1$s">%1$s</a>', | |
535 'params' => array( | |
536 'member_ip' => false, | |
537 ), | |
538 ), | |
539 ), | |
540 'sort' => array( | |
541 'default' => 'INET_ATON(member_ip)', | |
542 'reverse' => 'INET_ATON(member_ip) DESC', | |
543 ), | |
544 ), | |
545 'last_active' => array( | |
546 'header' => array( | |
547 'value' => $txt['viewmembers_online'], | |
548 ), | |
549 'data' => array( | |
550 'function' => create_function('$rowData', ' | |
551 global $txt; | |
552 | |
553 // Calculate number of days since last online. | |
554 if (empty($rowData[\'last_login\'])) | |
555 $difference = $txt[\'never\']; | |
556 else | |
557 { | |
558 $num_days_difference = jeffsdatediff($rowData[\'last_login\']); | |
559 | |
560 // Today. | |
561 if (empty($num_days_difference)) | |
562 $difference = $txt[\'viewmembers_today\']; | |
563 | |
564 // Yesterday. | |
565 elseif ($num_days_difference == 1) | |
566 $difference = sprintf(\'1 %1$s\', $txt[\'viewmembers_day_ago\']); | |
567 | |
568 // X days ago. | |
569 else | |
570 $difference = sprintf(\'%1$d %2$s\', $num_days_difference, $txt[\'viewmembers_days_ago\']); | |
571 } | |
572 | |
573 // Show it in italics if they\'re not activated... | |
574 if ($rowData[\'is_activated\'] % 10 != 1) | |
575 $difference = sprintf(\'<em title="%1$s">%2$s</em>\', $txt[\'not_activated\'], $difference); | |
576 | |
577 return $difference; | |
578 '), | |
579 ), | |
580 'sort' => array( | |
581 'default' => 'last_login DESC', | |
582 'reverse' => 'last_login', | |
583 ), | |
584 ), | |
585 'posts' => array( | |
586 'header' => array( | |
587 'value' => $txt['member_postcount'], | |
588 ), | |
589 'data' => array( | |
590 'db' => 'posts', | |
591 ), | |
592 'sort' => array( | |
593 'default' => 'posts', | |
594 'reverse' => 'posts DESC', | |
595 ), | |
596 ), | |
597 'check' => array( | |
598 'header' => array( | |
599 'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />', | |
600 ), | |
601 'data' => array( | |
602 'function' => create_function('$rowData', ' | |
603 global $user_info; | |
604 | |
605 return \'<input type="checkbox" name="delete[]" value="\' . $rowData[\'id_member\'] . \'" class="input_check" \' . ($rowData[\'id_member\'] == $user_info[\'id\'] || $rowData[\'id_group\'] == 1 || in_array(1, explode(\',\', $rowData[\'additional_groups\'])) ? \'disabled="disabled"\' : \'\') . \' />\'; | |
606 '), | |
607 'class' => 'windowbg', | |
608 'style' => 'text-align: center', | |
609 ), | |
610 ), | |
611 ), | |
612 'form' => array( | |
613 'href' => $scripturl . '?action=admin;area=viewmembers' . $context['params_url'], | |
614 'include_start' => true, | |
615 'include_sort' => true, | |
616 ), | |
617 'additional_rows' => array( | |
618 array( | |
619 'position' => 'below_table_data', | |
620 'value' => '<input type="submit" name="delete_members" value="' . $txt['admin_delete_members'] . '" onclick="return confirm(\'' . $txt['confirm_delete_members'] . '\');" class="button_submit" />', | |
621 'style' => 'text-align: right;', | |
622 ), | |
623 ), | |
624 ); | |
625 | |
626 // Without not enough permissions, don't show 'delete members' checkboxes. | |
627 if (!allowedTo('profile_remove_any')) | |
628 unset($listOptions['cols']['check'], $listOptions['form'], $listOptions['additional_rows']); | |
629 | |
630 require_once($sourcedir . '/Subs-List.php'); | |
631 createList($listOptions); | |
632 | |
633 $context['sub_template'] = 'show_list'; | |
634 $context['default_list'] = 'member_list'; | |
635 } | |
636 | |
637 // Search the member list, using one or more criteria. | |
638 function SearchMembers() | |
639 { | |
640 global $context, $txt, $smcFunc; | |
641 | |
642 // Get a list of all the membergroups and postgroups that can be selected. | |
643 $context['membergroups'] = array( | |
644 array( | |
645 'id' => 0, | |
646 'name' => $txt['membergroups_members'], | |
647 'can_be_additional' => false | |
648 ) | |
649 ); | |
650 $context['postgroups'] = array(); | |
651 | |
652 $request = $smcFunc['db_query']('', ' | |
653 SELECT id_group, group_name, min_posts | |
654 FROM {db_prefix}membergroups | |
655 WHERE id_group != {int:moderator_group} | |
656 ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', | |
657 array( | |
658 'moderator_group' => 3, | |
659 'newbie_group' => 4, | |
660 ) | |
661 ); | |
662 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
663 { | |
664 if ($row['min_posts'] == -1) | |
665 $context['membergroups'][] = array( | |
666 'id' => $row['id_group'], | |
667 'name' => $row['group_name'], | |
668 'can_be_additional' => true | |
669 ); | |
670 else | |
671 $context['postgroups'][] = array( | |
672 'id' => $row['id_group'], | |
673 'name' => $row['group_name'] | |
674 ); | |
675 } | |
676 $smcFunc['db_free_result']($request); | |
677 | |
678 $context['page_title'] = $txt['admin_members']; | |
679 $context['sub_template'] = 'search_members'; | |
680 } | |
681 | |
682 // List all members who are awaiting approval / activation | |
683 function MembersAwaitingActivation() | |
684 { | |
685 global $txt, $context, $scripturl, $modSettings, $smcFunc; | |
686 global $sourcedir; | |
687 | |
688 // Not a lot here! | |
689 $context['page_title'] = $txt['admin_members']; | |
690 $context['sub_template'] = 'admin_browse'; | |
691 $context['browse_type'] = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve'); | |
692 if (isset($context['tabs'][$context['browse_type']])) | |
693 $context['tabs'][$context['browse_type']]['is_selected'] = true; | |
694 | |
695 // Allowed filters are those we can have, in theory. | |
696 $context['allowed_filters'] = $context['browse_type'] == 'approve' ? array(3, 4, 5) : array(0, 2); | |
697 $context['current_filter'] = isset($_REQUEST['filter']) && in_array($_REQUEST['filter'], $context['allowed_filters']) && !empty($context['activation_numbers'][$_REQUEST['filter']]) ? (int) $_REQUEST['filter'] : -1; | |
698 | |
699 // Sort out the different sub areas that we can actually filter by. | |
700 $context['available_filters'] = array(); | |
701 foreach ($context['activation_numbers'] as $type => $amount) | |
702 { | |
703 // We have some of these... | |
704 if (in_array($type, $context['allowed_filters']) && $amount > 0) | |
705 $context['available_filters'][] = array( | |
706 'type' => $type, | |
707 'amount' => $amount, | |
708 'desc' => isset($txt['admin_browse_filter_type_' . $type]) ? $txt['admin_browse_filter_type_' . $type] : '?', | |
709 'selected' => $type == $context['current_filter'] | |
710 ); | |
711 } | |
712 | |
713 // If the filter was not sent, set it to whatever has people in it! | |
714 if ($context['current_filter'] == -1 && !empty($context['available_filters'][0]['amount'])) | |
715 $context['current_filter'] = $context['available_filters'][0]['type']; | |
716 | |
717 // This little variable is used to determine if we should flag where we are looking. | |
718 $context['show_filter'] = ($context['current_filter'] != 0 && $context['current_filter'] != 3) || count($context['available_filters']) > 1; | |
719 | |
720 // The columns that can be sorted. | |
721 $context['columns'] = array( | |
722 'id_member' => array('label' => $txt['admin_browse_id']), | |
723 'member_name' => array('label' => $txt['admin_browse_username']), | |
724 'email_address' => array('label' => $txt['admin_browse_email']), | |
725 'member_ip' => array('label' => $txt['admin_browse_ip']), | |
726 'date_registered' => array('label' => $txt['admin_browse_registered']), | |
727 ); | |
728 | |
729 // Are we showing duplicate information? | |
730 if (isset($_GET['showdupes'])) | |
731 $_SESSION['showdupes'] = (int) $_GET['showdupes']; | |
732 $context['show_duplicates'] = !empty($_SESSION['showdupes']); | |
733 | |
734 // Determine which actions we should allow on this page. | |
735 if ($context['browse_type'] == 'approve') | |
736 { | |
737 // If we are approving deleted accounts we have a slightly different list... actually a mirror ;) | |
738 if ($context['current_filter'] == 4) | |
739 $context['allowed_actions'] = array( | |
740 'reject' => $txt['admin_browse_w_approve_deletion'], | |
741 'ok' => $txt['admin_browse_w_reject'], | |
742 ); | |
743 else | |
744 $context['allowed_actions'] = array( | |
745 'ok' => $txt['admin_browse_w_approve'], | |
746 'okemail' => $txt['admin_browse_w_approve'] . ' ' . $txt['admin_browse_w_email'], | |
747 'require_activation' => $txt['admin_browse_w_approve_require_activate'], | |
748 'reject' => $txt['admin_browse_w_reject'], | |
749 'rejectemail' => $txt['admin_browse_w_reject'] . ' ' . $txt['admin_browse_w_email'], | |
750 ); | |
751 } | |
752 elseif ($context['browse_type'] == 'activate') | |
753 $context['allowed_actions'] = array( | |
754 'ok' => $txt['admin_browse_w_activate'], | |
755 'okemail' => $txt['admin_browse_w_activate'] . ' ' . $txt['admin_browse_w_email'], | |
756 'delete' => $txt['admin_browse_w_delete'], | |
757 'deleteemail' => $txt['admin_browse_w_delete'] . ' ' . $txt['admin_browse_w_email'], | |
758 'remind' => $txt['admin_browse_w_remind'] . ' ' . $txt['admin_browse_w_email'], | |
759 ); | |
760 | |
761 // Create an option list for actions allowed to be done with selected members. | |
762 $allowed_actions = ' | |
763 <option selected="selected" value="">' . $txt['admin_browse_with_selected'] . ':</option> | |
764 <option value="" disabled="disabled">-----------------------------</option>'; | |
765 foreach ($context['allowed_actions'] as $key => $desc) | |
766 $allowed_actions .= ' | |
767 <option value="' . $key . '">' . $desc . '</option>'; | |
768 | |
769 // Setup the Javascript function for selecting an action for the list. | |
770 $javascript = ' | |
771 function onSelectChange() | |
772 { | |
773 if (document.forms.postForm.todo.value == "") | |
774 return; | |
775 | |
776 var message = "";'; | |
777 | |
778 // We have special messages for approving deletion of accounts - it's surprisingly logical - honest. | |
779 if ($context['current_filter'] == 4) | |
780 $javascript .= ' | |
781 if (document.forms.postForm.todo.value.indexOf("reject") != -1) | |
782 message = "' . $txt['admin_browse_w_delete'] . '"; | |
783 else | |
784 message = "' . $txt['admin_browse_w_reject'] . '";'; | |
785 // Otherwise a nice standard message. | |
786 else | |
787 $javascript .= ' | |
788 if (document.forms.postForm.todo.value.indexOf("delete") != -1) | |
789 message = "' . $txt['admin_browse_w_delete'] . '"; | |
790 else if (document.forms.postForm.todo.value.indexOf("reject") != -1) | |
791 message = "' . $txt['admin_browse_w_reject'] . '"; | |
792 else if (document.forms.postForm.todo.value == "remind") | |
793 message = "' . $txt['admin_browse_w_remind'] . '"; | |
794 else | |
795 message = "' . ($context['browse_type'] == 'approve' ? $txt['admin_browse_w_approve'] : $txt['admin_browse_w_activate']) . '";'; | |
796 $javascript .= ' | |
797 if (confirm(message + " ' . $txt['admin_browse_warn'] . '")) | |
798 document.forms.postForm.submit(); | |
799 }'; | |
800 | |
801 $listOptions = array( | |
802 'id' => 'approve_list', | |
803 'items_per_page' => $modSettings['defaultMaxMembers'], | |
804 'base_href' => $scripturl . '?action=admin;area=viewmembers;sa=browse;type=' . $context['browse_type'] . (!empty($context['show_filter']) ? ';filter=' . $context['current_filter'] : ''), | |
805 'default_sort_col' => 'date_registered', | |
806 'get_items' => array( | |
807 'file' => $sourcedir . '/Subs-Members.php', | |
808 'function' => 'list_getMembers', | |
809 'params' => array( | |
810 'is_activated = {int:activated_status}', | |
811 array('activated_status' => $context['current_filter']), | |
812 $context['show_duplicates'], | |
813 ), | |
814 ), | |
815 'get_count' => array( | |
816 'file' => $sourcedir . '/Subs-Members.php', | |
817 'function' => 'list_getNumMembers', | |
818 'params' => array( | |
819 'is_activated = {int:activated_status}', | |
820 array('activated_status' => $context['current_filter']), | |
821 ), | |
822 ), | |
823 'columns' => array( | |
824 'id_member' => array( | |
825 'header' => array( | |
826 'value' => $txt['member_id'], | |
827 ), | |
828 'data' => array( | |
829 'db' => 'id_member', | |
830 'class' => 'windowbg', | |
831 'style' => 'text-align: center;', | |
832 ), | |
833 'sort' => array( | |
834 'default' => 'id_member', | |
835 'reverse' => 'id_member DESC', | |
836 ), | |
837 ), | |
838 'user_name' => array( | |
839 'header' => array( | |
840 'value' => $txt['username'], | |
841 ), | |
842 'data' => array( | |
843 'sprintf' => array( | |
844 'format' => '<a href="' . strtr($scripturl, array('%' => '%%')) . '?action=profile;u=%1$d">%2$s</a>', | |
845 'params' => array( | |
846 'id_member' => false, | |
847 'member_name' => false, | |
848 ), | |
849 ), | |
850 ), | |
851 'sort' => array( | |
852 'default' => 'member_name', | |
853 'reverse' => 'member_name DESC', | |
854 ), | |
855 ), | |
856 'email' => array( | |
857 'header' => array( | |
858 'value' => $txt['email_address'], | |
859 ), | |
860 'data' => array( | |
861 'sprintf' => array( | |
862 'format' => '<a href="mailto:%1$s">%1$s</a>', | |
863 'params' => array( | |
864 'email_address' => true, | |
865 ), | |
866 ), | |
867 'class' => 'windowbg', | |
868 ), | |
869 'sort' => array( | |
870 'default' => 'email_address', | |
871 'reverse' => 'email_address DESC', | |
872 ), | |
873 ), | |
874 'ip' => array( | |
875 'header' => array( | |
876 'value' => $txt['ip_address'], | |
877 ), | |
878 'data' => array( | |
879 'sprintf' => array( | |
880 'format' => '<a href="' . strtr($scripturl, array('%' => '%%')) . '?action=trackip;searchip=%1$s">%1$s</a>', | |
881 'params' => array( | |
882 'member_ip' => false, | |
883 ), | |
884 ), | |
885 ), | |
886 'sort' => array( | |
887 'default' => 'INET_ATON(member_ip)', | |
888 'reverse' => 'INET_ATON(member_ip) DESC', | |
889 ), | |
890 ), | |
891 'hostname' => array( | |
892 'header' => array( | |
893 'value' => $txt['hostname'], | |
894 ), | |
895 'data' => array( | |
896 'function' => create_function('$rowData', ' | |
897 global $modSettings; | |
898 | |
899 return host_from_ip($rowData[\'member_ip\']); | |
900 '), | |
901 'class' => 'smalltext', | |
902 ), | |
903 ), | |
904 'date_registered' => array( | |
905 'header' => array( | |
906 'value' => $txt['date_registered'], | |
907 ), | |
908 'data' => array( | |
909 'function' => create_function('$rowData', ' | |
910 return timeformat($rowData[\'date_registered\']); | |
911 '), | |
912 ), | |
913 'sort' => array( | |
914 'default' => 'date_registered DESC', | |
915 'reverse' => 'date_registered', | |
916 ), | |
917 ), | |
918 'duplicates' => array( | |
919 'header' => array( | |
920 'value' => $txt['duplicates'], | |
921 // Make sure it doesn't go too wide. | |
922 'style' => 'width: 20%', | |
923 ), | |
924 'data' => array( | |
925 'function' => create_function('$rowData', ' | |
926 global $scripturl, $txt; | |
927 | |
928 $member_links = array(); | |
929 foreach ($rowData[\'duplicate_members\'] as $member) | |
930 { | |
931 if ($member[\'id\']) | |
932 $member_links[] = \'<a href="\' . $scripturl . \'?action=profile;u=\' . $member[\'id\'] . \'" \' . (!empty($member[\'is_banned\']) ? \'style="color: red;"\' : \'\') . \'>\' . $member[\'name\'] . \'</a>\'; | |
933 else | |
934 $member_links[] = $member[\'name\'] . \' (\' . $txt[\'guest\'] . \')\'; | |
935 } | |
936 return implode (\', \', $member_links); | |
937 '), | |
938 'class' => 'smalltext', | |
939 ), | |
940 ), | |
941 'check' => array( | |
942 'header' => array( | |
943 'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />', | |
944 ), | |
945 'data' => array( | |
946 'sprintf' => array( | |
947 'format' => '<input type="checkbox" name="todoAction[]" value="%1$d" class="input_check" />', | |
948 'params' => array( | |
949 'id_member' => false, | |
950 ), | |
951 ), | |
952 'class' => 'windowbg', | |
953 'style' => 'text-align: center', | |
954 ), | |
955 ), | |
956 ), | |
957 'javascript' => $javascript, | |
958 'form' => array( | |
959 'href' => $scripturl . '?action=admin;area=viewmembers;sa=approve;type=' . $context['browse_type'], | |
960 'name' => 'postForm', | |
961 'include_start' => true, | |
962 'include_sort' => true, | |
963 'hidden_fields' => array( | |
964 'orig_filter' => $context['current_filter'], | |
965 ), | |
966 ), | |
967 'additional_rows' => array( | |
968 array( | |
969 'position' => 'below_table_data', | |
970 'value' => ' | |
971 <div class="floatleft"> | |
972 [<a href="' . $scripturl . '?action=admin;area=viewmembers;sa=browse;showdupes=' . ($context['show_duplicates'] ? 0 : 1) . ';type=' . $context['browse_type'] . (!empty($context['show_filter']) ? ';filter=' . $context['current_filter'] : '') . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . ($context['show_duplicates'] ? $txt['dont_check_for_duplicate'] : $txt['check_for_duplicate']) . '</a>] | |
973 </div> | |
974 <div class="floatright"> | |
975 <select name="todo" onchange="onSelectChange();"> | |
976 ' . $allowed_actions . ' | |
977 </select> | |
978 <noscript><input type="submit" value="' . $txt['go'] . '" class="button_submit" /></noscript> | |
979 </div>', | |
980 ), | |
981 ), | |
982 ); | |
983 | |
984 // Pick what column to actually include if we're showing duplicates. | |
985 if ($context['show_duplicates']) | |
986 unset($listOptions['columns']['email']); | |
987 else | |
988 unset($listOptions['columns']['duplicates']); | |
989 | |
990 // Only show hostname on duplicates as it takes a lot of time. | |
991 if (!$context['show_duplicates'] || !empty($modSettings['disableHostnameLookup'])) | |
992 unset($listOptions['columns']['hostname']); | |
993 | |
994 // Is there any need to show filters? | |
995 if (isset($context['available_filters']) && count($context['available_filters']) > 1) | |
996 { | |
997 $filterOptions = ' | |
998 <strong>' . $txt['admin_browse_filter_by'] . ':</strong> | |
999 <select name="filter" onchange="this.form.submit();">'; | |
1000 foreach ($context['available_filters'] as $filter) | |
1001 $filterOptions .= ' | |
1002 <option value="' . $filter['type'] . '"' . ($filter['selected'] ? ' selected="selected"' : '') . '>' . $filter['desc'] . ' - ' . $filter['amount'] . ' ' . ($filter['amount'] == 1 ? $txt['user'] : $txt['users']) . '</option>'; | |
1003 $filterOptions .= ' | |
1004 </select> | |
1005 <noscript><input type="submit" value="' . $txt['go'] . '" name="filter" class="button_submit" /></noscript>'; | |
1006 $listOptions['additional_rows'][] = array( | |
1007 'position' => 'above_column_headers', | |
1008 'value' => $filterOptions, | |
1009 'style' => 'text-align: center;', | |
1010 ); | |
1011 } | |
1012 | |
1013 // What about if we only have one filter, but it's not the "standard" filter - show them what they are looking at. | |
1014 if (!empty($context['show_filter']) && !empty($context['available_filters'])) | |
1015 $listOptions['additional_rows'][] = array( | |
1016 'position' => 'above_column_headers', | |
1017 'value' => '<strong>' . $txt['admin_browse_filter_show'] . ':</strong> ' . $context['available_filters'][0]['desc'], | |
1018 'class' => 'smalltext', | |
1019 'style' => 'text-align: left;', | |
1020 ); | |
1021 | |
1022 // Now that we have all the options, create the list. | |
1023 require_once($sourcedir . '/Subs-List.php'); | |
1024 createList($listOptions); | |
1025 } | |
1026 | |
1027 // Do the approve/activate/delete stuff | |
1028 function AdminApprove() | |
1029 { | |
1030 global $txt, $context, $scripturl, $modSettings, $sourcedir, $language, $user_info, $smcFunc; | |
1031 | |
1032 // First, check our session. | |
1033 checkSession(); | |
1034 | |
1035 require_once($sourcedir . '/Subs-Post.php'); | |
1036 | |
1037 // We also need to the login languages here - for emails. | |
1038 loadLanguage('Login'); | |
1039 | |
1040 // Sort out where we are going... | |
1041 $browse_type = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve'); | |
1042 $current_filter = (int) $_REQUEST['orig_filter']; | |
1043 | |
1044 // If we are applying a filter do just that - then redirect. | |
1045 if (isset($_REQUEST['filter']) && $_REQUEST['filter'] != $_REQUEST['orig_filter']) | |
1046 redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $_REQUEST['filter'] . ';start=' . $_REQUEST['start']); | |
1047 | |
1048 // Nothing to do? | |
1049 if (!isset($_POST['todoAction']) && !isset($_POST['time_passed'])) | |
1050 redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); | |
1051 | |
1052 // Are we dealing with members who have been waiting for > set amount of time? | |
1053 if (isset($_POST['time_passed'])) | |
1054 { | |
1055 $timeBefore = time() - 86400 * (int) $_POST['time_passed']; | |
1056 $condition = ' | |
1057 AND date_registered < {int:time_before}'; | |
1058 } | |
1059 // Coming from checkboxes - validate the members passed through to us. | |
1060 else | |
1061 { | |
1062 $members = array(); | |
1063 foreach ($_POST['todoAction'] as $id) | |
1064 $members[] = (int) $id; | |
1065 $condition = ' | |
1066 AND id_member IN ({array_int:members})'; | |
1067 } | |
1068 | |
1069 // Get information on each of the members, things that are important to us, like email address... | |
1070 $request = $smcFunc['db_query']('', ' | |
1071 SELECT id_member, member_name, real_name, email_address, validation_code, lngfile | |
1072 FROM {db_prefix}members | |
1073 WHERE is_activated = {int:activated_status}' . $condition . ' | |
1074 ORDER BY lngfile', | |
1075 array( | |
1076 'activated_status' => $current_filter, | |
1077 'time_before' => empty($timeBefore) ? 0 : $timeBefore, | |
1078 'members' => empty($members) ? array() : $members, | |
1079 ) | |
1080 ); | |
1081 | |
1082 $member_count = $smcFunc['db_num_rows']($request); | |
1083 | |
1084 // If no results then just return! | |
1085 if ($member_count == 0) | |
1086 redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); | |
1087 | |
1088 $member_info = array(); | |
1089 $members = array(); | |
1090 // Fill the info array. | |
1091 while ($row = $smcFunc['db_fetch_assoc']($request)) | |
1092 { | |
1093 $members[] = $row['id_member']; | |
1094 $member_info[] = array( | |
1095 'id' => $row['id_member'], | |
1096 'username' => $row['member_name'], | |
1097 'name' => $row['real_name'], | |
1098 'email' => $row['email_address'], | |
1099 'language' => empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'], | |
1100 'code' => $row['validation_code'] | |
1101 ); | |
1102 } | |
1103 $smcFunc['db_free_result']($request); | |
1104 | |
1105 // Are we activating or approving the members? | |
1106 if ($_POST['todo'] == 'ok' || $_POST['todo'] == 'okemail') | |
1107 { | |
1108 // Approve/activate this member. | |
1109 $smcFunc['db_query']('', ' | |
1110 UPDATE {db_prefix}members | |
1111 SET validation_code = {string:blank_string}, is_activated = {int:is_activated} | |
1112 WHERE is_activated = {int:activated_status}' . $condition, | |
1113 array( | |
1114 'is_activated' => 1, | |
1115 'time_before' => empty($timeBefore) ? 0 : $timeBefore, | |
1116 'members' => empty($members) ? array() : $members, | |
1117 'activated_status' => $current_filter, | |
1118 'blank_string' => '', | |
1119 ) | |
1120 ); | |
1121 | |
1122 // Do we have to let the integration code know about the activations? | |
1123 if (!empty($modSettings['integrate_activate'])) | |
1124 { | |
1125 foreach ($member_info as $member) | |
1126 call_integration_hook('integrate_activate', array($member['username'])); | |
1127 } | |
1128 | |
1129 // Check for email. | |
1130 if ($_POST['todo'] == 'okemail') | |
1131 { | |
1132 foreach ($member_info as $member) | |
1133 { | |
1134 $replacements = array( | |
1135 'NAME' => $member['name'], | |
1136 'USERNAME' => $member['username'], | |
1137 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member['id'], | |
1138 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', | |
1139 ); | |
1140 | |
1141 $emaildata = loadEmailTemplate('admin_approve_accept', $replacements, $member['language']); | |
1142 sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); | |
1143 } | |
1144 } | |
1145 } | |
1146 // Maybe we're sending it off for activation? | |
1147 elseif ($_POST['todo'] == 'require_activation') | |
1148 { | |
1149 require_once($sourcedir . '/Subs-Members.php'); | |
1150 | |
1151 // We have to do this for each member I'm afraid. | |
1152 foreach ($member_info as $member) | |
1153 { | |
1154 // Generate a random activation code. | |
1155 $validation_code = generateValidationCode(); | |
1156 | |
1157 // Set these members for activation - I know this includes two id_member checks but it's safer than bodging $condition ;). | |
1158 $smcFunc['db_query']('', ' | |
1159 UPDATE {db_prefix}members | |
1160 SET validation_code = {string:validation_code}, is_activated = {int:not_activated} | |
1161 WHERE is_activated = {int:activated_status} | |
1162 ' . $condition . ' | |
1163 AND id_member = {int:selected_member}', | |
1164 array( | |
1165 'not_activated' => 0, | |
1166 'activated_status' => $current_filter, | |
1167 'selected_member' => $member['id'], | |
1168 'validation_code' => $validation_code, | |
1169 'time_before' => empty($timeBefore) ? 0 : $timeBefore, | |
1170 'members' => empty($members) ? array() : $members, | |
1171 ) | |
1172 ); | |
1173 | |
1174 $replacements = array( | |
1175 'USERNAME' => $member['name'], | |
1176 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $validation_code, | |
1177 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], | |
1178 'ACTIVATIONCODE' => $validation_code, | |
1179 ); | |
1180 | |
1181 $emaildata = loadEmailTemplate('admin_approve_activation', $replacements, $member['language']); | |
1182 sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); | |
1183 } | |
1184 } | |
1185 // Are we rejecting them? | |
1186 elseif ($_POST['todo'] == 'reject' || $_POST['todo'] == 'rejectemail') | |
1187 { | |
1188 require_once($sourcedir . '/Subs-Members.php'); | |
1189 deleteMembers($members); | |
1190 | |
1191 // Send email telling them they aren't welcome? | |
1192 if ($_POST['todo'] == 'rejectemail') | |
1193 { | |
1194 foreach ($member_info as $member) | |
1195 { | |
1196 $replacements = array( | |
1197 'USERNAME' => $member['name'], | |
1198 ); | |
1199 | |
1200 $emaildata = loadEmailTemplate('admin_approve_reject', $replacements, $member['language']); | |
1201 sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); | |
1202 } | |
1203 } | |
1204 } | |
1205 // A simple delete? | |
1206 elseif ($_POST['todo'] == 'delete' || $_POST['todo'] == 'deleteemail') | |
1207 { | |
1208 require_once($sourcedir . '/Subs-Members.php'); | |
1209 deleteMembers($members); | |
1210 | |
1211 // Send email telling them they aren't welcome? | |
1212 if ($_POST['todo'] == 'deleteemail') | |
1213 { | |
1214 foreach ($member_info as $member) | |
1215 { | |
1216 $replacements = array( | |
1217 'USERNAME' => $member['name'], | |
1218 ); | |
1219 | |
1220 $emaildata = loadEmailTemplate('admin_approve_delete', $replacements, $member['language']); | |
1221 sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); | |
1222 } | |
1223 } | |
1224 } | |
1225 // Remind them to activate their account? | |
1226 elseif ($_POST['todo'] == 'remind') | |
1227 { | |
1228 foreach ($member_info as $member) | |
1229 { | |
1230 $replacements = array( | |
1231 'USERNAME' => $member['name'], | |
1232 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $member['code'], | |
1233 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], | |
1234 'ACTIVATIONCODE' => $member['code'], | |
1235 ); | |
1236 | |
1237 $emaildata = loadEmailTemplate('admin_approve_remind', $replacements, $member['language']); | |
1238 sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); | |
1239 } | |
1240 } | |
1241 | |
1242 // Back to the user's language! | |
1243 if (isset($current_language) && $current_language != $user_info['language']) | |
1244 { | |
1245 loadLanguage('index'); | |
1246 loadLanguage('ManageMembers'); | |
1247 } | |
1248 | |
1249 // Log what we did? | |
1250 if (!empty($modSettings['modlog_enabled']) && in_array($_POST['todo'], array('ok', 'okemail', 'require_activation', 'remind'))) | |
1251 { | |
1252 $log_action = $_POST['todo'] == 'remind' ? 'remind_member' : 'approve_member'; | |
1253 $log_inserts = array(); | |
1254 foreach ($member_info as $member) | |
1255 { | |
1256 $log_inserts[] = array( | |
1257 time(), 3, $user_info['id'], $user_info['ip'], $log_action, | |
1258 0, 0, 0, serialize(array('member' => $member['id'])), | |
1259 ); | |
1260 } | |
1261 $smcFunc['db_insert']('', | |
1262 '{db_prefix}log_actions', | |
1263 array( | |
1264 'log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', | |
1265 'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534', | |
1266 ), | |
1267 $log_inserts, | |
1268 array('id_action') | |
1269 ); | |
1270 } | |
1271 | |
1272 // Although updateStats *may* catch this, best to do it manually just in case (Doesn't always sort out unapprovedMembers). | |
1273 if (in_array($current_filter, array(3, 4))) | |
1274 updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > $member_count ? $modSettings['unapprovedMembers'] - $member_count : 0))); | |
1275 | |
1276 // Update the member's stats. (but, we know the member didn't change their name.) | |
1277 updateStats('member', false); | |
1278 | |
1279 // If they haven't been deleted, update the post group statistics on them... | |
1280 if (!in_array($_POST['todo'], array('delete', 'deleteemail', 'reject', 'rejectemail', 'remind'))) | |
1281 updateStats('postgroups', $members); | |
1282 | |
1283 redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); | |
1284 } | |
1285 | |
1286 function jeffsdatediff($old) | |
1287 { | |
1288 // Get the current time as the user would see it... | |
1289 $forumTime = forum_time(); | |
1290 | |
1291 // Calculate the seconds that have passed since midnight. | |
1292 $sinceMidnight = date('H', $forumTime) * 60 * 60 + date('i', $forumTime) * 60 + date('s', $forumTime); | |
1293 | |
1294 // Take the difference between the two times. | |
1295 $dis = time() - $old; | |
1296 | |
1297 // Before midnight? | |
1298 if ($dis < $sinceMidnight) | |
1299 return 0; | |
1300 else | |
1301 $dis -= $sinceMidnight; | |
1302 | |
1303 // Divide out the seconds in a day to get the number of days. | |
1304 return ceil($dis / (24 * 60 * 60)); | |
1305 } | |
1306 | |
1307 ?> |