annotate forum/Sources/SplitTopics.php @ 85:6d7b61434be7 website

Add a copy of this here, just in case!
author Chris Cannam
date Mon, 20 Jan 2014 11:02:36 +0000
parents e3e11437ecea
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 // Original module by Mach8 - We'll never forget you.
Chris@76 15
Chris@76 16 if (!defined('SMF'))
Chris@76 17 die('Hacking attempt...');
Chris@76 18
Chris@76 19 /* This file handles merging and splitting topics... it does this with:
Chris@76 20
Chris@76 21 void SplitTopics()
Chris@76 22 - splits a topic into two topics.
Chris@76 23 - delegates to the other functions (based on the URL parameter 'sa').
Chris@76 24 - loads the SplitTopics template.
Chris@76 25 - requires the split_any permission.
Chris@76 26 - is accessed with ?action=splittopics.
Chris@76 27
Chris@76 28 void SplitIndex()
Chris@76 29 - screen shown before the actual split.
Chris@76 30 - is accessed with ?action=splittopics;sa=index.
Chris@76 31 - default sub action for ?action=splittopics.
Chris@76 32 - uses 'ask' sub template of the SplitTopics template.
Chris@76 33 - redirects to SplitSelectTopics if the message given turns out to be
Chris@76 34 the first message of a topic.
Chris@76 35 - shows the user three ways to split the current topic.
Chris@76 36
Chris@76 37 void SplitExecute()
Chris@76 38 - do the actual split.
Chris@76 39 - is accessed with ?action=splittopics;sa=execute.
Chris@76 40 - uses the main SplitTopics template.
Chris@76 41 - supports three ways of splitting:
Chris@76 42 (1) only one message is split off.
Chris@76 43 (2) all messages after and including a given message are split off.
Chris@76 44 (3) select topics to split (redirects to SplitSelectTopics()).
Chris@76 45 - uses splitTopic function to do the actual splitting.
Chris@76 46
Chris@76 47 void SplitSelectTopics()
Chris@76 48 - allows the user to select the messages to be split.
Chris@76 49 - is accessed with ?action=splittopics;sa=selectTopics.
Chris@76 50 - uses 'select' sub template of the SplitTopics template or (for
Chris@76 51 XMLhttp) the 'split' sub template of the Xml template.
Chris@76 52 - supports XMLhttp for adding/removing a message to the selection.
Chris@76 53 - uses a session variable to store the selected topics.
Chris@76 54 - shows two independent page indexes for both the selected and
Chris@76 55 not-selected messages (;topic=1.x;start2=y).
Chris@76 56
Chris@76 57 void SplitSelectionExecute()
Chris@76 58 - do the actual split of a selection of topics.
Chris@76 59 - is accessed with ?action=splittopics;sa=splitSelection.
Chris@76 60 - uses the main SplitTopics template.
Chris@76 61 - uses splitTopic function to do the actual splitting.
Chris@76 62
Chris@76 63 int splitTopic(int topicID, array messagesToBeSplit, string newSubject)
Chris@76 64 - general function to split off a topic.
Chris@76 65 - creates a new topic and moves the messages with the IDs in
Chris@76 66 array messagesToBeSplit to the new topic.
Chris@76 67 - the subject of the newly created topic is set to 'newSubject'.
Chris@76 68 - marks the newly created message as read for the user splitting it.
Chris@76 69 - updates the statistics to reflect a newly created topic.
Chris@76 70 - logs the action in the moderation log.
Chris@76 71 - a notification is sent to all users monitoring this topic.
Chris@76 72 - returns the topic ID of the new split topic.
Chris@76 73
Chris@76 74 void MergeTopics()
Chris@76 75 - merges two or more topics into one topic.
Chris@76 76 - delegates to the other functions (based on the URL parameter sa).
Chris@76 77 - loads the SplitTopics template.
Chris@76 78 - requires the merge_any permission.
Chris@76 79 - is accessed with ?action=mergetopics.
Chris@76 80
Chris@76 81 void MergeIndex()
Chris@76 82 - allows to pick a topic to merge the current topic with.
Chris@76 83 - is accessed with ?action=mergetopics;sa=index
Chris@76 84 - default sub action for ?action=mergetopics.
Chris@76 85 - uses 'merge' sub template of the SplitTopics template.
Chris@76 86 - allows to set a different target board.
Chris@76 87
Chris@76 88 void MergeExecute(array topics = request)
Chris@76 89 - set merge options and do the actual merge of two or more topics.
Chris@76 90 - the merge options screen:
Chris@76 91 - shows topics to be merged and allows to set some merge options.
Chris@76 92 - is accessed by ?action=mergetopics;sa=options.and can also
Chris@76 93 internally be called by QuickModeration() (Subs-Boards.php).
Chris@76 94 - uses 'merge_extra_options' sub template of the SplitTopics
Chris@76 95 template.
Chris@76 96 - the actual merge:
Chris@76 97 - is accessed with ?action=mergetopics;sa=execute.
Chris@76 98 - updates the statistics to reflect the merge.
Chris@76 99 - logs the action in the moderation log.
Chris@76 100 - sends a notification is sent to all users monitoring this topic.
Chris@76 101 - redirects to ?action=mergetopics;sa=done.
Chris@76 102
Chris@76 103 void MergeDone()
Chris@76 104 - shows a 'merge completed' screen.
Chris@76 105 - is accessed with ?action=mergetopics;sa=done.
Chris@76 106 - uses 'merge_done' sub template of the SplitTopics template.
Chris@76 107 */
Chris@76 108
Chris@76 109 // Split a topic into two separate topics... in case it got offtopic, etc.
Chris@76 110 function SplitTopics()
Chris@76 111 {
Chris@76 112 global $topic, $sourcedir;
Chris@76 113
Chris@76 114 // And... which topic were you splitting, again?
Chris@76 115 if (empty($topic))
Chris@76 116 fatal_lang_error('numbers_one_to_nine', false);
Chris@76 117
Chris@76 118 // Are you allowed to split topics?
Chris@76 119 isAllowedTo('split_any');
Chris@76 120
Chris@76 121 // Load up the "dependencies" - the template, getMsgMemberID(), and sendNotifications().
Chris@76 122 if (!isset($_REQUEST['xml']))
Chris@76 123 loadTemplate('SplitTopics');
Chris@76 124 require_once($sourcedir . '/Subs-Boards.php');
Chris@76 125 require_once($sourcedir . '/Subs-Post.php');
Chris@76 126
Chris@76 127 $subActions = array(
Chris@76 128 'selectTopics' => 'SplitSelectTopics',
Chris@76 129 'execute' => 'SplitExecute',
Chris@76 130 'index' => 'SplitIndex',
Chris@76 131 'splitSelection' => 'SplitSelectionExecute',
Chris@76 132 );
Chris@76 133
Chris@76 134 // ?action=splittopics;sa=LETSBREAKIT won't work, sorry.
Chris@76 135 if (empty($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']]))
Chris@76 136 SplitIndex();
Chris@76 137 else
Chris@76 138 $subActions[$_REQUEST['sa']]();
Chris@76 139 }
Chris@76 140
Chris@76 141 // Part 1: General stuff.
Chris@76 142 function SplitIndex()
Chris@76 143 {
Chris@76 144 global $txt, $topic, $context, $smcFunc, $modSettings;
Chris@76 145
Chris@76 146 // Validate "at".
Chris@76 147 if (empty($_GET['at']))
Chris@76 148 fatal_lang_error('numbers_one_to_nine', false);
Chris@76 149 $_GET['at'] = (int) $_GET['at'];
Chris@76 150
Chris@76 151 // Retrieve the subject and stuff of the specific topic/message.
Chris@76 152 $request = $smcFunc['db_query']('', '
Chris@76 153 SELECT m.subject, t.num_replies, t.unapproved_posts, t.id_first_msg, t.approved
Chris@76 154 FROM {db_prefix}messages AS m
Chris@76 155 INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
Chris@76 156 WHERE m.id_msg = {int:split_at}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 157 AND m.approved = 1') . '
Chris@76 158 AND m.id_topic = {int:current_topic}
Chris@76 159 LIMIT 1',
Chris@76 160 array(
Chris@76 161 'current_topic' => $topic,
Chris@76 162 'split_at' => $_GET['at'],
Chris@76 163 )
Chris@76 164 );
Chris@76 165 if ($smcFunc['db_num_rows']($request) == 0)
Chris@76 166 fatal_lang_error('cant_find_messages');
Chris@76 167 list ($_REQUEST['subname'], $num_replies, $unapproved_posts, $id_first_msg, $approved) = $smcFunc['db_fetch_row']($request);
Chris@76 168 $smcFunc['db_free_result']($request);
Chris@76 169
Chris@76 170 // If not approved validate they can see it.
Chris@76 171 if ($modSettings['postmod_active'] && !$approved)
Chris@76 172 isAllowedTo('approve_posts');
Chris@76 173
Chris@76 174 // If this topic has unapproved posts, we need to count them too...
Chris@76 175 if ($modSettings['postmod_active'] && allowedTo('approve_posts'))
Chris@76 176 $num_replies += $unapproved_posts - ($approved ? 0 : 1);
Chris@76 177
Chris@76 178 // Check if there is more than one message in the topic. (there should be.)
Chris@76 179 if ($num_replies < 1)
Chris@76 180 fatal_lang_error('topic_one_post', false);
Chris@76 181
Chris@76 182 // Check if this is the first message in the topic (if so, the first and second option won't be available)
Chris@76 183 if ($id_first_msg == $_GET['at'])
Chris@76 184 return SplitSelectTopics();
Chris@76 185
Chris@76 186 // Basic template information....
Chris@76 187 $context['message'] = array(
Chris@76 188 'id' => $_GET['at'],
Chris@76 189 'subject' => $_REQUEST['subname']
Chris@76 190 );
Chris@76 191 $context['sub_template'] = 'ask';
Chris@76 192 $context['page_title'] = $txt['split'];
Chris@76 193 }
Chris@76 194
Chris@76 195 // Alright, you've decided what you want to do with it.... now to do it.
Chris@76 196 function SplitExecute()
Chris@76 197 {
Chris@76 198 global $txt, $board, $topic, $context, $user_info, $smcFunc, $modSettings;
Chris@76 199
Chris@76 200 // Check the session to make sure they meant to do this.
Chris@76 201 checkSession();
Chris@76 202
Chris@76 203 // Clean up the subject.
Chris@76 204 if (!isset($_POST['subname']) || $_POST['subname'] == '')
Chris@76 205 $_POST['subname'] = $txt['new_topic'];
Chris@76 206
Chris@76 207 // Redirect to the selector if they chose selective.
Chris@76 208 if ($_POST['step2'] == 'selective')
Chris@76 209 {
Chris@76 210 $_REQUEST['subname'] = $_POST['subname'];
Chris@76 211 return SplitSelectTopics();
Chris@76 212 }
Chris@76 213
Chris@76 214 $_POST['at'] = (int) $_POST['at'];
Chris@76 215 $messagesToBeSplit = array();
Chris@76 216
Chris@76 217 if ($_POST['step2'] == 'afterthis')
Chris@76 218 {
Chris@76 219 // Fetch the message IDs of the topic that are at or after the message.
Chris@76 220 $request = $smcFunc['db_query']('', '
Chris@76 221 SELECT id_msg
Chris@76 222 FROM {db_prefix}messages
Chris@76 223 WHERE id_topic = {int:current_topic}
Chris@76 224 AND id_msg >= {int:split_at}',
Chris@76 225 array(
Chris@76 226 'current_topic' => $topic,
Chris@76 227 'split_at' => $_POST['at'],
Chris@76 228 )
Chris@76 229 );
Chris@76 230 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 231 $messagesToBeSplit[] = $row['id_msg'];
Chris@76 232 $smcFunc['db_free_result']($request);
Chris@76 233 }
Chris@76 234 // Only the selected message has to be split. That should be easy.
Chris@76 235 elseif ($_POST['step2'] == 'onlythis')
Chris@76 236 $messagesToBeSplit[] = $_POST['at'];
Chris@76 237 // There's another action?!
Chris@76 238 else
Chris@76 239 fatal_lang_error('no_access', false);
Chris@76 240
Chris@76 241 $context['old_topic'] = $topic;
Chris@76 242 $context['new_topic'] = splitTopic($topic, $messagesToBeSplit, $_POST['subname']);
Chris@76 243 $context['page_title'] = $txt['split'];
Chris@76 244 }
Chris@76 245
Chris@76 246 // Get a selective list of topics...
Chris@76 247 function SplitSelectTopics()
Chris@76 248 {
Chris@76 249 global $txt, $scripturl, $topic, $context, $modSettings, $original_msgs, $smcFunc, $options;
Chris@76 250
Chris@76 251 $context['page_title'] = $txt['split'] . ' - ' . $txt['select_split_posts'];
Chris@76 252
Chris@76 253 // Haven't selected anything have we?
Chris@76 254 $_SESSION['split_selection'][$topic] = empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic];
Chris@76 255
Chris@76 256 $context['not_selected'] = array(
Chris@76 257 'num_messages' => 0,
Chris@76 258 'start' => empty($_REQUEST['start']) ? 0 : (int) $_REQUEST['start'],
Chris@76 259 'messages' => array(),
Chris@76 260 );
Chris@76 261
Chris@76 262 $context['selected'] = array(
Chris@76 263 'num_messages' => 0,
Chris@76 264 'start' => empty($_REQUEST['start2']) ? 0 : (int) $_REQUEST['start2'],
Chris@76 265 'messages' => array(),
Chris@76 266 );
Chris@76 267
Chris@76 268 $context['topic'] = array(
Chris@76 269 'id' => $topic,
Chris@76 270 'subject' => urlencode($_REQUEST['subname']),
Chris@76 271 );
Chris@76 272
Chris@76 273 // Some stuff for our favorite template.
Chris@76 274 $context['new_subject'] = $_REQUEST['subname'];
Chris@76 275
Chris@76 276 // Using the "select" sub template.
Chris@76 277 $context['sub_template'] = isset($_REQUEST['xml']) ? 'split' : 'select';
Chris@76 278
Chris@76 279 // Are we using a custom messages per page?
Chris@76 280 $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
Chris@76 281
Chris@76 282 // Get the message ID's from before the move.
Chris@76 283 if (isset($_REQUEST['xml']))
Chris@76 284 {
Chris@76 285 $original_msgs = array(
Chris@76 286 'not_selected' => array(),
Chris@76 287 'selected' => array(),
Chris@76 288 );
Chris@76 289 $request = $smcFunc['db_query']('', '
Chris@76 290 SELECT id_msg
Chris@76 291 FROM {db_prefix}messages
Chris@76 292 WHERE id_topic = {int:current_topic}' . (empty($_SESSION['split_selection'][$topic]) ? '' : '
Chris@76 293 AND id_msg NOT IN ({array_int:no_split_msgs})') . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 294 AND approved = {int:is_approved}') . '
Chris@76 295 ORDER BY id_msg DESC
Chris@76 296 LIMIT {int:start}, {int:messages_per_page}',
Chris@76 297 array(
Chris@76 298 'current_topic' => $topic,
Chris@76 299 'no_split_msgs' => empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic],
Chris@76 300 'is_approved' => 1,
Chris@76 301 'start' => $context['not_selected']['start'],
Chris@76 302 'messages_per_page' => $context['messages_per_page'],
Chris@76 303 )
Chris@76 304 );
Chris@76 305 // You can't split the last message off.
Chris@76 306 if (empty($context['not_selected']['start']) && $smcFunc['db_num_rows']($request) <= 1 && $_REQUEST['move'] == 'down')
Chris@76 307 $_REQUEST['move'] = '';
Chris@76 308 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 309 $original_msgs['not_selected'][] = $row['id_msg'];
Chris@76 310 $smcFunc['db_free_result']($request);
Chris@76 311 if (!empty($_SESSION['split_selection'][$topic]))
Chris@76 312 {
Chris@76 313 $request = $smcFunc['db_query']('', '
Chris@76 314 SELECT id_msg
Chris@76 315 FROM {db_prefix}messages
Chris@76 316 WHERE id_topic = {int:current_topic}
Chris@76 317 AND id_msg IN ({array_int:split_msgs})' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 318 AND approved = {int:is_approved}') . '
Chris@76 319 ORDER BY id_msg DESC
Chris@76 320 LIMIT {int:start}, {int:messages_per_page}',
Chris@76 321 array(
Chris@76 322 'current_topic' => $topic,
Chris@76 323 'split_msgs' => $_SESSION['split_selection'][$topic],
Chris@76 324 'is_approved' => 1,
Chris@76 325 'start' => $context['selected']['start'],
Chris@76 326 'messages_per_page' => $context['messages_per_page'],
Chris@76 327 )
Chris@76 328 );
Chris@76 329 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 330 $original_msgs['selected'][] = $row['id_msg'];
Chris@76 331 $smcFunc['db_free_result']($request);
Chris@76 332 }
Chris@76 333 }
Chris@76 334
Chris@76 335 // (De)select a message..
Chris@76 336 if (!empty($_REQUEST['move']))
Chris@76 337 {
Chris@76 338 $_REQUEST['msg'] = (int) $_REQUEST['msg'];
Chris@76 339
Chris@76 340 if ($_REQUEST['move'] == 'reset')
Chris@76 341 $_SESSION['split_selection'][$topic] = array();
Chris@76 342 elseif ($_REQUEST['move'] == 'up')
Chris@76 343 $_SESSION['split_selection'][$topic] = array_diff($_SESSION['split_selection'][$topic], array($_REQUEST['msg']));
Chris@76 344 else
Chris@76 345 $_SESSION['split_selection'][$topic][] = $_REQUEST['msg'];
Chris@76 346 }
Chris@76 347
Chris@76 348 // Make sure the selection is still accurate.
Chris@76 349 if (!empty($_SESSION['split_selection'][$topic]))
Chris@76 350 {
Chris@76 351 $request = $smcFunc['db_query']('', '
Chris@76 352 SELECT id_msg
Chris@76 353 FROM {db_prefix}messages
Chris@76 354 WHERE id_topic = {int:current_topic}
Chris@76 355 AND id_msg IN ({array_int:split_msgs})' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 356 AND approved = {int:is_approved}'),
Chris@76 357 array(
Chris@76 358 'current_topic' => $topic,
Chris@76 359 'split_msgs' => $_SESSION['split_selection'][$topic],
Chris@76 360 'is_approved' => 1,
Chris@76 361 )
Chris@76 362 );
Chris@76 363 $_SESSION['split_selection'][$topic] = array();
Chris@76 364 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 365 $_SESSION['split_selection'][$topic][] = $row['id_msg'];
Chris@76 366 $smcFunc['db_free_result']($request);
Chris@76 367 }
Chris@76 368
Chris@76 369 // Get the number of messages (not) selected to be split.
Chris@76 370 $request = $smcFunc['db_query']('', '
Chris@76 371 SELECT ' . (empty($_SESSION['split_selection'][$topic]) ? '0' : 'm.id_msg IN ({array_int:split_msgs})') . ' AS is_selected, COUNT(*) AS num_messages
Chris@76 372 FROM {db_prefix}messages AS m
Chris@76 373 WHERE m.id_topic = {int:current_topic}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 374 AND approved = {int:is_approved}') . (empty($_SESSION['split_selection'][$topic]) ? '' : '
Chris@76 375 GROUP BY is_selected'),
Chris@76 376 array(
Chris@76 377 'current_topic' => $topic,
Chris@76 378 'split_msgs' => !empty($_SESSION['split_selection'][$topic]) ? $_SESSION['split_selection'][$topic] : array(),
Chris@76 379 'is_approved' => 1,
Chris@76 380 )
Chris@76 381 );
Chris@76 382 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 383 $context[empty($row['is_selected']) ? 'not_selected' : 'selected']['num_messages'] = $row['num_messages'];
Chris@76 384 $smcFunc['db_free_result']($request);
Chris@76 385
Chris@76 386 // Fix an oversized starting page (to make sure both pageindexes are properly set).
Chris@76 387 if ($context['selected']['start'] >= $context['selected']['num_messages'])
Chris@76 388 $context['selected']['start'] = $context['selected']['num_messages'] <= $context['messages_per_page'] ? 0 : ($context['selected']['num_messages'] - (($context['selected']['num_messages'] % $context['messages_per_page']) == 0 ? $context['messages_per_page'] : ($context['selected']['num_messages'] % $context['messages_per_page'])));
Chris@76 389
Chris@76 390 // Build a page list of the not-selected topics...
Chris@76 391 $context['not_selected']['page_index'] = constructPageIndex($scripturl . '?action=splittopics;sa=selectTopics;subname=' . strtr(urlencode($_REQUEST['subname']), array('%' => '%%')) . ';topic=' . $topic . '.%1$d;start2=' . $context['selected']['start'], $context['not_selected']['start'], $context['not_selected']['num_messages'], $context['messages_per_page'], true);
Chris@76 392 // ...and one of the selected topics.
Chris@76 393 $context['selected']['page_index'] = constructPageIndex($scripturl . '?action=splittopics;sa=selectTopics;subname=' . strtr(urlencode($_REQUEST['subname']), array('%' => '%%')) . ';topic=' . $topic . '.' . $context['not_selected']['start'] . ';start2=%1$d', $context['selected']['start'], $context['selected']['num_messages'], $context['messages_per_page'], true);
Chris@76 394
Chris@76 395 // Get the messages and stick them into an array.
Chris@76 396 $request = $smcFunc['db_query']('', '
Chris@76 397 SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS real_name, m.poster_time, m.body, m.id_msg, m.smileys_enabled
Chris@76 398 FROM {db_prefix}messages AS m
Chris@76 399 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 400 WHERE m.id_topic = {int:current_topic}' . (empty($_SESSION['split_selection'][$topic]) ? '' : '
Chris@76 401 AND id_msg NOT IN ({array_int:no_split_msgs})') . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 402 AND approved = {int:is_approved}') . '
Chris@76 403 ORDER BY m.id_msg DESC
Chris@76 404 LIMIT {int:start}, {int:messages_per_page}',
Chris@76 405 array(
Chris@76 406 'current_topic' => $topic,
Chris@76 407 'no_split_msgs' => !empty($_SESSION['split_selection'][$topic]) ? $_SESSION['split_selection'][$topic] : array(),
Chris@76 408 'is_approved' => 1,
Chris@76 409 'start' => $context['not_selected']['start'],
Chris@76 410 'messages_per_page' => $context['messages_per_page'],
Chris@76 411 )
Chris@76 412 );
Chris@76 413 $context['messages'] = array();
Chris@76 414 for ($counter = 0; $row = $smcFunc['db_fetch_assoc']($request); $counter ++)
Chris@76 415 {
Chris@76 416 censorText($row['subject']);
Chris@76 417 censorText($row['body']);
Chris@76 418
Chris@76 419 $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
Chris@76 420
Chris@76 421 $context['not_selected']['messages'][$row['id_msg']] = array(
Chris@76 422 'id' => $row['id_msg'],
Chris@76 423 'alternate' => $counter % 2,
Chris@76 424 'subject' => $row['subject'],
Chris@76 425 'time' => timeformat($row['poster_time']),
Chris@76 426 'timestamp' => forum_time(true, $row['poster_time']),
Chris@76 427 'body' => $row['body'],
Chris@76 428 'poster' => $row['real_name'],
Chris@76 429 );
Chris@76 430 }
Chris@76 431 $smcFunc['db_free_result']($request);
Chris@76 432
Chris@76 433 // Now get the selected messages.
Chris@76 434 if (!empty($_SESSION['split_selection'][$topic]))
Chris@76 435 {
Chris@76 436 // Get the messages and stick them into an array.
Chris@76 437 $request = $smcFunc['db_query']('', '
Chris@76 438 SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS real_name, m.poster_time, m.body, m.id_msg, m.smileys_enabled
Chris@76 439 FROM {db_prefix}messages AS m
Chris@76 440 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 441 WHERE m.id_topic = {int:current_topic}
Chris@76 442 AND m.id_msg IN ({array_int:split_msgs})' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
Chris@76 443 AND approved = {int:is_approved}') . '
Chris@76 444 ORDER BY m.id_msg DESC
Chris@76 445 LIMIT {int:start}, {int:messages_per_page}',
Chris@76 446 array(
Chris@76 447 'current_topic' => $topic,
Chris@76 448 'split_msgs' => $_SESSION['split_selection'][$topic],
Chris@76 449 'is_approved' => 1,
Chris@76 450 'start' => $context['selected']['start'],
Chris@76 451 'messages_per_page' => $context['messages_per_page'],
Chris@76 452 )
Chris@76 453 );
Chris@76 454 $context['messages'] = array();
Chris@76 455 for ($counter = 0; $row = $smcFunc['db_fetch_assoc']($request); $counter ++)
Chris@76 456 {
Chris@76 457 censorText($row['subject']);
Chris@76 458 censorText($row['body']);
Chris@76 459
Chris@76 460 $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
Chris@76 461
Chris@76 462 $context['selected']['messages'][$row['id_msg']] = array(
Chris@76 463 'id' => $row['id_msg'],
Chris@76 464 'alternate' => $counter % 2,
Chris@76 465 'subject' => $row['subject'],
Chris@76 466 'time' => timeformat($row['poster_time']),
Chris@76 467 'timestamp' => forum_time(true, $row['poster_time']),
Chris@76 468 'body' => $row['body'],
Chris@76 469 'poster' => $row['real_name']
Chris@76 470 );
Chris@76 471 }
Chris@76 472 $smcFunc['db_free_result']($request);
Chris@76 473 }
Chris@76 474
Chris@76 475 // The XMLhttp method only needs the stuff that changed, so let's compare.
Chris@76 476 if (isset($_REQUEST['xml']))
Chris@76 477 {
Chris@76 478 $changes = array(
Chris@76 479 'remove' => array(
Chris@76 480 'not_selected' => array_diff($original_msgs['not_selected'], array_keys($context['not_selected']['messages'])),
Chris@76 481 'selected' => array_diff($original_msgs['selected'], array_keys($context['selected']['messages'])),
Chris@76 482 ),
Chris@76 483 'insert' => array(
Chris@76 484 'not_selected' => array_diff(array_keys($context['not_selected']['messages']), $original_msgs['not_selected']),
Chris@76 485 'selected' => array_diff(array_keys($context['selected']['messages']), $original_msgs['selected']),
Chris@76 486 ),
Chris@76 487 );
Chris@76 488
Chris@76 489 $context['changes'] = array();
Chris@76 490 foreach ($changes as $change_type => $change_array)
Chris@76 491 foreach ($change_array as $section => $msg_array)
Chris@76 492 {
Chris@76 493 if (empty($msg_array))
Chris@76 494 continue;
Chris@76 495
Chris@76 496 foreach ($msg_array as $id_msg)
Chris@76 497 {
Chris@76 498 $context['changes'][$change_type . $id_msg] = array(
Chris@76 499 'id' => $id_msg,
Chris@76 500 'type' => $change_type,
Chris@76 501 'section' => $section,
Chris@76 502 );
Chris@76 503 if ($change_type == 'insert')
Chris@76 504 $context['changes']['insert' . $id_msg]['insert_value'] = $context[$section]['messages'][$id_msg];
Chris@76 505 }
Chris@76 506 }
Chris@76 507 }
Chris@76 508 }
Chris@76 509
Chris@76 510 // Actually and selectively split the topics out.
Chris@76 511 function SplitSelectionExecute()
Chris@76 512 {
Chris@76 513 global $txt, $board, $topic, $context, $user_info;
Chris@76 514
Chris@76 515 // Make sure the session id was passed with post.
Chris@76 516 checkSession();
Chris@76 517
Chris@76 518 // Default the subject in case it's blank.
Chris@76 519 if (!isset($_POST['subname']) || $_POST['subname'] == '')
Chris@76 520 $_POST['subname'] = $txt['new_topic'];
Chris@76 521
Chris@76 522 // You must've selected some messages! Can't split out none!
Chris@76 523 if (empty($_SESSION['split_selection'][$topic]))
Chris@76 524 fatal_lang_error('no_posts_selected', false);
Chris@76 525
Chris@76 526 $context['old_topic'] = $topic;
Chris@76 527 $context['new_topic'] = splitTopic($topic, $_SESSION['split_selection'][$topic], $_POST['subname']);
Chris@76 528 $context['page_title'] = $txt['split'];
Chris@76 529 }
Chris@76 530
Chris@76 531 // Split a topic in two topics.
Chris@76 532 function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
Chris@76 533 {
Chris@76 534 global $user_info, $topic, $board, $modSettings, $smcFunc, $txt;
Chris@76 535
Chris@76 536 // Nothing to split?
Chris@76 537 if (empty($splitMessages))
Chris@76 538 fatal_lang_error('no_posts_selected', false);
Chris@76 539
Chris@76 540 // Get some board info.
Chris@76 541 $request = $smcFunc['db_query']('', '
Chris@76 542 SELECT id_board, approved
Chris@76 543 FROM {db_prefix}topics
Chris@76 544 WHERE id_topic = {int:id_topic}
Chris@76 545 LIMIT 1',
Chris@76 546 array(
Chris@76 547 'id_topic' => $split1_ID_TOPIC,
Chris@76 548 )
Chris@76 549 );
Chris@76 550 list ($id_board, $split1_approved) = $smcFunc['db_fetch_row']($request);
Chris@76 551 $smcFunc['db_free_result']($request);
Chris@76 552
Chris@76 553 // Find the new first and last not in the list. (old topic)
Chris@76 554 $request = $smcFunc['db_query']('', '
Chris@76 555 SELECT
Chris@76 556 MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg, COUNT(*) AS message_count, m.approved
Chris@76 557 FROM {db_prefix}messages AS m
Chris@76 558 INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:id_topic})
Chris@76 559 WHERE m.id_msg NOT IN ({array_int:no_msg_list})
Chris@76 560 AND m.id_topic = {int:id_topic}
Chris@76 561 GROUP BY m.approved
Chris@76 562 ORDER BY m.approved DESC
Chris@76 563 LIMIT 2',
Chris@76 564 array(
Chris@76 565 'id_topic' => $split1_ID_TOPIC,
Chris@76 566 'no_msg_list' => $splitMessages,
Chris@76 567 )
Chris@76 568 );
Chris@76 569 // You can't select ALL the messages!
Chris@76 570 if ($smcFunc['db_num_rows']($request) == 0)
Chris@76 571 fatal_lang_error('selected_all_posts', false);
Chris@76 572 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 573 {
Chris@76 574 // Get the right first and last message dependant on approved state...
Chris@76 575 if (empty($split1_first_msg) || $row['myid_first_msg'] < $split1_first_msg)
Chris@76 576 $split1_first_msg = $row['myid_first_msg'];
Chris@76 577 if (empty($split1_last_msg) || $row['approved'])
Chris@76 578 $split1_last_msg = $row['myid_last_msg'];
Chris@76 579
Chris@76 580 // Get the counts correct...
Chris@76 581 if ($row['approved'])
Chris@76 582 {
Chris@76 583 $split1_replies = $row['message_count'] - 1;
Chris@76 584 $split1_unapprovedposts = 0;
Chris@76 585 }
Chris@76 586 else
Chris@76 587 {
Chris@76 588 if (!isset($split1_replies))
Chris@76 589 $split1_replies = 0;
Chris@76 590 // If the topic isn't approved then num replies must go up by one... as first post wouldn't be counted.
Chris@76 591 elseif (!$split1_approved)
Chris@76 592 $split1_replies++;
Chris@76 593
Chris@76 594 $split1_unapprovedposts = $row['message_count'];
Chris@76 595 }
Chris@76 596 }
Chris@76 597 $smcFunc['db_free_result']($request);
Chris@76 598 $split1_firstMem = getMsgMemberID($split1_first_msg);
Chris@76 599 $split1_lastMem = getMsgMemberID($split1_last_msg);
Chris@76 600
Chris@76 601 // Find the first and last in the list. (new topic)
Chris@76 602 $request = $smcFunc['db_query']('', '
Chris@76 603 SELECT MIN(id_msg) AS myid_first_msg, MAX(id_msg) AS myid_last_msg, COUNT(*) AS message_count, approved
Chris@76 604 FROM {db_prefix}messages
Chris@76 605 WHERE id_msg IN ({array_int:msg_list})
Chris@76 606 AND id_topic = {int:id_topic}
Chris@76 607 GROUP BY id_topic, approved
Chris@76 608 ORDER BY approved DESC
Chris@76 609 LIMIT 2',
Chris@76 610 array(
Chris@76 611 'msg_list' => $splitMessages,
Chris@76 612 'id_topic' => $split1_ID_TOPIC,
Chris@76 613 )
Chris@76 614 );
Chris@76 615 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 616 {
Chris@76 617 // As before get the right first and last message dependant on approved state...
Chris@76 618 if (empty($split2_first_msg) || $row['myid_first_msg'] < $split2_first_msg)
Chris@76 619 $split2_first_msg = $row['myid_first_msg'];
Chris@76 620 if (empty($split2_last_msg) || $row['approved'])
Chris@76 621 $split2_last_msg = $row['myid_last_msg'];
Chris@76 622
Chris@76 623 // Then do the counts again...
Chris@76 624 if ($row['approved'])
Chris@76 625 {
Chris@76 626 $split2_approved = true;
Chris@76 627 $split2_replies = $row['message_count'] - 1;
Chris@76 628 $split2_unapprovedposts = 0;
Chris@76 629 }
Chris@76 630 else
Chris@76 631 {
Chris@76 632 // Should this one be approved??
Chris@76 633 if ($split2_first_msg == $row['myid_first_msg'])
Chris@76 634 $split2_approved = false;
Chris@76 635
Chris@76 636 if (!isset($split2_replies))
Chris@76 637 $split2_replies = 0;
Chris@76 638 // As before, fix number of replies.
Chris@76 639 elseif (!$split2_approved)
Chris@76 640 $split2_replies++;
Chris@76 641
Chris@76 642 $split2_unapprovedposts = $row['message_count'];
Chris@76 643 }
Chris@76 644 }
Chris@76 645 $smcFunc['db_free_result']($request);
Chris@76 646 $split2_firstMem = getMsgMemberID($split2_first_msg);
Chris@76 647 $split2_lastMem = getMsgMemberID($split2_last_msg);
Chris@76 648
Chris@76 649 // No database changes yet, so let's double check to see if everything makes at least a little sense.
Chris@76 650 if ($split1_first_msg <= 0 || $split1_last_msg <= 0 || $split2_first_msg <= 0 || $split2_last_msg <= 0 || $split1_replies < 0 || $split2_replies < 0 || $split1_unapprovedposts < 0 || $split2_unapprovedposts < 0 || !isset($split1_approved) || !isset($split2_approved))
Chris@76 651 fatal_lang_error('cant_find_messages');
Chris@76 652
Chris@76 653 // You cannot split off the first message of a topic.
Chris@76 654 if ($split1_first_msg > $split2_first_msg)
Chris@76 655 fatal_lang_error('split_first_post', false);
Chris@76 656
Chris@76 657 // We're off to insert the new topic! Use 0 for now to avoid UNIQUE errors.
Chris@76 658 $smcFunc['db_insert']('',
Chris@76 659 '{db_prefix}topics',
Chris@76 660 array(
Chris@76 661 'id_board' => 'int',
Chris@76 662 'id_member_started' => 'int',
Chris@76 663 'id_member_updated' => 'int',
Chris@76 664 'id_first_msg' => 'int',
Chris@76 665 'id_last_msg' => 'int',
Chris@76 666 'num_replies' => 'int',
Chris@76 667 'unapproved_posts' => 'int',
Chris@76 668 'approved' => 'int',
Chris@76 669 'is_sticky' => 'int',
Chris@76 670 ),
Chris@76 671 array(
Chris@76 672 (int) $id_board, $split2_firstMem, $split2_lastMem, 0,
Chris@76 673 0, $split2_replies, $split2_unapprovedposts, (int) $split2_approved, 0,
Chris@76 674 ),
Chris@76 675 array('id_topic')
Chris@76 676 );
Chris@76 677 $split2_ID_TOPIC = $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic');
Chris@76 678 if ($split2_ID_TOPIC <= 0)
Chris@76 679 fatal_lang_error('cant_insert_topic');
Chris@76 680
Chris@76 681 // Move the messages over to the other topic.
Chris@76 682 $new_subject = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($new_subject)), array("\r" => '', "\n" => '', "\t" => ''));
Chris@76 683 // Check the subject length.
Chris@76 684 if ($smcFunc['strlen']($new_subject) > 100)
Chris@76 685 $new_subject = $smcFunc['substr']($new_subject, 0, 100);
Chris@76 686 // Valid subject?
Chris@76 687 if ($new_subject != '')
Chris@76 688 {
Chris@76 689 $smcFunc['db_query']('', '
Chris@76 690 UPDATE {db_prefix}messages
Chris@76 691 SET
Chris@76 692 id_topic = {int:id_topic},
Chris@76 693 subject = CASE WHEN id_msg = {int:split_first_msg} THEN {string:new_subject} ELSE {string:new_subject_replies} END
Chris@76 694 WHERE id_msg IN ({array_int:split_msgs})',
Chris@76 695 array(
Chris@76 696 'split_msgs' => $splitMessages,
Chris@76 697 'id_topic' => $split2_ID_TOPIC,
Chris@76 698 'new_subject' => $new_subject,
Chris@76 699 'split_first_msg' => $split2_first_msg,
Chris@76 700 'new_subject_replies' => $txt['response_prefix'] . $new_subject,
Chris@76 701 )
Chris@76 702 );
Chris@76 703
Chris@76 704 // Cache the new topics subject... we can do it now as all the subjects are the same!
Chris@76 705 updateStats('subject', $split2_ID_TOPIC, $new_subject);
Chris@76 706 }
Chris@76 707
Chris@76 708 // Any associated reported posts better follow...
Chris@76 709 $smcFunc['db_query']('', '
Chris@76 710 UPDATE {db_prefix}log_reported
Chris@76 711 SET id_topic = {int:id_topic}
Chris@76 712 WHERE id_msg IN ({array_int:split_msgs})',
Chris@76 713 array(
Chris@76 714 'split_msgs' => $splitMessages,
Chris@76 715 'id_topic' => $split2_ID_TOPIC,
Chris@76 716 )
Chris@76 717 );
Chris@76 718
Chris@76 719 // Mess with the old topic's first, last, and number of messages.
Chris@76 720 $smcFunc['db_query']('', '
Chris@76 721 UPDATE {db_prefix}topics
Chris@76 722 SET
Chris@76 723 num_replies = {int:num_replies},
Chris@76 724 id_first_msg = {int:id_first_msg},
Chris@76 725 id_last_msg = {int:id_last_msg},
Chris@76 726 id_member_started = {int:id_member_started},
Chris@76 727 id_member_updated = {int:id_member_updated},
Chris@76 728 unapproved_posts = {int:unapproved_posts}
Chris@76 729 WHERE id_topic = {int:id_topic}',
Chris@76 730 array(
Chris@76 731 'num_replies' => $split1_replies,
Chris@76 732 'id_first_msg' => $split1_first_msg,
Chris@76 733 'id_last_msg' => $split1_last_msg,
Chris@76 734 'id_member_started' => $split1_firstMem,
Chris@76 735 'id_member_updated' => $split1_lastMem,
Chris@76 736 'unapproved_posts' => $split1_unapprovedposts,
Chris@76 737 'id_topic' => $split1_ID_TOPIC,
Chris@76 738 )
Chris@76 739 );
Chris@76 740
Chris@76 741 // Now, put the first/last message back to what they should be.
Chris@76 742 $smcFunc['db_query']('', '
Chris@76 743 UPDATE {db_prefix}topics
Chris@76 744 SET
Chris@76 745 id_first_msg = {int:id_first_msg},
Chris@76 746 id_last_msg = {int:id_last_msg}
Chris@76 747 WHERE id_topic = {int:id_topic}',
Chris@76 748 array(
Chris@76 749 'id_first_msg' => $split2_first_msg,
Chris@76 750 'id_last_msg' => $split2_last_msg,
Chris@76 751 'id_topic' => $split2_ID_TOPIC,
Chris@76 752 )
Chris@76 753 );
Chris@76 754
Chris@76 755 // If the new topic isn't approved ensure the first message flags this just in case.
Chris@76 756 if (!$split2_approved)
Chris@76 757 $smcFunc['db_query']('', '
Chris@76 758 UPDATE {db_prefix}messages
Chris@76 759 SET approved = {int:approved}
Chris@76 760 WHERE id_msg = {int:id_msg}
Chris@76 761 AND id_topic = {int:id_topic}',
Chris@76 762 array(
Chris@76 763 'approved' => 0,
Chris@76 764 'id_msg' => $split2_first_msg,
Chris@76 765 'id_topic' => $split2_ID_TOPIC,
Chris@76 766 )
Chris@76 767 );
Chris@76 768
Chris@76 769 // The board has more topics now (Or more unapproved ones!).
Chris@76 770 $smcFunc['db_query']('', '
Chris@76 771 UPDATE {db_prefix}boards
Chris@76 772 SET ' . ($split2_approved ? '
Chris@76 773 num_topics = num_topics + 1' : '
Chris@76 774 unapproved_topics = unapproved_topics + 1') . '
Chris@76 775 WHERE id_board = {int:id_board}',
Chris@76 776 array(
Chris@76 777 'id_board' => $id_board,
Chris@76 778 )
Chris@76 779 );
Chris@76 780
Chris@76 781 // Copy log topic entries.
Chris@76 782 // !!! This should really be chunked.
Chris@76 783 $request = $smcFunc['db_query']('', '
Chris@76 784 SELECT id_member, id_msg
Chris@76 785 FROM {db_prefix}log_topics
Chris@76 786 WHERE id_topic = {int:id_topic}',
Chris@76 787 array(
Chris@76 788 'id_topic' => (int) $split1_ID_TOPIC,
Chris@76 789 )
Chris@76 790 );
Chris@76 791 if ($smcFunc['db_num_rows']($request) > 0)
Chris@76 792 {
Chris@76 793 $replaceEntries = array();
Chris@76 794 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 795 $replaceEntries[] = array($row['id_member'], $split2_ID_TOPIC, $row['id_msg']);
Chris@76 796
Chris@76 797 $smcFunc['db_insert']('ignore',
Chris@76 798 '{db_prefix}log_topics',
Chris@76 799 array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'),
Chris@76 800 $replaceEntries,
Chris@76 801 array('id_member', 'id_topic')
Chris@76 802 );
Chris@76 803 unset($replaceEntries);
Chris@76 804 }
Chris@76 805 $smcFunc['db_free_result']($request);
Chris@76 806
Chris@76 807 // Housekeeping.
Chris@76 808 updateStats('topic');
Chris@76 809 updateLastMessages($id_board);
Chris@76 810
Chris@76 811 logAction('split', array('topic' => $split1_ID_TOPIC, 'new_topic' => $split2_ID_TOPIC, 'board' => $id_board));
Chris@76 812
Chris@76 813 // Notify people that this topic has been split?
Chris@76 814 sendNotifications($split1_ID_TOPIC, 'split');
Chris@76 815
Chris@76 816 // Return the ID of the newly created topic.
Chris@76 817 return $split2_ID_TOPIC;
Chris@76 818 }
Chris@76 819
Chris@76 820 // Merge two topics into one topic... useful if they have the same basic subject.
Chris@76 821 function MergeTopics()
Chris@76 822 {
Chris@76 823 // Load the template....
Chris@76 824 loadTemplate('SplitTopics');
Chris@76 825
Chris@76 826 $subActions = array(
Chris@76 827 'done' => 'MergeDone',
Chris@76 828 'execute' => 'MergeExecute',
Chris@76 829 'index' => 'MergeIndex',
Chris@76 830 'options' => 'MergeExecute',
Chris@76 831 );
Chris@76 832
Chris@76 833 // ?action=mergetopics;sa=LETSBREAKIT won't work, sorry.
Chris@76 834 if (empty($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']]))
Chris@76 835 MergeIndex();
Chris@76 836 else
Chris@76 837 $subActions[$_REQUEST['sa']]();
Chris@76 838 }
Chris@76 839
Chris@76 840 // Merge two topics together.
Chris@76 841 function MergeIndex()
Chris@76 842 {
Chris@76 843 global $txt, $board, $context, $smcFunc;
Chris@76 844 global $scripturl, $topic, $user_info, $modSettings;
Chris@76 845
Chris@76 846 if (!isset($_GET['from']))
Chris@76 847 fatal_lang_error('no_access', false);
Chris@76 848 $_GET['from'] = (int) $_GET['from'];
Chris@76 849
Chris@76 850 $_REQUEST['targetboard'] = isset($_REQUEST['targetboard']) ? (int) $_REQUEST['targetboard'] : $board;
Chris@76 851 $context['target_board'] = $_REQUEST['targetboard'];
Chris@76 852
Chris@76 853 // Prepare a handy query bit for approval...
Chris@76 854 if ($modSettings['postmod_active'])
Chris@76 855 {
Chris@76 856 $can_approve_boards = boardsAllowedTo('approve_posts');
Chris@76 857 $onlyApproved = $can_approve_boards !== array(0) && !in_array($_REQUEST['targetboard'], $can_approve_boards);
Chris@76 858 }
Chris@76 859 else
Chris@76 860 $onlyApproved = false;
Chris@76 861
Chris@76 862 // How many topics are on this board? (used for paging.)
Chris@76 863 $request = $smcFunc['db_query']('', '
Chris@76 864 SELECT COUNT(*)
Chris@76 865 FROM {db_prefix}topics AS t
Chris@76 866 WHERE t.id_board = {int:id_board}' . ($onlyApproved ? '
Chris@76 867 AND t.approved = {int:is_approved}' : ''),
Chris@76 868 array(
Chris@76 869 'id_board' => $_REQUEST['targetboard'],
Chris@76 870 'is_approved' => 1,
Chris@76 871 )
Chris@76 872 );
Chris@76 873 list ($topiccount) = $smcFunc['db_fetch_row']($request);
Chris@76 874 $smcFunc['db_free_result']($request);
Chris@76 875
Chris@76 876 // Make the page list.
Chris@76 877 $context['page_index'] = constructPageIndex($scripturl . '?action=mergetopics;from=' . $_GET['from'] . ';targetboard=' . $_REQUEST['targetboard'] . ';board=' . $board . '.%1$d', $_REQUEST['start'], $topiccount, $modSettings['defaultMaxTopics'], true);
Chris@76 878
Chris@76 879 // Get the topic's subject.
Chris@76 880 $request = $smcFunc['db_query']('', '
Chris@76 881 SELECT m.subject
Chris@76 882 FROM {db_prefix}topics AS t
Chris@76 883 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
Chris@76 884 WHERE t.id_topic = {int:id_topic}
Chris@76 885 AND t.id_board = {int:current_board}' . ($onlyApproved ? '
Chris@76 886 AND t.approved = {int:is_approved}' : '') . '
Chris@76 887 LIMIT 1',
Chris@76 888 array(
Chris@76 889 'current_board' => $board,
Chris@76 890 'id_topic' => $_GET['from'],
Chris@76 891 'is_approved' => 1,
Chris@76 892 )
Chris@76 893 );
Chris@76 894 if ($smcFunc['db_num_rows']($request) == 0)
Chris@76 895 fatal_lang_error('no_board');
Chris@76 896 list ($subject) = $smcFunc['db_fetch_row']($request);
Chris@76 897 $smcFunc['db_free_result']($request);
Chris@76 898
Chris@76 899 // Tell the template a few things..
Chris@76 900 $context['origin_topic'] = $_GET['from'];
Chris@76 901 $context['origin_subject'] = $subject;
Chris@76 902 $context['origin_js_subject'] = addcslashes(addslashes($subject), '/');
Chris@76 903 $context['page_title'] = $txt['merge'];
Chris@76 904
Chris@76 905 // Check which boards you have merge permissions on.
Chris@76 906 $merge_boards = boardsAllowedTo('merge_any');
Chris@76 907
Chris@76 908 if (empty($merge_boards))
Chris@76 909 fatal_lang_error('cannot_merge_any', 'user');
Chris@76 910
Chris@76 911 // Get a list of boards they can navigate to to merge.
Chris@76 912 $request = $smcFunc['db_query']('order_by_board_order', '
Chris@76 913 SELECT b.id_board, b.name AS board_name, c.name AS cat_name
Chris@76 914 FROM {db_prefix}boards AS b
Chris@76 915 LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
Chris@76 916 WHERE {query_see_board}' . (!in_array(0, $merge_boards) ? '
Chris@76 917 AND b.id_board IN ({array_int:merge_boards})' : ''),
Chris@76 918 array(
Chris@76 919 'merge_boards' => $merge_boards,
Chris@76 920 )
Chris@76 921 );
Chris@76 922 $context['boards'] = array();
Chris@76 923 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 924 $context['boards'][] = array(
Chris@76 925 'id' => $row['id_board'],
Chris@76 926 'name' => $row['board_name'],
Chris@76 927 'category' => $row['cat_name']
Chris@76 928 );
Chris@76 929 $smcFunc['db_free_result']($request);
Chris@76 930
Chris@76 931 // Get some topics to merge it with.
Chris@76 932 $request = $smcFunc['db_query']('', '
Chris@76 933 SELECT t.id_topic, m.subject, m.id_member, IFNULL(mem.real_name, m.poster_name) AS poster_name
Chris@76 934 FROM {db_prefix}topics AS t
Chris@76 935 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
Chris@76 936 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 937 WHERE t.id_board = {int:id_board}
Chris@76 938 AND t.id_topic != {int:id_topic}' . ($onlyApproved ? '
Chris@76 939 AND t.approved = {int:is_approved}' : '') . '
Chris@76 940 ORDER BY {raw:sort}
Chris@76 941 LIMIT {int:offset}, {int:limit}',
Chris@76 942 array(
Chris@76 943 'id_board' => $_REQUEST['targetboard'],
Chris@76 944 'id_topic' => $_GET['from'],
Chris@76 945 'sort' => (!empty($modSettings['enableStickyTopics']) ? 't.is_sticky DESC, ' : '') . 't.id_last_msg DESC',
Chris@76 946 'offset' => $_REQUEST['start'],
Chris@76 947 'limit' => $modSettings['defaultMaxTopics'],
Chris@76 948 'is_approved' => 1,
Chris@76 949 )
Chris@76 950 );
Chris@76 951 $context['topics'] = array();
Chris@76 952 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 953 {
Chris@76 954 censorText($row['subject']);
Chris@76 955
Chris@76 956 $context['topics'][] = array(
Chris@76 957 'id' => $row['id_topic'],
Chris@76 958 'poster' => array(
Chris@76 959 'id' => $row['id_member'],
Chris@76 960 'name' => $row['poster_name'],
Chris@76 961 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'],
Chris@76 962 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" target="_blank" class="new_win">' . $row['poster_name'] . '</a>'
Chris@76 963 ),
Chris@76 964 'subject' => $row['subject'],
Chris@76 965 'js_subject' => addcslashes(addslashes($row['subject']), '/')
Chris@76 966 );
Chris@76 967 }
Chris@76 968 $smcFunc['db_free_result']($request);
Chris@76 969
Chris@76 970 if (empty($context['topics']) && count($context['boards']) <= 1)
Chris@76 971 fatal_lang_error('merge_need_more_topics');
Chris@76 972
Chris@76 973 $context['sub_template'] = 'merge';
Chris@76 974 }
Chris@76 975
Chris@76 976 // Now that the topic IDs are known, do the proper merging.
Chris@76 977 function MergeExecute($topics = array())
Chris@76 978 {
Chris@76 979 global $user_info, $txt, $context, $scripturl, $sourcedir;
Chris@76 980 global $smcFunc, $language, $modSettings;
Chris@76 981
Chris@76 982 // Check the session.
Chris@76 983 checkSession('request');
Chris@76 984
Chris@76 985 // Handle URLs from MergeIndex.
Chris@76 986 if (!empty($_GET['from']) && !empty($_GET['to']))
Chris@76 987 $topics = array((int) $_GET['from'], (int) $_GET['to']);
Chris@76 988
Chris@76 989 // If we came from a form, the topic IDs came by post.
Chris@76 990 if (!empty($_POST['topics']) && is_array($_POST['topics']))
Chris@76 991 $topics = $_POST['topics'];
Chris@76 992
Chris@76 993 // There's nothing to merge with just one topic...
Chris@76 994 if (empty($topics) || !is_array($topics) || count($topics) == 1)
Chris@76 995 fatal_lang_error('merge_need_more_topics');
Chris@76 996
Chris@76 997 // Make sure every topic is numeric, or some nasty things could be done with the DB.
Chris@76 998 foreach ($topics as $id => $topic)
Chris@76 999 $topics[$id] = (int) $topic;
Chris@76 1000
Chris@76 1001 // Joy of all joys, make sure they're not pi**ing about with unapproved topics they can't see :P
Chris@76 1002 if ($modSettings['postmod_active'])
Chris@76 1003 $can_approve_boards = boardsAllowedTo('approve_posts');
Chris@76 1004
Chris@76 1005 // Get info about the topics and polls that will be merged.
Chris@76 1006 $request = $smcFunc['db_query']('', '
Chris@76 1007 SELECT
Chris@76 1008 t.id_topic, t.id_board, t.id_poll, t.num_views, t.is_sticky, t.approved, t.num_replies, t.unapproved_posts,
Chris@76 1009 m1.subject, m1.poster_time AS time_started, IFNULL(mem1.id_member, 0) AS id_member_started, IFNULL(mem1.real_name, m1.poster_name) AS name_started,
Chris@76 1010 m2.poster_time AS time_updated, IFNULL(mem2.id_member, 0) AS id_member_updated, IFNULL(mem2.real_name, m2.poster_name) AS name_updated
Chris@76 1011 FROM {db_prefix}topics AS t
Chris@76 1012 INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg)
Chris@76 1013 INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg)
Chris@76 1014 LEFT JOIN {db_prefix}members AS mem1 ON (mem1.id_member = m1.id_member)
Chris@76 1015 LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
Chris@76 1016 WHERE t.id_topic IN ({array_int:topic_list})
Chris@76 1017 ORDER BY t.id_first_msg
Chris@76 1018 LIMIT ' . count($topics),
Chris@76 1019 array(
Chris@76 1020 'topic_list' => $topics,
Chris@76 1021 )
Chris@76 1022 );
Chris@76 1023 if ($smcFunc['db_num_rows']($request) < 2)
Chris@76 1024 fatal_lang_error('no_topic_id');
Chris@76 1025 $num_views = 0;
Chris@76 1026 $is_sticky = 0;
Chris@76 1027 $boardTotals = array();
Chris@76 1028 $boards = array();
Chris@76 1029 $polls = array();
Chris@76 1030 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1031 {
Chris@76 1032 // Make a note for the board counts...
Chris@76 1033 if (!isset($boardTotals[$row['id_board']]))
Chris@76 1034 $boardTotals[$row['id_board']] = array(
Chris@76 1035 'posts' => 0,
Chris@76 1036 'topics' => 0,
Chris@76 1037 'unapproved_posts' => 0,
Chris@76 1038 'unapproved_topics' => 0
Chris@76 1039 );
Chris@76 1040
Chris@76 1041 // We can't see unapproved topics here?
Chris@76 1042 if ($modSettings['postmod_active'] && !$row['approved'] && $can_approve_boards != array(0) && in_array($row['id_board'], $can_approve_boards))
Chris@76 1043 continue;
Chris@76 1044 elseif (!$row['approved'])
Chris@76 1045 $boardTotals[$row['id_board']]['unapproved_topics']++;
Chris@76 1046 else
Chris@76 1047 $boardTotals[$row['id_board']]['topics']++;
Chris@76 1048
Chris@76 1049 $boardTotals[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts'];
Chris@76 1050 $boardTotals[$row['id_board']]['posts'] += $row['num_replies'] + ($row['approved'] ? 1 : 0);
Chris@76 1051
Chris@76 1052 $topic_data[$row['id_topic']] = array(
Chris@76 1053 'id' => $row['id_topic'],
Chris@76 1054 'board' => $row['id_board'],
Chris@76 1055 'poll' => $row['id_poll'],
Chris@76 1056 'num_views' => $row['num_views'],
Chris@76 1057 'subject' => $row['subject'],
Chris@76 1058 'started' => array(
Chris@76 1059 'time' => timeformat($row['time_started']),
Chris@76 1060 'timestamp' => forum_time(true, $row['time_started']),
Chris@76 1061 'href' => empty($row['id_member_started']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_started'],
Chris@76 1062 'link' => empty($row['id_member_started']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_started'] . '">' . $row['name_started'] . '</a>'
Chris@76 1063 ),
Chris@76 1064 'updated' => array(
Chris@76 1065 'time' => timeformat($row['time_updated']),
Chris@76 1066 'timestamp' => forum_time(true, $row['time_updated']),
Chris@76 1067 'href' => empty($row['id_member_updated']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_updated'],
Chris@76 1068 'link' => empty($row['id_member_updated']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_updated'] . '">' . $row['name_updated'] . '</a>'
Chris@76 1069 )
Chris@76 1070 );
Chris@76 1071 $num_views += $row['num_views'];
Chris@76 1072 $boards[] = $row['id_board'];
Chris@76 1073
Chris@76 1074 // If there's no poll, id_poll == 0...
Chris@76 1075 if ($row['id_poll'] > 0)
Chris@76 1076 $polls[] = $row['id_poll'];
Chris@76 1077 // Store the id_topic with the lowest id_first_msg.
Chris@76 1078 if (empty($firstTopic))
Chris@76 1079 $firstTopic = $row['id_topic'];
Chris@76 1080
Chris@76 1081 $is_sticky = max($is_sticky, $row['is_sticky']);
Chris@76 1082 }
Chris@76 1083 $smcFunc['db_free_result']($request);
Chris@76 1084
Chris@76 1085 // If we didn't get any topics then they've been messing with unapproved stuff.
Chris@76 1086 if (empty($topic_data))
Chris@76 1087 fatal_lang_error('no_topic_id');
Chris@76 1088
Chris@76 1089 $boards = array_values(array_unique($boards));
Chris@76 1090
Chris@76 1091 // The parameters of MergeExecute were set, so this must've been an internal call.
Chris@76 1092 if (!empty($topics))
Chris@76 1093 {
Chris@76 1094 isAllowedTo('merge_any', $boards);
Chris@76 1095 loadTemplate('SplitTopics');
Chris@76 1096 }
Chris@76 1097
Chris@76 1098 // Get the boards a user is allowed to merge in.
Chris@76 1099 $merge_boards = boardsAllowedTo('merge_any');
Chris@76 1100 if (empty($merge_boards))
Chris@76 1101 fatal_lang_error('cannot_merge_any', 'user');
Chris@76 1102
Chris@76 1103 // Make sure they can see all boards....
Chris@76 1104 $request = $smcFunc['db_query']('', '
Chris@76 1105 SELECT b.id_board
Chris@76 1106 FROM {db_prefix}boards AS b
Chris@76 1107 WHERE b.id_board IN ({array_int:boards})
Chris@76 1108 AND {query_see_board}' . (!in_array(0, $merge_boards) ? '
Chris@76 1109 AND b.id_board IN ({array_int:merge_boards})' : '') . '
Chris@76 1110 LIMIT ' . count($boards),
Chris@76 1111 array(
Chris@76 1112 'boards' => $boards,
Chris@76 1113 'merge_boards' => $merge_boards,
Chris@76 1114 )
Chris@76 1115 );
Chris@76 1116 // If the number of boards that's in the output isn't exactly the same as we've put in there, you're in trouble.
Chris@76 1117 if ($smcFunc['db_num_rows']($request) != count($boards))
Chris@76 1118 fatal_lang_error('no_board');
Chris@76 1119 $smcFunc['db_free_result']($request);
Chris@76 1120
Chris@76 1121 if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options')
Chris@76 1122 {
Chris@76 1123 if (count($polls) > 1)
Chris@76 1124 {
Chris@76 1125 $request = $smcFunc['db_query']('', '
Chris@76 1126 SELECT t.id_topic, t.id_poll, m.subject, p.question
Chris@76 1127 FROM {db_prefix}polls AS p
Chris@76 1128 INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
Chris@76 1129 INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
Chris@76 1130 WHERE p.id_poll IN ({array_int:polls})
Chris@76 1131 LIMIT ' . count($polls),
Chris@76 1132 array(
Chris@76 1133 'polls' => $polls,
Chris@76 1134 )
Chris@76 1135 );
Chris@76 1136 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1137 $context['polls'][] = array(
Chris@76 1138 'id' => $row['id_poll'],
Chris@76 1139 'topic' => array(
Chris@76 1140 'id' => $row['id_topic'],
Chris@76 1141 'subject' => $row['subject']
Chris@76 1142 ),
Chris@76 1143 'question' => $row['question'],
Chris@76 1144 'selected' => $row['id_topic'] == $firstTopic
Chris@76 1145 );
Chris@76 1146 $smcFunc['db_free_result']($request);
Chris@76 1147 }
Chris@76 1148 if (count($boards) > 1)
Chris@76 1149 {
Chris@76 1150 $request = $smcFunc['db_query']('', '
Chris@76 1151 SELECT id_board, name
Chris@76 1152 FROM {db_prefix}boards
Chris@76 1153 WHERE id_board IN ({array_int:boards})
Chris@76 1154 ORDER BY name
Chris@76 1155 LIMIT ' . count($boards),
Chris@76 1156 array(
Chris@76 1157 'boards' => $boards,
Chris@76 1158 )
Chris@76 1159 );
Chris@76 1160 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1161 $context['boards'][] = array(
Chris@76 1162 'id' => $row['id_board'],
Chris@76 1163 'name' => $row['name'],
Chris@76 1164 'selected' => $row['id_board'] == $topic_data[$firstTopic]['board']
Chris@76 1165 );
Chris@76 1166 $smcFunc['db_free_result']($request);
Chris@76 1167 }
Chris@76 1168
Chris@76 1169 $context['topics'] = $topic_data;
Chris@76 1170 foreach ($topic_data as $id => $topic)
Chris@76 1171 $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic;
Chris@76 1172
Chris@76 1173 $context['page_title'] = $txt['merge'];
Chris@76 1174 $context['sub_template'] = 'merge_extra_options';
Chris@76 1175 return;
Chris@76 1176 }
Chris@76 1177
Chris@76 1178 // Determine target board.
Chris@76 1179 $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];
Chris@76 1180 if (!in_array($target_board, $boards))
Chris@76 1181 fatal_lang_error('no_board');
Chris@76 1182
Chris@76 1183 // Determine which poll will survive and which polls won't.
Chris@76 1184 $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0);
Chris@76 1185 if ($target_poll > 0 && !in_array($target_poll, $polls))
Chris@76 1186 fatal_lang_error('no_access', false);
Chris@76 1187 $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll));
Chris@76 1188
Chris@76 1189 // Determine the subject of the newly merged topic - was a custom subject specified?
Chris@76 1190 if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '')
Chris@76 1191 {
Chris@76 1192 $target_subject = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
Chris@76 1193 // Keep checking the length.
Chris@76 1194 if ($smcFunc['strlen']($target_subject) > 100)
Chris@76 1195 $target_subject = $smcFunc['substr']($target_subject, 0, 100);
Chris@76 1196
Chris@76 1197 // Nothing left - odd but pick the first topics subject.
Chris@76 1198 if ($target_subject == '')
Chris@76 1199 $target_subject = $topic_data[$firstTopic]['subject'];
Chris@76 1200 }
Chris@76 1201 // A subject was selected from the list.
Chris@76 1202 elseif (!empty($topic_data[(int) $_POST['subject']]['subject']))
Chris@76 1203 $target_subject = $topic_data[(int) $_POST['subject']]['subject'];
Chris@76 1204 // Nothing worked? Just take the subject of the first message.
Chris@76 1205 else
Chris@76 1206 $target_subject = $topic_data[$firstTopic]['subject'];
Chris@76 1207
Chris@76 1208 // Get the first and last message and the number of messages....
Chris@76 1209 $request = $smcFunc['db_query']('', '
Chris@76 1210 SELECT approved, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg, COUNT(*) AS message_count
Chris@76 1211 FROM {db_prefix}messages
Chris@76 1212 WHERE id_topic IN ({array_int:topics})
Chris@76 1213 GROUP BY approved
Chris@76 1214 ORDER BY approved DESC',
Chris@76 1215 array(
Chris@76 1216 'topics' => $topics,
Chris@76 1217 )
Chris@76 1218 );
Chris@76 1219 $topic_approved = 1;
Chris@76 1220 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1221 {
Chris@76 1222 // If this is approved, or is fully unapproved.
Chris@76 1223 if ($row['approved'] || !isset($first_msg))
Chris@76 1224 {
Chris@76 1225 $first_msg = $row['first_msg'];
Chris@76 1226 $last_msg = $row['last_msg'];
Chris@76 1227 if ($row['approved'])
Chris@76 1228 {
Chris@76 1229 $num_replies = $row['message_count'] - 1;
Chris@76 1230 $num_unapproved = 0;
Chris@76 1231 }
Chris@76 1232 else
Chris@76 1233 {
Chris@76 1234 $topic_approved = 0;
Chris@76 1235 $num_replies = 0;
Chris@76 1236 $num_unapproved = $row['message_count'];
Chris@76 1237 }
Chris@76 1238 }
Chris@76 1239 else
Chris@76 1240 {
Chris@76 1241 // If this has a lower first_msg then the first post is not approved and hence the number of replies was wrong!
Chris@76 1242 if ($first_msg > $row['first_msg'])
Chris@76 1243 {
Chris@76 1244 $first_msg = $row['first_msg'];
Chris@76 1245 $num_replies++;
Chris@76 1246 $topic_approved = 0;
Chris@76 1247 }
Chris@76 1248 $num_unapproved = $row['message_count'];
Chris@76 1249 }
Chris@76 1250 }
Chris@76 1251 $smcFunc['db_free_result']($request);
Chris@76 1252
Chris@76 1253 // Ensure we have a board stat for the target board.
Chris@76 1254 if (!isset($boardTotals[$target_board]))
Chris@76 1255 {
Chris@76 1256 $boardTotals[$target_board] = array(
Chris@76 1257 'posts' => 0,
Chris@76 1258 'topics' => 0,
Chris@76 1259 'unapproved_posts' => 0,
Chris@76 1260 'unapproved_topics' => 0
Chris@76 1261 );
Chris@76 1262 }
Chris@76 1263
Chris@76 1264 // Fix the topic count stuff depending on what the new one counts as.
Chris@76 1265 if ($topic_approved)
Chris@76 1266 $boardTotals[$target_board]['topics']--;
Chris@76 1267 else
Chris@76 1268 $boardTotals[$target_board]['unapproved_topics']--;
Chris@76 1269
Chris@76 1270 $boardTotals[$target_board]['unapproved_posts'] -= $num_unapproved;
Chris@76 1271 $boardTotals[$target_board]['posts'] -= $topic_approved ? $num_replies + 1 : $num_replies;
Chris@76 1272
Chris@76 1273 // Get the member ID of the first and last message.
Chris@76 1274 $request = $smcFunc['db_query']('', '
Chris@76 1275 SELECT id_member
Chris@76 1276 FROM {db_prefix}messages
Chris@76 1277 WHERE id_msg IN ({int:first_msg}, {int:last_msg})
Chris@76 1278 ORDER BY id_msg
Chris@76 1279 LIMIT 2',
Chris@76 1280 array(
Chris@76 1281 'first_msg' => $first_msg,
Chris@76 1282 'last_msg' => $last_msg,
Chris@76 1283 )
Chris@76 1284 );
Chris@76 1285 list ($member_started) = $smcFunc['db_fetch_row']($request);
Chris@76 1286 list ($member_updated) = $smcFunc['db_fetch_row']($request);
Chris@76 1287 // First and last message are the same, so only row was returned.
Chris@76 1288 if ($member_updated === NULL)
Chris@76 1289 $member_updated = $member_started;
Chris@76 1290
Chris@76 1291 $smcFunc['db_free_result']($request);
Chris@76 1292
Chris@76 1293 // Assign the first topic ID to be the merged topic.
Chris@76 1294 $id_topic = min($topics);
Chris@76 1295
Chris@76 1296 // Delete the remaining topics.
Chris@76 1297 $deleted_topics = array_diff($topics, array($id_topic));
Chris@76 1298 $smcFunc['db_query']('', '
Chris@76 1299 DELETE FROM {db_prefix}topics
Chris@76 1300 WHERE id_topic IN ({array_int:deleted_topics})',
Chris@76 1301 array(
Chris@76 1302 'deleted_topics' => $deleted_topics,
Chris@76 1303 )
Chris@76 1304 );
Chris@76 1305 $smcFunc['db_query']('', '
Chris@76 1306 DELETE FROM {db_prefix}log_search_subjects
Chris@76 1307 WHERE id_topic IN ({array_int:deleted_topics})',
Chris@76 1308 array(
Chris@76 1309 'deleted_topics' => $deleted_topics,
Chris@76 1310 )
Chris@76 1311 );
Chris@76 1312
Chris@76 1313 // Asssign the properties of the newly merged topic.
Chris@76 1314 $smcFunc['db_query']('', '
Chris@76 1315 UPDATE {db_prefix}topics
Chris@76 1316 SET
Chris@76 1317 id_board = {int:id_board},
Chris@76 1318 id_member_started = {int:id_member_started},
Chris@76 1319 id_member_updated = {int:id_member_updated},
Chris@76 1320 id_first_msg = {int:id_first_msg},
Chris@76 1321 id_last_msg = {int:id_last_msg},
Chris@76 1322 id_poll = {int:id_poll},
Chris@76 1323 num_replies = {int:num_replies},
Chris@76 1324 unapproved_posts = {int:unapproved_posts},
Chris@76 1325 num_views = {int:num_views},
Chris@76 1326 is_sticky = {int:is_sticky},
Chris@76 1327 approved = {int:approved}
Chris@76 1328 WHERE id_topic = {int:id_topic}',
Chris@76 1329 array(
Chris@76 1330 'id_board' => $target_board,
Chris@76 1331 'is_sticky' => $is_sticky,
Chris@76 1332 'approved' => $topic_approved,
Chris@76 1333 'id_topic' => $id_topic,
Chris@76 1334 'id_member_started' => $member_started,
Chris@76 1335 'id_member_updated' => $member_updated,
Chris@76 1336 'id_first_msg' => $first_msg,
Chris@76 1337 'id_last_msg' => $last_msg,
Chris@76 1338 'id_poll' => $target_poll,
Chris@76 1339 'num_replies' => $num_replies,
Chris@76 1340 'unapproved_posts' => $num_unapproved,
Chris@76 1341 'num_views' => $num_views,
Chris@76 1342 )
Chris@76 1343 );
Chris@76 1344
Chris@76 1345 // Grab the response prefix (like 'Re: ') in the default forum language.
Chris@76 1346 if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix')))
Chris@76 1347 {
Chris@76 1348 if ($language === $user_info['language'])
Chris@76 1349 $context['response_prefix'] = $txt['response_prefix'];
Chris@76 1350 else
Chris@76 1351 {
Chris@76 1352 loadLanguage('index', $language, false);
Chris@76 1353 $context['response_prefix'] = $txt['response_prefix'];
Chris@76 1354 loadLanguage('index');
Chris@76 1355 }
Chris@76 1356 cache_put_data('response_prefix', $context['response_prefix'], 600);
Chris@76 1357 }
Chris@76 1358
Chris@76 1359 // Change the topic IDs of all messages that will be merged. Also adjust subjects if 'enforce subject' was checked.
Chris@76 1360 $smcFunc['db_query']('', '
Chris@76 1361 UPDATE {db_prefix}messages
Chris@76 1362 SET
Chris@76 1363 id_topic = {int:id_topic},
Chris@76 1364 id_board = {int:target_board}' . (empty($_POST['enforce_subject']) ? '' : ',
Chris@76 1365 subject = {string:subject}') . '
Chris@76 1366 WHERE id_topic IN ({array_int:topic_list})',
Chris@76 1367 array(
Chris@76 1368 'topic_list' => $topics,
Chris@76 1369 'id_topic' => $id_topic,
Chris@76 1370 'target_board' => $target_board,
Chris@76 1371 'subject' => $context['response_prefix'] . $target_subject,
Chris@76 1372 )
Chris@76 1373 );
Chris@76 1374
Chris@76 1375 // Any reported posts should reflect the new board.
Chris@76 1376 $smcFunc['db_query']('', '
Chris@76 1377 UPDATE {db_prefix}log_reported
Chris@76 1378 SET
Chris@76 1379 id_topic = {int:id_topic},
Chris@76 1380 id_board = {int:target_board}
Chris@76 1381 WHERE id_topic IN ({array_int:topics_list})',
Chris@76 1382 array(
Chris@76 1383 'topics_list' => $topics,
Chris@76 1384 'id_topic' => $id_topic,
Chris@76 1385 'target_board' => $target_board,
Chris@76 1386 )
Chris@76 1387 );
Chris@76 1388
Chris@76 1389 // Change the subject of the first message...
Chris@76 1390 $smcFunc['db_query']('', '
Chris@76 1391 UPDATE {db_prefix}messages
Chris@76 1392 SET subject = {string:target_subject}
Chris@76 1393 WHERE id_msg = {int:first_msg}',
Chris@76 1394 array(
Chris@76 1395 'first_msg' => $first_msg,
Chris@76 1396 'target_subject' => $target_subject,
Chris@76 1397 )
Chris@76 1398 );
Chris@76 1399
Chris@76 1400 // Adjust all calendar events to point to the new topic.
Chris@76 1401 $smcFunc['db_query']('', '
Chris@76 1402 UPDATE {db_prefix}calendar
Chris@76 1403 SET
Chris@76 1404 id_topic = {int:id_topic},
Chris@76 1405 id_board = {int:target_board}
Chris@76 1406 WHERE id_topic IN ({array_int:deleted_topics})',
Chris@76 1407 array(
Chris@76 1408 'deleted_topics' => $deleted_topics,
Chris@76 1409 'id_topic' => $id_topic,
Chris@76 1410 'target_board' => $target_board,
Chris@76 1411 )
Chris@76 1412 );
Chris@76 1413
Chris@76 1414 // Merge log topic entries.
Chris@76 1415 $request = $smcFunc['db_query']('', '
Chris@76 1416 SELECT id_member, MIN(id_msg) AS new_id_msg
Chris@76 1417 FROM {db_prefix}log_topics
Chris@76 1418 WHERE id_topic IN ({array_int:topics})
Chris@76 1419 GROUP BY id_member',
Chris@76 1420 array(
Chris@76 1421 'topics' => $topics,
Chris@76 1422 )
Chris@76 1423 );
Chris@76 1424 if ($smcFunc['db_num_rows']($request) > 0)
Chris@76 1425 {
Chris@76 1426 $replaceEntries = array();
Chris@76 1427 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1428 $replaceEntries[] = array($row['id_member'], $id_topic, $row['new_id_msg']);
Chris@76 1429
Chris@76 1430 $smcFunc['db_insert']('replace',
Chris@76 1431 '{db_prefix}log_topics',
Chris@76 1432 array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'),
Chris@76 1433 $replaceEntries,
Chris@76 1434 array('id_member', 'id_topic')
Chris@76 1435 );
Chris@76 1436 unset($replaceEntries);
Chris@76 1437
Chris@76 1438 // Get rid of the old log entries.
Chris@76 1439 $smcFunc['db_query']('', '
Chris@76 1440 DELETE FROM {db_prefix}log_topics
Chris@76 1441 WHERE id_topic IN ({array_int:deleted_topics})',
Chris@76 1442 array(
Chris@76 1443 'deleted_topics' => $deleted_topics,
Chris@76 1444 )
Chris@76 1445 );
Chris@76 1446 }
Chris@76 1447 $smcFunc['db_free_result']($request);
Chris@76 1448
Chris@76 1449 // Merge topic notifications.
Chris@76 1450 $notifications = isset($_POST['notifications']) && is_array($_POST['notifications']) ? array_intersect($topics, $_POST['notifications']) : array();
Chris@76 1451 if (!empty($notifications))
Chris@76 1452 {
Chris@76 1453 $request = $smcFunc['db_query']('', '
Chris@76 1454 SELECT id_member, MAX(sent) AS sent
Chris@76 1455 FROM {db_prefix}log_notify
Chris@76 1456 WHERE id_topic IN ({array_int:topics_list})
Chris@76 1457 GROUP BY id_member',
Chris@76 1458 array(
Chris@76 1459 'topics_list' => $notifications,
Chris@76 1460 )
Chris@76 1461 );
Chris@76 1462 if ($smcFunc['db_num_rows']($request) > 0)
Chris@76 1463 {
Chris@76 1464 $replaceEntries = array();
Chris@76 1465 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1466 $replaceEntries[] = array($row['id_member'], $id_topic, 0, $row['sent']);
Chris@76 1467
Chris@76 1468 $smcFunc['db_insert']('replace',
Chris@76 1469 '{db_prefix}log_notify',
Chris@76 1470 array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int', 'sent' => 'int'),
Chris@76 1471 $replaceEntries,
Chris@76 1472 array('id_member', 'id_topic', 'id_board')
Chris@76 1473 );
Chris@76 1474 unset($replaceEntries);
Chris@76 1475
Chris@76 1476 $smcFunc['db_query']('', '
Chris@76 1477 DELETE FROM {db_prefix}log_topics
Chris@76 1478 WHERE id_topic IN ({array_int:deleted_topics})',
Chris@76 1479 array(
Chris@76 1480 'deleted_topics' => $deleted_topics,
Chris@76 1481 )
Chris@76 1482 );
Chris@76 1483 }
Chris@76 1484 $smcFunc['db_free_result']($request);
Chris@76 1485 }
Chris@76 1486
Chris@76 1487 // Get rid of the redundant polls.
Chris@76 1488 if (!empty($deleted_polls))
Chris@76 1489 {
Chris@76 1490 $smcFunc['db_query']('', '
Chris@76 1491 DELETE FROM {db_prefix}polls
Chris@76 1492 WHERE id_poll IN ({array_int:deleted_polls})',
Chris@76 1493 array(
Chris@76 1494 'deleted_polls' => $deleted_polls,
Chris@76 1495 )
Chris@76 1496 );
Chris@76 1497 $smcFunc['db_query']('', '
Chris@76 1498 DELETE FROM {db_prefix}poll_choices
Chris@76 1499 WHERE id_poll IN ({array_int:deleted_polls})',
Chris@76 1500 array(
Chris@76 1501 'deleted_polls' => $deleted_polls,
Chris@76 1502 )
Chris@76 1503 );
Chris@76 1504 $smcFunc['db_query']('', '
Chris@76 1505 DELETE FROM {db_prefix}log_polls
Chris@76 1506 WHERE id_poll IN ({array_int:deleted_polls})',
Chris@76 1507 array(
Chris@76 1508 'deleted_polls' => $deleted_polls,
Chris@76 1509 )
Chris@76 1510 );
Chris@76 1511 }
Chris@76 1512
Chris@76 1513 // Cycle through each board...
Chris@76 1514 foreach ($boardTotals as $id_board => $stats)
Chris@76 1515 {
Chris@76 1516 $smcFunc['db_query']('', '
Chris@76 1517 UPDATE {db_prefix}boards
Chris@76 1518 SET
Chris@76 1519 num_topics = CASE WHEN {int:topics} > num_topics THEN 0 ELSE num_topics - {int:topics} END,
Chris@76 1520 unapproved_topics = CASE WHEN {int:unapproved_topics} > unapproved_topics THEN 0 ELSE unapproved_topics - {int:unapproved_topics} END,
Chris@76 1521 num_posts = CASE WHEN {int:posts} > num_posts THEN 0 ELSE num_posts - {int:posts} END,
Chris@76 1522 unapproved_posts = CASE WHEN {int:unapproved_posts} > unapproved_posts THEN 0 ELSE unapproved_posts - {int:unapproved_posts} END
Chris@76 1523 WHERE id_board = {int:id_board}',
Chris@76 1524 array(
Chris@76 1525 'id_board' => $id_board,
Chris@76 1526 'topics' => $stats['topics'],
Chris@76 1527 'unapproved_topics' => $stats['unapproved_topics'],
Chris@76 1528 'posts' => $stats['posts'],
Chris@76 1529 'unapproved_posts' => $stats['unapproved_posts'],
Chris@76 1530 )
Chris@76 1531 );
Chris@76 1532 }
Chris@76 1533
Chris@76 1534 // Determine the board the final topic resides in
Chris@76 1535 $request = $smcFunc['db_query']('', '
Chris@76 1536 SELECT id_board
Chris@76 1537 FROM {db_prefix}topics
Chris@76 1538 WHERE id_topic = {int:id_topic}
Chris@76 1539 LIMIT 1',
Chris@76 1540 array(
Chris@76 1541 'id_topic' => $id_topic,
Chris@76 1542 )
Chris@76 1543 );
Chris@76 1544 list($id_board) = $smcFunc['db_fetch_row']($request);
Chris@76 1545 $smcFunc['db_free_result']($request);
Chris@76 1546
Chris@76 1547 require_once($sourcedir . '/Subs-Post.php');
Chris@76 1548
Chris@76 1549 // Update all the statistics.
Chris@76 1550 updateStats('topic');
Chris@76 1551 updateStats('subject', $id_topic, $target_subject);
Chris@76 1552 updateLastMessages($boards);
Chris@76 1553
Chris@76 1554 logAction('merge', array('topic' => $id_topic, 'board' => $id_board));
Chris@76 1555
Chris@76 1556 // Notify people that these topics have been merged?
Chris@76 1557 sendNotifications($id_topic, 'merge');
Chris@76 1558
Chris@76 1559 // Send them to the all done page.
Chris@76 1560 redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board);
Chris@76 1561 }
Chris@76 1562
Chris@76 1563 // Tell the user the move was done properly.
Chris@76 1564 function MergeDone()
Chris@76 1565 {
Chris@76 1566 global $txt, $context;
Chris@76 1567
Chris@76 1568 // Make sure the template knows everything...
Chris@76 1569 $context['target_board'] = (int) $_GET['targetboard'];
Chris@76 1570 $context['target_topic'] = (int) $_GET['to'];
Chris@76 1571
Chris@76 1572 $context['page_title'] = $txt['merge'];
Chris@76 1573 $context['sub_template'] = 'merge_done';
Chris@76 1574 }
Chris@76 1575
Chris@76 1576 ?>