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