Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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