Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
3.97% |
14 / 353 |
|
50.00% |
2 / 4 |
CRAP | n/a |
0 / 0 |
|
| mcp_post_details | |
0.00% |
0 / 278 |
|
0.00% |
0 / 1 |
5550 | |||
| phpbb_get_num_posters_for_ip | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
| phpbb_get_num_ips_for_poster | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
| change_poster | |
0.00% |
0 / 61 |
|
0.00% |
0 / 1 |
210 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * |
| 4 | * This file is part of the phpBB Forum Software package. |
| 5 | * |
| 6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
| 7 | * @license GNU General Public License, version 2 (GPL-2.0) |
| 8 | * |
| 9 | * For full copyright and license information, please see |
| 10 | * the docs/CREDITS.txt file. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | /** |
| 15 | * @ignore |
| 16 | */ |
| 17 | if (!defined('IN_PHPBB')) |
| 18 | { |
| 19 | exit; |
| 20 | } |
| 21 | |
| 22 | /** |
| 23 | * Handling actions in post details screen |
| 24 | */ |
| 25 | function mcp_post_details($id, $mode, $action) |
| 26 | { |
| 27 | global $phpEx, $phpbb_root_path, $config, $request; |
| 28 | global $template, $db, $user, $auth; |
| 29 | global $phpbb_container, $phpbb_dispatcher; |
| 30 | |
| 31 | $user->add_lang('posting'); |
| 32 | |
| 33 | $post_id = $request->variable('p', 0); |
| 34 | $start = $request->variable('start', 0); |
| 35 | |
| 36 | // Get post data |
| 37 | $post_info = phpbb_get_post_data(array($post_id), false, true); |
| 38 | |
| 39 | add_form_key('mcp_post_details'); |
| 40 | |
| 41 | if (!count($post_info)) |
| 42 | { |
| 43 | trigger_error('POST_NOT_EXIST'); |
| 44 | } |
| 45 | |
| 46 | $post_info = $post_info[$post_id]; |
| 47 | $url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . phpbb_extra_url()); |
| 48 | |
| 49 | switch ($action) |
| 50 | { |
| 51 | case 'whois': |
| 52 | |
| 53 | if ($auth->acl_get('m_info', $post_info['forum_id'])) |
| 54 | { |
| 55 | $ip = $request->variable('ip', ''); |
| 56 | if (!function_exists('user_ipwhois')) |
| 57 | { |
| 58 | include($phpbb_root_path . 'includes/functions_user.' . $phpEx); |
| 59 | } |
| 60 | |
| 61 | $template->assign_vars(array( |
| 62 | 'RETURN_POST' => sprintf($user->lang['RETURN_POST'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id") . '">', '</a>'), |
| 63 | 'U_RETURN_POST' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&p=$post_id"), |
| 64 | 'L_RETURN_POST' => sprintf($user->lang['RETURN_POST'], '', ''), |
| 65 | 'WHOIS' => user_ipwhois($ip), |
| 66 | )); |
| 67 | } |
| 68 | |
| 69 | // We're done with the whois page so return |
| 70 | return; |
| 71 | |
| 72 | break; |
| 73 | |
| 74 | case 'chgposter': |
| 75 | case 'chgposter_ip': |
| 76 | |
| 77 | if ($action == 'chgposter') |
| 78 | { |
| 79 | $username = $request->variable('username', '', true); |
| 80 | $sql_where = "username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; |
| 81 | } |
| 82 | else |
| 83 | { |
| 84 | $new_user_id = $request->variable('u', 0); |
| 85 | $sql_where = 'user_id = ' . $new_user_id; |
| 86 | } |
| 87 | |
| 88 | $sql = 'SELECT * |
| 89 | FROM ' . USERS_TABLE . ' |
| 90 | WHERE ' . $sql_where; |
| 91 | $result = $db->sql_query($sql); |
| 92 | $row = $db->sql_fetchrow($result); |
| 93 | $db->sql_freeresult($result); |
| 94 | |
| 95 | if (!$row) |
| 96 | { |
| 97 | trigger_error('NO_USER'); |
| 98 | } |
| 99 | |
| 100 | if ($auth->acl_get('m_chgposter', $post_info['forum_id'])) |
| 101 | { |
| 102 | if (check_form_key('mcp_post_details')) |
| 103 | { |
| 104 | change_poster($post_info, $row); |
| 105 | } |
| 106 | else |
| 107 | { |
| 108 | trigger_error('FORM_INVALID'); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | break; |
| 113 | |
| 114 | default: |
| 115 | |
| 116 | /** |
| 117 | * This event allows you to handle custom post moderation options |
| 118 | * |
| 119 | * @event core.mcp_post_additional_options |
| 120 | * @var string action Post moderation action name |
| 121 | * @var array post_info Information on the affected post |
| 122 | * @since 3.1.5-RC1 |
| 123 | */ |
| 124 | $vars = array('action', 'post_info'); |
| 125 | extract($phpbb_dispatcher->trigger_event('core.mcp_post_additional_options', compact($vars))); |
| 126 | |
| 127 | break; |
| 128 | } |
| 129 | |
| 130 | // Set some vars |
| 131 | $users_ary = $usernames_ary = array(); |
| 132 | $attachments = array(); |
| 133 | $post_id = $post_info['post_id']; |
| 134 | |
| 135 | // Get topic tracking info |
| 136 | if ($config['load_db_lastread']) |
| 137 | { |
| 138 | $tmp_topic_data = array($post_info['topic_id'] => $post_info); |
| 139 | $topic_tracking_info = get_topic_tracking($post_info['forum_id'], $post_info['topic_id'], $tmp_topic_data, array($post_info['forum_id'] => $post_info['forum_mark_time'])); |
| 140 | unset($tmp_topic_data); |
| 141 | } |
| 142 | else |
| 143 | { |
| 144 | $topic_tracking_info = get_complete_topic_tracking($post_info['forum_id'], $post_info['topic_id']); |
| 145 | } |
| 146 | |
| 147 | $post_unread = (isset($topic_tracking_info[$post_info['topic_id']]) && $post_info['post_time'] > $topic_tracking_info[$post_info['topic_id']]) ? true : false; |
| 148 | |
| 149 | // Process message, leave it uncensored |
| 150 | $parse_flags = ($post_info['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; |
| 151 | $message = generate_text_for_display($post_info['post_text'], $post_info['bbcode_uid'], $post_info['bbcode_bitfield'], $parse_flags, false); |
| 152 | |
| 153 | if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id'])) |
| 154 | { |
| 155 | $sql = 'SELECT * |
| 156 | FROM ' . ATTACHMENTS_TABLE . ' |
| 157 | WHERE post_msg_id = ' . $post_id . ' |
| 158 | AND in_message = 0 |
| 159 | ORDER BY filetime DESC, post_msg_id ASC'; |
| 160 | $result = $db->sql_query($sql); |
| 161 | |
| 162 | while ($row = $db->sql_fetchrow($result)) |
| 163 | { |
| 164 | $attachments[] = $row; |
| 165 | } |
| 166 | $db->sql_freeresult($result); |
| 167 | |
| 168 | if (count($attachments)) |
| 169 | { |
| 170 | $user->add_lang('viewtopic'); |
| 171 | $update_count = array(); |
| 172 | parse_attachments($post_info['forum_id'], $message, $attachments, $update_count); |
| 173 | } |
| 174 | |
| 175 | // Display not already displayed Attachments for this post, we already parsed them. ;) |
| 176 | if (!empty($attachments)) |
| 177 | { |
| 178 | $template->assign_var('S_HAS_ATTACHMENTS', true); |
| 179 | |
| 180 | foreach ($attachments as $attachment) |
| 181 | { |
| 182 | $template->assign_block_vars('attachment', array( |
| 183 | 'DISPLAY_ATTACHMENT' => $attachment) |
| 184 | ); |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | // Deleting information |
| 190 | if ($post_info['post_visibility'] == ITEM_DELETED && $post_info['post_delete_user']) |
| 191 | { |
| 192 | // User having deleted the post also being the post author? |
| 193 | if (!$post_info['post_delete_user'] || $post_info['post_delete_user'] == $post_info['poster_id']) |
| 194 | { |
| 195 | $display_username = get_username_string('full', $post_info['poster_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']); |
| 196 | } |
| 197 | else |
| 198 | { |
| 199 | $sql = 'SELECT user_id, username, user_colour |
| 200 | FROM ' . USERS_TABLE . ' |
| 201 | WHERE user_id = ' . (int) $post_info['post_delete_user']; |
| 202 | $result = $db->sql_query($sql); |
| 203 | $user_delete_row = $db->sql_fetchrow($result); |
| 204 | $db->sql_freeresult($result); |
| 205 | $display_username = get_username_string('full', $post_info['post_delete_user'], $user_delete_row['username'], $user_delete_row['user_colour']); |
| 206 | } |
| 207 | |
| 208 | $user->add_lang('viewtopic'); |
| 209 | $l_deleted_by = $user->lang('DELETED_INFORMATION', $display_username, $user->format_date($post_info['post_delete_time'], false, true)); |
| 210 | } |
| 211 | else |
| 212 | { |
| 213 | $l_deleted_by = ''; |
| 214 | } |
| 215 | |
| 216 | // parse signature |
| 217 | $parse_flags = ($post_info['user_sig_bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; |
| 218 | $post_info['user_sig'] = generate_text_for_display($post_info['user_sig'], $post_info['user_sig_bbcode_uid'], $post_info['user_sig_bbcode_bitfield'], $parse_flags, true); |
| 219 | |
| 220 | $mcp_post_template_data = array( |
| 221 | 'U_MCP_ACTION' => "$url&i=main&quickmod=1&mode=post_details", // Use this for mode paramaters |
| 222 | 'U_POST_ACTION' => "$url&i=$id&mode=post_details", // Use this for action parameters |
| 223 | 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id"), |
| 224 | |
| 225 | 'S_CAN_APPROVE' => $auth->acl_get('m_approve', $post_info['forum_id']), |
| 226 | 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), |
| 227 | 'S_CAN_CHGPOSTER' => $auth->acl_get('m_chgposter', $post_info['forum_id']), |
| 228 | 'S_CAN_LOCK_POST' => $auth->acl_get('m_lock', $post_info['forum_id']), |
| 229 | 'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']), |
| 230 | |
| 231 | 'S_POST_REPORTED' => ($post_info['post_reported']) ? true : false, |
| 232 | 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE) ? true : false, |
| 233 | 'S_POST_DELETED' => ($post_info['post_visibility'] == ITEM_DELETED) ? true : false, |
| 234 | 'S_POST_LOCKED' => ($post_info['post_edit_locked']) ? true : false, |
| 235 | 'S_USER_NOTES' => true, |
| 236 | 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, |
| 237 | 'DELETED_MESSAGE' => $l_deleted_by, |
| 238 | 'DELETE_REASON' => $post_info['post_delete_reason'], |
| 239 | |
| 240 | 'U_EDIT' => ($auth->acl_get('m_edit', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&p={$post_info['post_id']}") : '', |
| 241 | 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=mcp_chgposter&field=username&select_single=true'), |
| 242 | 'U_MCP_APPROVE' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=approve_details&p=' . $post_id), |
| 243 | 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=report_details&p=' . $post_id), |
| 244 | 'U_MCP_USER_NOTES' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&mode=user_notes&u=' . $post_info['user_id']), |
| 245 | 'U_MCP_WARN_USER' => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&mode=warn_user&u=' . $post_info['user_id']) : '', |
| 246 | 'U_VIEW_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $post_info['post_id'] . '#p' . $post_info['post_id']), |
| 247 | 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $post_info['topic_id']), |
| 248 | |
| 249 | 'MINI_POST_IMG' => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'), |
| 250 | 'MINI_POST' => ($post_unread) ? $user->lang['UNREAD_POST'] : $user->lang['POST'], |
| 251 | |
| 252 | 'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "p=$post_id") . "#p$post_id\">", '</a>'), |
| 253 | 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$post_info['forum_id']}&start={$start}") . '">', '</a>'), |
| 254 | 'REPORTED_IMG' => $user->img('icon_topic_reported', $user->lang['POST_REPORTED']), |
| 255 | 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', $user->lang['POST_UNAPPROVED']), |
| 256 | 'DELETED_IMG' => $user->img('icon_topic_deleted', $user->lang['POST_DELETED']), |
| 257 | 'EDIT_IMG' => $user->img('icon_post_edit', $user->lang['EDIT_POST']), |
| 258 | 'SEARCH_IMG' => $user->img('icon_user_search', $user->lang['SEARCH']), |
| 259 | |
| 260 | 'POST_AUTHOR_FULL' => get_username_string('full', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']), |
| 261 | 'POST_AUTHOR_COLOUR' => get_username_string('colour', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']), |
| 262 | 'POST_AUTHOR' => get_username_string('username', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']), |
| 263 | 'U_POST_AUTHOR' => get_username_string('profile', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']), |
| 264 | |
| 265 | 'POST_PREVIEW' => $message, |
| 266 | 'POST_SUBJECT' => $post_info['post_subject'], |
| 267 | 'POST_DATE' => $user->format_date($post_info['post_time']), |
| 268 | 'POST_IP' => $post_info['poster_ip'], |
| 269 | 'POST_IPADDR' => ($auth->acl_get('m_info', $post_info['forum_id']) && $request->variable('lookup', '')) ? @gethostbyaddr($post_info['poster_ip']) : '', |
| 270 | 'POST_ID' => $post_info['post_id'], |
| 271 | 'SIGNATURE' => $post_info['user_sig'], |
| 272 | |
| 273 | 'U_LOOKUP_IP' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? "$url&i=$id&mode=$mode&lookup={$post_info['poster_ip']}#ip" : '', |
| 274 | 'U_WHOIS' => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&action=whois&p=$post_id&ip={$post_info['poster_ip']}") : '', |
| 275 | ); |
| 276 | |
| 277 | $s_additional_opts = false; |
| 278 | |
| 279 | /** |
| 280 | * Event to add/modify MCP post template data |
| 281 | * |
| 282 | * @event core.mcp_post_template_data |
| 283 | * @var array post_info Array with the post information |
| 284 | * @var array mcp_post_template_data Array with the MCP post template data |
| 285 | * @var array attachments Array with the post attachments, if any |
| 286 | * @var bool s_additional_opts Must be set to true in extension if additional options are presented in MCP post panel |
| 287 | * @since 3.1.5-RC1 |
| 288 | */ |
| 289 | $vars = array( |
| 290 | 'post_info', |
| 291 | 'mcp_post_template_data', |
| 292 | 'attachments', |
| 293 | 's_additional_opts', |
| 294 | ); |
| 295 | extract($phpbb_dispatcher->trigger_event('core.mcp_post_template_data', compact($vars))); |
| 296 | |
| 297 | $template->assign_vars($mcp_post_template_data); |
| 298 | $template->assign_var('S_MCP_POST_ADDITIONAL_OPTS', $s_additional_opts); |
| 299 | |
| 300 | unset($mcp_post_template_data); |
| 301 | |
| 302 | // Get User Notes |
| 303 | $log_data = array(); |
| 304 | $log_count = false; |
| 305 | view_log('user', $log_data, $log_count, $config['posts_per_page'], 0, 0, 0, $post_info['user_id']); |
| 306 | |
| 307 | if (!empty($log_data)) |
| 308 | { |
| 309 | $template->assign_var('S_USER_NOTES', true); |
| 310 | |
| 311 | foreach ($log_data as $row) |
| 312 | { |
| 313 | $template->assign_block_vars('usernotes', array( |
| 314 | 'REPORT_BY' => $row['username_full'], |
| 315 | 'REPORT_AT' => $user->format_date($row['time']), |
| 316 | 'ACTION' => $row['action'], |
| 317 | 'ID' => $row['id']) |
| 318 | ); |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | // Get Reports |
| 323 | if ($auth->acl_get('m_report', $post_info['forum_id'])) |
| 324 | { |
| 325 | $sql = 'SELECT r.*, re.*, u.user_id, u.username |
| 326 | FROM ' . REPORTS_TABLE . ' r, ' . USERS_TABLE . ' u, ' . REPORTS_REASONS_TABLE . " re |
| 327 | WHERE r.post_id = $post_id |
| 328 | AND r.reason_id = re.reason_id |
| 329 | AND u.user_id = r.user_id |
| 330 | ORDER BY r.report_time DESC"; |
| 331 | $result = $db->sql_query($sql); |
| 332 | |
| 333 | if ($row = $db->sql_fetchrow($result)) |
| 334 | { |
| 335 | $template->assign_var('S_SHOW_REPORTS', true); |
| 336 | |
| 337 | do |
| 338 | { |
| 339 | // If the reason is defined within the language file, we will use the localized version, else just use the database entry... |
| 340 | if (isset($user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) |
| 341 | { |
| 342 | $row['reson_description'] = $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]; |
| 343 | $row['reason_title'] = $user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]; |
| 344 | } |
| 345 | |
| 346 | $template->assign_block_vars('reports', array( |
| 347 | 'REPORT_ID' => $row['report_id'], |
| 348 | 'REASON_TITLE' => $row['reason_title'], |
| 349 | 'REASON_DESC' => $row['reason_description'], |
| 350 | 'REPORTER' => get_username_string('username', $row['user_id'], $row['username']), |
| 351 | 'U_REPORTER' => get_username_string('profile', $row['user_id'], $row['username']), |
| 352 | 'USER_NOTIFY' => ($row['user_notify']) ? true : false, |
| 353 | 'REPORT_TIME' => $user->format_date($row['report_time']), |
| 354 | 'REPORT_TEXT' => bbcode_nl2br(trim($row['report_text'])), |
| 355 | )); |
| 356 | } |
| 357 | while ($row = $db->sql_fetchrow($result)); |
| 358 | } |
| 359 | $db->sql_freeresult($result); |
| 360 | } |
| 361 | |
| 362 | // Get IP |
| 363 | if ($auth->acl_get('m_info', $post_info['forum_id'])) |
| 364 | { |
| 365 | /** @var \phpbb\pagination $pagination */ |
| 366 | $pagination = $phpbb_container->get('pagination'); |
| 367 | |
| 368 | $start_users = $request->variable('start_users', 0); |
| 369 | $rdns_ip_num = $request->variable('rdns', ''); |
| 370 | $lookup_all = $rdns_ip_num === 'all'; |
| 371 | |
| 372 | $base_url = $url . '&i=main&mode=post_details'; |
| 373 | $base_url .= $lookup_all ? '&rdns=all' : ''; |
| 374 | |
| 375 | if (!$lookup_all) |
| 376 | { |
| 377 | $template->assign_var('U_LOOKUP_ALL', $base_url . '&rdns=all'); |
| 378 | } |
| 379 | |
| 380 | $num_users = false; |
| 381 | if ($start_users) |
| 382 | { |
| 383 | $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']); |
| 384 | $start_users = $pagination->validate_start($start_users, $config['posts_per_page'], $num_users); |
| 385 | } |
| 386 | |
| 387 | // Get other users who've posted under this IP |
| 388 | $sql = 'SELECT poster_id, COUNT(poster_id) as postings |
| 389 | FROM ' . POSTS_TABLE . " |
| 390 | WHERE poster_ip = '" . $db->sql_escape($post_info['poster_ip']) . "' |
| 391 | AND poster_id <> " . (int) $post_info['poster_id'] . " |
| 392 | GROUP BY poster_id |
| 393 | ORDER BY postings DESC, poster_id ASC"; |
| 394 | $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_users); |
| 395 | |
| 396 | $page_users = 0; |
| 397 | while ($row = $db->sql_fetchrow($result)) |
| 398 | { |
| 399 | $page_users++; |
| 400 | $users_ary[$row['poster_id']] = $row; |
| 401 | } |
| 402 | $db->sql_freeresult($result); |
| 403 | |
| 404 | if ($page_users == $config['posts_per_page'] || $start_users) |
| 405 | { |
| 406 | if ($num_users === false) |
| 407 | { |
| 408 | $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']); |
| 409 | } |
| 410 | |
| 411 | $pagination->generate_template_pagination( |
| 412 | $base_url, |
| 413 | 'pagination', |
| 414 | 'start_users', |
| 415 | $num_users, |
| 416 | $config['posts_per_page'], |
| 417 | $start_users |
| 418 | ); |
| 419 | } |
| 420 | |
| 421 | if (count($users_ary)) |
| 422 | { |
| 423 | // Get the usernames |
| 424 | $sql = 'SELECT user_id, username |
| 425 | FROM ' . USERS_TABLE . ' |
| 426 | WHERE ' . $db->sql_in_set('user_id', array_keys($users_ary)); |
| 427 | $result = $db->sql_query($sql); |
| 428 | |
| 429 | while ($row = $db->sql_fetchrow($result)) |
| 430 | { |
| 431 | $users_ary[$row['user_id']]['username'] = $row['username']; |
| 432 | $usernames_ary[utf8_clean_string($row['username'])] = $users_ary[$row['user_id']]; |
| 433 | } |
| 434 | $db->sql_freeresult($result); |
| 435 | |
| 436 | foreach ($users_ary as $user_id => $user_row) |
| 437 | { |
| 438 | $template->assign_block_vars('userrow', array( |
| 439 | 'USERNAME' => get_username_string('username', $user_id, $user_row['username']), |
| 440 | 'NUM_POSTS' => $user_row['postings'], |
| 441 | 'L_POST_S' => ($user_row['postings'] == 1) ? $user->lang['POST'] : $user->lang['POSTS'], |
| 442 | |
| 443 | 'U_PROFILE' => get_username_string('profile', $user_id, $user_row['username']), |
| 444 | 'U_SEARCHPOSTS' => append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user_id . '&sr=topics')) |
| 445 | ); |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | // Get other IP's this user has posted under |
| 450 | |
| 451 | // A compound index on poster_id, poster_ip (posts table) would help speed up this query a lot, |
| 452 | // but the extra size is only valuable if there are persons having more than a thousands posts. |
| 453 | // This is better left to the really really big forums. |
| 454 | $start_ips = $request->variable('start_ips', 0); |
| 455 | |
| 456 | $num_ips = false; |
| 457 | if ($start_ips) |
| 458 | { |
| 459 | $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']); |
| 460 | $start_ips = $pagination->validate_start($start_ips, $config['posts_per_page'], $num_ips); |
| 461 | } |
| 462 | |
| 463 | $sql = 'SELECT poster_ip, COUNT(poster_ip) AS postings |
| 464 | FROM ' . POSTS_TABLE . ' |
| 465 | WHERE poster_id = ' . $post_info['poster_id'] . " |
| 466 | GROUP BY poster_ip |
| 467 | ORDER BY postings DESC, poster_ip ASC"; |
| 468 | $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_ips); |
| 469 | |
| 470 | $page_ips = 0; |
| 471 | while ($row = $db->sql_fetchrow($result)) |
| 472 | { |
| 473 | $page_ips++; |
| 474 | $hostname = (($rdns_ip_num == $row['poster_ip'] || $rdns_ip_num == 'all') && $row['poster_ip']) ? @gethostbyaddr($row['poster_ip']) : ''; |
| 475 | |
| 476 | $template->assign_block_vars('iprow', array( |
| 477 | 'IP' => $row['poster_ip'], |
| 478 | 'HOSTNAME' => $hostname, |
| 479 | 'NUM_POSTS' => $row['postings'], |
| 480 | 'L_POST_S' => ($row['postings'] == 1) ? $user->lang['POST'] : $user->lang['POSTS'], |
| 481 | |
| 482 | 'U_LOOKUP_IP' => (!$lookup_all && $rdns_ip_num != $row['poster_ip']) ? "$base_url&start_ips={$start_ips}&rdns={$row['poster_ip']}#ip" : '', |
| 483 | 'U_WHOIS' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&mode=$mode&action=whois&p=$post_id&ip={$row['poster_ip']}")) |
| 484 | ); |
| 485 | } |
| 486 | $db->sql_freeresult($result); |
| 487 | |
| 488 | if ($page_ips == $config['posts_per_page'] || $start_ips) |
| 489 | { |
| 490 | if ($num_ips === false) |
| 491 | { |
| 492 | $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']); |
| 493 | } |
| 494 | |
| 495 | $pagination->generate_template_pagination( |
| 496 | $base_url, |
| 497 | 'pagination_ips', |
| 498 | 'start_ips', |
| 499 | $num_ips, |
| 500 | $config['posts_per_page'], |
| 501 | $start_ips |
| 502 | ); |
| 503 | } |
| 504 | |
| 505 | $user_select = ''; |
| 506 | |
| 507 | if (count($usernames_ary)) |
| 508 | { |
| 509 | ksort($usernames_ary); |
| 510 | |
| 511 | foreach ($usernames_ary as $row) |
| 512 | { |
| 513 | $user_select .= '<option value="' . $row['poster_id'] . '">' . $row['username'] . "</option>\n"; |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | $template->assign_var('S_USER_SELECT', $user_select); |
| 518 | } |
| 519 | |
| 520 | } |
| 521 | |
| 522 | /** |
| 523 | * Get the number of posters for a given ip |
| 524 | * |
| 525 | * @param \phpbb\db\driver\driver_interface $db DBAL interface |
| 526 | * @param string $poster_ip IP |
| 527 | * @return int Number of posters |
| 528 | */ |
| 529 | function phpbb_get_num_posters_for_ip(\phpbb\db\driver\driver_interface $db, $poster_ip) |
| 530 | { |
| 531 | $sql = 'SELECT COUNT(DISTINCT poster_id) as num_users |
| 532 | FROM ' . POSTS_TABLE . " |
| 533 | WHERE poster_ip = '" . $db->sql_escape($poster_ip) . "'"; |
| 534 | $result = $db->sql_query($sql); |
| 535 | $num_users = (int) $db->sql_fetchfield('num_users'); |
| 536 | $db->sql_freeresult($result); |
| 537 | |
| 538 | return $num_users; |
| 539 | } |
| 540 | |
| 541 | /** |
| 542 | * Get the number of ips for a given poster |
| 543 | * |
| 544 | * @param \phpbb\db\driver\driver_interface $db |
| 545 | * @param int $poster_id Poster user ID |
| 546 | * @return int Number of IPs for given poster |
| 547 | */ |
| 548 | function phpbb_get_num_ips_for_poster(\phpbb\db\driver\driver_interface $db, $poster_id) |
| 549 | { |
| 550 | $sql = 'SELECT COUNT(DISTINCT poster_ip) as num_ips |
| 551 | FROM ' . POSTS_TABLE . ' |
| 552 | WHERE poster_id = ' . (int) $poster_id; |
| 553 | $result = $db->sql_query($sql); |
| 554 | $num_ips = (int) $db->sql_fetchfield('num_ips'); |
| 555 | $db->sql_freeresult($result); |
| 556 | |
| 557 | return $num_ips; |
| 558 | } |
| 559 | |
| 560 | /** |
| 561 | * Change a post's poster |
| 562 | */ |
| 563 | function change_poster(&$post_info, $userdata) |
| 564 | { |
| 565 | global $db, $config, $user, $phpbb_log, $phpbb_dispatcher, $phpbb_container; |
| 566 | |
| 567 | if (empty($userdata) || $userdata['user_id'] == $post_info['user_id']) |
| 568 | { |
| 569 | return; |
| 570 | } |
| 571 | |
| 572 | $post_id = $post_info['post_id']; |
| 573 | |
| 574 | $sql = 'UPDATE ' . POSTS_TABLE . " |
| 575 | SET poster_id = {$userdata['user_id']} |
| 576 | WHERE post_id = $post_id"; |
| 577 | $db->sql_query($sql); |
| 578 | |
| 579 | // Resync topic/forum if needed |
| 580 | if ($post_info['topic_last_post_id'] == $post_id || $post_info['forum_last_post_id'] == $post_id || $post_info['topic_first_post_id'] == $post_id) |
| 581 | { |
| 582 | sync('topic', 'topic_id', $post_info['topic_id'], false, false); |
| 583 | sync('forum', 'forum_id', $post_info['forum_id'], false, false); |
| 584 | } |
| 585 | |
| 586 | // Adjust post counts... only if the post is approved (else, it was not added the users post count anyway) |
| 587 | if ($post_info['post_postcount'] && $post_info['post_visibility'] == ITEM_APPROVED) |
| 588 | { |
| 589 | $sql = 'UPDATE ' . USERS_TABLE . ' |
| 590 | SET user_posts = user_posts - 1 |
| 591 | WHERE user_id = ' . $post_info['user_id'] .' |
| 592 | AND user_posts > 0'; |
| 593 | $db->sql_query($sql); |
| 594 | |
| 595 | $sql = 'UPDATE ' . USERS_TABLE . ' |
| 596 | SET user_posts = user_posts + 1 |
| 597 | WHERE user_id = ' . $userdata['user_id']; |
| 598 | $db->sql_query($sql); |
| 599 | } |
| 600 | |
| 601 | // Add posted to information for this topic for the new user |
| 602 | markread('post', $post_info['forum_id'], $post_info['topic_id'], time(), $userdata['user_id']); |
| 603 | |
| 604 | // Remove the dotted topic option if the old user has no more posts within this topic |
| 605 | if ($config['load_db_track'] && $post_info['user_id'] != ANONYMOUS) |
| 606 | { |
| 607 | $sql = 'SELECT topic_id |
| 608 | FROM ' . POSTS_TABLE . ' |
| 609 | WHERE topic_id = ' . $post_info['topic_id'] . ' |
| 610 | AND poster_id = ' . $post_info['user_id']; |
| 611 | $result = $db->sql_query_limit($sql, 1); |
| 612 | $topic_id = (int) $db->sql_fetchfield('topic_id'); |
| 613 | $db->sql_freeresult($result); |
| 614 | |
| 615 | if (!$topic_id) |
| 616 | { |
| 617 | $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . ' |
| 618 | WHERE user_id = ' . $post_info['user_id'] . ' |
| 619 | AND topic_id = ' . $post_info['topic_id']; |
| 620 | $db->sql_query($sql); |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | // change the poster_id within the attachments table, else the data becomes out of sync and errors displayed because of wrong ownership |
| 625 | if ($post_info['post_attachment']) |
| 626 | { |
| 627 | $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' |
| 628 | SET poster_id = ' . $userdata['user_id'] . ' |
| 629 | WHERE poster_id = ' . $post_info['user_id'] . ' |
| 630 | AND post_msg_id = ' . $post_info['post_id'] . ' |
| 631 | AND topic_id = ' . $post_info['topic_id']; |
| 632 | $db->sql_query($sql); |
| 633 | } |
| 634 | |
| 635 | // refresh search cache of this post |
| 636 | try |
| 637 | { |
| 638 | $search_backend_factory = $phpbb_container->get('search.backend_factory'); |
| 639 | $search = $search_backend_factory->get_active(); |
| 640 | } |
| 641 | catch (\phpbb\search\exception\no_search_backend_found_exception $e) |
| 642 | { |
| 643 | trigger_error('NO_SUCH_SEARCH_MODULE'); |
| 644 | } |
| 645 | |
| 646 | $search->index_remove([], [$post_info['user_id'], $userdata['user_id']], []); |
| 647 | |
| 648 | $from_username = $post_info['username']; |
| 649 | $to_username = $userdata['username']; |
| 650 | |
| 651 | /** |
| 652 | * This event allows you to perform additional tasks after changing a post's poster |
| 653 | * |
| 654 | * @event core.mcp_change_poster_after |
| 655 | * @var array userdata Information on a post's new poster |
| 656 | * @var array post_info Information on the affected post |
| 657 | * @since 3.1.6-RC1 |
| 658 | * @changed 3.1.7-RC1 Change location to prevent post_info from being set to the new post information |
| 659 | */ |
| 660 | $vars = array('userdata', 'post_info'); |
| 661 | extract($phpbb_dispatcher->trigger_event('core.mcp_change_poster_after', compact($vars))); |
| 662 | |
| 663 | // Renew post info |
| 664 | $post_info = phpbb_get_post_data(array($post_id), false, true); |
| 665 | |
| 666 | if (!count($post_info)) |
| 667 | { |
| 668 | trigger_error('POST_NOT_EXIST'); |
| 669 | } |
| 670 | |
| 671 | $post_info = $post_info[$post_id]; |
| 672 | |
| 673 | // Now add log entry |
| 674 | $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MCP_CHANGE_POSTER', false, array( |
| 675 | 'forum_id' => $post_info['forum_id'], |
| 676 | 'topic_id' => $post_info['topic_id'], |
| 677 | 'post_id' => $post_info['post_id'], |
| 678 | $post_info['topic_title'], |
| 679 | $from_username, |
| 680 | $to_username |
| 681 | )); |
| 682 | } |