PageRenderTime 56ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/admin_users.php

https://github.com/gencer/fluxbb
PHP | 1318 lines | 1017 code | 244 blank | 57 comment | 141 complexity | f708547d46fabc1e24ea9b49be9a75fe MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Copyright (C) 2008-2012 FluxBB
  4. * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
  5. * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  6. */
  7. // Tell header.php to use the admin template
  8. define('PUN_ADMIN_CONSOLE', 1);
  9. define('PUN_ROOT', dirname(__FILE__).'/');
  10. require PUN_ROOT.'include/common.php';
  11. require PUN_ROOT.'include/common_admin.php';
  12. if (!$pun_user['is_admmod'])
  13. message($lang->t('No permission'));
  14. // Load the admin_users.php language file
  15. $lang->load('admin_users');
  16. // Show IP statistics for a certain user ID
  17. if (isset($_GET['ip_stats']))
  18. {
  19. $ip_stats = intval($_GET['ip_stats']);
  20. if ($ip_stats < 1)
  21. message($lang->t('Bad request'));
  22. // Fetch ip count: TODO: This query is horrible - why do we fetch all the data just to count it? We should use something like
  23. // SELECT COUNT(DISTINCT poster_ip) FROM posts WHERE poster_id = :poster_id - though PostgreSQL doesn't seem to support that :(
  24. $query = $db->select(array('poster_ip' => 'p.poster_ip', 'last_used' => 'MAX(p.posted) AS last_used'), 'posts AS p');
  25. $query->where = 'p.poster_id = :poster_id';
  26. $query->group = array('poster_ip' => 'p.poster_ip');
  27. $params = array(':poster_id' => $ip_stats);
  28. $result = $query->run($params);
  29. $num_ips = count($result);
  30. unset ($result, $query, $params);
  31. // Determine the ip offset (based on $_GET['p'])
  32. $num_pages = ceil($num_ips / 50);
  33. $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
  34. $start_from = 50 * ($p - 1);
  35. // Generate paging links
  36. $paging_links = '<span class="pages-label">'.$lang->t('Pages').' </span>'.paginate($num_pages, $p, 'admin_users.php?ip_stats='.$ip_stats );
  37. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'), $lang->t('Results head'));
  38. define('PUN_ACTIVE_PAGE', 'admin');
  39. require PUN_ROOT.'header.php';
  40. ?>
  41. <div class="linkst">
  42. <div class="inbox crumbsplus">
  43. <ul class="crumbs">
  44. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  45. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  46. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  47. </ul>
  48. <div class="pagepost">
  49. <p class="pagelink"><?php echo $paging_links ?></p>
  50. </div>
  51. <div class="clearer"></div>
  52. </div>
  53. </div>
  54. <div id="users1" class="blocktable">
  55. <h2><span><?php echo $lang->t('Results head') ?></span></h2>
  56. <div class="box">
  57. <div class="inbox">
  58. <table cellspacing="0">
  59. <thead>
  60. <tr>
  61. <th class="tcl" scope="col"><?php echo $lang->t('Results IP address head') ?></th>
  62. <th class="tc2" scope="col"><?php echo $lang->t('Results last used head') ?></th>
  63. <th class="tc3" scope="col"><?php echo $lang->t('Results times found head') ?></th>
  64. <th class="tcr" scope="col"><?php echo $lang->t('Results action head') ?></th>
  65. </tr>
  66. </thead>
  67. <tbody>
  68. <?php
  69. $query = $db->select(array('poster_ip' => 'p.poster_ip', 'last_used' => 'MAX(p.posted) AS last_used', 'used_times' => 'COUNT(p.id) AS used_times'), 'posts AS p');
  70. $query->where = 'p.poster_id = :poster_id';
  71. $query->group = array('poster_ip' => 'p.poster_ip');
  72. $query->order = array('last_used' => 'last_used DESC');
  73. $query->offset = $start_from;
  74. $query->limit = 50;
  75. $params = array(':poster_id' => $ip_stats);
  76. $result = $query->run($params);
  77. if (!empty($result))
  78. {
  79. foreach ($result as $cur_ip)
  80. {
  81. ?>
  82. <tr>
  83. <td class="tcl"><a href="moderate.php?get_host=<?php echo $cur_ip['poster_ip'] ?>"><?php echo $cur_ip['poster_ip'] ?></a></td>
  84. <td class="tc2"><?php echo format_time($cur_ip['last_used']) ?></td>
  85. <td class="tc3"><?php echo $cur_ip['used_times'] ?></td>
  86. <td class="tcr"><a href="admin_users.php?show_users=<?php echo $cur_ip['poster_ip'] ?>"><?php echo $lang->t('Results find more link') ?></a></td>
  87. </tr>
  88. <?php
  89. }
  90. }
  91. else
  92. echo "\t\t\t\t".'<tr><td class="tcl" colspan="4">'.$lang->t('Results no posts found').'</td></tr>'."\n";
  93. unset ($result, $query, $params);
  94. ?>
  95. </tbody>
  96. </table>
  97. </div>
  98. </div>
  99. </div>
  100. <div class="linksb">
  101. <div class="inbox crumbsplus">
  102. <div class="pagepost">
  103. <p class="pagelink"><?php echo $paging_links ?></p>
  104. </div>
  105. <ul class="crumbs">
  106. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  107. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  108. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  109. </ul>
  110. <div class="clearer"></div>
  111. </div>
  112. </div>
  113. <?php
  114. require PUN_ROOT.'footer.php';
  115. }
  116. if (isset($_GET['show_users']))
  117. {
  118. $ip = trim($_GET['show_users']);
  119. if (!@preg_match('%^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$%', $ip) && !@preg_match('%^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$%', $ip))
  120. message($lang->t('Bad IP message'));
  121. // Fetch user count: TODO: Again, we really shouldn't fetch all the data just to count it...
  122. $query = $db->select(array('poster_id' => 'p.poster_id', 'poster' => 'p.poster'), 'posts AS p', true);
  123. $query->where = 'poster_ip = :poster_ip';
  124. $params = array(':poster_ip' => $ip);
  125. $result = $query->run($params);
  126. $num_users = count($result);
  127. unset ($result, $query, $params);
  128. // Determine the user offset (based on $_GET['p'])
  129. $num_pages = ceil($num_users / 50);
  130. $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
  131. $start_from = 50 * ($p - 1);
  132. // Generate paging links
  133. $paging_links = '<span class="pages-label">'.$lang->t('Pages').' </span>'.paginate($num_pages, $p, 'admin_users.php?show_users='.$ip);
  134. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'), $lang->t('Results head'));
  135. define('PUN_ACTIVE_PAGE', 'admin');
  136. require PUN_ROOT.'header.php';
  137. ?>
  138. <div class="linkst">
  139. <div class="inbox crumbsplus">
  140. <ul class="crumbs">
  141. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  142. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  143. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  144. </ul>
  145. <div class="pagepost">
  146. <p class="pagelink"><?php echo $paging_links ?></p>
  147. </div>
  148. <div class="clearer"></div>
  149. </div>
  150. </div>
  151. <div id="users2" class="blocktable">
  152. <h2><span><?php echo $lang->t('Results head') ?></span></h2>
  153. <div class="box">
  154. <div class="inbox">
  155. <table cellspacing="0">
  156. <thead>
  157. <tr>
  158. <th class="tcl" scope="col"><?php echo $lang->t('Results username head') ?></th>
  159. <th class="tc2" scope="col"><?php echo $lang->t('Results email head') ?></th>
  160. <th class="tc3" scope="col"><?php echo $lang->t('Results title head') ?></th>
  161. <th class="tc4" scope="col"><?php echo $lang->t('Results posts head') ?></th>
  162. <th class="tc5" scope="col"><?php echo $lang->t('Results admin note head') ?></th>
  163. <th class="tcr" scope="col"><?php echo $lang->t('Results actions head') ?></th>
  164. </tr>
  165. </thead>
  166. <tbody>
  167. <?php
  168. $query = $db->select(array('poster_id' => 'p.poster_id', 'poster' => 'p.poster'), 'posts AS p', true);
  169. $query->where = 'p.poster_ip = :poster_ip';
  170. $query->order = array('poster' => 'p.poster DESC');
  171. $params = array(':poster_ip' => $ip);
  172. $result = $query->run($params);
  173. $num_posts = count($result);
  174. unset ($query, $params);
  175. if ($num_posts)
  176. {
  177. $query = $db->select(array('id' => 'u.id', 'username' => 'u.username', 'email' => 'u.email', 'title' => 'u.title', 'num_posts' => 'u.num_posts', 'admin_note' => 'u.admin_note', 'g_id' => 'g.g_id', 'g_user_title' => 'g.g_user_title'), 'users AS u');
  178. $query->innerJoin('g', 'groups AS g', 'g.g_id = u.group_id');
  179. $query->where = 'u.id > 1 AND u.id = :poster_id';
  180. // Loop through users and print out some info
  181. foreach ($result as $cur_post)
  182. {
  183. $poster_id = $cur_post['poster_id'];
  184. $poster = $cur_post['poster'];
  185. // TODO: Do we really need a query within a query here...?
  186. $params = array(':poster_id' => $poster_id);
  187. $result_user = $query->run($params);
  188. if (!empty($result_user))
  189. {
  190. $user_data = $result_user[0];
  191. $user_title = get_title($user_data);
  192. $actions = '<a href="admin_users.php?ip_stats='.$user_data['id'].'">'.$lang->t('Results view IP link').'</a> | <a href="search.php?action=show_user_posts&amp;user_id='.$user_data['id'].'">'.$lang->t('Results show posts link').'</a>';
  193. ?>
  194. <tr>
  195. <td class="tcl"><?php echo '<a href="profile.php?id='.$user_data['id'].'">'.pun_htmlspecialchars($user_data['username']).'</a>' ?></td>
  196. <td class="tc2"><a href="mailto:<?php echo $user_data['email'] ?>"><?php echo $user_data['email'] ?></a></td>
  197. <td class="tc3"><?php echo $user_title ?></td>
  198. <td class="tc4"><?php echo forum_number_format($user_data['num_posts']) ?></td>
  199. <td class="tc5"><?php echo ($user_data['admin_note'] != '') ? pun_htmlspecialchars($user_data['admin_note']) : '&#160;' ?></td>
  200. <td class="tcr"><?php echo $actions ?></td>
  201. </tr>
  202. <?php
  203. }
  204. else
  205. {
  206. ?>
  207. <tr>
  208. <td class="tcl"><?php echo pun_htmlspecialchars($poster) ?></td>
  209. <td class="tc2">&#160;</td>
  210. <td class="tc3"><?php echo $lang->t('Results guest') ?></td>
  211. <td class="tc4">&#160;</td>
  212. <td class="tc5">&#160;</td>
  213. <td class="tcr">&#160;</td>
  214. </tr>
  215. <?php
  216. }
  217. }
  218. unset ($query, $params, $result_user);
  219. }
  220. else
  221. echo "\t\t\t\t".'<tr><td class="tcl" colspan="6">'.$lang->t('Results no IP found').'</td></tr>'."\n";
  222. unset ($result);
  223. ?>
  224. </tbody>
  225. </table>
  226. </div>
  227. </div>
  228. </div>
  229. <div class="linksb">
  230. <div class="inbox crumbsplus">
  231. <div class="pagepost">
  232. <p class="pagelink"><?php echo $paging_links ?></p>
  233. </div>
  234. <ul class="crumbs">
  235. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  236. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  237. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  238. </ul>
  239. <div class="clearer"></div>
  240. </div>
  241. </div>
  242. <?php
  243. require PUN_ROOT.'footer.php';
  244. }
  245. // Move multiple users to other user groups
  246. else if (isset($_POST['move_users']) || isset($_POST['move_users_comply']))
  247. {
  248. if ($pun_user['g_id'] > PUN_ADMIN)
  249. message($lang->t('No permission'));
  250. confirm_referrer('admin_users.php');
  251. if (isset($_POST['users']))
  252. {
  253. $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
  254. $user_ids = array_map('intval', $user_ids);
  255. // Delete invalid IDs
  256. $user_ids = array_diff($user_ids, array(0, 1));
  257. }
  258. else
  259. $user_ids = array();
  260. if (empty($user_ids))
  261. message($lang->t('No users selected'));
  262. // Are we trying to batch move any admins?
  263. $query = $db->select(array('count' => 'COUNT(u.*) AS count'), 'users AS u');
  264. $query->where = 'u.id IN :user_ids AND u.group_id = :group_id';
  265. $params = array(':user_ids' => $user_ids, ':group_id' => PUN_ADMIN);
  266. $result = $query->run($params);
  267. if ($result[0]['count'] > 0)
  268. message($lang->t('No move admins message'));
  269. unset($query, $params, $result);
  270. // Fetch all user groups
  271. $query = $db->select(array('g_id' => 'g.g_id', 'g_title' => 'g.g_title'), 'groups AS g');
  272. $query->where = 'g.g_id NOT IN :group_ids';
  273. $query->order = array('g_title' => 'g.g_title ASC');
  274. $params = array(':group_ids' => array(PUN_GUEST, PUN_ADMIN));
  275. $result = $query->run($params);
  276. $all_groups = array();
  277. foreach ($result as $row)
  278. $all_groups[$row['g_id']] = $row['g_title'];
  279. unset($query, $params, $result);
  280. if (isset($_POST['move_users_comply']))
  281. {
  282. $new_group = isset($_POST['new_group']) && isset($all_groups[$_POST['new_group']]) ? $_POST['new_group'] : message($lang->t('Invalid group message'));
  283. // Is the new group a moderator group?
  284. $query = $db->select(array('g_moderator' => 'g.g_moderator'), 'groups AS g');
  285. $query->where = 'g.g_id = :group_id';
  286. $params = array(':group_id' => $new_group);
  287. $result = $query->run($params);
  288. $new_group_mod = $result[0]['g_moderator'];
  289. unset ($result, $query, $params);
  290. // Fetch user groups
  291. $user_groups = array();
  292. $query = $db->select(array('id' => 'u.id', 'group_id' => 'u.group_id'), 'users AS u');
  293. $query->where = 'u.id IN :user_ids';
  294. $params = array(':user_ids' => $user_ids);
  295. $result = $query->run($params);
  296. foreach ($result as $cur_user)
  297. {
  298. if (!isset($user_groups[$cur_user['group_id']]))
  299. $user_groups[$cur_user['group_id']] = array();
  300. $user_groups[$cur_user['group_id']][] = $cur_user['id'];
  301. }
  302. unset($query, $params, $result);
  303. // Are any users moderators?
  304. $group_ids = array_keys($user_groups);
  305. $query = $db->select(array('g_id' => 'g.g_id', 'g_moderator' => 'g.g_moderator'), 'groups AS g');
  306. $query->where = 'g.g_id IN :group_ids';
  307. $params = array(':group_ids' => $group_ids);
  308. $result = $query->run($params);
  309. foreach ($result as $cur_group)
  310. {
  311. if ($cur_group['g_moderator'] == '0')
  312. unset($user_groups[$cur_group['g_id']]);
  313. }
  314. unset($query, $params, $result);
  315. if (!empty($user_groups) && $new_group != PUN_ADMIN && $new_group_mod != '1')
  316. {
  317. // Fetch forum list and clean up their moderator list
  318. $query = $db->select(array('id' => 'f.id', 'moderators' => 'f.moderators'), 'forums AS f');
  319. $params = array();
  320. $result = $query->run($params);
  321. unset ($query, $params);
  322. $update_query = $db->update(array('moderators' => ':moderators'), 'forums');
  323. $update_query->where = 'id = :forum_id';
  324. foreach ($result as $cur_forum)
  325. {
  326. $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
  327. foreach ($user_groups as $group_users)
  328. $cur_moderators = array_diff($cur_moderators, $group_users);
  329. $params = array(':moderators' => empty($cur_moderators) ? null : serialize($cur_moderators), ':forum_id' => $cur_forum['id']);
  330. $update_query->run($params);
  331. unset ($params);
  332. }
  333. unset ($result, $update_query);
  334. }
  335. // Change user group
  336. $query = $db->update(array('group_id' => ':group_id'), 'users');
  337. $query->where = 'id IN :uids';
  338. $params = array(':group_id' => $new_group, ':uids' => $user_ids);
  339. $query->run($params);
  340. unset ($query, $params);
  341. redirect('admin_users.php', $lang->t('Users move redirect'));
  342. }
  343. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'), $lang->t('Move users'));
  344. define('PUN_ACTIVE_PAGE', 'admin');
  345. require PUN_ROOT.'header.php';
  346. generate_admin_menu('users');
  347. ?>
  348. <div class="blockform">
  349. <h2><span><?php echo $lang->t('Move users') ?></span></h2>
  350. <div class="box">
  351. <form name="confirm_move_users" method="post" action="admin_users.php">
  352. <input type="hidden" name="users" value="<?php echo implode(',', $user_ids) ?>" />
  353. <div class="inform">
  354. <fieldset>
  355. <legend><?php echo $lang->t('Move users subhead') ?></legend>
  356. <div class="infldset">
  357. <table class="aligntop" cellspacing="0">
  358. <tr>
  359. <th scope="row"><?php echo $lang->t('New group label') ?></th>
  360. <td>
  361. <select name="new_group" tabindex="1">
  362. <?php foreach ($all_groups as $gid => $group) : ?> <option value="<?php echo $gid ?>"><?php echo pun_htmlspecialchars($group) ?></option>
  363. <?php endforeach; ?>
  364. </select>
  365. <span><?php echo $lang->t('New group help') ?></span>
  366. </td>
  367. </tr>
  368. </table>
  369. </div>
  370. </fieldset>
  371. </div>
  372. <p class="submitend"><input type="submit" name="move_users_comply" value="<?php echo $lang->t('Save') ?>" tabindex="2" /></p>
  373. </form>
  374. </div>
  375. </div>
  376. <div class="clearer"></div>
  377. </div>
  378. <?php
  379. require PUN_ROOT.'footer.php';
  380. }
  381. // Delete multiple users
  382. else if (isset($_POST['delete_users']) || isset($_POST['delete_users_comply']))
  383. {
  384. if ($pun_user['g_id'] > PUN_ADMIN)
  385. message($lang->t('No permission'));
  386. confirm_referrer('admin_users.php');
  387. if (isset($_POST['users']))
  388. {
  389. $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
  390. $user_ids = array_map('intval', $user_ids);
  391. // Delete invalid IDs
  392. $user_ids = array_diff($user_ids, array(0, 1));
  393. }
  394. else
  395. $user_ids = array();
  396. if (empty($user_ids))
  397. message($lang->t('No users selected'));
  398. // Are we trying to delete any admins?
  399. $query = $db->select(array('count' => 'COUNT(u.*) AS count'), 'users AS u');
  400. $query->where = 'u.id IN :user_ids AND group_id = :group_id';
  401. $params = array(':user_ids' => $user_ids, ':group_id' => PUN_ADMIN);
  402. $result = $query->run($params);
  403. if ($result[0]['count'] > 0)
  404. message($lang->t('No delete admins message'));
  405. unset($query, $params, $result);
  406. if (isset($_POST['delete_users_comply']))
  407. {
  408. // Fetch user groups
  409. $query = $db->select(array('id' => 'u.id', 'group_id' => 'u.group_id'), 'users AS u');
  410. $query->where = 'u.id IN :user_ids';
  411. $params = array(':user_ids' => $user_ids);
  412. $result = $query->run($params);
  413. $user_groups = array();
  414. foreach ($result as $cur_user)
  415. {
  416. if (!isset($user_groups[$cur_user['group_id']]))
  417. $user_groups[$cur_user['group_id']] = array();
  418. $user_groups[$cur_user['group_id']][] = $cur_user['id'];
  419. }
  420. unset($query, $params, $result);
  421. // Are any users moderators?
  422. $group_ids = array_keys($user_groups);
  423. $query = $db->select(array('g_id' => 'g.g_id', 'g_moderator' => 'g.g_moderator'), 'groups AS g');
  424. $query->where = 'g.g_id IN :group_ids';
  425. $params = array(':group_ids' => $group_ids);
  426. $result = $query->run($params);
  427. foreach ($result as $cur_group)
  428. {
  429. if ($cur_group['g_moderator'] == '0')
  430. unset($user_groups[$cur_group['g_id']]);
  431. }
  432. unset($query, $params, $result);
  433. // Fetch forum list and clean up their moderator list
  434. $query = $db->select(array('id' => 'f.id', 'moderators' => 'f.moderators'), 'forums AS f');
  435. $params = array();
  436. $result = $query->run($params);
  437. unset ($query, $params);
  438. $update_query = $db->update(array('moderators' => ':moderators'), 'forums');
  439. $update_query->where = 'id = :forum_id';
  440. foreach ($result as $cur_forum)
  441. {
  442. $cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
  443. foreach ($user_groups as $group_users)
  444. $cur_moderators = array_diff($cur_moderators, $group_users);
  445. $params = array(':moderators' => empty($cur_moderators) ? null : serialize ($cur_moderators), ':forum_id' => $cur_forum['id']);
  446. $update_query->run($params);
  447. unset ($params);
  448. }
  449. unset ($result, $update_query);
  450. // Delete any subscriptions
  451. $query = $db->delete('topic_subscriptions');
  452. $query->where = 'user_id IN :uids';
  453. $params = array(':uids' => $user_ids);
  454. $query->run($params);
  455. unset ($query, $params);
  456. $query = $db->delete('forum_subscriptions');
  457. $query->where = 'user_id IN :uids';
  458. $params = array(':uids' => $user_ids);
  459. $query->run($params);
  460. unset ($query, $params);
  461. // Remove them from the online list (if they happen to be logged in)
  462. $query = $db->delete('online');
  463. $query->where = 'user_id IN :uids';
  464. $params = array(':uids' => $user_ids);
  465. $query->run($params);
  466. unset ($query, $params);
  467. // Should we delete all posts made by these users?
  468. if (isset($_POST['delete_posts']))
  469. {
  470. require PUN_ROOT.'include/search_idx.php';
  471. @set_time_limit(0);
  472. // Find all posts made by this user
  473. $query = $db->select(array('id' => 'p.id', 'topic_id' => 'p.topic_id', 'forum_id' => 't.forum_id'), 'posts AS p');
  474. $query->innerJoin('t', 'topics AS t', 't.id = p.topic_id');
  475. $query->innerJoin('f', 'forums AS f', 'f.id = t.forum_id');
  476. $query->where = 'p.poster_id IN :uids';
  477. $params = array(':uids' => $user_ids);
  478. $result = $query->run($params);
  479. unset ($query, $params);
  480. if (!empty($result))
  481. {
  482. $query = $db->select(array('id' => 'p.id'), 'posts AS p');
  483. $query->where = 'p.topic_id = :topic_id';
  484. $query->order = array('posted' => 'p.posted');
  485. $query->limit = '1';
  486. foreach ($result as $cur_post)
  487. {
  488. // Determine whether this post is the "topic post" or not
  489. $params = array(':topic_id' => $cur_post['topic_id']);
  490. $result2 = $query->run($params);
  491. if (isset($result2[0]['id']) && $result2[0]['id'] == $cur_post['id'])
  492. delete_topic($cur_post['topic_id']);
  493. else
  494. delete_post($cur_post['id'], $cur_post['topic_id']);
  495. update_forum($cur_post['forum_id']);
  496. }
  497. unset ($query, $params, $result2);
  498. }
  499. unset ($result);
  500. }
  501. else
  502. {
  503. // Set all their posts to guest
  504. $query = $db->update(array('poster_id' => '1'), 'posts');
  505. $query->where = 'poster_id IN :uids';
  506. $params = array(':uids' => $user_ids);
  507. $query->run($params);
  508. unset ($query, $params);
  509. }
  510. // Delete the users
  511. $query = $db->delete('users');
  512. $query->where = 'id IN :uids';
  513. $params = array(':uids' => $user_ids);
  514. $query->run($params);
  515. unset ($query, $params);
  516. // Delete user avatars
  517. foreach ($user_ids as $user_id)
  518. delete_avatar($user_id);
  519. // Regenerate the users info cache
  520. $cache->delete('boardstats');
  521. redirect('admin_users.php', $lang->t('Users delete redirect'));
  522. }
  523. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'), $lang->t('Delete users'));
  524. define('PUN_ACTIVE_PAGE', 'admin');
  525. require PUN_ROOT.'header.php';
  526. generate_admin_menu('users');
  527. ?>
  528. <div class="blockform">
  529. <h2><span><?php echo $lang->t('Delete users') ?></span></h2>
  530. <div class="box">
  531. <form name="confirm_del_users" method="post" action="admin_users.php">
  532. <input type="hidden" name="users" value="<?php echo implode(',', $user_ids) ?>" />
  533. <div class="inform">
  534. <fieldset>
  535. <legend><?php echo $lang->t('Confirm delete users subhead') ?></legend>
  536. <div class="infldset">
  537. <p><?php echo $lang->t('Confirm delete users info') ?></p>
  538. <div class="rbox">
  539. <label><input type="checkbox" name="delete_posts" value="1" checked="checked" /><?php echo $lang->t('Delete posts') ?><br /></label>
  540. </div>
  541. <p class="warntext"><strong><?php echo $lang->t('Delete warning') ?></strong></p>
  542. </div>
  543. </fieldset>
  544. </div>
  545. <p class="buttons"><input type="submit" name="delete_users_comply" value="<?php echo $lang->t('Delete') ?>" /> <a href="javascript:history.go(-1)"><?php echo $lang->t('Go back') ?></a></p>
  546. </form>
  547. </div>
  548. </div>
  549. <div class="clearer"></div>
  550. </div>
  551. <?php
  552. require PUN_ROOT.'footer.php';
  553. }
  554. // Ban multiple users
  555. else if (isset($_POST['ban_users']) || isset($_POST['ban_users_comply']))
  556. {
  557. if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_moderator'] != '1' || $pun_user['g_mod_ban_users'] == '0'))
  558. message($lang->t('No permission'));
  559. confirm_referrer('admin_users.php');
  560. if (isset($_POST['users']))
  561. {
  562. $user_ids = is_array($_POST['users']) ? array_keys($_POST['users']) : explode(',', $_POST['users']);
  563. $user_ids = array_map('intval', $user_ids);
  564. // Delete invalid IDs
  565. $user_ids = array_diff($user_ids, array(0, 1));
  566. }
  567. else
  568. $user_ids = array();
  569. if (empty($user_ids))
  570. message($lang->t('No users selected'));
  571. // Are we trying to ban any admins?
  572. $query = $db->select(array('count' => 'COUNT(u.id) AS count'), 'users AS u');
  573. $query->where = 'u.id IN :user_ids AND u.group_id = :group_id';
  574. $params = array(':user_ids' => $user_ids, ':group_id' => PUN_ADMIN);
  575. $result = $query->run($params);
  576. if ($result[0]['count'])
  577. message($lang->t('No ban admins message'));
  578. unset($query, $params, $result);
  579. // Also, we cannot ban moderators
  580. $query = $db->select(array('count' => 'COUNT(u.id) AS count'), 'users AS u');
  581. $query->innerJoin('g', 'groups AS g', 'u.group_id = g.g_id');
  582. $query->where = 'g.g_moderator = 1 AND u.id IN :user_ids';
  583. $params = array(':user_ids' => $user_ids);
  584. $result = $query->run($params);
  585. if ($result[0]['count'])
  586. message($lang->t('No ban mods message'));
  587. unset($query, $params, $result);
  588. if (isset($_POST['ban_users_comply']))
  589. {
  590. $ban_message = pun_trim($_POST['ban_message']);
  591. $ban_expire = pun_trim($_POST['ban_expire']);
  592. $ban_the_ip = isset($_POST['ban_the_ip']) ? intval($_POST['ban_the_ip']) : 0;
  593. if ($ban_expire != '' && $ban_expire != 'Never')
  594. {
  595. $ban_expire = strtotime($ban_expire.' GMT');
  596. if ($ban_expire == -1 || !$ban_expire)
  597. message($lang->t('Invalid date message').' '.$lang->t('Invalid date reasons'));
  598. $diff = ($pun_user['timezone'] + $pun_user['dst']) * 3600;
  599. $ban_expire -= $diff;
  600. if ($ban_expire <= time())
  601. message($lang->t('Invalid date message').' '.$lang->t('Invalid date reasons'));
  602. }
  603. else
  604. $ban_expire = 'NULL';
  605. // Fetch user information
  606. $user_info = array();
  607. $query = $db->select(array('id' => 'u.id', 'username' => 'u.username', 'email' => 'u.email', 'registration_ip' => 'u.registration_ip'), 'users AS u');
  608. $query->where = 'u.id IN :user_ids';
  609. $params = array(':user_ids' => $user_ids);
  610. $result = $query->run($params);
  611. foreach ($result as $cur_user)
  612. $user_info[$cur_user['id']] = array('username' => $cur_user['username'], 'email' => $cur_user['email'], 'ip' => $cur_user['registration_ip']);
  613. unset($query, $params, $result);
  614. // Overwrite the registration IP with one from the last post (if it exists)
  615. if ($ban_the_ip != 0)
  616. {
  617. // Fetch last post id
  618. $query_pid = $db->select(array('id' => 'MAX(id) AS id'), 'posts');
  619. $query_pid->where = 'poster_id IN :user_ids';
  620. $query_pid->group = array('poster_id' => 'poster_id');
  621. $query = $db->select(array('poster_id' => 'p.poster_id', 'poster_ip' => 'p.poster_ip'), $db->prefix.'posts AS p');
  622. $query->usePrefix = false; // Don't want prefix for innerJoin
  623. $query->innerJoin('i', '('.$query_pid->compile().') AS i', 'p.id = i.id');
  624. $params = array(':user_ids' => $user_ids);
  625. $result = $query->run($params);
  626. foreach ($result as $cur_address)
  627. $user_info[$cur_address['poster_id']]['ip'] = $cur_address['poster_ip'];
  628. unset($query_pid, $query, $params, $result);
  629. }
  630. // And insert the bans!
  631. foreach ($user_ids as $user_id)
  632. {
  633. $ban_username = $user_info[$user_id]['username'];
  634. $ban_email = $user_info[$user_id]['email'];
  635. $ban_ip = ($ban_the_ip != 0) ? $user_info[$user_id]['ip'] : NULL;
  636. $query = $db->insert(array('username' => ':username', 'ip' => ':ip', 'email' => ':email', 'message' => ':message', 'expire' => ':expire', 'ban_creator' => ':user_id'), 'bans');
  637. $params = array(':username' => $ban_username, ':ip' => $ban_ip, ':email' => $ban_email, ':message' => $ban_message, ':expire' => $ban_expire, ':user_id' => $pun_user['id']);
  638. $query->run($params);
  639. unset($query, $params);
  640. }
  641. // Regenerate the bans cache
  642. $cache->delete('bans');
  643. redirect('admin_users.php', $lang->t('Users banned redirect'));
  644. }
  645. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Bans'));
  646. $focus_element = array('bans2', 'ban_message');
  647. define('PUN_ACTIVE_PAGE', 'admin');
  648. require PUN_ROOT.'header.php';
  649. generate_admin_menu('users');
  650. ?>
  651. <div class="blockform">
  652. <h2><span><?php echo $lang->t('Ban users') ?></span></h2>
  653. <div class="box">
  654. <form id="bans2" name="confirm_ban_users" method="post" action="admin_users.php">
  655. <input type="hidden" name="users" value="<?php echo implode(',', $user_ids) ?>" />
  656. <div class="inform">
  657. <fieldset>
  658. <legend><?php echo $lang->t('Message expiry subhead') ?></legend>
  659. <div class="infldset">
  660. <table class="aligntop" cellspacing="0">
  661. <tr>
  662. <th scope="row"><?php echo $lang->t('Ban message label') ?></th>
  663. <td>
  664. <input type="text" name="ban_message" size="50" maxlength="255" tabindex="1" />
  665. <span><?php echo $lang->t('Bans message help') ?></span>
  666. </td>
  667. </tr>
  668. <tr>
  669. <th scope="row"><?php echo $lang->t('Expire date label') ?></th>
  670. <td>
  671. <input type="text" name="ban_expire" size="17" maxlength="10" tabindex="2" />
  672. <span><?php echo $lang->t('Expire date help') ?></span>
  673. </td>
  674. </tr>
  675. <tr>
  676. <th scope="row"><?php echo $lang->t('Ban IP label') ?></th>
  677. <td>
  678. <input type="radio" name="ban_the_ip" tabindex="3" value="1" checked="checked" />&#160;<strong><?php echo $lang->t('Yes') ?></strong>&#160;&#160;&#160;<input type="radio" name="ban_the_ip" tabindex="4" value="0" checked="checked" />&#160;<strong><?php echo $lang->t('No') ?></strong>
  679. <span><?php echo $lang->t('Ban IP help') ?></span>
  680. </td>
  681. </tr>
  682. </table>
  683. </div>
  684. </fieldset>
  685. </div>
  686. <p class="submitend"><input type="submit" name="ban_users_comply" value="<?php echo $lang->t('Save') ?>" tabindex="3" /></p>
  687. </form>
  688. </div>
  689. </div>
  690. <div class="clearer"></div>
  691. </div>
  692. <?php
  693. require PUN_ROOT.'footer.php';
  694. }
  695. else if (isset($_GET['find_user']))
  696. {
  697. $form = isset($_GET['form']) ? $_GET['form'] : array();
  698. // trim() all elements in $form
  699. $form = array_map('pun_trim', $form);
  700. $conditions = $query_str = array();
  701. $posts_greater = isset($_GET['posts_greater']) ? trim($_GET['posts_greater']) : '';
  702. $posts_less = isset($_GET['posts_less']) ? trim($_GET['posts_less']) : '';
  703. $last_post_after = isset($_GET['last_post_after']) ? trim($_GET['last_post_after']) : '';
  704. $last_post_before = isset($_GET['last_post_before']) ? trim($_GET['last_post_before']) : '';
  705. $last_visit_after = isset($_GET['last_visit_after']) ? trim($_GET['last_visit_after']) : '';
  706. $last_visit_before = isset($_GET['last_visit_before']) ? trim($_GET['last_visit_before']) : '';
  707. $registered_after = isset($_GET['registered_after']) ? trim($_GET['registered_after']) : '';
  708. $registered_before = isset($_GET['registered_before']) ? trim($_GET['registered_before']) : '';
  709. $order_by = isset($_GET['order_by']) && in_array($_GET['order_by'], array('username', 'email', 'num_posts', 'last_post', 'last_visit', 'registered')) ? $_GET['order_by'] : 'username';
  710. $direction = isset($_GET['direction']) && $_GET['direction'] == 'DESC' ? 'DESC' : 'ASC';
  711. $user_group = isset($_GET['user_group']) ? intval($_GET['user_group']) : -1;
  712. $query_str[] = 'order_by='.$order_by;
  713. $query_str[] = 'direction='.$direction;
  714. $query_str[] = 'user_group='.$user_group;
  715. if (preg_match('%[^0-9]%', $posts_greater.$posts_less))
  716. message($lang->t('Non numeric message'));
  717. // Try to convert date/time to timestamps
  718. if ($last_post_after != '')
  719. {
  720. $query_str[] = 'last_post_after='.$last_post_after;
  721. $last_post_after = strtotime($last_post_after);
  722. if ($last_post_after === false || $last_post_after == -1)
  723. message($lang->t('Invalid date time message'));
  724. $conditions[] = 'u.last_post>'.$last_post_after;
  725. }
  726. if ($last_post_before != '')
  727. {
  728. $query_str[] = 'last_post_before='.$last_post_before;
  729. $last_post_before = strtotime($last_post_before);
  730. if ($last_post_before === false || $last_post_before == -1)
  731. message($lang->t('Invalid date time message'));
  732. $conditions[] = 'u.last_post<'.$last_post_before;
  733. }
  734. if ($last_visit_after != '')
  735. {
  736. $query_str[] = 'last_visit_after='.$last_visit_after;
  737. $last_visit_after = strtotime($last_visit_after);
  738. if ($last_visit_after === false || $last_visit_after == -1)
  739. message($lang->t('Invalid date time message'));
  740. $conditions[] = 'u.last_visit>'.$last_visit_after;
  741. }
  742. if ($last_visit_before != '')
  743. {
  744. $query_str[] = 'last_visit_before='.$last_visit_before;
  745. $last_visit_before = strtotime($last_visit_before);
  746. if ($last_visit_before === false || $last_visit_before == -1)
  747. message($lang->t('Invalid date time message'));
  748. $conditions[] = 'u.last_visit<'.$last_visit_before;
  749. }
  750. if ($registered_after != '')
  751. {
  752. $query_str[] = 'registered_after='.$registered_after;
  753. $registered_after = strtotime($registered_after);
  754. if ($registered_after === false || $registered_after == -1)
  755. message($lang->t('Invalid date time message'));
  756. $conditions[] = 'u.registered>'.$registered_after;
  757. }
  758. if ($registered_before != '')
  759. {
  760. $query_str[] = 'registered_before='.$registered_before;
  761. $registered_before = strtotime($registered_before);
  762. if ($registered_before === false || $registered_before == -1)
  763. message($lang->t('Invalid date time message'));
  764. $conditions[] = 'u.registered<'.$registered_before;
  765. }
  766. $like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE';
  767. foreach ($form as $key => $input)
  768. {
  769. if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note')))
  770. {
  771. $conditions[] = 'u.'.$key.' '.$like_command.' '.$db->quote(str_replace('*', '%', $input));
  772. $query_str[] = 'form%5B'.$key.'%5D='.urlencode($input);
  773. }
  774. }
  775. if ($posts_greater != '')
  776. {
  777. $query_str[] = 'posts_greater='.$posts_greater;
  778. $conditions[] = 'u.num_posts>'.$posts_greater;
  779. }
  780. if ($posts_less != '')
  781. {
  782. $query_str[] = 'posts_less='.$posts_less;
  783. $conditions[] = 'u.num_posts<'.$posts_less;
  784. }
  785. if ($user_group > -1)
  786. $conditions[] = 'u.group_id='.$user_group;
  787. // Fetch user count
  788. $query = $db->select(array('count' => 'COUNT(u.id) AS num_users'), 'users AS u ');
  789. $query->leftJoin('g', 'groups AS g', 'g.g_id = u.group_id');
  790. $query->where = 'u.id > 1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '');
  791. $result = $query->run();
  792. $num_users = $result[0]['num_users'];
  793. // Determine the user offset (based on $_GET['p'])
  794. $num_pages = ceil($num_users / 50);
  795. $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
  796. $start_from = 50 * ($p - 1);
  797. // Generate paging links
  798. $paging_links = '<span class="pages-label">'.$lang->t('Pages').' </span>'.paginate($num_pages, $p, 'admin_users.php?find_user=&amp;'.implode('&amp;', $query_str));
  799. // Some helper variables for permissions
  800. $can_delete = $can_move = $pun_user['g_id'] == PUN_ADMIN;
  801. $can_ban = $pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_moderator'] == '1' && $pun_user['g_mod_ban_users'] == '1');
  802. $can_action = ($can_delete || $can_ban || $can_move) && $num_users > 0;
  803. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'), $lang->t('Results head'));
  804. $page_head = array('js' => '<script type="text/javascript" src="common.js"></script>');
  805. define('PUN_ACTIVE_PAGE', 'admin');
  806. require PUN_ROOT.'header.php';
  807. ?>
  808. <div class="linkst">
  809. <div class="inbox crumbsplus">
  810. <ul class="crumbs">
  811. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  812. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  813. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  814. </ul>
  815. <div class="pagepost">
  816. <p class="pagelink"><?php echo $paging_links ?></p>
  817. </div>
  818. <div class="clearer"></div>
  819. </div>
  820. </div>
  821. <form id="search-users-form" action="admin_users.php" method="post">
  822. <div id="users2" class="blocktable">
  823. <h2><span><?php echo $lang->t('Results head') ?></span></h2>
  824. <div class="box">
  825. <div class="inbox">
  826. <table cellspacing="0">
  827. <thead>
  828. <tr>
  829. <th class="tcl" scope="col"><?php echo $lang->t('Results username head') ?></th>
  830. <th class="tc2" scope="col"><?php echo $lang->t('Results email head') ?></th>
  831. <th class="tc3" scope="col"><?php echo $lang->t('Results title head') ?></th>
  832. <th class="tc4" scope="col"><?php echo $lang->t('Results posts head') ?></th>
  833. <th class="tc5" scope="col"><?php echo $lang->t('Results admin note head') ?></th>
  834. <th class="tcr" scope="col"><?php echo $lang->t('Results actions head') ?></th>
  835. <?php if ($can_action): ?> <th class="tcmod" scope="col"><?php echo $lang->t('Select') ?></th>
  836. <?php endif; ?>
  837. </tr>
  838. </thead>
  839. <tbody>
  840. <?php
  841. $query = $db->select(array('id' => 'u.id', 'username' => 'u.username', 'email' => 'u.email', 'title' => 'u.title', 'num_posts' => 'u.num_posts', 'admin_note' => 'u.admin_note', 'g_id' => 'g.g_id', 'g_user_title' => 'g.g_user_title'), 'users AS u');
  842. $query->leftJoin('g', 'groups AS g', 'g.g_id = u.group_id');
  843. $query->where = 'u.id > 1'.(!empty($conditions) ? ' AND '.implode(' AND ', $conditions) : '');
  844. $query->order = array('order' => $order_by.' '.$direction);
  845. $query->limit = '50';
  846. $query->offset = $start_from;
  847. $result = $query->run();
  848. if (!empty($result))
  849. {
  850. foreach ($result as $user_data)
  851. {
  852. $user_title = get_title($user_data);
  853. // This script is a special case in that we want to display "Not verified" for non-verified users
  854. if (($user_data['g_id'] == '' || $user_data['g_id'] == PUN_UNVERIFIED) && $user_title != $lang->t('Banned'))
  855. $user_title = '<span class="warntext">'.$lang->t('Not verified').'</span>';
  856. $actions = '<a href="admin_users.php?ip_stats='.$user_data['id'].'">'.$lang->t('Results view IP link').'</a> | <a href="search.php?action=show_user_posts&amp;user_id='.$user_data['id'].'">'.$lang->t('Results show posts link').'</a>';
  857. ?>
  858. <tr>
  859. <td class="tcl"><?php echo '<a href="profile.php?id='.$user_data['id'].'">'.pun_htmlspecialchars($user_data['username']).'</a>' ?></td>
  860. <td class="tc2"><a href="mailto:<?php echo $user_data['email'] ?>"><?php echo $user_data['email'] ?></a></td>
  861. <td class="tc3"><?php echo $user_title ?></td>
  862. <td class="tc4"><?php echo forum_number_format($user_data['num_posts']) ?></td>
  863. <td class="tc5"><?php echo ($user_data['admin_note'] != '') ? pun_htmlspecialchars($user_data['admin_note']) : '&#160;' ?></td>
  864. <td class="tcr"><?php echo $actions ?></td>
  865. <?php if ($can_action): ?> <td class="tcmod"><input type="checkbox" name="users[<?php echo $user_data['id'] ?>]" value="1" /></td>
  866. <?php endif; ?>
  867. </tr>
  868. <?php
  869. }
  870. }
  871. else
  872. echo "\t\t\t\t".'<tr><td class="tcl" colspan="6">'.$lang->t('No match').'</td></tr>'."\n";
  873. unset ($result, $query);
  874. ?>
  875. </tbody>
  876. </table>
  877. </div>
  878. </div>
  879. </div>
  880. <div class="linksb">
  881. <div class="inbox crumbsplus">
  882. <div class="pagepost">
  883. <p class="pagelink"><?php echo $paging_links ?></p>
  884. <?php if ($can_action): ?> <p class="conr modbuttons"><a href="#" onclick="return select_checkboxes('search-users-form', this, '<?php echo $lang->t('Unselect all') ?>')"><?php echo $lang->t('Select all') ?></a> <?php if ($can_ban) : ?><input type="submit" name="ban_users" value="<?php echo $lang->t('Ban') ?>" /><?php endif; if ($can_delete) : ?><input type="submit" name="delete_users" value="<?php echo $lang->t('Delete') ?>" /><?php endif; if ($can_move) : ?><input type="submit" name="move_users" value="<?php echo $lang->t('Change group') ?>" /><?php endif; ?></p>
  885. <?php endif; ?>
  886. </div>
  887. <ul class="crumbs">
  888. <li><a href="admin_index.php"><?php echo $lang->t('Admin').' '.$lang->t('Index') ?></a></li>
  889. <li><span>»&#160;</span><a href="admin_users.php"><?php echo $lang->t('Users') ?></a></li>
  890. <li><span>»&#160;</span><strong><?php echo $lang->t('Results head') ?></strong></li>
  891. </ul>
  892. <div class="clearer"></div>
  893. </div>
  894. </div>
  895. </form>
  896. <?php
  897. require PUN_ROOT.'footer.php';
  898. }
  899. else
  900. {
  901. $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang->t('Admin'), $lang->t('Users'));
  902. $focus_element = array('find_user', 'form[username]');
  903. define('PUN_ACTIVE_PAGE', 'admin');
  904. require PUN_ROOT.'header.php';
  905. generate_admin_menu('users');
  906. ?>
  907. <div class="blockform">
  908. <h2><span><?php echo $lang->t('User search head') ?></span></h2>
  909. <div class="box">
  910. <form id="find_user" method="get" action="admin_users.php">
  911. <p class="submittop"><input type="submit" name="find_user" value="<?php echo $lang->t('Submit search') ?>" tabindex="1" /></p>
  912. <div class="inform">
  913. <fieldset>
  914. <legend><?php echo $lang->t('User search subhead') ?></legend>
  915. <div class="infldset">
  916. <p><?php echo $lang->t('User search info') ?></p>
  917. <table class="aligntop" cellspacing="0">
  918. <tr>
  919. <th scope="row"><?php echo $lang->t('Username label') ?></th>
  920. <td><input type="text" name="form[username]" size="25" maxlength="25" tabindex="2" /></td>
  921. </tr>
  922. <tr>
  923. <th scope="row"><?php echo $lang->t('Email address label') ?></th>
  924. <td><input type="text" name="form[email]" size="30" maxlength="80" tabindex="3" /></td>
  925. </tr>
  926. <tr>
  927. <th scope="row"><?php echo $lang->t('Title label') ?></th>
  928. <td><input type="text" name="form[title]" size="30" maxlength="50" tabindex="4" /></td>
  929. </tr>
  930. <tr>
  931. <th scope="row"><?php echo $lang->t('Real name label') ?></th>
  932. <td><input type="text" name="form[realname]" size="30" maxlength="40" tabindex="5" /></td>
  933. </tr>
  934. <tr>
  935. <th scope="row"><?php echo $lang->t('Website label') ?></th>
  936. <td><input type="text" name="form[url]" size="35" maxlength="100" tabindex="6" /></td>
  937. </tr>
  938. <tr>
  939. <th scope="row"><?php echo $lang->t('Jabber label') ?></th>
  940. <td><input type="text" name="form[jabber]" size="30" maxlength="75" tabindex="7" /></td>
  941. </tr>
  942. <tr>
  943. <th scope="row"><?php echo $lang->t('ICQ label') ?></th>
  944. <td><input type="text" name="form[icq]" size="12" maxlength="12" tabindex="8" /></td>
  945. </tr>
  946. <tr>
  947. <th scope="row"><?php echo $lang->t('MSN label') ?></th>
  948. <td><input type="text" name="form[msn]" size="30" maxlength="50" tabindex="9" /></td>
  949. </tr>
  950. <tr>
  951. <th scope="row"><?php echo $lang->t('AOL label') ?></th>
  952. <td><input type="text" name="form[aim]" size="20" maxlength="20" tabindex="10" /></td>
  953. </tr>
  954. <tr>
  955. <th scope="row"><?php echo $lang->t('Yahoo label') ?></th>
  956. <td><input type="text" name="form[yahoo]" size="20" maxlength="20" tabindex="11" /></td>
  957. </tr>
  958. <tr>
  959. <th scope="row"><?php echo $lang->t('Location label') ?></th>
  960. <td><input type="text" name="form[location]" size="30" maxlength="30" tabindex="12" /></td>
  961. </tr>
  962. <tr>
  963. <th scope="row"><?php echo $lang->t('Signature label') ?></th>
  964. <td><input type="text" name="form[signature]" size="35" maxlength="512" tabindex="13" /></td>
  965. </tr>
  966. <tr>
  967. <th scope="row"><?php echo $lang->t('Admin note label') ?></th>
  968. <td><input type="text" name="form[admin_note]" size="30" maxlength="30" tabindex="14" /></td>
  969. </tr>
  970. <tr>
  971. <th scope="row"><?php echo $lang->t('Posts more than label') ?></th>
  972. <td><input type="text" name="posts_greater" size="5" maxlength="8" tabindex="15" /></td>
  973. </tr>
  974. <tr>
  975. <th scope="row"><?php echo $lang->t('Posts less than label') ?></th>
  976. <td><input type="text" name="posts_less" size="5" maxlength="8" tabindex="16" /></td>
  977. </tr>
  978. <tr>
  979. <th scope="row"><?php echo $lang->t('Last post after label') ?></th>
  980. <td><input type="text" name="last_post_after" size="24" maxlength="19" tabindex="17" />
  981. <span><?php echo $lang->t('Date help') ?></span></td>
  982. </tr>
  983. <tr>
  984. <th scope="row"><?php echo $lang->t('Last post before label') ?></th>
  985. <td><input type="text" name="last_post_before" size="24" maxlength="19" tabindex="18" />
  986. <span><?php echo $lang->t('Date help') ?></span></td>
  987. </tr>
  988. <tr>
  989. <th scope="row"><?php echo $lang->t('Last visit after label') ?></th>
  990. <td><input type="text" name="last_visit_after" size="24" maxlength="19" tabindex="17" />
  991. <span><?php echo $lang->t('Date help') ?></span></td>
  992. </tr>
  993. <tr>
  994. <th scope="row"><?php echo $lang->t('Last visit before label') ?></th>
  995. <td><input type="text" name="last_visit_before" size="24" maxlength="19" tabindex="18" />
  996. <span><?php echo $lang->t('Date help') ?></span></td>
  997. </tr>
  998. <tr>
  999. <th scope="row"><?php echo $lang->t('Registered after label') ?></th>
  1000. <td><input type="text" name="registered_after" size="24" maxlength="19" tabindex="19" />
  1001. <span><?php echo $lang->t('Date help') ?></span></td>
  1002. </tr>
  1003. <tr>
  1004. <th scope="row"><?php echo $lang->t('Registered before label') ?></th>
  1005. <td><input type="text" name="registered_before" size="24" maxlength="19" tabindex="20" />
  1006. <span><?php echo $lang->t('Date help') ?></span></td>
  1007. </tr>
  1008. <tr>
  1009. <th scope="row"><?php echo $lang->t('Order by label') ?></th>
  1010. <td>
  1011. <select name="order_by" tabindex="21">
  1012. <option value="username" selected="selected"><?php echo $lang->t('Order by username') ?></option>
  1013. <option value="email"><?php echo $lang->t('Order by email') ?></option>
  1014. <option value="num_posts"><?php echo $lang->t('Order by posts') ?></option>
  1015. <option value="last_post"><?php echo $lang->t('Order by last post') ?></option>
  1016. <option value="last_visit"><?php echo $lang->t('Order by last visit') ?></option>
  1017. <option value="registered"><?php echo $lang->t('Order by registered') ?></option>
  1018. </select>&#160;&#160;&#160;<select name="direction" tabindex="22">
  1019. <option value="ASC" selected="selected"><?php echo $lang->t('Ascending') ?></option>
  1020. <option value="DESC"><?php echo $lang->t('Descending') ?></option>
  1021. </select>
  1022. </td>
  1023. </tr>
  1024. <tr>
  1025. <th scope="row"><?php echo $lang->t('User group label') ?></th>
  1026. <td>
  1027. <select name="user_group" tabindex="23">
  1028. <option value="-1" selected="selected"><?php echo $lang->t('All groups') ?></option>
  1029. <option value="0"><?php echo $lang->t('Unverified users') ?></option>
  1030. <?php
  1031. $query = $db->select(array('g_id' => 'g.g_id', 'g_title' => 'g.g_title'), 'groups AS g');
  1032. $query->where = 'g.g_id != :group_guest';
  1033. $query->order = array('g_title' => 'g.g_title DESC');
  1034. $params = array(':group_guest' => PUN_GUEST);
  1035. $result = $query->run($params);
  1036. foreach ($result as $cur_group)
  1037. echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
  1038. unset ($result, $query, $params);
  1039. ?>
  1040. </select>
  1041. </td>
  1042. </tr>
  1043. </table>
  1044. </div>
  1045. </fieldset>
  1046. </div>
  1047. <p class="submitend"><input type="submit" name="find_user" value="<?php echo $lang->t('Submit search') ?>" tabindex="25" /></p>
  1048. </form>
  1049. </div>
  1050. <h2 class="block2"><span><?php echo $lang->t('IP search head') ?></span></h2>
  1051. <div class="box">
  1052. <form method="get" action="admin_users.php">
  1053. <div class="inform">
  1054. <fieldset>
  1055. <legend><?php echo $lang->t('IP search subhead') ?></legend>
  1056. <div class="infldset">
  1057. <table class="aligntop" cellspacing="0">
  1058. <tr>
  1059. <th scope="row"><?php echo $lang->t('IP address label') ?><div><input type="submit" value="<?php echo $lang->t('Find IP address') ?>" tabindex="26" /></div></th>
  1060. <td><input type="text" name="show_users" size="18" maxlength="15" tabindex="24" />
  1061. <span><?php echo $lang->t('IP address help') ?></span></td>
  1062. </tr>
  1063. </table>
  1064. </div>
  1065. </fieldset>
  1066. </div>
  1067. </form>
  1068. </div>
  1069. </div>
  1070. <div class="clearer"></div>
  1071. </div>
  1072. <?php
  1073. require PUN_ROOT.'footer.php';
  1074. }