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

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 53.18 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_main
0024  * Handling mcp actions
0025  */
0026  class mcp_main
0027  {
0028      var $p_master;
0029      var $u_action;
0030   
0031      function __construct($p_master)
0032      {
0033          $this->p_master = $p_master;
0034      }
0035   
0036      function main($id, $mode)
0037      {
0038          global $auth, $user, $action;
0039          global $phpbb_root_path, $phpEx, $request;
0040          global $phpbb_dispatcher;
0041   
0042          $quickmod = ($mode == 'quickmod') ? true : false;
0043   
0044          /**
0045          * Event to perform additional actions before an MCP action is executed.
0046          *
0047          * @event core.mcp_main_before
0048          * @var    string    action                The action that is about to be performed
0049          * @var    string    mode                The mode in which the MCP is accessed, e.g. front, forum_view, topic_view, post_details, quickmod
0050          * @var    boolean    quickmod            Whether or not the action is performed via QuickMod
0051          * @since 3.2.8-RC1
0052          */
0053          $vars = [
0054              'action',
0055              'mode',
0056              'quickmod',
0057          ];
0058          extract($phpbb_dispatcher->trigger_event('core.mcp_main_before', compact($vars)));
0059   
0060          switch ($action)
0061          {
0062              case 'lock':
0063              case 'unlock':
0064                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0065   
0066                  if (!count($topic_ids))
0067                  {
0068                      trigger_error('NO_TOPIC_SELECTED');
0069                  }
0070   
0071                  lock_unlock($action, $topic_ids);
0072              break;
0073   
0074              case 'lock_post':
0075              case 'unlock_post':
0076   
0077                  $post_ids = (!$quickmod) ? $request->variable('post_id_list', array(0)) : array($request->variable('p', 0));
0078   
0079                  if (!count($post_ids))
0080                  {
0081                      trigger_error('NO_POST_SELECTED');
0082                  }
0083   
0084                  lock_unlock($action, $post_ids);
0085              break;
0086   
0087              case 'make_announce':
0088              case 'make_sticky':
0089              case 'make_global':
0090              case 'make_normal':
0091   
0092                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0093   
0094                  if (!count($topic_ids))
0095                  {
0096                      trigger_error('NO_TOPIC_SELECTED');
0097                  }
0098   
0099                  change_topic_type($action, $topic_ids);
0100              break;
0101   
0102              case 'move':
0103                  $user->add_lang('viewtopic');
0104   
0105                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0106   
0107                  if (!count($topic_ids))
0108                  {
0109                      trigger_error('NO_TOPIC_SELECTED');
0110                  }
0111   
0112                  mcp_move_topic($topic_ids);
0113              break;
0114   
0115              case 'fork':
0116                  $user->add_lang('viewtopic');
0117   
0118                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0119   
0120                  if (!count($topic_ids))
0121                  {
0122                      trigger_error('NO_TOPIC_SELECTED');
0123                  }
0124   
0125                  mcp_fork_topic($topic_ids);
0126              break;
0127   
0128              case 'delete_topic':
0129                  $user->add_lang('viewtopic');
0130   
0131                  // f parameter is not reliable for permission usage, however we just use it to decide
0132                  // which permission we will check later on. So if it is manipulated, we will still catch it later on.
0133                  $forum_id = $request->variable('f', 0);
0134                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0135                  $soft_delete = (($request->is_set_post('confirm') && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id)) ? true : false;
0136   
0137                  if (!count($topic_ids))
0138                  {
0139                      trigger_error('NO_TOPIC_SELECTED');
0140                  }
0141   
0142                  mcp_delete_topic($topic_ids, $soft_delete, $request->variable('delete_reason', '', true));
0143              break;
0144   
0145              case 'delete_post':
0146                  $user->add_lang('posting');
0147   
0148                  // f parameter is not reliable for permission usage, however we just use it to decide
0149                  // which permission we will check later on. So if it is manipulated, we will still catch it later on.
0150                  $forum_id = $request->variable('f', 0);
0151                  $post_ids = (!$quickmod) ? $request->variable('post_id_list', array(0)) : array($request->variable('p', 0));
0152                  $soft_delete = (($request->is_set_post('confirm') && !$request->is_set_post('delete_permanent')) || !$auth->acl_get('m_delete', $forum_id)) ? true : false;
0153   
0154                  if (!count($post_ids))
0155                  {
0156                      trigger_error('NO_POST_SELECTED');
0157                  }
0158   
0159                  mcp_delete_post($post_ids, $soft_delete, $request->variable('delete_reason', '', true));
0160              break;
0161   
0162              case 'restore_topic':
0163                  $user->add_lang('posting');
0164   
0165                  $topic_ids = (!$quickmod) ? $request->variable('topic_id_list', array(0)) : array($request->variable('t', 0));
0166   
0167                  if (!count($topic_ids))
0168                  {
0169                      trigger_error('NO_TOPIC_SELECTED');
0170                  }
0171   
0172                  mcp_restore_topic($topic_ids);
0173              break;
0174   
0175              default:
0176                  /**
0177                  * This event allows you to handle custom quickmod options
0178                  *
0179                  * @event core.modify_quickmod_actions
0180                  * @var    string    action        Topic quick moderation action name
0181                  * @var    bool    quickmod    Flag indicating whether MCP is in quick moderation mode
0182                  * @since 3.1.0-a4
0183                  * @changed 3.1.0-RC4 Added variables: action, quickmod
0184                  */
0185                  $vars = array('action', 'quickmod');
0186                  extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_actions', compact($vars)));
0187              break;
0188          }
0189   
0190          switch ($mode)
0191          {
0192              case 'front':
0193                  if (!function_exists('mcp_front_view'))
0194                  {
0195                      include($phpbb_root_path . 'includes/mcp/mcp_front.' . $phpEx);
0196                  }
0197   
0198                  $user->add_lang('acp/common');
0199   
0200                  mcp_front_view($id, $mode, $action);
0201   
0202                  $this->tpl_name = 'mcp_front';
0203                  $this->page_title = 'MCP_MAIN';
0204              break;
0205   
0206              case 'forum_view':
0207                  if (!function_exists('mcp_forum_view'))
0208                  {
0209                      include($phpbb_root_path . 'includes/mcp/mcp_forum.' . $phpEx);
0210                  }
0211   
0212                  $user->add_lang('viewforum');
0213   
0214                  $forum_id = $request->variable('f', 0);
0215   
0216                  $forum_info = phpbb_get_forum_data($forum_id, 'm_', true);
0217   
0218                  if (!count($forum_info))
0219                  {
0220                      $this->main('main', 'front');
0221                      return;
0222                  }
0223   
0224                  $forum_info = $forum_info[$forum_id];
0225   
0226                  mcp_forum_view($id, $mode, $action, $forum_info);
0227   
0228                  $this->tpl_name = 'mcp_forum';
0229                  $this->page_title = 'MCP_MAIN_FORUM_VIEW';
0230              break;
0231   
0232              case 'topic_view':
0233                  if (!function_exists('mcp_topic_view'))
0234                  {
0235                      include($phpbb_root_path . 'includes/mcp/mcp_topic.' . $phpEx);
0236                  }
0237   
0238                  mcp_topic_view($id, $mode, $action);
0239   
0240                  $this->tpl_name = 'mcp_topic';
0241                  $this->page_title = 'MCP_MAIN_TOPIC_VIEW';
0242              break;
0243   
0244              case 'post_details':
0245                  if (!function_exists('mcp_post_details'))
0246                  {
0247                      include($phpbb_root_path . 'includes/mcp/mcp_post.' . $phpEx);
0248                  }
0249   
0250                  mcp_post_details($id, $mode, $action);
0251   
0252                  $this->tpl_name = ($action == 'whois') ? 'mcp_whois' : 'mcp_post';
0253                  $this->page_title = 'MCP_MAIN_POST_DETAILS';
0254              break;
0255   
0256              default:
0257                  if ($quickmod)
0258                  {
0259                      switch ($action)
0260                      {
0261                          case 'lock':
0262                          case 'unlock':
0263                          case 'make_announce':
0264                          case 'make_sticky':
0265                          case 'make_global':
0266                          case 'make_normal':
0267                          case 'make_onindex':
0268                          case 'move':
0269                          case 'fork':
0270                          case 'delete_topic':
0271                              trigger_error('TOPIC_NOT_EXIST');
0272                          break;
0273   
0274                          case 'lock_post':
0275                          case 'unlock_post':
0276                          case 'delete_post':
0277                              trigger_error('POST_NOT_EXIST');
0278                          break;
0279                      }
0280                  }
0281   
0282                  trigger_error('NO_MODE', E_USER_ERROR);
0283              break;
0284          }
0285      }
0286  }
0287   
0288  /**
0289  * Lock/Unlock Topic/Post
0290  */
0291  function lock_unlock($action, $ids)
0292  {
0293      global $user, $db, $request, $phpbb_log, $phpbb_dispatcher;
0294   
0295      if ($action == 'lock' || $action == 'unlock')
0296      {
0297          $table = TOPICS_TABLE;
0298          $sql_id = 'topic_id';
0299          $set_id = 'topic_status';
0300          $l_prefix = 'TOPIC';
0301      }
0302      else
0303      {
0304          $table = POSTS_TABLE;
0305          $sql_id = 'post_id';
0306          $set_id = 'post_edit_locked';
0307          $l_prefix = 'POST';
0308      }
0309   
0310      $orig_ids = $ids;
0311   
0312      if (!phpbb_check_ids($ids, $table, $sql_id, array('m_lock')))
0313      {
0314          // Make sure that for f_user_lock only the lock action is triggered.
0315          if ($action != 'lock')
0316          {
0317              return;
0318          }
0319   
0320          $ids = $orig_ids;
0321   
0322          if (!phpbb_check_ids($ids, $table, $sql_id, array('f_user_lock')))
0323          {
0324              return;
0325          }
0326      }
0327      unset($orig_ids);
0328   
0329      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
0330      $redirect = reapply_sid($redirect);
0331   
0332      $s_hidden_fields = build_hidden_fields(array(
0333          $sql_id . '_list'    => $ids,
0334          'action'            => $action,
0335          'redirect'            => $redirect)
0336      );
0337   
0338      if (confirm_box(true))
0339      {
0340          $sql = "UPDATE $table
0341              SET $set_id = " . (($action == 'lock' || $action == 'lock_post') ? ITEM_LOCKED : ITEM_UNLOCKED) . '
0342              WHERE ' . $db->sql_in_set($sql_id, $ids);
0343          $db->sql_query($sql);
0344   
0345          $data = ($action == 'lock' || $action == 'unlock') ? phpbb_get_topic_data($ids) : phpbb_get_post_data($ids);
0346   
0347          foreach ($data as $id => $row)
0348          {
0349              $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_' . strtoupper($action), false, array(
0350                  'forum_id' => $row['forum_id'],
0351                  'topic_id' => $row['topic_id'],
0352                  'post_id'  => isset($row['post_id']) ? $row['post_id'] : 0,
0353                  $row['topic_title']
0354              ));
0355          }
0356   
0357          /**
0358           * Perform additional actions after locking/unlocking posts/topics
0359           *
0360           * @event core.mcp_lock_unlock_after
0361           * @var    string    action                Variable containing the action we perform on the posts/topics ('lock', 'unlock', 'lock_post' or 'unlock_post')
0362           * @var    array    ids                    Array containing the post/topic IDs that have been locked/unlocked
0363           * @var    array    data                Array containing posts/topics data
0364           * @since 3.1.7-RC1
0365           */
0366          $vars = array(
0367              'action',
0368              'ids',
0369              'data',
0370          );
0371          extract($phpbb_dispatcher->trigger_event('core.mcp_lock_unlock_after', compact($vars)));
0372   
0373          $success_msg = $l_prefix . ((count($ids) == 1) ? '' : 'S') . '_' . (($action == 'lock' || $action == 'lock_post') ? 'LOCKED' : 'UNLOCKED') . '_SUCCESS';
0374   
0375          meta_refresh(2, $redirect);
0376          $message = $user->lang[$success_msg];
0377   
0378          if (!$request->is_ajax())
0379          {
0380              $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>');
0381          }
0382          trigger_error($message);
0383      }
0384      else
0385      {
0386          confirm_box(false, strtoupper($action) . '_' . $l_prefix . ((count($ids) == 1) ? '' : 'S'), $s_hidden_fields);
0387      }
0388   
0389      redirect($redirect);
0390  }
0391   
0392  /**
0393  * Change Topic Type
0394  */
0395  function change_topic_type($action, $topic_ids)
0396  {
0397      global $user, $db, $request, $phpbb_log, $phpbb_dispatcher;
0398   
0399      switch ($action)
0400      {
0401          case 'make_announce':
0402              $new_topic_type = POST_ANNOUNCE;
0403              $check_acl = 'f_announce';
0404              $l_new_type = (count($topic_ids) == 1) ? 'MCP_MAKE_ANNOUNCEMENT' : 'MCP_MAKE_ANNOUNCEMENTS';
0405          break;
0406   
0407          case 'make_global':
0408              $new_topic_type = POST_GLOBAL;
0409              $check_acl = 'f_announce_global';
0410              $l_new_type = (count($topic_ids) == 1) ? 'MCP_MAKE_GLOBAL' : 'MCP_MAKE_GLOBALS';
0411          break;
0412   
0413          case 'make_sticky':
0414              $new_topic_type = POST_STICKY;
0415              $check_acl = 'f_sticky';
0416              $l_new_type = (count($topic_ids) == 1) ? 'MCP_MAKE_STICKY' : 'MCP_MAKE_STICKIES';
0417          break;
0418   
0419          default:
0420              $new_topic_type = POST_NORMAL;
0421              $check_acl = false;
0422              $l_new_type = (count($topic_ids) == 1) ? 'MCP_MAKE_NORMAL' : 'MCP_MAKE_NORMALS';
0423          break;
0424      }
0425   
0426      $forum_id = phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', $check_acl, true);
0427   
0428      if ($forum_id === false)
0429      {
0430          return;
0431      }
0432   
0433      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
0434      $redirect = reapply_sid($redirect);
0435   
0436      $s_hidden_fields = array(
0437          'topic_id_list'    => $topic_ids,
0438          'f'                => $forum_id,
0439          'action'        => $action,
0440          'redirect'        => $redirect,
0441      );
0442   
0443      if (confirm_box(true))
0444      {
0445   
0446          /**
0447           * Perform additional actions before changing topic(s) type
0448           *
0449           * @event core.mcp_change_topic_type_before
0450           * @var    int        new_topic_type        The candidated topic type.
0451           * @var    int        forum_id            The forum ID for the topic ID(s).
0452           * @var    array    topic_ids            Array containing the topic ID(s) that will be changed
0453           * @since 3.2.6-RC1
0454           */
0455          $vars = array(
0456              'new_topic_type',
0457              'forum_id',
0458              'topic_ids',
0459          );
0460          extract($phpbb_dispatcher->trigger_event('core.mcp_change_topic_type_before', compact($vars)));
0461   
0462          $db->sql_transaction('begin');
0463   
0464          $sql = 'UPDATE ' . TOPICS_TABLE . "
0465              SET topic_type = $new_topic_type
0466              WHERE " . $db->sql_in_set('topic_id', $topic_ids);
0467          $db->sql_query($sql);
0468   
0469          if (($new_topic_type == POST_GLOBAL) && count($topic_ids))
0470          {
0471              // Delete topic shadows for global announcements
0472              $sql = 'DELETE FROM ' . TOPICS_TABLE . '
0473                  WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids);
0474              $db->sql_query($sql);
0475          }
0476   
0477          $db->sql_transaction('commit');
0478   
0479          $success_msg = (count($topic_ids) == 1) ? 'TOPIC_TYPE_CHANGED' : 'TOPICS_TYPE_CHANGED';
0480   
0481          if (count($topic_ids))
0482          {
0483              $data = phpbb_get_topic_data($topic_ids);
0484   
0485              foreach ($data as $topic_id => $row)
0486              {
0487                  $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_TOPIC_TYPE_CHANGED', false, array(
0488                      'forum_id' => $forum_id,
0489                      'topic_id' => $topic_id,
0490                      $row['topic_title']
0491                  ));
0492              }
0493          }
0494   
0495          /**
0496           * Perform additional actions after changing topic types
0497           *
0498           * @event core.mcp_change_topic_type_after
0499           * @var    int        new_topic_type        The newly changed topic type.
0500           * @var    int        forum_id            The forum ID where the newly changed topic type belongs to.
0501           * @var    array    topic_ids            Array containing the topic IDs that have been changed
0502           * @since 3.2.6-RC1
0503           */
0504          $vars = array(
0505              'new_topic_type',
0506              'forum_id',
0507              'topic_ids',
0508          );
0509          extract($phpbb_dispatcher->trigger_event('core.mcp_change_topic_type_after', compact($vars)));
0510   
0511          meta_refresh(2, $redirect);
0512          $message = $user->lang[$success_msg];
0513   
0514          if (!$request->is_ajax())
0515          {
0516              $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>');
0517          }
0518          trigger_error($message);
0519      }
0520      else
0521      {
0522          confirm_box(false, $l_new_type, build_hidden_fields($s_hidden_fields));
0523      }
0524   
0525      redirect($redirect);
0526  }
0527   
0528  /**
0529  * Move Topic
0530  */
0531  function mcp_move_topic($topic_ids)
0532  {
0533      global $auth, $user, $db, $template, $phpbb_log, $request, $phpbb_dispatcher;
0534      global $phpEx, $phpbb_root_path;
0535   
0536      // Here we limit the operation to one forum only
0537      $forum_id = phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_move'), true);
0538   
0539      if ($forum_id === false)
0540      {
0541          return;
0542      }
0543   
0544      $to_forum_id = $request->variable('to_forum_id', 0);
0545      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
0546      $additional_msg = $success_msg = '';
0547   
0548      $s_hidden_fields = build_hidden_fields(array(
0549          'topic_id_list'    => $topic_ids,
0550          'f'                => $forum_id,
0551          'action'        => 'move',
0552          'redirect'        => $redirect)
0553      );
0554   
0555      if ($to_forum_id)
0556      {
0557          $forum_data = phpbb_get_forum_data($to_forum_id, 'f_post');
0558   
0559          if (!count($forum_data))
0560          {
0561              $additional_msg = $user->lang['FORUM_NOT_EXIST'];
0562          }
0563          else
0564          {
0565              $forum_data = $forum_data[$to_forum_id];
0566   
0567              if ($forum_data['forum_type'] != FORUM_POST)
0568              {
0569                  $additional_msg = $user->lang['FORUM_NOT_POSTABLE'];
0570              }
0571              else if (!$auth->acl_get('f_post', $to_forum_id) || (!$auth->acl_get('m_approve', $to_forum_id) && !$auth->acl_get('f_noapprove', $to_forum_id)))
0572              {
0573                  $additional_msg = $user->lang['USER_CANNOT_POST'];
0574              }
0575              else if ($forum_id == $to_forum_id)
0576              {
0577                  $additional_msg = $user->lang['CANNOT_MOVE_SAME_FORUM'];
0578              }
0579          }
0580      }
0581      else if (isset($_POST['confirm']))
0582      {
0583          $additional_msg = $user->lang['FORUM_NOT_EXIST'];
0584      }
0585   
0586      if (!$to_forum_id || $additional_msg)
0587      {
0588          $request->overwrite('confirm', null, \phpbb\request\request_interface::POST);
0589          $request->overwrite('confirm_key', null);
0590      }
0591   
0592      if (confirm_box(true))
0593      {
0594          $topic_data = phpbb_get_topic_data($topic_ids);
0595          $leave_shadow = (isset($_POST['move_leave_shadow'])) ? true : false;
0596   
0597          $forum_sync_data = array();
0598   
0599          $forum_sync_data[$forum_id] = current($topic_data);
0600          $forum_sync_data[$to_forum_id] = $forum_data;
0601   
0602          $topics_moved = $topics_moved_unapproved = $topics_moved_softdeleted = 0;
0603          $posts_moved = $posts_moved_unapproved = $posts_moved_softdeleted = 0;
0604   
0605          foreach ($topic_data as $topic_id => $topic_info)
0606          {
0607              if ($topic_info['topic_visibility'] == ITEM_APPROVED)
0608              {
0609                  $topics_moved++;
0610              }
0611              else if ($topic_info['topic_visibility'] == ITEM_UNAPPROVED || $topic_info['topic_visibility'] == ITEM_REAPPROVE)
0612              {
0613                  $topics_moved_unapproved++;
0614              }
0615              else if ($topic_info['topic_visibility'] == ITEM_DELETED)
0616              {
0617                  $topics_moved_softdeleted++;
0618              }
0619   
0620              $posts_moved += $topic_info['topic_posts_approved'];
0621              $posts_moved_unapproved += $topic_info['topic_posts_unapproved'];
0622              $posts_moved_softdeleted += $topic_info['topic_posts_softdeleted'];
0623          }
0624   
0625          $db->sql_transaction('begin');
0626   
0627          // Move topics, but do not resync yet
0628          move_topics($topic_ids, $to_forum_id, false);
0629   
0630          if ($request->is_set_post('move_lock_topics') && $auth->acl_get('m_lock', $to_forum_id))
0631          {
0632              $sql = 'UPDATE ' . TOPICS_TABLE . '
0633                  SET topic_status = ' . ITEM_LOCKED . '
0634                  WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
0635              $db->sql_query($sql);
0636          }
0637   
0638          $shadow_topics = 0;
0639          $forum_ids = array($to_forum_id);
0640          foreach ($topic_data as $topic_id => $row)
0641          {
0642              // Get the list of forums to resync
0643              $forum_ids[] = $row['forum_id'];
0644   
0645              // We add the $to_forum_id twice, because 'forum_id' is updated
0646              // when the topic is moved again later.
0647              $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_MOVE', false, array(
0648                  'forum_id'        => (int) $to_forum_id,
0649                  'topic_id'        => (int) $topic_id,
0650                  $row['forum_name'],
0651                  $forum_data['forum_name'],
0652                  (int) $row['forum_id'],
0653                  (int) $forum_data['forum_id'],
0654              ));
0655   
0656              // Leave a redirection if required and only if the topic is visible to users
0657              if ($leave_shadow && $row['topic_visibility'] == ITEM_APPROVED && $row['topic_type'] != POST_GLOBAL)
0658              {
0659                  $shadow = array(
0660                      'forum_id'                =>    (int) $row['forum_id'],
0661                      'icon_id'                =>    (int) $row['icon_id'],
0662                      'topic_attachment'        =>    (int) $row['topic_attachment'],
0663                      'topic_visibility'        =>    ITEM_APPROVED, // a shadow topic is always approved
0664                      'topic_reported'        =>    0, // a shadow topic is never reported
0665                      'topic_title'            =>    (string) $row['topic_title'],
0666                      'topic_poster'            =>    (int) $row['topic_poster'],
0667                      'topic_time'            =>    (int) $row['topic_time'],
0668                      'topic_time_limit'        =>    (int) $row['topic_time_limit'],
0669                      'topic_views'            =>    (int) $row['topic_views'],
0670                      'topic_posts_approved'    =>    (int) $row['topic_posts_approved'],
0671                      'topic_posts_unapproved'=>    (int) $row['topic_posts_unapproved'],
0672                      'topic_posts_softdeleted'=>    (int) $row['topic_posts_softdeleted'],
0673                      'topic_status'            =>    ITEM_MOVED,
0674                      'topic_type'            =>    POST_NORMAL,
0675                      'topic_first_post_id'    =>    (int) $row['topic_first_post_id'],
0676                      'topic_first_poster_colour'=>(string) $row['topic_first_poster_colour'],
0677                      'topic_first_poster_name'=>    (string) $row['topic_first_poster_name'],
0678                      'topic_last_post_id'    =>    (int) $row['topic_last_post_id'],
0679                      'topic_last_poster_id'    =>    (int) $row['topic_last_poster_id'],
0680                      'topic_last_poster_colour'=>(string) $row['topic_last_poster_colour'],
0681                      'topic_last_poster_name'=>    (string) $row['topic_last_poster_name'],
0682                      'topic_last_post_subject'=>    (string) $row['topic_last_post_subject'],
0683                      'topic_last_post_time'    =>    (int) $row['topic_last_post_time'],
0684                      'topic_last_view_time'    =>    (int) $row['topic_last_view_time'],
0685                      'topic_moved_id'        =>    (int) $row['topic_id'],
0686                      'topic_bumped'            =>    (int) $row['topic_bumped'],
0687                      'topic_bumper'            =>    (int) $row['topic_bumper'],
0688                      'poll_title'            =>    (string) $row['poll_title'],
0689                      'poll_start'            =>    (int) $row['poll_start'],
0690                      'poll_length'            =>    (int) $row['poll_length'],
0691                      'poll_max_options'        =>    (int) $row['poll_max_options'],
0692                      'poll_last_vote'        =>    (int) $row['poll_last_vote']
0693                  );
0694   
0695                  /**
0696                  * Perform actions before shadow topic is created.
0697                  *
0698                  * @event core.mcp_main_modify_shadow_sql
0699                  * @var    array    shadow    SQL array to be used by $db->sql_build_array
0700                  * @var    array    row        Topic data
0701                  * @since 3.1.11-RC1
0702                  * @changed 3.1.11-RC1 Added variable: row
0703                  */
0704                  $vars = array(
0705                      'shadow',
0706                      'row',
0707                  );
0708                  extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_shadow_sql', compact($vars)));
0709   
0710                  $db->sql_query('INSERT INTO ' . TOPICS_TABLE . $db->sql_build_array('INSERT', $shadow));
0711   
0712                  // Shadow topics only count on new "topics" and not posts... a shadow topic alone has 0 posts
0713                  $shadow_topics++;
0714              }
0715          }
0716          unset($topic_data);
0717   
0718          $sync_sql = array();
0719          if ($posts_moved)
0720          {
0721              $sync_sql[$to_forum_id][] = 'forum_posts_approved = forum_posts_approved + ' . (int) $posts_moved;
0722              $sync_sql[$forum_id][] = 'forum_posts_approved = forum_posts_approved - ' . (int) $posts_moved;
0723          }
0724          if ($posts_moved_unapproved)
0725          {
0726              $sync_sql[$to_forum_id][] = 'forum_posts_unapproved = forum_posts_unapproved + ' . (int) $posts_moved_unapproved;
0727              $sync_sql[$forum_id][] = 'forum_posts_unapproved = forum_posts_unapproved - ' . (int) $posts_moved_unapproved;
0728          }
0729          if ($posts_moved_softdeleted)
0730          {
0731              $sync_sql[$to_forum_id][] = 'forum_posts_softdeleted = forum_posts_softdeleted + ' . (int) $posts_moved_softdeleted;
0732              $sync_sql[$forum_id][] = 'forum_posts_softdeleted = forum_posts_softdeleted - ' . (int) $posts_moved_softdeleted;
0733          }
0734   
0735          if ($topics_moved)
0736          {
0737              $sync_sql[$to_forum_id][] = 'forum_topics_approved = forum_topics_approved + ' . (int) $topics_moved;
0738              if ($topics_moved - $shadow_topics > 0)
0739              {
0740                  $sync_sql[$forum_id][] = 'forum_topics_approved = forum_topics_approved - ' . (int) ($topics_moved - $shadow_topics);
0741              }
0742          }
0743          if ($topics_moved_unapproved)
0744          {
0745              $sync_sql[$to_forum_id][] = 'forum_topics_unapproved = forum_topics_unapproved + ' . (int) $topics_moved_unapproved;
0746              $sync_sql[$forum_id][] = 'forum_topics_unapproved = forum_topics_unapproved - ' . (int) $topics_moved_unapproved;
0747          }
0748          if ($topics_moved_softdeleted)
0749          {
0750              $sync_sql[$to_forum_id][] = 'forum_topics_softdeleted = forum_topics_softdeleted + ' . (int) $topics_moved_softdeleted;
0751              $sync_sql[$forum_id][] = 'forum_topics_softdeleted = forum_topics_softdeleted - ' . (int) $topics_moved_softdeleted;
0752          }
0753   
0754          $success_msg = (count($topic_ids) == 1) ? 'TOPIC_MOVED_SUCCESS' : 'TOPICS_MOVED_SUCCESS';
0755   
0756          foreach ($sync_sql as $forum_id_key => $array)
0757          {
0758              $sql = 'UPDATE ' . FORUMS_TABLE . '
0759                  SET ' . implode(', ', $array) . '
0760                  WHERE forum_id = ' . $forum_id_key;
0761              $db->sql_query($sql);
0762          }
0763   
0764          $db->sql_transaction('commit');
0765   
0766          sync('forum', 'forum_id', array($forum_id, $to_forum_id));
0767      }
0768      else
0769      {
0770          $template->assign_vars(array(
0771              'S_FORUM_SELECT'        => make_forum_select($to_forum_id, $forum_id, false, true, true, true),
0772              'S_CAN_LEAVE_SHADOW'    => true,
0773              'S_CAN_LOCK_TOPIC'        => ($auth->acl_get('m_lock', $to_forum_id)) ? true : false,
0774              'ADDITIONAL_MSG'        => $additional_msg)
0775          );
0776   
0777          confirm_box(false, 'MOVE_TOPIC' . ((count($topic_ids) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_move.html');
0778      }
0779   
0780      $redirect = $request->variable('redirect', "index.$phpEx");
0781      $redirect = reapply_sid($redirect);
0782   
0783      if (!$success_msg)
0784      {
0785          redirect($redirect);
0786      }
0787      else
0788      {
0789          meta_refresh(3, $redirect);
0790   
0791          $message = $user->lang[$success_msg];
0792          $message .= '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>');
0793          $message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id") . '">', '</a>');
0794          $message .= '<br /><br />' . sprintf($user->lang['RETURN_NEW_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$to_forum_id") . '">', '</a>');
0795   
0796          trigger_error($message);
0797      }
0798  }
0799   
0800  /**
0801  * Restore Topics
0802  */
0803  function mcp_restore_topic($topic_ids)
0804  {
0805      global $user, $phpEx, $phpbb_root_path, $request, $phpbb_container, $phpbb_log;
0806   
0807      if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_approve')))
0808      {
0809          return;
0810      }
0811   
0812      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
0813      $forum_id = $request->variable('f', 0);
0814   
0815      $s_hidden_fields = build_hidden_fields(array(
0816          'topic_id_list'    => $topic_ids,
0817          'f'                => $forum_id,
0818          'action'        => 'restore_topic',
0819          'redirect'        => $redirect,
0820      ));
0821      $success_msg = '';
0822   
0823      if (confirm_box(true))
0824      {
0825          $success_msg = (count($topic_ids) == 1) ? 'TOPIC_RESTORED_SUCCESS' : 'TOPICS_RESTORED_SUCCESS';
0826   
0827          $data = phpbb_get_topic_data($topic_ids);
0828   
0829          /* @var $phpbb_content_visibility \phpbb\content_visibility */
0830          $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0831          foreach ($data as $topic_id => $row)
0832          {
0833              $return = $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $row['forum_id'], $user->data['user_id'], time(), '');
0834              if (!empty($return))
0835              {
0836                  $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_RESTORE_TOPIC', false, array(
0837                      'forum_id' => $row['forum_id'],
0838                      'topic_id' => $topic_id,
0839                      $row['topic_title'],
0840                      $row['topic_first_poster_name']
0841                  ));
0842              }
0843          }
0844      }
0845      else
0846      {
0847          confirm_box(false, (count($topic_ids) == 1) ? 'RESTORE_TOPIC' : 'RESTORE_TOPICS', $s_hidden_fields);
0848      }
0849   
0850      $topic_id = $request->variable('t', 0);
0851      if (!$request->is_set('quickmod', \phpbb\request\request_interface::REQUEST))
0852      {
0853          $redirect = $request->variable('redirect', "index.$phpEx");
0854          $redirect = reapply_sid($redirect);
0855          $redirect_message = 'PAGE';
0856      }
0857      else if ($topic_id)
0858      {
0859          $redirect = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id);
0860          $redirect_message = 'TOPIC';
0861      }
0862      else
0863      {
0864          $redirect = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
0865          $redirect_message = 'FORUM';
0866      }
0867   
0868      if (!$success_msg)
0869      {
0870          redirect($redirect);
0871      }
0872      else
0873      {
0874          meta_refresh(3, $redirect);
0875          trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_' . $redirect_message], '<a href="' . $redirect . '">', '</a>'));
0876      }
0877  }
0878   
0879  /**
0880  * Delete Topics
0881  */
0882  function mcp_delete_topic($topic_ids, $is_soft = false, $soft_delete_reason = '', $action = 'delete_topic')
0883  {
0884      global $auth, $user, $db, $phpEx, $phpbb_root_path, $request, $phpbb_container, $phpbb_log, $phpbb_dispatcher;
0885   
0886      $forum_id = $request->variable('f', 0);
0887      $check_permission = ($is_soft) ? ['m_softdelete'] : ['m_delete'];
0888      /**
0889      * This event allows you to modify the current user's checked permissions when deleting a topic
0890      *
0891      * @event core.mcp_delete_topic_modify_permissions
0892      * @var    array    topic_ids                The array of topic IDs to be deleted
0893      * @var    int        forum_id                The current forum ID
0894      * @var    bool    is_soft                    Boolean designating whether we're soft deleting or not
0895      * @var    string    soft_delete_reason        The reason we're soft deleting
0896      * @var    string    action                    The current delete action
0897      * @var    array    check_permission        The array with a permission to check for, can be set to false to not check them
0898      * @since 3.3.3-RC1
0899      */
0900      $vars = array(
0901          'topic_ids',
0902          'forum_id',
0903          'is_soft',
0904          'soft_delete_reason',
0905          'action',
0906          'check_permission',
0907      );
0908      extract($phpbb_dispatcher->trigger_event('core.mcp_delete_topic_modify_permissions', compact($vars)));
0909   
0910      if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', $check_permission))
0911      {
0912          return;
0913      }
0914   
0915      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
0916   
0917      $s_hidden_fields = array(
0918          'topic_id_list'    => $topic_ids,
0919          'f'                => $forum_id,
0920          'action'        => $action,
0921          'redirect'        => $redirect,
0922      );
0923      $success_msg = '';
0924   
0925      if (confirm_box(true))
0926      {
0927          $success_msg = (count($topic_ids) == 1) ? 'TOPIC_DELETED_SUCCESS' : 'TOPICS_DELETED_SUCCESS';
0928   
0929          $data = phpbb_get_topic_data($topic_ids);
0930   
0931          foreach ($data as $topic_id => $row)
0932          {
0933              if ($row['topic_moved_id'])
0934              {
0935                  $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_DELETE_SHADOW_TOPIC', false, array(
0936                      'forum_id' => $row['forum_id'],
0937                      'topic_id' => $topic_id,
0938                      $row['topic_title']
0939                  ));
0940              }
0941              else
0942              {
0943                  // Only soft delete non-shadow topics
0944                  if ($is_soft)
0945                  {
0946                      /* @var $phpbb_content_visibility \phpbb\content_visibility */
0947                      $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0948                      $return = $phpbb_content_visibility->set_topic_visibility(ITEM_DELETED, $topic_id, $row['forum_id'], $user->data['user_id'], time(), $soft_delete_reason);
0949                      if (!empty($return))
0950                      {
0951                          $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_SOFTDELETE_TOPIC', false, array(
0952                              'forum_id' => $row['forum_id'],
0953                              'topic_id' => $topic_id,
0954                              $row['topic_title'],
0955                              $row['topic_first_poster_name'],
0956                              $soft_delete_reason
0957                          ));
0958                      }
0959                  }
0960                  else
0961                  {
0962                      $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_DELETE_TOPIC', false, array(
0963                          'forum_id' => $row['forum_id'],
0964                          'topic_id' => $topic_id,
0965                          $row['topic_title'],
0966                          $row['topic_first_poster_name'],
0967                          $soft_delete_reason
0968                      ));
0969                  }
0970              }
0971          }
0972   
0973          if (!$is_soft)
0974          {
0975              delete_topics('topic_id', $topic_ids);
0976          }
0977      }
0978      else
0979      {
0980          global $template;
0981   
0982          $user->add_lang('posting');
0983   
0984          // If there are only shadow topics, we neither need a reason nor softdelete
0985          $sql = 'SELECT topic_id
0986              FROM ' . TOPICS_TABLE . '
0987              WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
0988                  AND topic_moved_id = 0';
0989          $result = $db->sql_query_limit($sql, 1);
0990          $only_shadow = !$db->sql_fetchfield('topic_id');
0991          $db->sql_freeresult($result);
0992   
0993          $only_softdeleted = false;
0994          if (!$only_shadow && $auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
0995          {
0996              // If there are only soft deleted topics, we display a message why the option is not available
0997              $sql = 'SELECT topic_id
0998                  FROM ' . TOPICS_TABLE . '
0999                  WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . '
1000                      AND topic_visibility <> ' . ITEM_DELETED;
1001              $result = $db->sql_query_limit($sql, 1);
1002              $only_softdeleted = !$db->sql_fetchfield('topic_id');
1003              $db->sql_freeresult($result);
1004          }
1005   
1006          $template->assign_vars(array(
1007              'S_SHADOW_TOPICS'                    => $only_shadow,
1008              'S_SOFTDELETED'                        => $only_softdeleted,
1009              'S_TOPIC_MODE'                        => true,
1010              'S_ALLOWED_DELETE'                    => $auth->acl_get('m_delete', $forum_id),
1011              'S_ALLOWED_SOFTDELETE'                => $auth->acl_get('m_softdelete', $forum_id),
1012              'DELETE_TOPIC_PERMANENTLY_EXPLAIN'    => $user->lang('DELETE_TOPIC_PERMANENTLY', count($topic_ids)),
1013          ));
1014   
1015          $count = count($topic_ids);
1016          $l_confirm = $count === 1 ? 'DELETE_TOPIC' : 'DELETE_TOPICS';
1017          if ($only_softdeleted)
1018          {
1019              $l_confirm = array($l_confirm . '_PERMANENTLY', $count);
1020              $s_hidden_fields['delete_permanent'] = '1';
1021          }
1022          else if ($only_shadow || !$auth->acl_get('m_softdelete', $forum_id))
1023          {
1024              $s_hidden_fields['delete_permanent'] = '1';
1025          }
1026   
1027          /**
1028          * This event allows you to modify the hidden form fields when deleting topics
1029          *
1030          * @event core.mcp_delete_topic_modify_hidden_fields
1031          * @var    string    l_confirm                The confirmation text language variable (DELETE_TOPIC(S), DELETE_TOPIC(S)_PERMANENTLY)
1032          * @var    array    s_hidden_fields            The array holding the hidden form fields
1033          * @var    array    topic_ids                The array of topic IDs to be deleted
1034          * @var    int        forum_id                The current forum ID
1035          * @var    bool    only_softdeleted        If the topic_ids are all soft deleted, this is true
1036          * @var    bool    only_shadow                If the topic_ids are all shadow topics, this is true
1037          * @since 3.3.3-RC1
1038          */
1039          $vars = array(
1040              'l_confirm',
1041              's_hidden_fields',
1042              'topic_ids',
1043              'forum_id',
1044              'only_softdeleted',
1045              'only_shadow',
1046          );
1047          extract($phpbb_dispatcher->trigger_event('core.mcp_delete_topic_modify_hidden_fields', compact($vars)));
1048   
1049          confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html');
1050      }
1051   
1052      $topic_id = $request->variable('t', 0);
1053      if (!$request->is_set('quickmod', \phpbb\request\request_interface::REQUEST))
1054      {
1055          $redirect = $request->variable('redirect', "index.$phpEx");
1056          $redirect = reapply_sid($redirect);
1057          $redirect_message = 'PAGE';
1058      }
1059      else if ($is_soft && $topic_id)
1060      {
1061          $redirect = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id);
1062          $redirect_message = 'TOPIC';
1063      }
1064      else
1065      {
1066          $redirect = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
1067          $redirect_message = 'FORUM';
1068      }
1069   
1070      if (!$success_msg)
1071      {
1072          redirect($redirect);
1073      }
1074      else
1075      {
1076          meta_refresh(3, $redirect);
1077          trigger_error($user->lang[$success_msg] . '<br /><br />' . sprintf($user->lang['RETURN_' . $redirect_message], '<a href="' . $redirect . '">', '</a>'));
1078      }
1079  }
1080   
1081  /**
1082  * Delete Posts
1083  */
1084  function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '', $action = 'delete_post')
1085  {
1086      global $auth, $user, $db, $phpEx, $phpbb_root_path, $request, $phpbb_container, $phpbb_log;
1087   
1088      $check_permission = ($is_soft) ? 'm_softdelete' : 'm_delete';
1089      if (!phpbb_check_ids($post_ids, POSTS_TABLE, 'post_id', array($check_permission)))
1090      {
1091          return;
1092      }
1093   
1094      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
1095      $forum_id = $request->variable('f', 0);
1096      $topic_id = 0;
1097   
1098      $s_hidden_fields = array(
1099          'post_id_list'    => $post_ids,
1100          'f'                => $forum_id,
1101          'action'        => $action,
1102          'redirect'        => $redirect,
1103      );
1104      $success_msg = '';
1105   
1106      if (confirm_box(true) && $is_soft)
1107      {
1108          $post_info = phpbb_get_post_data($post_ids);
1109   
1110          $topic_info = $approve_log = array();
1111   
1112          // Group the posts by topic_id
1113          foreach ($post_info as $post_id => $post_data)
1114          {
1115              if ($post_data['post_visibility'] != ITEM_APPROVED)
1116              {
1117                  continue;
1118              }
1119              $topic_id = (int) $post_data['topic_id'];
1120   
1121              $topic_info[$topic_id]['posts'][] = (int) $post_id;
1122              $topic_info[$topic_id]['forum_id'] = (int) $post_data['forum_id'];
1123   
1124              if ($post_id == $post_data['topic_first_post_id'])
1125              {
1126                  $topic_info[$topic_id]['first_post'] = true;
1127              }
1128   
1129              if ($post_id == $post_data['topic_last_post_id'])
1130              {
1131                  $topic_info[$topic_id]['last_post'] = true;
1132              }
1133   
1134              $approve_log[] = array(
1135                  'forum_id'        => $post_data['forum_id'],
1136                  'topic_id'        => $post_data['topic_id'],
1137                  'post_id'        => $post_id,
1138                  'post_subject'    => $post_data['post_subject'],
1139                  'poster_id'        => $post_data['poster_id'],
1140                  'post_username'    => $post_data['post_username'],
1141                  'username'        => $post_data['username'],
1142              );
1143          }
1144   
1145          /* @var $phpbb_content_visibility \phpbb\content_visibility */
1146          $phpbb_content_visibility = $phpbb_container->get('content.visibility');
1147          foreach ($topic_info as $topic_id => $topic_data)
1148          {
1149              $phpbb_content_visibility->set_post_visibility(ITEM_DELETED, $topic_data['posts'], $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), $soft_delete_reason, isset($topic_data['first_post']), isset($topic_data['last_post']));
1150          }
1151          $affected_topics = count($topic_info);
1152          // None of the topics is really deleted, so a redirect won't hurt much.
1153          $deleted_topics = 0;
1154   
1155          $success_msg = (count($post_info) == 1) ? $user->lang['POST_DELETED_SUCCESS'] : $user->lang['POSTS_DELETED_SUCCESS'];
1156   
1157          foreach ($approve_log as $row)
1158          {
1159              $post_username = ($row['poster_id'] == ANONYMOUS && !empty($row['post_username'])) ? $row['post_username'] : $row['username'];
1160              $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_SOFTDELETE_POST', false, array(
1161                  'forum_id' => $row['forum_id'],
1162                  'topic_id' => $row['topic_id'],
1163                  'post_id'  => $row['post_id'],
1164                  $row['post_subject'],
1165                  $post_username,
1166                  $soft_delete_reason
1167              ));
1168          }
1169   
1170          // Return links
1171          $return_link = array();
1172          if ($affected_topics == 1 && $topic_id)
1173          {
1174              $return_link[] = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id") . '">', '</a>');
1175          }
1176          $return_link[] = sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
1177   
1178      }
1179      else if (confirm_box(true))
1180      {
1181          if (!function_exists('delete_posts'))
1182          {
1183              include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1184          }
1185   
1186          // Count the number of topics that are affected
1187          // I did not use COUNT(DISTINCT ...) because I remember having problems
1188          // with it on older versions of MySQL -- Ashe
1189   
1190          $sql = 'SELECT DISTINCT topic_id
1191              FROM ' . POSTS_TABLE . '
1192              WHERE ' . $db->sql_in_set('post_id', $post_ids);
1193          $result = $db->sql_query($sql);
1194   
1195          $topic_id_list = array();
1196          while ($row = $db->sql_fetchrow($result))
1197          {
1198              $topic_id_list[] = $topic_id = $row['topic_id'];
1199          }
1200          $affected_topics = count($topic_id_list);
1201          $db->sql_freeresult($result);
1202   
1203          $post_data = phpbb_get_post_data($post_ids);
1204   
1205          foreach ($post_data as $id => $row)
1206          {
1207              $post_username = ($row['poster_id'] == ANONYMOUS && !empty($row['post_username'])) ? $row['post_username'] : $row['username'];
1208              $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_DELETE_POST', false, array(
1209                  'forum_id' => $row['forum_id'],
1210                  'topic_id' => $row['topic_id'],
1211                  'post_id'  => $row['post_id'],
1212                  $row['post_subject'],
1213                  $post_username,
1214                  $soft_delete_reason
1215              ));
1216          }
1217   
1218          // Now delete the posts, topics and forums are automatically resync'ed
1219          delete_posts('post_id', $post_ids);
1220   
1221          $sql = 'SELECT COUNT(topic_id) AS topics_left
1222              FROM ' . TOPICS_TABLE . '
1223              WHERE ' . $db->sql_in_set('topic_id', $topic_id_list);
1224          $result = $db->sql_query_limit($sql, 1);
1225   
1226          $deleted_topics = ($row = $db->sql_fetchrow($result)) ? ($affected_topics - $row['topics_left']) : $affected_topics;
1227          $db->sql_freeresult($result);
1228   
1229          // Return links
1230          $return_link = array();
1231          if ($affected_topics == 1 && !$deleted_topics && $topic_id)
1232          {
1233              $return_link[] = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id") . '">', '</a>');
1234          }
1235          $return_link[] = sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
1236   
1237          if (count($post_ids) == 1)
1238          {
1239              if ($deleted_topics)
1240              {
1241                  // We deleted the only post of a topic, which in turn has
1242                  // been removed from the database
1243                  $success_msg = $user->lang['TOPIC_DELETED_SUCCESS'];
1244              }
1245              else
1246              {
1247                  // Remove any post id anchor
1248                  if (($anchor_pos = strrpos($redirect, '#p')) !== false)
1249                  {
1250                      $redirect = substr($redirect, 0, $anchor_pos);
1251                  }
1252   
1253                  $success_msg = $user->lang['POST_DELETED_SUCCESS'];
1254              }
1255          }
1256          else
1257          {
1258              if ($deleted_topics)
1259              {
1260                  // Some of topics disappeared
1261                  $success_msg = $user->lang['POSTS_DELETED_SUCCESS'] . '<br /><br />' . $user->lang['EMPTY_TOPICS_REMOVED_WARNING'];
1262              }
1263              else
1264              {
1265                  $success_msg = $user->lang['POSTS_DELETED_SUCCESS'];
1266              }
1267          }
1268      }
1269      else
1270      {
1271          global $template;
1272   
1273          $user->add_lang('posting');
1274   
1275          $only_softdeleted = false;
1276          if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id))
1277          {
1278              // If there are only soft deleted posts, we display a message why the option is not available
1279              $sql = 'SELECT post_id
1280                  FROM ' . POSTS_TABLE . '
1281                  WHERE ' . $db->sql_in_set('post_id', $post_ids) . '
1282                      AND post_visibility <> ' . ITEM_DELETED;
1283              $result = $db->sql_query_limit($sql, 1);
1284              $only_softdeleted = !$db->sql_fetchfield('post_id');
1285              $db->sql_freeresult($result);
1286          }
1287   
1288          $template->assign_vars(array(
1289              'S_SOFTDELETED'                        => $only_softdeleted,
1290              'S_ALLOWED_DELETE'                    => $auth->acl_get('m_delete', $forum_id),
1291              'S_ALLOWED_SOFTDELETE'                => $auth->acl_get('m_softdelete', $forum_id),
1292              'DELETE_POST_PERMANENTLY_EXPLAIN'    => $user->lang('DELETE_POST_PERMANENTLY', count($post_ids)),
1293          ));
1294   
1295          $count = count($post_ids);
1296          $l_confirm = $count === 1 ? 'DELETE_POST' : 'DELETE_POSTS';
1297          if ($only_softdeleted)
1298          {
1299              $l_confirm = array($l_confirm . '_PERMANENTLY', $count);
1300              $s_hidden_fields['delete_permanent'] = '1';
1301          }
1302          else if (!$auth->acl_get('m_softdelete', $forum_id))
1303          {
1304              $s_hidden_fields['delete_permanent'] = '1';
1305          }
1306   
1307          confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html');
1308      }
1309   
1310      $redirect = reapply_sid($redirect);
1311   
1312      if (!$success_msg)
1313      {
1314          redirect($redirect);
1315      }
1316      else
1317      {
1318          if ($affected_topics != 1 || $deleted_topics || !$topic_id)
1319          {
1320              $redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&i=main&mode=forum_view", false);
1321          }
1322   
1323          meta_refresh(3, $redirect);
1324          trigger_error($success_msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . '<br /><br />' . implode('<br /><br />', $return_link));
1325      }
1326  }
1327   
1328  /**
1329  * Fork Topic
1330  */
1331  function mcp_fork_topic($topic_ids)
1332  {
1333      global $auth, $user, $db, $template, $config;
1334      global $phpEx, $phpbb_root_path, $phpbb_log, $request, $phpbb_dispatcher;
1335   
1336      if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id', array('m_')))
1337      {
1338          return;
1339      }
1340   
1341      $to_forum_id = $request->variable('to_forum_id', 0);
1342      $forum_id = $request->variable('f', 0);
1343      $redirect = $request->variable('redirect', build_url(array('action', 'quickmod')));
1344      $additional_msg = $success_msg = '';
1345      $counter = array();
1346   
1347      $s_hidden_fields = build_hidden_fields(array(
1348          'topic_id_list'    => $topic_ids,
1349          'f'                => $forum_id,
1350          'action'        => 'fork',
1351          'redirect'        => $redirect)
1352      );
1353   
1354      if ($to_forum_id)
1355      {
1356          $forum_data = phpbb_get_forum_data($to_forum_id, 'f_post');
1357   
1358          if (!count($topic_ids))
1359          {
1360              $additional_msg = $user->lang['NO_TOPIC_SELECTED'];
1361          }
1362          else if (!count($forum_data))
1363          {
1364              $additional_msg = $user->lang['FORUM_NOT_EXIST'];
1365          }
1366          else
1367          {
1368              $forum_data = $forum_data[$to_forum_id];
1369   
1370              if ($forum_data['forum_type'] != FORUM_POST)
1371              {
1372                  $additional_msg = $user->lang['FORUM_NOT_POSTABLE'];
1373              }
1374              else if (!$auth->acl_get('f_post', $to_forum_id))
1375              {
1376                  $additional_msg = $user->lang['USER_CANNOT_POST'];
1377              }
1378          }
1379      }
1380      else if (isset($_POST['confirm']))
1381      {
1382          $additional_msg = $user->lang['FORUM_NOT_EXIST'];
1383      }
1384   
1385      if ($additional_msg)
1386      {
1387          $request->overwrite('confirm', null, \phpbb\request\request_interface::POST);
1388          $request->overwrite('confirm_key', null);
1389      }
1390   
1391      if (confirm_box(true))
1392      {
1393          $topic_data = phpbb_get_topic_data($topic_ids, 'f_post');
1394   
1395          $total_topics = $total_topics_unapproved = $total_topics_softdeleted = 0;
1396          $total_posts = $total_posts_unapproved = $total_posts_softdeleted = 0;
1397          $new_topic_id_list = array();
1398   
1399          foreach ($topic_data as $topic_id => $topic_row)
1400          {
1401              if (!isset($search_type) && $topic_row['enable_indexing'])
1402              {
1403                  // Select the search method and do some additional checks to ensure it can actually be utilised
1404                  $search_type = $config['search_type'];
1405   
1406                  if (!class_exists($search_type))
1407                  {
1408                      trigger_error('NO_SUCH_SEARCH_MODULE');
1409                  }
1410   
1411                  $error = false;
1412                  $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
1413                  $search_mode = 'post';
1414   
1415                  if ($error)
1416                  {
1417                      trigger_error($error);
1418                  }
1419              }
1420              else if (!isset($search_type) && !$topic_row['enable_indexing'])
1421              {
1422                  $search_type = false;
1423              }
1424   
1425              $sql_ary = array(
1426                  'forum_id'                    => (int) $to_forum_id,
1427                  'icon_id'                    => (int) $topic_row['icon_id'],
1428                  'topic_attachment'            => (int) $topic_row['topic_attachment'],
1429                  'topic_visibility'            => (int) $topic_row['topic_visibility'],
1430                  'topic_reported'            => 0,
1431                  'topic_title'                => (string) $topic_row['topic_title'],
1432                  'topic_poster'                => (int) $topic_row['topic_poster'],
1433                  'topic_time'                => (int) $topic_row['topic_time'],
1434                  'topic_posts_approved'        => (int) $topic_row['topic_posts_approved'],
1435                  'topic_posts_unapproved'    => (int) $topic_row['topic_posts_unapproved'],
1436                  'topic_posts_softdeleted'    => (int) $topic_row['topic_posts_softdeleted'],
1437                  'topic_status'                => (int) $topic_row['topic_status'],
1438                  'topic_type'                => (int) $topic_row['topic_type'],
1439                  'topic_first_poster_name'    => (string) $topic_row['topic_first_poster_name'],
1440                  'topic_last_poster_id'        => (int) $topic_row['topic_last_poster_id'],
1441                  'topic_last_poster_name'    => (string) $topic_row['topic_last_poster_name'],
1442                  'topic_last_post_time'        => (int) $topic_row['topic_last_post_time'],
1443                  'topic_last_view_time'        => (int) $topic_row['topic_last_view_time'],
1444                  'topic_bumped'                => (int) $topic_row['topic_bumped'],
1445                  'topic_bumper'                => (int) $topic_row['topic_bumper'],
1446                  'poll_title'                => (string) $topic_row['poll_title'],
1447                  'poll_start'                => (int) $topic_row['poll_start'],
1448                  'poll_length'                => (int) $topic_row['poll_length'],
1449                  'poll_max_options'            => (int) $topic_row['poll_max_options'],
1450                  'poll_vote_change'            => (int) $topic_row['poll_vote_change'],
1451              );
1452   
1453              /**
1454              * Perform actions before forked topic is created.
1455              *
1456              * @event core.mcp_main_modify_fork_sql
1457              * @var    array    sql_ary        SQL array to be used by $db->sql_build_array
1458              * @var    array    topic_row    Topic data
1459              * @since 3.1.11-RC1
1460              * @changed 3.1.11-RC1 Added variable: topic_row
1461              */
1462              $vars = array(
1463                  'sql_ary',
1464                  'topic_row',
1465              );
1466              extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_fork_sql', compact($vars)));
1467   
1468              $db->sql_query('INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1469              $new_topic_id = $db->sql_nextid();
1470              $new_topic_id_list[$topic_id] = $new_topic_id;
1471   
1472              switch ($topic_row['topic_visibility'])
1473              {
1474                  case ITEM_APPROVED:
1475                      $total_topics++;
1476                  break;
1477                  case ITEM_UNAPPROVED:
1478                  case ITEM_REAPPROVE:
1479                      $total_topics_unapproved++;
1480                  break;
1481                  case ITEM_DELETED:
1482                      $total_topics_softdeleted++;
1483                  break;
1484              }
1485   
1486              if ($topic_row['poll_start'])
1487              {
1488                  $sql = 'SELECT *
1489                      FROM ' . POLL_OPTIONS_TABLE . "
1490                      WHERE topic_id = $topic_id";
1491                  $result = $db->sql_query($sql);
1492   
1493                  while ($row = $db->sql_fetchrow($result))
1494                  {
1495                      $sql_ary = array(
1496                          'poll_option_id'    => (int) $row['poll_option_id'],
1497                          'topic_id'            => (int) $new_topic_id,
1498                          'poll_option_text'    => (string) $row['poll_option_text'],
1499                          'poll_option_total'    => 0
1500                      );
1501   
1502                      $db->sql_query('INSERT INTO ' . POLL_OPTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1503                  }
1504                  $db->sql_freeresult($result);
1505              }
1506   
1507              $sql = 'SELECT *
1508                  FROM ' . POSTS_TABLE . "
1509                  WHERE topic_id = $topic_id
1510                  ORDER BY post_time ASC, post_id ASC";
1511              $result = $db->sql_query($sql);
1512   
1513              $post_rows = array();
1514              while ($row = $db->sql_fetchrow($result))
1515              {
1516                  $post_rows[] = $row;
1517              }
1518              $db->sql_freeresult($result);
1519   
1520              if (!count($post_rows))
1521              {
1522                  continue;
1523              }
1524   
1525              foreach ($post_rows as $row)
1526              {
1527                  $sql_ary = array(
1528                      'topic_id'            => (int) $new_topic_id,
1529                      'forum_id'            => (int) $to_forum_id,
1530                      'poster_id'            => (int) $row['poster_id'],
1531                      'icon_id'            => (int) $row['icon_id'],
1532                      'poster_ip'            => (string) $row['poster_ip'],
1533                      'post_time'            => (int) $row['post_time'],
1534                      'post_visibility'    => (int) $row['post_visibility'],
1535                      'post_reported'        => 0,
1536                      'enable_bbcode'        => (int) $row['enable_bbcode'],
1537                      'enable_smilies'    => (int) $row['enable_smilies'],
1538                      'enable_magic_url'    => (int) $row['enable_magic_url'],
1539                      'enable_sig'        => (int) $row['enable_sig'],
1540                      'post_username'        => (string) $row['post_username'],
1541                      'post_subject'        => (string) $row['post_subject'],
1542                      'post_text'            => (string) $row['post_text'],
1543                      'post_edit_reason'    => (string) $row['post_edit_reason'],
1544                      'post_edit_user'    => (int) $row['post_edit_user'],
1545                      'post_checksum'        => (string) $row['post_checksum'],
1546                      'post_attachment'    => (int) $row['post_attachment'],
1547                      'bbcode_bitfield'    => $row['bbcode_bitfield'],
1548                      'bbcode_uid'        => (string) $row['bbcode_uid'],
1549                      'post_edit_time'    => (int) $row['post_edit_time'],
1550                      'post_edit_count'    => (int) $row['post_edit_count'],
1551                      'post_edit_locked'    => (int) $row['post_edit_locked'],
1552                      'post_postcount'    => $row['post_postcount'],
1553                  );
1554                  // Adjust post count only if the post can be incremented to the user counter
1555                  if ($row['post_postcount'])
1556                  {
1557                      if (isset($counter[$row['poster_id']]))
1558                      {
1559                          ++$counter[$row['poster_id']];
1560                      }
1561                      else
1562                      {
1563                          $counter[$row['poster_id']] = 1;
1564                      }
1565                  }
1566   
1567                  /**
1568                  * Modify the forked post's sql array before it's inserted into the database.
1569                  *
1570                  * @event core.mcp_main_modify_fork_post_sql
1571                  * @var    int        new_topic_id    The newly created topic ID
1572                  * @var    int        to_forum_id        The forum ID where the forked topic has been moved to
1573                  * @var    array    sql_ary            SQL Array with the post's data
1574                  * @var    array    row                Post data
1575                  * @var    array    counter            Array with post counts
1576                  * @since 3.3.5-RC1
1577                  */
1578                  $vars = [
1579                      'new_topic_id',
1580                      'to_forum_id',
1581                      'sql_ary',
1582                      'row',
1583                      'counter',
1584                  ];
1585                  extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_fork_post_sql', compact($vars)));
1586                  $db->sql_query('INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1587                  $new_post_id = $db->sql_nextid();
1588   
1589                  /**
1590                  * Perform actions after forked topic is created.
1591                  *
1592                  * @event core.mcp_main_fork_sql_after
1593                  * @var    int        new_topic_id    The newly created topic ID
1594                  * @var    int        to_forum_id        The forum ID where the forked topic has been moved to
1595                  * @var    int        new_post_id        The newly created post ID
1596                  * @var    array    row                Post data
1597                  * @since 3.2.4-RC1
1598                  */
1599                  $vars = array(
1600                      'new_topic_id',
1601                      'to_forum_id',
1602                      'new_post_id',
1603                      'row',
1604                  );
1605                  extract($phpbb_dispatcher->trigger_event('core.mcp_main_fork_sql_after', compact($vars)));
1606   
1607                  switch ($row['post_visibility'])
1608                  {
1609                      case ITEM_APPROVED:
1610                          $total_posts++;
1611                      break;
1612                      case ITEM_UNAPPROVED:
1613                      case ITEM_REAPPROVE:
1614                          $total_posts_unapproved++;
1615                      break;
1616                      case ITEM_DELETED:
1617                          $total_posts_softdeleted++;
1618                      break;
1619                  }
1620   
1621                  // Copy whether the topic is dotted
1622                  markread('post', $to_forum_id, $new_topic_id, 0, $row['poster_id']);
1623   
1624                  if (!empty($search_type))
1625                  {
1626                      $search->index($search_mode, $new_post_id, $sql_ary['post_text'], $sql_ary['post_subject'], $sql_ary['poster_id'], ($topic_row['topic_type'] == POST_GLOBAL) ? 0 : $to_forum_id);
1627                      $search_mode = 'reply'; // After one we index replies
1628                  }
1629   
1630                  // Copy Attachments
1631                  if ($row['post_attachment'])
1632                  {
1633                      $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . '
1634                          WHERE post_msg_id = ' . (int) $row['post_id'] . '
1635                              AND topic_id = ' . (int) $topic_id . '
1636                              AND in_message = 0
1637                          ORDER BY attach_id ASC';
1638                      $result = $db->sql_query($sql);
1639   
1640                      $sql_ary = array();
1641                      while ($attach_row = $db->sql_fetchrow($result))
1642                      {
1643                          $sql_ary[] = array(
1644                              'post_msg_id'        => (int) $new_post_id,
1645                              'topic_id'            => (int) $new_topic_id,
1646                              'in_message'        => 0,
1647                              'is_orphan'            => (int) $attach_row['is_orphan'],
1648                              'poster_id'            => (int) $attach_row['poster_id'],
1649                              'physical_filename'    => (string) utf8_basename($attach_row['physical_filename']),
1650                              'real_filename'        => (string) utf8_basename($attach_row['real_filename']),
1651                              'download_count'    => (int) $attach_row['download_count'],
1652                              'attach_comment'    => (string) $attach_row['attach_comment'],
1653                              'extension'            => (string) $attach_row['extension'],
1654                              'mimetype'            => (string) $attach_row['mimetype'],
1655                              'filesize'            => (int) $attach_row['filesize'],
1656                              'filetime'            => (int) $attach_row['filetime'],
1657                              'thumbnail'            => (int) $attach_row['thumbnail']
1658                          );
1659                      }
1660                      $db->sql_freeresult($result);
1661   
1662                      if (count($sql_ary))
1663                      {
1664                          $db->sql_multi_insert(ATTACHMENTS_TABLE, $sql_ary);
1665                      }
1666                  }
1667              }
1668   
1669              // Copy topic subscriptions to new topic
1670              $sql = 'SELECT user_id, notify_status
1671                  FROM ' . TOPICS_WATCH_TABLE . '
1672                  WHERE topic_id = ' . $topic_id;
1673              $result = $db->sql_query($sql);
1674   
1675              $sql_ary = array();
1676              while ($row = $db->sql_fetchrow($result))
1677              {
1678                  $sql_ary[] = array(
1679                      'topic_id'        => (int) $new_topic_id,
1680                      'user_id'        => (int) $row['user_id'],
1681                      'notify_status'    => (int) $row['notify_status'],
1682                  );
1683              }
1684              $db->sql_freeresult($result);
1685   
1686              if (count($sql_ary))
1687              {
1688                  $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary);
1689              }
1690   
1691              // Copy bookmarks to new topic
1692              $sql = 'SELECT user_id
1693                  FROM ' . BOOKMARKS_TABLE . '
1694                  WHERE topic_id = ' . $topic_id;
1695              $result = $db->sql_query($sql);
1696   
1697              $sql_ary = array();
1698              while ($row = $db->sql_fetchrow($result))
1699              {
1700                  $sql_ary[] = array(
1701                      'topic_id'        => (int) $new_topic_id,
1702                      'user_id'        => (int) $row['user_id'],
1703                  );
1704              }
1705              $db->sql_freeresult($result);
1706   
1707              if (count($sql_ary))
1708              {
1709                  $db->sql_multi_insert(BOOKMARKS_TABLE, $sql_ary);
1710              }
1711          }
1712   
1713          // Sync new topics, parent forums and board stats
1714          $sql = 'UPDATE ' . FORUMS_TABLE . '
1715              SET forum_posts_approved = forum_posts_approved + ' . $total_posts . ',
1716                  forum_posts_unapproved = forum_posts_unapproved + ' . $total_posts_unapproved . ',
1717                  forum_posts_softdeleted = forum_posts_softdeleted + ' . $total_posts_softdeleted . ',
1718                  forum_topics_approved = forum_topics_approved + ' . $total_topics . ',
1719                  forum_topics_unapproved = forum_topics_unapproved + ' . $total_topics_unapproved . ',
1720                  forum_topics_softdeleted = forum_topics_softdeleted + ' . $total_topics_softdeleted . '
1721              WHERE forum_id = ' . $to_forum_id;
1722          $db->sql_query($sql);
1723   
1724          if (!empty($counter))
1725          {
1726              // Do only one query per user and not a query per post.
1727              foreach ($counter as $user_id => $count)
1728              {
1729                  $sql = 'UPDATE ' . USERS_TABLE . '
1730                      SET user_posts = user_posts + ' . (int) $count . '
1731                      WHERE user_id = ' . (int) $user_id;
1732                  $db->sql_query($sql);
1733              }
1734          }
1735   
1736          sync('topic', 'topic_id', $new_topic_id_list);
1737          sync('forum', 'forum_id', $to_forum_id);
1738   
1739          $config->increment('num_topics', count($new_topic_id_list), false);
1740          $config->increment('num_posts', $total_posts, false);
1741   
1742          foreach ($new_topic_id_list as $topic_id => $new_topic_id)
1743          {
1744              $phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_FORK', false, array(
1745                  'forum_id' => $to_forum_id,
1746                  'topic_id' => $new_topic_id,
1747                  $topic_row['forum_name']
1748              ));
1749          }
1750   
1751          $success_msg = (count($topic_ids) == 1) ? 'TOPIC_FORKED_SUCCESS' : 'TOPICS_FORKED_SUCCESS';
1752      }
1753      else
1754      {
1755          $template->assign_vars(array(
1756              'S_FORUM_SELECT'        => make_forum_select($to_forum_id, false, false, true, true, true),
1757              'S_CAN_LEAVE_SHADOW'    => false,
1758              'ADDITIONAL_MSG'        => $additional_msg)
1759          );
1760   
1761          confirm_box(false, 'FORK_TOPIC' . ((count($topic_ids) == 1) ? '' : 'S'), $s_hidden_fields, 'mcp_move.html');
1762      }
1763   
1764      $redirect = $request->variable('redirect', "index.$phpEx");
1765      $redirect = reapply_sid($redirect);
1766   
1767      if (!$success_msg)
1768      {
1769          redirect($redirect);
1770      }
1771      else
1772      {
1773          $redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
1774          meta_refresh(3, $redirect_url);
1775          $return_link = sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect_url . '">', '</a>');
1776   
1777          if ($forum_id != $to_forum_id)
1778          {
1779              $return_link .= '<br /><br />' . sprintf($user->lang['RETURN_NEW_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $to_forum_id) . '">', '</a>');
1780          }
1781   
1782          trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link);
1783      }
1784  }
1785