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_queue.php

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


0001  <?php
0002  /**
0003  *
0004  * This file is part of the phpBB Forum Software package.
0005  *
0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007  * @license GNU General Public License, version 2 (GPL-2.0)
0008  *
0009  * For full copyright and license information, please see
0010  * the docs/CREDITS.txt file.
0011  *
0012  */
0013   
0014  /**
0015  * @ignore
0016  */
0017  if (!defined('IN_PHPBB'))
0018  {
0019      exit;
0020  }
0021   
0022  /**
0023  * mcp_queue
0024  * Handling the moderation queue
0025  */
0026  class mcp_queue
0027  {
0028      var $p_master;
0029      var $u_action;
0030   
0031      public function __construct($p_master)
0032      {
0033          $this->p_master = $p_master;
0034      }
0035   
0036      public function main($id, $mode)
0037      {
0038          global $auth, $db, $user, $template, $request;
0039          global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container;
0040          global $phpbb_dispatcher;
0041   
0042          include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
0043   
0044          $forum_id = $request->variable('f', 0);
0045          $start = $request->variable('start', 0);
0046   
0047          $this->page_title = 'MCP_QUEUE';
0048   
0049          switch ($action)
0050          {
0051              case 'approve':
0052              case 'restore':
0053                  include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
0054   
0055                  $post_id_list = $request->variable('post_id_list', array(0));
0056                  $topic_id_list = $request->variable('topic_id_list', array(0));
0057   
0058                  if (!empty($post_id_list))
0059                  {
0060                      self::approve_posts($action, $post_id_list, 'queue', $mode);
0061                  }
0062                  else if (!empty($topic_id_list))
0063                  {
0064                      self::approve_topics($action, $topic_id_list, 'queue', $mode);
0065                  }
0066                  else
0067                  {
0068                      trigger_error('NO_POST_SELECTED');
0069                  }
0070              break;
0071   
0072              case 'delete':
0073                  $post_id_list = $request->variable('post_id_list', array(0));
0074                  $topic_id_list = $request->variable('topic_id_list', array(0));
0075                  $delete_reason = $request->variable('delete_reason', '', true);
0076   
0077                  if (!empty($post_id_list))
0078                  {
0079                      if (!function_exists('mcp_delete_post'))
0080                      {
0081                          global $phpbb_root_path, $phpEx;
0082                          include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx);
0083                      }
0084                      mcp_delete_post($post_id_list, false, $delete_reason, $action);
0085                  }
0086                  else if (!empty($topic_id_list))
0087                  {
0088                      if (!function_exists('mcp_delete_topic'))
0089                      {
0090                          global $phpbb_root_path, $phpEx;
0091                          include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx);
0092                      }
0093                      mcp_delete_topic($topic_id_list, false, $delete_reason, $action);
0094                  }
0095                  else
0096                  {
0097                      trigger_error('NO_POST_SELECTED');
0098                  }
0099              break;
0100   
0101              case 'disapprove':
0102                  $post_id_list = $request->variable('post_id_list', array(0));
0103                  $topic_id_list = $request->variable('topic_id_list', array(0));
0104   
0105                  if (!empty($topic_id_list) && $mode == 'deleted_topics')
0106                  {
0107                      if (!function_exists('mcp_delete_topic'))
0108                      {
0109                          global $phpbb_root_path, $phpEx;
0110                          include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx);
0111                      }
0112                      mcp_delete_topic($topic_id_list, false, '', 'disapprove');
0113                      return;
0114                  }
0115   
0116                  if (!class_exists('messenger'))
0117                  {
0118                      include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
0119                  }
0120   
0121                  if (!empty($topic_id_list))
0122                  {
0123                      $post_visibility = ($mode == 'deleted_topics') ? ITEM_DELETED : array(ITEM_UNAPPROVED, ITEM_REAPPROVE);
0124                      $sql = 'SELECT post_id
0125                          FROM ' . POSTS_TABLE . '
0126                          WHERE ' . $db->sql_in_set('post_visibility', $post_visibility) . '
0127                              AND ' . $db->sql_in_set('topic_id', $topic_id_list);
0128                      $result = $db->sql_query($sql);
0129   
0130                      $post_id_list = array();
0131                      while ($row = $db->sql_fetchrow($result))
0132                      {
0133                          $post_id_list[] = (int) $row['post_id'];
0134                      }
0135                      $db->sql_freeresult($result);
0136                  }
0137   
0138                  if (!empty($post_id_list))
0139                  {
0140                      self::disapprove_posts($post_id_list, 'queue', $mode);
0141                  }
0142                  else
0143                  {
0144                      trigger_error('NO_POST_SELECTED');
0145                  }
0146              break;
0147          }
0148   
0149          switch ($mode)
0150          {
0151              case 'approve_details':
0152   
0153                  $this->tpl_name = 'mcp_post';
0154   
0155                  $user->add_lang(array('posting', 'viewtopic'));
0156   
0157                  $post_id = $request->variable('p', 0);
0158                  $topic_id = $request->variable('t', 0);
0159                  $topic_info = [];
0160   
0161                  /* @var $phpbb_notifications \phpbb\notification\manager */
0162                  $phpbb_notifications = $phpbb_container->get('notification_manager');
0163   
0164                  if ($topic_id)
0165                  {
0166                      $topic_info = phpbb_get_topic_data(array($topic_id), 'm_approve');
0167                      if (isset($topic_info[$topic_id]['topic_first_post_id']))
0168                      {
0169                          $post_id = (int) $topic_info[$topic_id]['topic_first_post_id'];
0170   
0171                          $phpbb_notifications->mark_notifications('topic_in_queue', $topic_id, $user->data['user_id']);
0172                      }
0173                      else
0174                      {
0175                          $topic_id = 0;
0176                      }
0177                  }
0178   
0179                  $phpbb_notifications->mark_notifications('post_in_queue', $post_id, $user->data['user_id']);
0180   
0181                  $post_info = phpbb_get_post_data(array($post_id), 'm_approve', true);
0182   
0183                  if (!count($post_info))
0184                  {
0185                      trigger_error('NO_POST_SELECTED');
0186                  }
0187   
0188                  $post_info = $post_info[$post_id];
0189   
0190                  if ($post_info['topic_first_post_id'] != $post_id && topic_review($post_info['topic_id'], $post_info['forum_id'], 'topic_review', 0, false))
0191                  {
0192                      $template->assign_vars(array(
0193                          'S_TOPIC_REVIEW'    => true,
0194                          'S_BBCODE_ALLOWED'    => $post_info['enable_bbcode'],
0195                          'TOPIC_TITLE'        => $post_info['topic_title'],
0196                      ));
0197                  }
0198   
0199                  $attachments = $topic_tracking_info = array();
0200   
0201                  // Get topic tracking info
0202                  if ($config['load_db_lastread'])
0203                  {
0204                      $tmp_topic_data = array($post_info['topic_id'] => $post_info);
0205                      $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']));
0206                      unset($tmp_topic_data);
0207                  }
0208                  else
0209                  {
0210                      $topic_tracking_info = get_complete_topic_tracking($post_info['forum_id'], $post_info['topic_id']);
0211                  }
0212   
0213                  $post_unread = (isset($topic_tracking_info[$post_info['topic_id']]) && $post_info['post_time'] > $topic_tracking_info[$post_info['topic_id']]) ? true : false;
0214   
0215                  // Process message, leave it uncensored
0216                  $parse_flags = ($post_info['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
0217                  $message = generate_text_for_display($post_info['post_text'], $post_info['bbcode_uid'], $post_info['bbcode_bitfield'], $parse_flags, false);
0218   
0219                  if ($post_info['post_attachment'] && $auth->acl_get('u_download') && $auth->acl_get('f_download', $post_info['forum_id']))
0220                  {
0221                      $sql = 'SELECT *
0222                          FROM ' . ATTACHMENTS_TABLE . '
0223                          WHERE post_msg_id = ' . $post_id . '
0224                              AND in_message = 0
0225                          ORDER BY filetime DESC, post_msg_id ASC';
0226                      $result = $db->sql_query($sql);
0227   
0228                      while ($row = $db->sql_fetchrow($result))
0229                      {
0230                          $attachments[] = $row;
0231                      }
0232                      $db->sql_freeresult($result);
0233   
0234                      if (count($attachments))
0235                      {
0236                          $update_count = array();
0237                          parse_attachments($post_info['forum_id'], $message, $attachments, $update_count);
0238                      }
0239   
0240                      // Display not already displayed Attachments for this post, we already parsed them. ;)
0241                      if (!empty($attachments))
0242                      {
0243                          $template->assign_var('S_HAS_ATTACHMENTS', true);
0244   
0245                          foreach ($attachments as $attachment)
0246                          {
0247                              $template->assign_block_vars('attachment', array(
0248                                  'DISPLAY_ATTACHMENT'    => $attachment,
0249                              ));
0250                          }
0251                      }
0252                  }
0253   
0254                  // Deleting information
0255                  if ($post_info['post_visibility'] == ITEM_DELETED && $post_info['post_delete_user'])
0256                  {
0257                      // User having deleted the post also being the post author?
0258                      if (!$post_info['post_delete_user'] || $post_info['post_delete_user'] == $post_info['poster_id'])
0259                      {
0260                          $display_username = get_username_string('full', $post_info['poster_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']);
0261                      }
0262                      else
0263                      {
0264                          $sql = 'SELECT u.user_id, u.username, u.user_colour
0265                              FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
0266                              WHERE p.post_id =  ' . $post_info['post_id'] . '
0267                                  AND p.post_delete_user = u.user_id';
0268                          $result = $db->sql_query($sql);
0269                          $post_delete_userinfo = $db->sql_fetchrow($result);
0270                          $db->sql_freeresult($result);
0271                          $display_username = get_username_string('full', $post_info['post_delete_user'], $post_delete_userinfo['username'], $post_delete_userinfo['user_colour']);
0272                      }
0273   
0274                      $l_deleted_by = $user->lang('DELETED_INFORMATION', $display_username, $user->format_date($post_info['post_delete_time'], false, true));
0275                  }
0276                  else
0277                  {
0278                      $l_deleted_by = '';
0279                  }
0280   
0281                  $post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $post_info['post_id'] . '#p' . $post_info['post_id']);
0282                  $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $post_info['topic_id']);
0283   
0284                  $post_data = array(
0285                      'S_MCP_QUEUE'            => true,
0286                      'U_APPROVE_ACTION'        => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id"),
0287                      'S_CAN_APPROVE'            => $auth->acl_get('m_approve', $post_info['forum_id']),
0288                      'S_CAN_DELETE_POST'        => $auth->acl_get('m_delete', $post_info['forum_id']),
0289                      'S_CAN_VIEWIP'            => $auth->acl_get('m_info', $post_info['forum_id']),
0290                      'S_POST_REPORTED'        => $post_info['post_reported'],
0291                      'S_POST_UNAPPROVED'        => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE,
0292                      'S_POST_LOCKED'            => $post_info['post_edit_locked'],
0293                      'S_USER_NOTES'            => true,
0294                      'S_POST_DELETED'        => ($post_info['post_visibility'] == ITEM_DELETED),
0295                      'DELETED_MESSAGE'        => $l_deleted_by,
0296                      'DELETE_REASON'            => $post_info['post_delete_reason'],
0297   
0298                      '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']}") : '',
0299                      'U_MCP_APPROVE'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;p=' . $post_id),
0300                      'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;p=' . $post_id),
0301                      'U_MCP_USER_NOTES'        => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $post_info['user_id']),
0302                      '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']) : '',
0303                      'U_VIEW_POST'            => $post_url,
0304                      'U_VIEW_TOPIC'            => $topic_url,
0305   
0306                      'MINI_POST_IMG'            => ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),
0307   
0308                      'RETURN_QUEUE'            => sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&amp;mode=unapproved_topics' : '&amp;mode=unapproved_posts')) . '&amp;start=' . $start . '">', '</a>'),
0309                      'RETURN_POST'            => sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'),
0310                      'RETURN_TOPIC_SIMPLE'    => sprintf($user->lang['RETURN_TOPIC_SIMPLE'], '<a href="' . $topic_url . '">', '</a>'),
0311                      'REPORTED_IMG'            => $user->img('icon_topic_reported', $user->lang['POST_REPORTED']),
0312                      'UNAPPROVED_IMG'        => $user->img('icon_topic_unapproved', $user->lang['POST_UNAPPROVED']),
0313                      'EDIT_IMG'                => $user->img('icon_post_edit', $user->lang['EDIT_POST']),
0314   
0315                      'POST_AUTHOR_FULL'        => get_username_string('full', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
0316                      'POST_AUTHOR_COLOUR'    => get_username_string('colour', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
0317                      'POST_AUTHOR'            => get_username_string('username', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
0318                      'U_POST_AUTHOR'            => get_username_string('profile', $post_info['user_id'], $post_info['username'], $post_info['user_colour'], $post_info['post_username']),
0319   
0320                      'POST_PREVIEW'            => $message,
0321                      'POST_SUBJECT'            => $post_info['post_subject'],
0322                      'POST_DATE'                => $user->format_date($post_info['post_time']),
0323                      'POST_IP'                => $post_info['poster_ip'],
0324                      'POST_IPADDR'            => ($auth->acl_get('m_info', $post_info['forum_id']) && $request->variable('lookup', '')) ? @gethostbyaddr($post_info['poster_ip']) : '',
0325                      'POST_ID'                => $post_info['post_id'],
0326                      'S_FIRST_POST'            => ($post_info['topic_first_post_id'] == $post_id),
0327   
0328                      'U_LOOKUP_IP'            => ($auth->acl_get('m_info', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;p=' . $post_id . '&amp;lookup=' . $post_info['poster_ip']) . '#ip' : '',
0329                  );
0330   
0331                  /**
0332                  * Alter post awaiting approval template before it is rendered
0333                  *
0334                  * @event core.mcp_queue_approve_details_template
0335                  * @var    int        post_id        Post ID
0336                  * @var    int        topic_id    Topic ID
0337                  * @var    array    topic_info    Topic data
0338                  * @var    array    post_info    Post data
0339                  * @var array    post_data    Post template data
0340                  * @var    string    message        Post message
0341                  * @var    string    post_url    Post URL
0342                  * @var    string    topic_url    Topic URL
0343                  * @since 3.2.2-RC1
0344                  */
0345                  $vars = array(
0346                      'post_id',
0347                      'topic_id',
0348                      'topic_info',
0349                      'post_info',
0350                      'post_data',
0351                      'message',
0352                      'post_url',
0353                      'topic_url',
0354                  );
0355                  extract($phpbb_dispatcher->trigger_event('core.mcp_queue_approve_details_template', compact($vars)));
0356   
0357                  $template->assign_vars($post_data);
0358   
0359              break;
0360   
0361              case 'unapproved_topics':
0362              case 'unapproved_posts':
0363              case 'deleted_topics':
0364              case 'deleted_posts':
0365                  $m_perm = 'm_approve';
0366                  $is_topics = ($mode == 'unapproved_topics' || $mode == 'deleted_topics') ? true : false;
0367                  $is_restore = ($mode == 'deleted_posts' || $mode == 'deleted_topics') ? true : false;
0368                  $visibility_const = (!$is_restore) ? array(ITEM_UNAPPROVED, ITEM_REAPPROVE) : ITEM_DELETED;
0369   
0370                  $user->add_lang(array('viewtopic', 'viewforum'));
0371   
0372                  $topic_id = $request->variable('t', 0);
0373                  $forum_info = array();
0374   
0375                  // If 'sort' is set, "Go" was pressed which is located behind the forums <select> box
0376                  // Then, unset the topic id so it does not override the forum id
0377                  $topic_id = $request->is_set_post('sort') ? 0 : $topic_id;
0378   
0379                  if ($topic_id)
0380                  {
0381                      $topic_info = phpbb_get_topic_data(array($topic_id));
0382   
0383                      if (!count($topic_info))
0384                      {
0385                          trigger_error('TOPIC_NOT_EXIST');
0386                      }
0387   
0388                      $topic_info = $topic_info[$topic_id];
0389                      $forum_id = $topic_info['forum_id'];
0390                  }
0391   
0392                  $forum_list_approve = get_forum_list($m_perm, false, true);
0393                  $forum_list_read = array_flip(get_forum_list('f_read', true, true)); // Flipped so we can isset() the forum IDs
0394   
0395                  // Remove forums we cannot read
0396                  foreach ($forum_list_approve as $k => $forum_data)
0397                  {
0398                      if (!isset($forum_list_read[$forum_data['forum_id']]))
0399                      {
0400                          unset($forum_list_approve[$k]);
0401                      }
0402                  }
0403                  unset($forum_list_read);
0404   
0405                  if (!$forum_id)
0406                  {
0407                      $forum_list = array();
0408                      foreach ($forum_list_approve as $row)
0409                      {
0410                          $forum_list[] = $row['forum_id'];
0411                      }
0412   
0413                      if (!count($forum_list))
0414                      {
0415                          trigger_error('NOT_MODERATOR');
0416                      }
0417   
0418                      $sql = 'SELECT SUM(forum_topics_approved) as sum_forum_topics
0419                          FROM ' . FORUMS_TABLE . '
0420                          WHERE ' . $db->sql_in_set('forum_id', $forum_list);
0421                      $result = $db->sql_query($sql);
0422                      $forum_info['forum_topics_approved'] = (int) $db->sql_fetchfield('sum_forum_topics');
0423                      $db->sql_freeresult($result);
0424                  }
0425                  else
0426                  {
0427                      $forum_info = phpbb_get_forum_data(array($forum_id), $m_perm);
0428   
0429                      if (!count($forum_info))
0430                      {
0431                          trigger_error('NOT_MODERATOR');
0432                      }
0433   
0434                      $forum_list = $forum_id;
0435                  }
0436   
0437                  $forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>';
0438                  foreach ($forum_list_approve as $row)
0439                  {
0440                      $forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp; &nbsp;', $row['padding']) . truncate_string($row['forum_name'], 30, 255, false, $user->lang['ELLIPSIS']) . '</option>';
0441                  }
0442   
0443                  $sort_days = $total = 0;
0444                  $sort_key = $sort_dir = '';
0445                  $sort_by_sql = $sort_order_sql = array();
0446                  phpbb_mcp_sorting($mode, $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id, $topic_id);
0447   
0448                  $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : '';
0449   
0450                  $forum_names = array();
0451   
0452                  if (!$is_topics)
0453                  {
0454                      $sql = 'SELECT p.post_id
0455                          FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t' . (($sort_order_sql[0] == 'u') ? ', ' . USERS_TABLE . ' u' : '') . '
0456                          WHERE ' . $db->sql_in_set('p.forum_id', $forum_list) . '
0457                              AND ' . $db->sql_in_set('p.post_visibility', $visibility_const) . '
0458                              ' . (($sort_order_sql[0] == 'u') ? 'AND u.user_id = p.poster_id' : '') . '
0459                              ' . (($topic_id) ? 'AND p.topic_id = ' . $topic_id : '') . "
0460                              AND t.topic_id = p.topic_id
0461                              AND (t.topic_visibility <> p.post_visibility
0462                                  OR t.topic_delete_user = 0)
0463                              $limit_time_sql
0464                          ORDER BY $sort_order_sql";
0465   
0466                      /**
0467                      * Alter sql query to get posts in queue to be accepted
0468                      *
0469                      * @event core.mcp_queue_get_posts_query_before
0470                      * @var    string    sql                        Associative array with the query to be executed
0471                      * @var    array    forum_list                List of forums that contain the posts
0472                      * @var    int        visibility_const        Integer with one of the possible ITEM_* constant values
0473                      * @var    int        topic_id                If topic_id not equal to 0, the topic id to filter the posts to display
0474                      * @var    string    limit_time_sql            String with the SQL code to limit the time interval of the post (Note: May be empty string)
0475                      * @var    string    sort_order_sql            String with the ORDER BY SQL code used in this query
0476                      * @since 3.1.0-RC3
0477                      */
0478                      $vars = array(
0479                          'sql',
0480                          'forum_list',
0481                          'visibility_const',
0482                          'topic_id',
0483                          'limit_time_sql',
0484                          'sort_order_sql',
0485                      );
0486                      extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_query_before', compact($vars)));
0487   
0488                      $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
0489   
0490                      $i = 0;
0491                      $post_ids = array();
0492                      while ($row = $db->sql_fetchrow($result))
0493                      {
0494                          $post_ids[] = $row['post_id'];
0495                          $row_num[$row['post_id']] = $i++;
0496                      }
0497                      $db->sql_freeresult($result);
0498   
0499                      if (count($post_ids))
0500                      {
0501                          $sql = 'SELECT t.topic_id, t.topic_title, t.forum_id, p.post_id, p.post_subject, p.post_username, p.poster_id, p.post_time, p.post_attachment, u.username, u.username_clean, u.user_colour
0502                              FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . USERS_TABLE . ' u
0503                              WHERE ' . $db->sql_in_set('p.post_id', $post_ids) . '
0504                                  AND t.topic_id = p.topic_id
0505                                  AND u.user_id = p.poster_id
0506                              ORDER BY ' . $sort_order_sql;
0507   
0508                          /**
0509                          * Alter sql query to get information on all posts in queue
0510                          *
0511                          * @event core.mcp_queue_get_posts_for_posts_query_before
0512                          * @var    string    sql                        String with the query to be executed
0513                          * @var    array    forum_list                List of forums that contain the posts
0514                          * @var    int        visibility_const        Integer with one of the possible ITEM_* constant values
0515                          * @var    int        topic_id                topic_id in the page request
0516                          * @var    string    limit_time_sql            String with the SQL code to limit the time interval of the post (Note: May be empty string)
0517                          * @var    string    sort_order_sql            String with the ORDER BY SQL code used in this query
0518                          * @since 3.2.3-RC2
0519                          */
0520                          $vars = array(
0521                              'sql',
0522                              'forum_list',
0523                              'visibility_const',
0524                              'topic_id',
0525                              'limit_time_sql',
0526                              'sort_order_sql',
0527                          );
0528                          extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_for_posts_query_before', compact($vars)));
0529   
0530                          $result = $db->sql_query($sql);
0531   
0532                          $post_data = $rowset = array();
0533                          while ($row = $db->sql_fetchrow($result))
0534                          {
0535                              $forum_names[] = $row['forum_id'];
0536                              $post_data[$row['post_id']] = $row;
0537                          }
0538                          $db->sql_freeresult($result);
0539   
0540                          foreach ($post_ids as $post_id)
0541                          {
0542                              $rowset[] = $post_data[$post_id];
0543                          }
0544                          unset($post_data, $post_ids);
0545                      }
0546                      else
0547                      {
0548                          $rowset = array();
0549                      }
0550                  }
0551                  else
0552                  {
0553                      $sql = 'SELECT t.forum_id, t.topic_id, t.topic_title, t.topic_title AS post_subject, t.topic_time AS post_time, t.topic_poster AS poster_id, t.topic_first_post_id AS post_id, t.topic_attachment AS post_attachment, t.topic_first_poster_name AS username, t.topic_first_poster_colour AS user_colour
0554                          FROM ' . TOPICS_TABLE . ' t
0555                          WHERE ' . $db->sql_in_set('forum_id', $forum_list) . '
0556                              AND  ' . $db->sql_in_set('topic_visibility', $visibility_const) . "
0557                              AND topic_delete_user <> 0
0558                              $limit_time_sql
0559                          ORDER BY $sort_order_sql";
0560   
0561                      /**
0562                      * Alter sql query to get information on all topics in the list of forums provided.
0563                      *
0564                      * @event core.mcp_queue_get_posts_for_topics_query_before
0565                      * @var    string    sql                        String with the query to be executed
0566                      * @var    array    forum_list                List of forums that contain the posts
0567                      * @var    int        visibility_const        Integer with one of the possible ITEM_* constant values
0568                      * @var    int        topic_id                topic_id in the page request
0569                      * @var    string    limit_time_sql            String with the SQL code to limit the time interval of the post (Note: May be empty string)
0570                      * @var    string    sort_order_sql            String with the ORDER BY SQL code used in this query
0571                      * @since 3.1.0-RC3
0572                      */
0573                      $vars = array(
0574                          'sql',
0575                          'forum_list',
0576                          'visibility_const',
0577                          'topic_id',
0578                          'limit_time_sql',
0579                          'sort_order_sql',
0580                      );
0581                      extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_for_topics_query_before', compact($vars)));
0582   
0583                      $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
0584   
0585                      $rowset = array();
0586                      while ($row = $db->sql_fetchrow($result))
0587                      {
0588                          $forum_names[] = $row['forum_id'];
0589                          $rowset[] = $row;
0590                      }
0591                      $db->sql_freeresult($result);
0592                  }
0593   
0594                  if (count($forum_names))
0595                  {
0596                      // Select the names for the forum_ids
0597                      $sql = 'SELECT forum_id, forum_name
0598                          FROM ' . FORUMS_TABLE . '
0599                          WHERE ' . $db->sql_in_set('forum_id', $forum_names);
0600                      $result = $db->sql_query($sql, 3600);
0601   
0602                      $forum_names = array();
0603                      while ($row = $db->sql_fetchrow($result))
0604                      {
0605                          $forum_names[$row['forum_id']] = $row['forum_name'];
0606                      }
0607                      $db->sql_freeresult($result);
0608                  }
0609   
0610                  foreach ($rowset as $row)
0611                  {
0612                      if (empty($row['post_username']))
0613                      {
0614                          $row['post_username'] = $row['username'] ?: $user->lang['GUEST'];
0615                      }
0616   
0617                      $post_row = array(
0618                          'U_TOPIC'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $row['topic_id']),
0619                          'U_VIEWFORUM'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
0620                          'U_VIEWPOST'        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . (($mode == 'unapproved_posts') ? '#p' . $row['post_id'] : ''),
0621                          'U_VIEW_DETAILS'    => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;start=$start&amp;mode=approve_details&amp;p={$row['post_id']}" . (($mode == 'unapproved_topics') ? "&amp;t={$row['topic_id']}" : '')),
0622   
0623                          'POST_AUTHOR_FULL'        => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
0624                          'POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
0625                          'POST_AUTHOR'            => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
0626                          'U_POST_AUTHOR'            => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
0627   
0628                          'POST_ID'        => $row['post_id'],
0629                          'TOPIC_ID'        => $row['topic_id'],
0630                          'FORUM_NAME'    => $forum_names[$row['forum_id']],
0631                          'POST_SUBJECT'    => ($row['post_subject'] != '') ? $row['post_subject'] : $user->lang['NO_SUBJECT'],
0632                          'TOPIC_TITLE'    => $row['topic_title'],
0633                          'POST_TIME'        => $user->format_date($row['post_time']),
0634                          'S_HAS_ATTACHMENTS'    => $auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['post_attachment'],
0635                      );
0636   
0637                      /**
0638                      * Alter sql query to get information on all topics in the list of forums provided.
0639                      *
0640                      * @event core.mcp_queue_get_posts_modify_post_row
0641                      * @var    array    post_row    Template variables for current post
0642                      * @var    array    row            Post data
0643                      * @var    array    forum_names    Forum names
0644                      * @since 3.2.3-RC2
0645                      */
0646                      $vars = array(
0647                          'post_row',
0648                          'row',
0649                          'forum_names',
0650                      );
0651                      extract($phpbb_dispatcher->trigger_event('core.mcp_queue_get_posts_modify_post_row', compact($vars)));
0652   
0653                      $template->assign_block_vars('postrow', $post_row);
0654                  }
0655                  unset($rowset, $forum_names);
0656   
0657                  /* @var \phpbb\pagination $pagination */
0658                  $pagination = $phpbb_container->get('pagination');
0659   
0660                  $base_url = $this->u_action . "&amp;f=$forum_id&amp;st=$sort_days&amp;sk=$sort_key&amp;sd=$sort_dir";
0661                  $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start);
0662   
0663                  // Now display the page
0664                  $template->assign_vars(array(
0665                      'L_DISPLAY_ITEMS'        => (!$is_topics) ? $user->lang['DISPLAY_POSTS'] : $user->lang['DISPLAY_TOPICS'],
0666                      'L_EXPLAIN'                => $user->lang['MCP_QUEUE_' . strtoupper($mode) . '_EXPLAIN'],
0667                      'L_TITLE'                => $user->lang['MCP_QUEUE_' . strtoupper($mode)],
0668                      'L_ONLY_TOPIC'            => ($topic_id) ? sprintf($user->lang['ONLY_TOPIC'], $topic_info['topic_title']) : '',
0669   
0670                      'S_FORUM_OPTIONS'        => $forum_options,
0671                      'S_MCP_ACTION'            => build_url(array('t', 'f', 'sd', 'st', 'sk')),
0672                      'S_TOPICS'                => $is_topics,
0673                      'S_RESTORE'                => $is_restore,
0674   
0675                      'TOPIC_ID'                => $topic_id,
0676                      'TOTAL'                    => $user->lang(((!$is_topics) ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total),
0677                  ));
0678   
0679                  $this->tpl_name = 'mcp_queue';
0680              break;
0681          }
0682      }
0683   
0684      /**
0685      * Approve/Restore posts
0686      *
0687      * @param $action        string    Action we perform on the posts ('approve' or 'restore')
0688      * @param $post_id_list    array    IDs of the posts to approve/restore
0689      * @param $id            mixed    Category of the current active module
0690      * @param $mode            string    Active module
0691      * @return null
0692      */
0693      static public function approve_posts($action, $post_id_list, $id, $mode)
0694      {
0695          global $template, $user, $request, $phpbb_container, $phpbb_dispatcher;
0696          global $phpEx, $phpbb_root_path, $phpbb_log;
0697   
0698          if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve')))
0699          {
0700              send_status_line(403, 'Forbidden');
0701              trigger_error('NOT_AUTHORISED');
0702          }
0703   
0704          $redirect = $request->variable('redirect', build_url(array('quickmod')));
0705          $redirect = reapply_sid($redirect);
0706          $post_url = '';
0707          $approve_log = array();
0708          $num_topics = 0;
0709   
0710          $s_hidden_fields = build_hidden_fields(array(
0711              'i'                => $id,
0712              'mode'            => $mode,
0713              'post_id_list'    => $post_id_list,
0714              'action'        => $action,
0715              'redirect'        => $redirect,
0716          ));
0717   
0718          $post_info = phpbb_get_post_data($post_id_list, 'm_approve');
0719   
0720          if (confirm_box(true))
0721          {
0722              $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster']));
0723   
0724              $topic_info = array();
0725   
0726              // Group the posts by topic_id
0727              foreach ($post_info as $post_id => $post_data)
0728              {
0729                  if ($post_data['post_visibility'] == ITEM_APPROVED)
0730                  {
0731                      continue;
0732                  }
0733                  $topic_id = (int) $post_data['topic_id'];
0734   
0735                  $topic_info[$topic_id]['posts'][] = (int) $post_id;
0736                  $topic_info[$topic_id]['forum_id'] = (int) $post_data['forum_id'];
0737   
0738                  // Refresh the first post, if the time or id is older then the current one
0739                  if ($post_id <= $post_data['topic_first_post_id'] || $post_data['post_time'] <= $post_data['topic_time'])
0740                  {
0741                      $topic_info[$topic_id]['first_post'] = true;
0742                  }
0743   
0744                  // Refresh the last post, if the time or id is newer then the current one
0745                  if ($post_id >= $post_data['topic_last_post_id'] || $post_data['post_time'] >= $post_data['topic_last_post_time'])
0746                  {
0747                      $topic_info[$topic_id]['last_post'] = true;
0748                  }
0749   
0750                  $post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "p={$post_data['post_id']}") . '#p' . $post_data['post_id'];
0751   
0752                  $approve_log[] = array(
0753                      'forum_id'        => $post_data['forum_id'],
0754                      'topic_id'        => $post_data['topic_id'],
0755                      'post_id'        => $post_id,
0756                      'post_subject'    => $post_data['post_subject'],
0757                  );
0758              }
0759   
0760              /* @var $phpbb_content_visibility \phpbb\content_visibility */
0761              $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0762              foreach ($topic_info as $topic_id => $topic_data)
0763              {
0764                  $phpbb_content_visibility->set_post_visibility(ITEM_APPROVED, $topic_data['posts'], $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), '', isset($topic_data['first_post']), isset($topic_data['last_post']));
0765              }
0766   
0767              foreach ($approve_log as $log_data)
0768              {
0769                  $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_POST_' . strtoupper($action) . 'D', false, array(
0770                      'forum_id' => $log_data['forum_id'],
0771                      'topic_id' => $log_data['topic_id'],
0772                      'post_id'  => $log_data['post_id'],
0773                      $log_data['post_subject']
0774                  ));
0775              }
0776   
0777              // Only send out the mails, when the posts are being approved
0778              if ($action == 'approve')
0779              {
0780                  /* @var $phpbb_notifications \phpbb\notification\manager */
0781                  $phpbb_notifications = $phpbb_container->get('notification_manager');
0782   
0783                  // Handle notifications
0784                  foreach ($post_info as $post_id => $post_data)
0785                  {
0786                      // A single topic approval may also happen here, so handle deleting the respective notification.
0787                      if (!$post_data['topic_posts_approved'])
0788                      {
0789                          $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $post_data['topic_id']);
0790   
0791                          if ($post_data['post_visibility'] == ITEM_UNAPPROVED)
0792                          {
0793                              $phpbb_notifications->add_notifications(array('notification.type.topic'), $post_data);
0794                          }
0795                          if ($post_data['post_visibility'] != ITEM_APPROVED)
0796                          {
0797                              $num_topics++;
0798                          }
0799                      }
0800                      else
0801                      {
0802                          // Only add notifications, if we are not reapproving post
0803                          // When the topic was already approved, but was edited and
0804                          // now needs re-approval, we don't want to notify the users
0805                          // again.
0806                          if ($post_data['post_visibility'] == ITEM_UNAPPROVED)
0807                          {
0808                              $phpbb_notifications->add_notifications(array(
0809                                  'notification.type.bookmark',
0810                                  'notification.type.post',
0811                              ), $post_data);
0812                          }
0813                      }
0814                      $phpbb_notifications->add_notifications(array('notification.type.quote'), $post_data);
0815                      $phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
0816   
0817                      $phpbb_notifications->mark_notifications(array(
0818                          'notification.type.quote',
0819                          'notification.type.bookmark',
0820                          'notification.type.post',
0821                      ), $post_data['post_id'], $user->data['user_id']);
0822   
0823                      // Notify Poster?
0824                      if ($notify_poster)
0825                      {
0826                          if ($post_data['poster_id'] == ANONYMOUS)
0827                          {
0828                              continue;
0829                          }
0830   
0831                          if (!$post_data['topic_posts_approved'])
0832                          {
0833                              $phpbb_notifications->add_notifications('notification.type.approve_topic', $post_data);
0834                          }
0835                          else
0836                          {
0837                              $phpbb_notifications->add_notifications('notification.type.approve_post', $post_data);
0838                          }
0839                      }
0840                  }
0841              }
0842   
0843              if ($num_topics >= 1)
0844              {
0845                  $success_msg = ($num_topics == 1) ? 'TOPIC_' . strtoupper($action) . 'D_SUCCESS' : 'TOPICS_' . strtoupper($action) . 'D_SUCCESS';
0846              }
0847              else
0848              {
0849                  $success_msg = (count($post_info) == 1) ? 'POST_' . strtoupper($action) . 'D_SUCCESS' : 'POSTS_' . strtoupper($action) . 'D_SUCCESS';
0850              }
0851   
0852              /**
0853               * Perform additional actions during post(s) approval
0854               *
0855               * @event core.approve_posts_after
0856               * @var    string    action                Variable containing the action we perform on the posts ('approve' or 'restore')
0857               * @var    array    post_info            Array containing info for all posts being approved
0858               * @var    array    topic_info            Array containing info for all parent topics of the posts
0859               * @var    int        num_topics            Variable containing number of topics
0860               * @var bool    notify_poster        Variable telling if the post should be notified or not
0861               * @var    string    success_msg            Variable containing the language key for the success message
0862               * @var string    redirect            Variable containing the redirect url
0863               * @since 3.1.4-RC1
0864               */
0865              $vars = array(
0866                  'action',
0867                  'post_info',
0868                  'topic_info',
0869                  'num_topics',
0870                  'notify_poster',
0871                  'success_msg',
0872                  'redirect',
0873              );
0874              extract($phpbb_dispatcher->trigger_event('core.approve_posts_after', compact($vars)));
0875   
0876              meta_refresh(3, $redirect);
0877              $message = $user->lang[$success_msg];
0878   
0879              if ($request->is_ajax())
0880              {
0881                  $json_response = new \phpbb\json_response;
0882                  $json_response->send(array(
0883                      'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
0884                      'MESSAGE_TEXT'        => $message,
0885                      'REFRESH_DATA'        => null,
0886                      'visible'            => true,
0887                  ));
0888              }
0889              $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>');
0890   
0891              // If approving one post, also give links back to post...
0892              if (count($post_info) == 1 && $post_url)
0893              {
0894                  $message .= '<br /><br />' . $user->lang('RETURN_POST', '<a href="' . $post_url . '">', '</a>');
0895              }
0896              trigger_error($message);
0897          }
0898          else
0899          {
0900              $show_notify = false;
0901   
0902              if ($action == 'approve')
0903              {
0904                  foreach ($post_info as $post_data)
0905                  {
0906                      if (!$post_data['topic_posts_approved'])
0907                      {
0908                          $num_topics++;
0909                      }
0910   
0911                      if (!$show_notify && $post_data['poster_id'] != ANONYMOUS)
0912                      {
0913                          $show_notify = true;
0914                      }
0915                  }
0916              }
0917   
0918              $template->assign_vars(array(
0919                  'S_NOTIFY_POSTER'            => $show_notify,
0920                  'S_' . strtoupper($action)    => true,
0921              ));
0922   
0923              // Create the confirm box message
0924              $action_msg = strtoupper($action);
0925              $num_posts = count($post_id_list) - $num_topics;
0926              if ($num_topics > 0 && $num_posts <= 0)
0927              {
0928                  $action_msg .= '_TOPIC' . (($num_topics == 1) ? '' : 'S');
0929              }
0930              else
0931              {
0932                  $action_msg .= '_POST' . ((count($post_id_list) == 1) ? '' : 'S');
0933              }
0934              confirm_box(false, $action_msg, $s_hidden_fields, 'mcp_approve.html');
0935          }
0936   
0937          redirect($redirect);
0938      }
0939   
0940      /**
0941      * Approve/Restore topics
0942      *
0943      * @param $action        string    Action we perform on the posts ('approve' or 'restore')
0944      * @param $topic_id_list    array    IDs of the topics to approve/restore
0945      * @param $id            mixed    Category of the current active module
0946      * @param $mode            string    Active module
0947      * @return null
0948      */
0949      static public function approve_topics($action, $topic_id_list, $id, $mode)
0950      {
0951          global $db, $template, $user, $phpbb_log;
0952          global $phpEx, $phpbb_root_path, $request, $phpbb_container, $phpbb_dispatcher;
0953   
0954          if (!phpbb_check_ids($topic_id_list, TOPICS_TABLE, 'topic_id', array('m_approve')))
0955          {
0956              send_status_line(403, 'Forbidden');
0957              trigger_error('NOT_AUTHORISED');
0958          }
0959   
0960          $redirect = $request->variable('redirect', build_url(array('quickmod')));
0961          $redirect = reapply_sid($redirect);
0962          $success_msg = $topic_url = '';
0963          $approve_log = array();
0964   
0965          $s_hidden_fields = build_hidden_fields(array(
0966              'i'                => $id,
0967              'mode'            => $mode,
0968              'topic_id_list'    => $topic_id_list,
0969              'action'        => $action,
0970              'redirect'        => $redirect,
0971          ));
0972   
0973          $topic_info = phpbb_get_topic_data($topic_id_list, 'm_approve');
0974   
0975          if (confirm_box(true))
0976          {
0977              $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster'])) ? true : false;
0978   
0979              /* @var $phpbb_content_visibility \phpbb\content_visibility */
0980              $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0981              $first_post_ids = array();
0982   
0983              foreach ($topic_info as $topic_id => $topic_data)
0984              {
0985                  $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), '');
0986                  $first_post_ids[$topic_id] = (int) $topic_data['topic_first_post_id'];
0987   
0988                  $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$topic_id}");
0989   
0990                  $approve_log[] = array(
0991                      'forum_id'        => $topic_data['forum_id'],
0992                      'topic_id'        => $topic_data['topic_id'],
0993                      'topic_title'    => $topic_data['topic_title'],
0994                  );
0995              }
0996   
0997              if (count($topic_info) >= 1)
0998              {
0999                  $success_msg = (count($topic_info) == 1) ? 'TOPIC_' . strtoupper($action) . 'D_SUCCESS' : 'TOPICS_' . strtoupper($action) . 'D_SUCCESS';
1000              }
1001   
1002              foreach ($approve_log as $log_data)
1003              {
1004                  $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_TOPIC_' . strtoupper($action) . 'D', false, array(
1005                      'forum_id' => $log_data['forum_id'],
1006                      'topic_id' => $log_data['topic_id'],
1007                      $log_data['topic_title']
1008                  ));
1009              }
1010   
1011              // Only send out the mails, when the posts are being approved
1012              if ($action == 'approve')
1013              {
1014                  // Grab the first post text as it's needed for the quote notification.
1015                  $sql = 'SELECT topic_id, post_text
1016                      FROM ' . POSTS_TABLE . '
1017                      WHERE ' . $db->sql_in_set('post_id', $first_post_ids);
1018                  $result = $db->sql_query($sql);
1019   
1020                  while ($row = $db->sql_fetchrow($result))
1021                  {
1022                      $topic_info[$row['topic_id']]['post_text'] = $row['post_text'];
1023                  }
1024                  $db->sql_freeresult($result);
1025   
1026                  // Handle notifications
1027                  /* @var $phpbb_notifications \phpbb\notification\manager */
1028                  $phpbb_notifications = $phpbb_container->get('notification_manager');
1029   
1030                  foreach ($topic_info as $topic_id => $topic_data)
1031                  {
1032                      $topic_data = array_merge($topic_data, array(
1033                          'post_id'        => $topic_data['topic_first_post_id'],
1034                          'post_subject'    => $topic_data['topic_title'],
1035                          'post_time'        => $topic_data['topic_time'],
1036                          'poster_id'        => $topic_data['topic_poster'],
1037                          'post_username'    => $topic_data['topic_first_poster_name'],
1038                      ));
1039   
1040                      $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $topic_id);
1041   
1042                      // Only add notifications, if we are not reapproving post
1043                      // When the topic was already approved, but was edited and
1044                      // now needs re-approval, we don't want to notify the users
1045                      // again.
1046                      if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED)
1047                      {
1048                          $phpbb_notifications->add_notifications(array(
1049                              'notification.type.quote',
1050                              'notification.type.topic',
1051                          ), $topic_data);
1052                      }
1053   
1054                      $phpbb_notifications->mark_notifications('quote', $topic_data['post_id'], $user->data['user_id']);
1055                      $phpbb_notifications->mark_notifications('topic', $topic_id, $user->data['user_id']);
1056   
1057                      if ($notify_poster)
1058                      {
1059                          $phpbb_notifications->add_notifications('notification.type.approve_topic', $topic_data);
1060                      }
1061                  }
1062              }
1063   
1064              /**
1065               * Perform additional actions during topics(s) approval
1066               *
1067               * @event core.approve_topics_after
1068               * @var    string    action                Variable containing the action we perform on the posts ('approve' or 'restore')
1069               * @var    mixed    topic_info            Array containing info for all topics being approved
1070               * @var    array    first_post_ids        Array containing ids of all first posts
1071               * @var bool    notify_poster        Variable telling if the poster should be notified or not
1072               * @var    string    success_msg            Variable containing the language key for the success message
1073               * @var string    redirect            Variable containing the redirect url
1074               * @since 3.1.4-RC1
1075               */
1076              $vars = array(
1077                  'action',
1078                  'topic_info',
1079                  'first_post_ids',
1080                  'notify_poster',
1081                  'success_msg',
1082                  'redirect',
1083              );
1084              extract($phpbb_dispatcher->trigger_event('core.approve_topics_after', compact($vars)));
1085   
1086              meta_refresh(3, $redirect);
1087              $message = $user->lang[$success_msg];
1088   
1089              if ($request->is_ajax())
1090              {
1091                  $json_response = new \phpbb\json_response;
1092                  $json_response->send(array(
1093                      'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
1094                      'MESSAGE_TEXT'        => $message,
1095                      'REFRESH_DATA'        => null,
1096                      'visible'            => true,
1097                  ));
1098              }
1099              $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>');
1100   
1101              // If approving one topic, also give links back to topic...
1102              if (count($topic_info) == 1 && $topic_url)
1103              {
1104                  $message .= '<br /><br />' . $user->lang('RETURN_TOPIC', '<a href="' . $topic_url . '">', '</a>');
1105              }
1106              trigger_error($message);
1107          }
1108          else
1109          {
1110              $show_notify = false;
1111   
1112              if ($action == 'approve')
1113              {
1114                  foreach ($topic_info as $topic_data)
1115                  {
1116                      if ($topic_data['topic_poster'] == ANONYMOUS)
1117                      {
1118                          continue;
1119                      }
1120                      else
1121                      {
1122                          $show_notify = true;
1123                          break;
1124                      }
1125                  }
1126              }
1127   
1128              $template->assign_vars(array(
1129                  'S_NOTIFY_POSTER'            => $show_notify,
1130                  'S_' . strtoupper($action)    => true,
1131              ));
1132   
1133              confirm_box(false, strtoupper($action) . '_TOPIC' . ((count($topic_id_list) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_approve.html');
1134          }
1135   
1136          redirect($redirect);
1137      }
1138   
1139      /**
1140      * Disapprove Post
1141      *
1142      * @param $post_id_list    array    IDs of the posts to disapprove/delete
1143      * @param $id            mixed    Category of the current active module
1144      * @param $mode            string    Active module
1145      * @return null
1146      */
1147      static public function disapprove_posts($post_id_list, $id, $mode)
1148      {
1149          global $db, $template, $user, $phpbb_container, $phpbb_dispatcher;
1150          global $phpEx, $phpbb_root_path, $request, $phpbb_log;
1151   
1152          if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve')))
1153          {
1154              send_status_line(403, 'Forbidden');
1155              trigger_error('NOT_AUTHORISED');
1156          }
1157   
1158          $redirect = $request->variable('redirect', build_url(array('t', 'mode', 'quickmod')) . "&amp;mode=$mode");
1159          $redirect = reapply_sid($redirect);
1160          $reason = $request->variable('reason', '', true);
1161          $reason_id = $request->variable('reason_id', 0);
1162          $additional_msg = '';
1163   
1164          $s_hidden_fields = build_hidden_fields(array(
1165              'i'                => $id,
1166              'mode'            => $mode,
1167              'post_id_list'    => $post_id_list,
1168              'action'        => 'disapprove',
1169              'redirect'        => $redirect,
1170          ));
1171   
1172          $notify_poster = $request->is_set('notify_poster');
1173          $disapprove_reason = '';
1174   
1175          if ($reason_id)
1176          {
1177              $sql = 'SELECT reason_title, reason_description
1178                  FROM ' . REPORTS_REASONS_TABLE . "
1179                  WHERE reason_id = $reason_id";
1180              $result = $db->sql_query($sql);
1181              $row = $db->sql_fetchrow($result);
1182              $db->sql_freeresult($result);
1183   
1184              if (!$row || (!$reason && strtolower($row['reason_title']) == 'other'))
1185              {
1186                  $additional_msg = $user->lang['NO_REASON_DISAPPROVAL'];
1187   
1188                  $request->overwrite('confirm', null, \phpbb\request\request_interface::POST);
1189                  $request->overwrite('confirm_key', null, \phpbb\request\request_interface::POST);
1190                  $request->overwrite('confirm_key', null, \phpbb\request\request_interface::REQUEST);
1191              }
1192              else
1193              {
1194                  // If the reason is defined within the language file, we will use the localized version, else just use the database entry...
1195                  $disapprove_reason = (strtolower($row['reason_title']) != 'other') ? ((isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description']) : '';
1196                  $disapprove_reason .= ($reason) ? "\n\n" . $reason : '';
1197   
1198                  if (isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]))
1199                  {
1200                      $disapprove_reason_lang = strtoupper($row['reason_title']);
1201                  }
1202              }
1203          }
1204   
1205          $post_info = phpbb_get_post_data($post_id_list, 'm_approve');
1206   
1207          $is_disapproving = false;
1208          foreach ($post_info as $post_id => $post_data)
1209          {
1210              if ($post_data['post_visibility'] == ITEM_DELETED)
1211              {
1212                  continue;
1213              }
1214   
1215              $is_disapproving = true;
1216          }
1217   
1218          if (confirm_box(true))
1219          {
1220              $disapprove_log_topics = $disapprove_log_posts = array();
1221              $topic_posts_unapproved = $post_disapprove_list = $topic_information = array();
1222   
1223              // Build a list of posts to be disapproved and get the related topics real replies count
1224              foreach ($post_info as $post_id => $post_data)
1225              {
1226                  if ($mode === 'unapproved_topics' && $post_data['post_visibility'] == ITEM_APPROVED)
1227                  {
1228                      continue;
1229                  }
1230   
1231                  $post_disapprove_list[$post_id] = $post_data['topic_id'];
1232                  if (!isset($topic_posts_unapproved[$post_data['topic_id']]))
1233                  {
1234                      $topic_information[$post_data['topic_id']] = $post_data;
1235                      $topic_posts_unapproved[$post_data['topic_id']] = 0;
1236                  }
1237                  $topic_posts_unapproved[$post_data['topic_id']]++;
1238              }
1239   
1240              // Do not try to disapprove if no posts are selected
1241              if (empty($post_disapprove_list))
1242              {
1243                  trigger_error('NO_POST_SELECTED');
1244              }
1245   
1246              // Now we build the log array
1247              foreach ($post_disapprove_list as $post_id => $topic_id)
1248              {
1249                  // If the count of disapproved posts for the topic is equal
1250                  // to the number of unapproved posts in the topic, and there are no different
1251                  // posts, we disapprove the hole topic
1252                  if ($topic_information[$topic_id]['topic_posts_approved'] == 0 &&
1253                      $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 &&
1254                      $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id])
1255                  {
1256                      // Don't write the log more than once for every topic
1257                      if (!isset($disapprove_log_topics[$topic_id]))
1258                      {
1259                          // Build disapproved topics log
1260                          $disapprove_log_topics[$topic_id] = array(
1261                              'type'            => 'topic',
1262                              'post_subject'    => $post_info[$post_id]['topic_title'],
1263                              'forum_id'        => $post_info[$post_id]['forum_id'],
1264                              'topic_id'        => 0, // useless to log a topic id, as it will be deleted
1265                              'post_username'    => ($post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username'])) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username'],
1266                          );
1267                      }
1268                  }
1269                  else
1270                  {
1271                      // Build disapproved posts log
1272                      $disapprove_log_posts[] = array(
1273                          'type'            => 'post',
1274                          'post_subject'    => $post_info[$post_id]['post_subject'],
1275                          'forum_id'        => $post_info[$post_id]['forum_id'],
1276                          'topic_id'        => $post_info[$post_id]['topic_id'],
1277                          'post_username'    => ($post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username'])) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username'],
1278                      );
1279   
1280                  }
1281              }
1282   
1283              // Get disapproved posts/topics counts separately
1284              $num_disapproved_topics = count($disapprove_log_topics);
1285              $num_disapproved_posts = count($disapprove_log_posts);
1286   
1287              // Build the whole log
1288              $disapprove_log = array_merge($disapprove_log_topics, $disapprove_log_posts);
1289   
1290              // Unset unneeded arrays
1291              unset($post_data, $disapprove_log_topics, $disapprove_log_posts);
1292   
1293              // Let's do the job - delete disapproved posts
1294              if (count($post_disapprove_list))
1295              {
1296                  if (!function_exists('delete_posts'))
1297                  {
1298                      include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1299                  }
1300   
1301                  // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts
1302                  // Note: function delete_posts triggers related forums/topics sync,
1303                  // so we don't need to call update_post_information later and to adjust real topic replies or forum topics count manually
1304                  delete_posts('post_id', array_keys($post_disapprove_list));
1305   
1306                  foreach ($disapprove_log as $log_data)
1307                  {
1308                      if ($is_disapproving)
1309                      {
1310                          $l_log_message = ($log_data['type'] == 'topic') ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED';
1311                          $phpbb_log->add('mod', $user->data['user_id'], $user->ip, $l_log_message, false, array(
1312                              'forum_id' => $log_data['forum_id'],
1313                              'topic_id' => $log_data['topic_id'],
1314                              $log_data['post_subject'],
1315                              $disapprove_reason,
1316                              $log_data['post_username']
1317                          ));
1318                      }
1319                      else
1320                      {
1321                          $l_log_message = ($log_data['type'] == 'topic') ? 'LOG_DELETE_TOPIC' : 'LOG_DELETE_POST';
1322                          $phpbb_log->add('mod', $user->data['user_id'], $user->ip, $l_log_message, false, array(
1323                              'forum_id' => $log_data['forum_id'],
1324                              'topic_id' => $log_data['topic_id'],
1325                              $log_data['post_subject'],
1326                              $log_data['post_username']
1327                          ));
1328                      }
1329                  }
1330              }
1331   
1332              /* @var $phpbb_notifications \phpbb\notification\manager */
1333              $phpbb_notifications = $phpbb_container->get('notification_manager');
1334   
1335              $lang_reasons = array();
1336   
1337              foreach ($post_info as $post_id => $post_data)
1338              {
1339                  $disapprove_all_posts_in_topic = $topic_information[$topic_id]['topic_posts_approved'] == 0 &&
1340                      $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 &&
1341                      $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id];
1342   
1343                  $phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
1344   
1345                  // Do we disapprove the whole topic? Remove potential notifications
1346                  if ($disapprove_all_posts_in_topic)
1347                  {
1348                      $phpbb_notifications->delete_notifications('notification.type.topic_in_queue', $post_data['topic_id']);
1349                  }
1350   
1351                  // Notify Poster?
1352                  if ($notify_poster)
1353                  {
1354                      if ($post_data['poster_id'] == ANONYMOUS)
1355                      {
1356                          continue;
1357                      }
1358   
1359                      $post_data['disapprove_reason'] = $disapprove_reason;
1360                      if (isset($disapprove_reason_lang))
1361                      {
1362                          // Okay we need to get the reason from the posters language
1363                          if (!isset($lang_reasons[$post_data['user_lang']]))
1364                          {
1365                              // Assign the current users translation as the default, this is not ideal but getting the board default adds another layer of complexity.
1366                              $lang_reasons[$post_data['user_lang']] = $user->lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang];
1367   
1368                              // Only load up the language pack if the language is different to the current one
1369                              if ($post_data['user_lang'] != $user->lang_name && file_exists($phpbb_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx))
1370                              {
1371                                  // Load up the language pack
1372                                  $lang = array();
1373                                  @include($phpbb_root_path . '/language/' . basename($post_data['user_lang']) . '/mcp.' . $phpEx);
1374   
1375                                  // If we find the reason in this language pack use it
1376                                  if (isset($lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]))
1377                                  {
1378                                      $lang_reasons[$post_data['user_lang']] = $lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang];
1379                                  }
1380   
1381                                  unset($lang); // Free memory
1382                              }
1383                          }
1384   
1385                          $post_data['disapprove_reason'] = $lang_reasons[$post_data['user_lang']];
1386                          $post_data['disapprove_reason'] .= ($reason) ? "\n\n" . $reason : '';
1387                      }
1388   
1389                      if ($disapprove_all_posts_in_topic && $topic_information[$topic_id]['topic_posts_unapproved'] == 1)
1390                      {
1391                          // If there is only 1 post when disapproving the topic,
1392                          // we send the user a "disapprove topic" notification...
1393                          $phpbb_notifications->add_notifications('notification.type.disapprove_topic', $post_data);
1394                      }
1395                      else
1396                      {
1397                          // ... otherwise there are multiple unapproved posts and
1398                          // all of them are disapproved as posts.
1399                          $phpbb_notifications->add_notifications('notification.type.disapprove_post', $post_data);
1400                      }
1401                  }
1402              }
1403   
1404              if ($num_disapproved_topics)
1405              {
1406                  $success_msg = ($num_disapproved_topics == 1) ? 'TOPIC' : 'TOPICS';
1407              }
1408              else
1409              {
1410                  $success_msg = ($num_disapproved_posts == 1) ? 'POST' : 'POSTS';
1411              }
1412   
1413              if ($is_disapproving)
1414              {
1415                  $success_msg .= '_DISAPPROVED_SUCCESS';
1416              }
1417              else
1418              {
1419                  $success_msg .= '_DELETED_SUCCESS';
1420              }
1421   
1422              // If we came from viewtopic, we try to go back to it.
1423              if (strpos($redirect, $phpbb_root_path . 'viewtopic.' . $phpEx) === 0)
1424              {
1425                  if ($num_disapproved_topics == 0)
1426                  {
1427                      // So we need to remove the post id part from the Url
1428                      $redirect = str_replace("&amp;p={$post_id_list[0]}#p{$post_id_list[0]}", '', $redirect);
1429                  }
1430                  else
1431                  {
1432                      // However this is only possible if the topic still exists,
1433                      // Otherwise we go back to the viewforum page
1434                      $redirect = append_sid($phpbb_root_path . 'viewforum.' . $phpEx, 'f=' . $post_data['forum_id']);
1435                  }
1436              }
1437   
1438              $disapprove_reason_lang = $disapprove_reason_lang ?? '';
1439   
1440              /**
1441               * Perform additional actions during post(s) disapproval
1442               *
1443               * @event core.disapprove_posts_after
1444               * @var    array    post_info                    Array containing info for all posts being disapproved
1445               * @var    array    topic_information            Array containing information for the topics
1446               * @var    array    topic_posts_unapproved        Array containing list of topic ids and the count of disapproved posts in them
1447               * @var    array    post_disapprove_list        Array containing list of posts and their topic id
1448               * @var    int        num_disapproved_topics        Variable containing the number of disapproved topics
1449               * @var    int        num_disapproved_posts        Variable containing the number of disapproved posts
1450               * @var array    lang_reasons                Array containing the language keys for reasons
1451               * @var    string    disapprove_reason            Variable containing the language key for the success message
1452               * @var    string    disapprove_reason_lang        Variable containing the language key for the success message
1453               * @var bool    is_disapproving                Variable telling if anything is going to be disapproved
1454               * @var bool    notify_poster                Variable telling if the post should be notified or not
1455               * @var    string    success_msg                    Variable containing the language key for the success message
1456               * @var string    redirect                    Variable containing the redirect url
1457               * @since 3.1.4-RC1
1458               */
1459              $vars = array(
1460                  'post_info',
1461                  'topic_information',
1462                  'topic_posts_unapproved',
1463                  'post_disapprove_list',
1464                  'num_disapproved_topics',
1465                  'num_disapproved_posts',
1466                  'lang_reasons',
1467                  'disapprove_reason',
1468                  'disapprove_reason_lang',
1469                  'is_disapproving',
1470                  'notify_poster',
1471                  'success_msg',
1472                  'redirect',
1473              );
1474              extract($phpbb_dispatcher->trigger_event('core.disapprove_posts_after', compact($vars)));
1475   
1476              unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang);
1477   
1478              meta_refresh(3, $redirect);
1479              $message = $user->lang[$success_msg];
1480   
1481              if ($request->is_ajax())
1482              {
1483                  $json_response = new \phpbb\json_response;
1484                  $json_response->send(array(
1485                      'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
1486                      'MESSAGE_TEXT'        => $message,
1487                      'REFRESH_DATA'        => null,
1488                      'visible'            => false,
1489                  ));
1490              }
1491              $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>');
1492              trigger_error($message);
1493          }
1494          else
1495          {
1496              $show_notify = false;
1497   
1498              foreach ($post_info as $post_data)
1499              {
1500                  if ($post_data['poster_id'] == ANONYMOUS)
1501                  {
1502                      continue;
1503                  }
1504                  else
1505                  {
1506                      $show_notify = true;
1507                      break;
1508                  }
1509              }
1510   
1511              $l_confirm_msg = 'DISAPPROVE_POST';
1512              $confirm_template = 'mcp_approve.html';
1513              if ($is_disapproving)
1514              {
1515                  $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id);
1516              }
1517              else
1518              {
1519                  $user->add_lang('posting');
1520   
1521                  $l_confirm_msg = 'DELETE_POST_PERMANENTLY';
1522                  $confirm_template = 'confirm_delete_body.html';
1523              }
1524              $l_confirm_msg .= ((count($post_id_list) == 1) ? '' : 'S');
1525   
1526              $template->assign_vars(array(
1527                  'S_NOTIFY_POSTER'    => $show_notify,
1528                  'S_APPROVE'            => false,
1529                  'REASON'            => ($is_disapproving) ? $reason : '',
1530                  'ADDITIONAL_MSG'    => $additional_msg,
1531              ));
1532   
1533              confirm_box(false, $l_confirm_msg, $s_hidden_fields, $confirm_template);
1534          }
1535   
1536          redirect($redirect);
1537      }
1538  }
1539