Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

mcp_post.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 23.65 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  /**
015  * @ignore
016  */
017  if (!defined('IN_PHPBB'))
018  {
019      exit;
020  }
021   
022  /**
023  * Handling actions in post details screen
024  */
025  function mcp_post_details($id, $mode, $action)
026  {
027      global $phpEx, $phpbb_root_path, $config, $request;
028      global $template, $db, $user, $auth;
029      global $phpbb_container, $phpbb_dispatcher;
030   
031      $user->add_lang('posting');
032   
033      $post_id = $request->variable('p', 0);
034      $start    = $request->variable('start', 0);
035   
036      // Get post data
037      $post_info = phpbb_get_post_data(array($post_id), false, true);
038   
039      add_form_key('mcp_post_details');
040   
041      if (!count($post_info))
042      {
043          trigger_error('POST_NOT_EXIST');
044      }
045   
046      $post_info = $post_info[$post_id];
047      $url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . phpbb_extra_url());
048   
049      switch ($action)
050      {
051          case 'whois':
052   
053              if ($auth->acl_get('m_info', $post_info['forum_id']))
054              {
055                  $ip = $request->variable('ip', '');
056                  if (!function_exists('user_ipwhois'))
057                  {
058                      include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
059                  }
060   
061                  $template->assign_vars(array(
062                      'RETURN_POST'    => sprintf($user->lang['RETURN_POST'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;p=$post_id") . '">', '</a>'),
063                      'U_RETURN_POST'    => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;p=$post_id"),
064                      'L_RETURN_POST'    => sprintf($user->lang['RETURN_POST'], '', ''),
065                      'WHOIS'            => user_ipwhois($ip),
066                  ));
067              }
068   
069              // We're done with the whois page so return
070              return;
071   
072          break;
073   
074          case 'chgposter':
075          case 'chgposter_ip':
076   
077              if ($action == 'chgposter')
078              {
079                  $username = $request->variable('username', '', true);
080                  $sql_where = "username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
081              }
082              else
083              {
084                  $new_user_id = $request->variable('u', 0);
085                  $sql_where = 'user_id = ' . $new_user_id;
086              }
087   
088              $sql = 'SELECT *
089                  FROM ' . USERS_TABLE . '
090                  WHERE ' . $sql_where;
091              $result = $db->sql_query($sql);
092              $row = $db->sql_fetchrow($result);
093              $db->sql_freeresult($result);
094   
095              if (!$row)
096              {
097                  trigger_error('NO_USER');
098              }
099   
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 = $extensions = 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&amp;i=main&amp;quickmod=1&amp;mode=post_details", // Use this for mode paramaters
222          'U_POST_ACTION'            => "$url&amp;i=$id&amp;mode=post_details", // Use this for action parameters
223          'U_APPROVE_ACTION'        => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;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&amp;p={$post_info['post_id']}") : '',
241          'U_FIND_USERNAME'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=mcp_chgposter&amp;field=username&amp;select_single=true'),
242          'U_MCP_APPROVE'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;p=' . $post_id),
243          'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;p=' . $post_id),
244          'U_MCP_USER_NOTES'        => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $post_info['user_id']),
245          'U_MCP_WARN_USER'        => ($auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_user&amp;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   
251          'RETURN_TOPIC'            => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "p=$post_id") . "#p$post_id\">", '</a>'),
252          'RETURN_FORUM'            => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$post_info['forum_id']}&amp;start={$start}") . '">', '</a>'),
253          'REPORTED_IMG'            => $user->img('icon_topic_reported', $user->lang['POST_REPORTED']),
254          'UNAPPROVED_IMG'        => $user->img('icon_topic_unapproved', $user->lang['POST_UNAPPROVED']),
255          'DELETED_IMG'            => $user->img('icon_topic_deleted', $user->lang['POST_DELETED']),
256          'EDIT_IMG'                => $user->img('icon_post_edit', $user->lang['EDIT_POST']),
257          'SEARCH_IMG'            => $user->img('icon_user_search', $user->lang['SEARCH']),
258   
259          'POST_AUTHOR_FULL'        => get_username_string('full', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
260          'POST_AUTHOR_COLOUR'    => get_username_string('colour', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
261          'POST_AUTHOR'            => get_username_string('username', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
262          'U_POST_AUTHOR'            => get_username_string('profile', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
263   
264          'POST_PREVIEW'            => $message,
265          'POST_SUBJECT'            => $post_info['post_subject'],
266          'POST_DATE'                => $user->format_date($post_info['post_time']),
267          'POST_IP'                => $post_info['poster_ip'],
268          'POST_IPADDR'            => ($auth->acl_get('m_info', $post_info['forum_id']) && $request->variable('lookup', '')) ? @gethostbyaddr($post_info['poster_ip']) : '',
269          'POST_ID'                => $post_info['post_id'],
270          'SIGNATURE'                => $post_info['user_sig'],
271   
272          'U_LOOKUP_IP'            => ($auth->acl_get('m_info', $post_info['forum_id'])) ? "$url&amp;i=$id&amp;mode=$mode&amp;lookup={$post_info['poster_ip']}#ip" : '',
273          'U_WHOIS'                => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;action=whois&amp;p=$post_id&amp;ip={$post_info['poster_ip']}") : '',
274      );
275   
276      $s_additional_opts = false;
277   
278      /**
279      * Event to add/modify MCP post template data
280      *
281      * @event core.mcp_post_template_data
282      * @var    array    post_info                    Array with the post information
283      * @var    array    mcp_post_template_data        Array with the MCP post template data
284      * @var    array    attachments                    Array with the post attachments, if any
285      * @var    bool    s_additional_opts            Must be set to true in extension if additional options are presented in MCP post panel
286      * @since 3.1.5-RC1
287      */
288      $vars = array(
289          'post_info',
290          'mcp_post_template_data',
291          'attachments',
292          's_additional_opts',
293      );
294      extract($phpbb_dispatcher->trigger_event('core.mcp_post_template_data', compact($vars)));
295   
296      $template->assign_vars($mcp_post_template_data);
297      $template->assign_var('S_MCP_POST_ADDITIONAL_OPTS', $s_additional_opts);
298   
299      unset($mcp_post_template_data);
300   
301      // Get User Notes
302      $log_data = array();
303      $log_count = false;
304      view_log('user', $log_data, $log_count, $config['posts_per_page'], 0, 0, 0, $post_info['user_id']);
305   
306      if (!empty($log_data))
307      {
308          $template->assign_var('S_USER_NOTES', true);
309   
310          foreach ($log_data as $row)
311          {
312              $template->assign_block_vars('usernotes', array(
313                  'REPORT_BY'        => $row['username_full'],
314                  'REPORT_AT'        => $user->format_date($row['time']),
315                  'ACTION'        => $row['action'],
316                  'ID'            => $row['id'])
317              );
318          }
319      }
320   
321      // Get Reports
322      if ($auth->acl_get('m_report', $post_info['forum_id']))
323      {
324          $sql = 'SELECT r.*, re.*, u.user_id, u.username
325              FROM ' . REPORTS_TABLE . ' r, ' . USERS_TABLE . ' u, ' . REPORTS_REASONS_TABLE . " re
326              WHERE r.post_id = $post_id
327                  AND r.reason_id = re.reason_id
328                  AND u.user_id = r.user_id
329              ORDER BY r.report_time DESC";
330          $result = $db->sql_query($sql);
331   
332          if ($row = $db->sql_fetchrow($result))
333          {
334              $template->assign_var('S_SHOW_REPORTS', true);
335   
336              do
337              {
338                  // If the reason is defined within the language file, we will use the localized version, else just use the database entry...
339                  if (isset($user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]))
340                  {
341                      $row['reson_description'] = $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])];
342                      $row['reason_title'] = $user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])];
343                  }
344   
345                  $template->assign_block_vars('reports', array(
346                      'REPORT_ID'        => $row['report_id'],
347                      'REASON_TITLE'    => $row['reason_title'],
348                      'REASON_DESC'    => $row['reason_description'],
349                      'REPORTER'        => get_username_string('username', $row['user_id'], $row['username']),
350                      'U_REPORTER'    => get_username_string('profile', $row['user_id'], $row['username']),
351                      'USER_NOTIFY'    => ($row['user_notify']) ? true : false,
352                      'REPORT_TIME'    => $user->format_date($row['report_time']),
353                      'REPORT_TEXT'    => bbcode_nl2br(trim($row['report_text'])),
354                  ));
355              }
356              while ($row = $db->sql_fetchrow($result));
357          }
358          $db->sql_freeresult($result);
359      }
360   
361      // Get IP
362      if ($auth->acl_get('m_info', $post_info['forum_id']))
363      {
364          /** @var \phpbb\pagination $pagination */
365          $pagination = $phpbb_container->get('pagination');
366   
367          $start_users = $request->variable('start_users', 0);
368          $rdns_ip_num = $request->variable('rdns', '');
369          $lookup_all = $rdns_ip_num === 'all';
370   
371          $base_url = $url . '&amp;i=main&amp;mode=post_details';
372          $base_url .= $lookup_all ? '&amp;rdns=all' : '';
373   
374          if (!$lookup_all)
375          {
376              $template->assign_var('U_LOOKUP_ALL', $base_url . '&amp;rdns=all');
377          }
378   
379          $num_users = false;
380          if ($start_users)
381          {
382              $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']);
383              $start_users = $pagination->validate_start($start_users, $config['posts_per_page'], $num_users);
384          }
385   
386          // Get other users who've posted under this IP
387          $sql = 'SELECT poster_id, COUNT(poster_id) as postings
388              FROM ' . POSTS_TABLE . "
389              WHERE poster_ip = '" . $db->sql_escape($post_info['poster_ip']) . "'
390                  AND poster_id <> " . (int) $post_info['poster_id'] . "
391              GROUP BY poster_id
392              ORDER BY postings DESC, poster_id ASC";
393          $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_users);
394   
395          $page_users = 0;
396          while ($row = $db->sql_fetchrow($result))
397          {
398              $page_users++;
399              $users_ary[$row['poster_id']] = $row;
400          }
401          $db->sql_freeresult($result);
402   
403          if ($page_users == $config['posts_per_page'] || $start_users)
404          {
405              if ($num_users === false)
406              {
407                  $num_users = phpbb_get_num_posters_for_ip($db, $post_info['poster_ip']);
408              }
409   
410              $pagination->generate_template_pagination(
411                  $base_url,
412                  'pagination',
413                  'start_users',
414                  $num_users,
415                  $config['posts_per_page'],
416                  $start_users
417              );
418          }
419   
420          if (count($users_ary))
421          {
422              // Get the usernames
423              $sql = 'SELECT user_id, username
424                  FROM ' . USERS_TABLE . '
425                  WHERE ' . $db->sql_in_set('user_id', array_keys($users_ary));
426              $result = $db->sql_query($sql);
427   
428              while ($row = $db->sql_fetchrow($result))
429              {
430                  $users_ary[$row['user_id']]['username'] = $row['username'];
431                  $usernames_ary[utf8_clean_string($row['username'])] = $users_ary[$row['user_id']];
432              }
433              $db->sql_freeresult($result);
434   
435              foreach ($users_ary as $user_id => $user_row)
436              {
437                  $template->assign_block_vars('userrow', array(
438                      'USERNAME'        => get_username_string('username', $user_id, $user_row['username']),
439                      'NUM_POSTS'        => $user_row['postings'],
440                      'L_POST_S'        => ($user_row['postings'] == 1) ? $user->lang['POST'] : $user->lang['POSTS'],
441   
442                      'U_PROFILE'        => get_username_string('profile', $user_id, $user_row['username']),
443                      'U_SEARCHPOSTS' => append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user_id . '&amp;sr=topics'))
444                  );
445              }
446          }
447   
448          // Get other IP's this user has posted under
449   
450          // A compound index on poster_id, poster_ip (posts table) would help speed up this query a lot,
451          // but the extra size is only valuable if there are persons having more than a thousands posts.
452          // This is better left to the really really big forums.
453          $start_ips = $request->variable('start_ips', 0);
454   
455          $num_ips = false;
456          if ($start_ips)
457          {
458              $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']);
459              $start_ips = $pagination->validate_start($start_ips, $config['posts_per_page'], $num_ips);
460          }
461   
462          $sql = 'SELECT poster_ip, COUNT(poster_ip) AS postings
463              FROM ' . POSTS_TABLE . '
464              WHERE poster_id = ' . $post_info['poster_id'] . "
465              GROUP BY poster_ip
466              ORDER BY postings DESC, poster_ip ASC";
467          $result = $db->sql_query_limit($sql, $config['posts_per_page'], $start_ips);
468   
469          $page_ips = 0;
470          while ($row = $db->sql_fetchrow($result))
471          {
472              $page_ips++;
473              $hostname = (($rdns_ip_num == $row['poster_ip'] || $rdns_ip_num == 'all') && $row['poster_ip']) ? @gethostbyaddr($row['poster_ip']) : '';
474   
475              $template->assign_block_vars('iprow', array(
476                  'IP'            => $row['poster_ip'],
477                  'HOSTNAME'        => $hostname,
478                  'NUM_POSTS'        => $row['postings'],
479                  'L_POST_S'        => ($row['postings'] == 1) ? $user->lang['POST'] : $user->lang['POSTS'],
480   
481                  'U_LOOKUP_IP'    => (!$lookup_all && $rdns_ip_num != $row['poster_ip']) ? "$base_url&amp;start_ips={$start_ips}&amp;rdns={$row['poster_ip']}#ip" : '',
482                  'U_WHOIS'        => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&amp;mode=$mode&amp;action=whois&amp;p=$post_id&amp;ip={$row['poster_ip']}"))
483              );
484          }
485          $db->sql_freeresult($result);
486   
487          if ($page_ips == $config['posts_per_page'] || $start_ips)
488          {
489              if ($num_ips === false)
490              {
491                  $num_ips = phpbb_get_num_ips_for_poster($db, $post_info['poster_id']);
492              }
493   
494              $pagination->generate_template_pagination(
495                  $base_url,
496                  'pagination_ips',
497                  'start_ips',
498                  $num_ips,
499                  $config['posts_per_page'],
500                  $start_ips
501              );
502          }
503   
504          $user_select = '';
505   
506          if (count($usernames_ary))
507          {
508              ksort($usernames_ary);
509   
510              foreach ($usernames_ary as $row)
511              {
512                  $user_select .= '<option value="' . $row['poster_id'] . '">' . $row['username'] . "</option>\n";
513              }
514          }
515   
516          $template->assign_var('S_USER_SELECT', $user_select);
517      }
518   
519  }
520   
521  /**
522   * Get the number of posters for a given ip
523   *
524   * @param \phpbb\db\driver\driver_interface $db DBAL interface
525   * @param string $poster_ip IP
526   * @return int Number of posters
527   */
528  function phpbb_get_num_posters_for_ip(\phpbb\db\driver\driver_interface $db, $poster_ip)
529  {
530      $sql = 'SELECT COUNT(DISTINCT poster_id) as num_users
531          FROM ' . POSTS_TABLE . "
532          WHERE poster_ip = '" . $db->sql_escape($poster_ip) . "'";
533      $result = $db->sql_query($sql);
534      $num_users = (int) $db->sql_fetchfield('num_users');
535      $db->sql_freeresult($result);
536   
537      return $num_users;
538  }
539   
540  /**
541   * Get the number of ips for a given poster
542   *
543   * @param \phpbb\db\driver\driver_interface $db
544   * @param int $poster_id Poster user ID
545   * @return int Number of IPs for given poster
546   */
547  function phpbb_get_num_ips_for_poster(\phpbb\db\driver\driver_interface $db, $poster_id)
548  {
549      $sql = 'SELECT COUNT(DISTINCT poster_ip) as num_ips
550          FROM ' . POSTS_TABLE . '
551          WHERE poster_id = ' . (int) $poster_id;
552      $result = $db->sql_query($sql);
553      $num_ips = (int) $db->sql_fetchfield('num_ips');
554      $db->sql_freeresult($result);
555   
556      return $num_ips;
557  }
558   
559  /**
560  * Change a post's poster
561  */
562  function change_poster(&$post_info, $userdata)
563  {
564      global $auth, $db, $config, $phpbb_root_path, $phpEx, $user, $phpbb_log, $phpbb_dispatcher;
565   
566      if (empty($userdata) || $userdata['user_id'] == $post_info['user_id'])
567      {
568          return;
569      }
570   
571      $post_id = $post_info['post_id'];
572   
573      $sql = 'UPDATE ' . POSTS_TABLE . "
574          SET poster_id = {$userdata['user_id']}
575          WHERE post_id = $post_id";
576      $db->sql_query($sql);
577   
578      // Resync topic/forum if needed
579      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)
580      {
581          sync('topic', 'topic_id', $post_info['topic_id'], false, false);
582          sync('forum', 'forum_id', $post_info['forum_id'], false, false);
583      }
584   
585      // Adjust post counts... only if the post is approved (else, it was not added the users post count anyway)
586      if ($post_info['post_postcount'] && $post_info['post_visibility'] == ITEM_APPROVED)
587      {
588          $sql = 'UPDATE ' . USERS_TABLE . '
589              SET user_posts = user_posts - 1
590              WHERE user_id = ' . $post_info['user_id'] .'
591              AND user_posts > 0';
592          $db->sql_query($sql);
593   
594          $sql = 'UPDATE ' . USERS_TABLE . '
595              SET user_posts = user_posts + 1
596              WHERE user_id = ' . $userdata['user_id'];
597          $db->sql_query($sql);
598      }
599   
600      // Add posted to information for this topic for the new user
601      markread('post', $post_info['forum_id'], $post_info['topic_id'], time(), $userdata['user_id']);
602   
603      // Remove the dotted topic option if the old user has no more posts within this topic
604      if ($config['load_db_track'] && $post_info['user_id'] != ANONYMOUS)
605      {
606          $sql = 'SELECT topic_id
607              FROM ' . POSTS_TABLE . '
608              WHERE topic_id = ' . $post_info['topic_id'] . '
609                  AND poster_id = ' . $post_info['user_id'];
610          $result = $db->sql_query_limit($sql, 1);
611          $topic_id = (int) $db->sql_fetchfield('topic_id');
612          $db->sql_freeresult($result);
613   
614          if (!$topic_id)
615          {
616              $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . '
617                  WHERE user_id = ' . $post_info['user_id'] . '
618                      AND topic_id = ' . $post_info['topic_id'];
619              $db->sql_query($sql);
620          }
621      }
622   
623      // change the poster_id within the attachments table, else the data becomes out of sync and errors displayed because of wrong ownership
624      if ($post_info['post_attachment'])
625      {
626          $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
627              SET poster_id = ' . $userdata['user_id'] . '
628              WHERE poster_id = ' . $post_info['user_id'] . '
629                  AND post_msg_id = ' . $post_info['post_id'] . '
630                  AND topic_id = ' . $post_info['topic_id'];
631          $db->sql_query($sql);
632      }
633   
634      // refresh search cache of this post
635      $search_type = $config['search_type'];
636   
637      if (class_exists($search_type))
638      {
639          // We do some additional checks in the module to ensure it can actually be utilised
640          $error = false;
641          $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
642   
643          if (!$error && method_exists($search, 'destroy_cache'))
644          {
645              $search->destroy_cache(array(), array($post_info['user_id'], $userdata['user_id']));
646          }
647      }
648   
649      $from_username = $post_info['username'];
650      $to_username = $userdata['username'];
651   
652      /**
653      * This event allows you to perform additional tasks after changing a post's poster
654      *
655      * @event core.mcp_change_poster_after
656      * @var    array    userdata    Information on a post's new poster
657      * @var    array    post_info    Information on the affected post
658      * @since 3.1.6-RC1
659      * @changed 3.1.7-RC1        Change location to prevent post_info from being set to the new post information
660      */
661      $vars = array('userdata', 'post_info');
662      extract($phpbb_dispatcher->trigger_event('core.mcp_change_poster_after', compact($vars)));
663   
664      // Renew post info
665      $post_info = phpbb_get_post_data(array($post_id), false, true);
666   
667      if (!count($post_info))
668      {
669          trigger_error('POST_NOT_EXIST');
670      }
671   
672      $post_info = $post_info[$post_id];
673   
674      // Now add log entry
675      $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MCP_CHANGE_POSTER', false, array(
676          'forum_id' => $post_info['forum_id'],
677          'topic_id' => $post_info['topic_id'],
678          'post_id'  => $post_info['post_id'],
679          $post_info['topic_title'],
680          $from_username,
681          $to_username
682      ));
683  }
684