Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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