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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
mcp_main.php
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&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&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