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