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