[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id$ 10 */ 11 12 class Moderation 13 { 14 /** 15 * Close one or more threads 16 * 17 * @param array Thread IDs 18 * @return boolean true 19 */ 20 function close_threads($tids) 21 { 22 global $db, $plugins; 23 24 if(!is_array($tids)) 25 { 26 $tids = array($tids); 27 } 28 29 // Make sure we only have valid values 30 $tids = array_map('intval', $tids); 31 32 $plugins->run_hooks("class_moderation_close_threads", $tids); 33 34 $tid_list = implode(',', $tids); 35 36 $openthread = array( 37 "closed" => 1, 38 ); 39 $db->update_query("threads", $openthread, "tid IN ($tid_list) AND closed NOT LIKE 'moved|%'"); 40 41 return true; 42 } 43 44 /** 45 * Open one or more threads 46 * 47 * @param int Thread IDs 48 * @return boolean true 49 */ 50 51 function open_threads($tids) 52 { 53 global $db, $plugins; 54 55 if(!is_array($tids)) 56 { 57 $tids = array($tids); 58 } 59 60 // Make sure we only have valid values 61 $tids = array_map('intval', $tids); 62 63 $plugins->run_hooks("class_moderation_open_threads", $tids); 64 65 $tid_list = implode(',', $tids); 66 67 $closethread = array( 68 "closed" => 0, 69 ); 70 $db->update_query("threads", $closethread, "tid IN ($tid_list)"); 71 72 return true; 73 } 74 75 /** 76 * Stick one or more threads 77 * 78 * @param int Thread IDs 79 * @return boolean true 80 */ 81 function stick_threads($tids) 82 { 83 global $db, $plugins; 84 85 if(!is_array($tids)) 86 { 87 $tids = array($tids); 88 } 89 90 // Make sure we only have valid values 91 $tids = array_map('intval', $tids); 92 93 $plugins->run_hooks("class_moderation_stick_threads", $tids); 94 95 $tid_list = implode(',', $tids); 96 97 $stickthread = array( 98 "sticky" => 1, 99 ); 100 $db->update_query("threads", $stickthread, "tid IN ($tid_list)"); 101 102 return true; 103 } 104 105 /** 106 * Unstick one or more thread 107 * 108 * @param int Thread IDs 109 * @return boolean true 110 */ 111 function unstick_threads($tids) 112 { 113 global $db, $plugins; 114 115 if(!is_array($tids)) 116 { 117 $tids = array($tids); 118 } 119 120 // Make sure we only have valid values 121 $tids = array_map('intval', $tids); 122 123 $plugins->run_hooks("class_moderation_unstick_threads", $tids); 124 125 $tid_list = implode(',', $tids); 126 127 $unstickthread = array( 128 "sticky" => 0, 129 ); 130 $db->update_query("threads", $unstickthread, "tid IN ($tid_list)"); 131 132 return true; 133 } 134 135 /** 136 * Remove redirects that redirect to the specified thread 137 * 138 * @param int Thread ID of the thread 139 * @return boolean true 140 */ 141 function remove_redirects($tid) 142 { 143 global $db, $plugins; 144 145 $plugins->run_hooks("class_moderation_remove_redirects", $tid); 146 147 // Delete the redirects 148 $tid = intval($tid); 149 $db->delete_query("threads", "closed='moved|$tid'"); 150 151 return true; 152 } 153 154 /** 155 * Delete a thread 156 * 157 * @param int Thread ID of the thread 158 * @return boolean true 159 */ 160 function delete_thread($tid) 161 { 162 global $db, $cache, $plugins; 163 164 $tid = intval($tid); 165 $plugins->run_hooks("class_moderation_delete_thread_start", $tid); 166 167 $thread = get_thread($tid); 168 169 $userposts = array(); 170 171 // Find the pid, uid, visibility, and forum post count status 172 $query = $db->query(" 173 SELECT p.pid, p.uid, p.visible, f.usepostcounts 174 FROM ".TABLE_PREFIX."posts p 175 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 176 WHERE p.tid='{$tid}' 177 "); 178 $pids = array(); 179 $num_unapproved_posts = $num_approved_posts = 0; 180 while($post = $db->fetch_array($query)) 181 { 182 $pids[] = $post['pid']; 183 $usepostcounts = $post['usepostcounts']; 184 185 if(!function_exists("remove_attachments")) 186 { 187 require MYBB_ROOT."inc/functions_upload.php"; 188 } 189 190 // Remove attachments 191 remove_attachments($post['pid']); 192 193 // If the post is unapproved, count it! 194 if($post['visible'] == 0 || $thread['visible'] == 0) 195 { 196 $num_unapproved_posts++; 197 } 198 else 199 { 200 $num_approved_posts++; 201 202 // Count the post counts for each user to be subtracted 203 ++$userposts[$post['uid']]; 204 } 205 } 206 207 // Remove post count from users 208 if($usepostcounts != 0) 209 { 210 if(is_array($userposts)) 211 { 212 foreach($userposts as $uid => $subtract) 213 { 214 $db->update_query("users", array('postnum' => "postnum-{$subtract}"), "uid='".intval($uid)."'", 1, true); 215 } 216 } 217 } 218 // Delete posts and their attachments 219 if($pids) 220 { 221 $pids = implode(',', $pids); 222 $db->delete_query("posts", "pid IN ($pids)"); 223 $db->delete_query("attachments", "pid IN ($pids)"); 224 $db->delete_query("reportedposts", "pid IN ($pids)"); 225 } 226 227 // Implied counters for unapproved thread 228 if($thread['visible'] == 0) 229 { 230 $num_unapproved_posts += $num_approved_posts; 231 } 232 233 // Delete threads, redirects, subscriptions, polls, and poll votes 234 $db->delete_query("threads", "tid='$tid'"); 235 $db->delete_query("threads", "closed='moved|$tid'"); 236 $db->delete_query("threadsubscriptions", "tid='$tid'"); 237 $db->delete_query("polls", "tid='$tid'"); 238 $db->delete_query("pollvotes", "pid='".$thread['poll']."'"); 239 $db->delete_query("threadsread", "tid='$tid'"); 240 $db->delete_query("threadratings", "tid='$tid'"); 241 242 $updated_counters = array( 243 "posts" => "-{$num_approved_posts}", 244 "unapprovedposts" => "-{$num_unapproved_posts}" 245 ); 246 247 if($thread['visible'] == 1) 248 { 249 $updated_counters['threads'] = -1; 250 } 251 else 252 { 253 $updated_counters['unapprovedthreads'] = -1; 254 } 255 256 if(substr($thread['closed'], 0, 5) != "moved") 257 { 258 // Update forum count 259 update_forum_counters($thread['fid'], $updated_counters); 260 } 261 262 $plugins->run_hooks("class_moderation_delete_thread", $tid); 263 264 return true; 265 } 266 267 /** 268 * Delete a poll 269 * 270 * @param int Poll id 271 * @return boolean true 272 */ 273 function delete_poll($pid) 274 { 275 global $db, $plugins; 276 277 $pid = intval($pid); 278 279 $plugins->run_hooks("class_moderation_delete_poll", $pid); 280 281 $db->delete_query("polls", "pid='$pid'"); 282 $db->delete_query("pollvotes", "pid='$pid'"); 283 $pollarray = array( 284 'poll' => '0', 285 ); 286 $db->update_query("threads", $pollarray, "poll='$pid'"); 287 288 return true; 289 } 290 291 /** 292 * Approve one or more threads 293 * 294 * @param array Thread IDs 295 * @return boolean true 296 */ 297 function approve_threads($tids) 298 { 299 global $db, $cache, $plugins; 300 301 if(!is_array($tids)) 302 { 303 $tids = array($tids); 304 } 305 306 // Make sure we only have valid values 307 $tids = array_map('intval', $tids); 308 309 foreach($tids as $tid) 310 { 311 $thread = get_thread($tid); 312 if($thread['visible'] == 1 || !$thread['tid']) 313 { 314 continue; 315 } 316 $tid_list[] = $thread['tid']; 317 318 $forum = get_forum($thread['fid']); 319 320 $forum_counters[$forum['fid']]['num_threads']++; 321 $forum_counters[$forum['fid']]['num_posts'] += $thread['replies']+1; // Remove implied visible from count 322 323 if($forum['usepostcounts'] != 0) 324 { 325 // On approving thread restore user post counts 326 $query = $db->simple_select("posts", "COUNT(pid) as posts, uid", "tid='{$tid}' AND (visible='1' OR pid='{$thread['firstpost']}') AND uid > 0 GROUP BY uid"); 327 while($counter = $db->fetch_array($query)) 328 { 329 $db->update_query("users", array('postnum' => "postnum+{$counter['posts']}"), "uid='".$counter['uid']."'", 1, true); 330 } 331 } 332 $posts_to_approve[] = $thread['firstpost']; 333 } 334 335 if(is_array($tid_list)) 336 { 337 $tid_moved_list = ""; 338 $comma = ""; 339 foreach($tid_list as $tid) 340 { 341 $tid_moved_list .= "{$comma}'moved|{$tid}'"; 342 $comma = ","; 343 } 344 $tid_list = implode(',', $tid_list); 345 $approve = array( 346 "visible" => 1 347 ); 348 $db->update_query("threads", $approve, "tid IN ($tid_list) OR closed IN ({$tid_moved_list})"); 349 $db->update_query("posts", $approve, "pid IN (".implode(',', $posts_to_approve).")"); 350 351 $plugins->run_hooks("class_moderation_approve_threads", $tids); 352 353 if(is_array($forum_counters)) 354 { 355 foreach($forum_counters as $fid => $counters) 356 { 357 // Update stats 358 $update_array = array( 359 "threads" => "+{$counters['num_threads']}", 360 "unapprovedthreads" => "-{$counters['num_threads']}", 361 "posts" => "+{$counters['num_posts']}", 362 "unapprovedposts" => "-{$counters['num_posts']}" 363 ); 364 update_forum_counters($fid, $update_array); 365 } 366 } 367 } 368 return true; 369 } 370 371 /** 372 * Unapprove one or more threads 373 * 374 * @param array Thread IDs 375 * @return boolean true 376 */ 377 function unapprove_threads($tids) 378 { 379 global $db, $cache, $plugins; 380 381 if(!is_array($tids)) 382 { 383 $tids = array($tids); 384 } 385 386 // Make sure we only have valid values 387 $tids = array_map('intval', $tids); 388 389 $tid_list = implode(',', $tids); 390 $tid_moved_list = ""; 391 $comma = ""; 392 foreach($tids as $tid) 393 { 394 $tid_moved_list .= "{$comma}'moved|{$tid}'"; 395 $comma = ","; 396 } 397 398 foreach($tids as $tid) 399 { 400 $thread = get_thread($tid); 401 $forum = get_forum($thread['fid']); 402 403 if($thread['visible'] == 1) 404 { 405 $forum_counters[$forum['fid']]['num_threads']++; 406 $forum_counters[$forum['fid']]['num_posts'] += $thread['replies']+1; // Add implied invisible to count 407 408 // On unapproving thread update user post counts 409 if($forum['usepostcounts'] != 0) 410 { 411 $query = $db->simple_select("posts", "COUNT(pid) AS posts, uid", "tid='{$tid}' AND (visible='1' OR pid='{$thread['firstpost']}') AND uid > 0 GROUP BY uid"); 412 while($counter = $db->fetch_array($query)) 413 { 414 $db->update_query("users", array('postnum' => "postnum-{$counter['posts']}"), "uid='".$counter['uid']."'", 1, true); 415 } 416 } 417 } 418 $posts_to_unapprove[] = $thread['firstpost']; 419 } 420 421 $approve = array( 422 "visible" => 0 423 ); 424 $db->update_query("threads", $approve, "tid IN ($tid_list) OR closed IN ({$tid_moved_list})"); 425 $db->update_query("posts", $approve, "pid IN (".implode(',', $posts_to_unapprove).")"); 426 427 $plugins->run_hooks("class_moderation_unapprove_threads", $tids); 428 429 if(is_array($forum_counters)) 430 { 431 foreach($forum_counters as $fid => $counters) 432 { 433 // Update stats 434 $update_array = array( 435 "threads" => "-{$counters['num_threads']}", 436 "unapprovedthreads" => "+{$counters['num_threads']}", 437 "posts" => "-{$counters['num_posts']}", 438 "unapprovedposts" => "+{$counters['num_posts']}" 439 ); 440 update_forum_counters($fid, $update_array); 441 } 442 } 443 444 return true; 445 } 446 447 /** 448 * Delete a specific post 449 * 450 * @param int Post ID 451 * @return boolean true 452 */ 453 function delete_post($pid) 454 { 455 global $db, $cache, $plugins; 456 457 $pid = $plugins->run_hooks("class_moderation_delete_post_start", $pid); 458 // Get pid, uid, fid, tid, visibility, forum post count status of post 459 $pid = intval($pid); 460 $query = $db->query(" 461 SELECT p.pid, p.uid, p.fid, p.tid, p.visible, f.usepostcounts, t.visible as threadvisible 462 FROM ".TABLE_PREFIX."posts p 463 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 464 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 465 WHERE p.pid='$pid' 466 "); 467 $post = $db->fetch_array($query); 468 // If post counts enabled in this forum and it hasn't already been unapproved, remove 1 469 if($post['usepostcounts'] != 0 && $post['visible'] != 0 && $post['threadvisible'] != 0) 470 { 471 $db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true); 472 } 473 474 if(!function_exists("remove_attachments")) 475 { 476 require MYBB_ROOT."inc/functions_upload.php"; 477 } 478 479 // Remove attachments 480 remove_attachments($pid); 481 482 // Delete the post 483 $db->delete_query("posts", "pid='$pid'"); 484 485 // Remove any reports attached to this post 486 $db->delete_query("reportedposts", "pid='$pid'"); 487 488 $num_unapproved_posts = $num_approved_posts = 0; 489 // Update unapproved post count 490 if($post['visible'] == 0 || $post['threadvisible'] == 0) 491 { 492 ++$num_unapproved_posts; 493 } 494 else 495 { 496 ++$num_approved_posts; 497 } 498 $plugins->run_hooks("class_moderation_delete_post", $post['pid']); 499 500 // Update stats 501 $update_array = array( 502 "replies" => "-{$num_approved_posts}", 503 "unapprovedposts" => "-{$num_unapproved_posts}" 504 ); 505 update_thread_counters($post['tid'], $update_array); 506 507 // Update stats 508 $update_array = array( 509 "posts" => "-{$num_approved_posts}", 510 "unapprovedposts" => "-{$num_unapproved_posts}" 511 ); 512 513 update_forum_counters($post['fid'], $update_array); 514 515 return true; 516 } 517 518 /** 519 * Merge posts within thread 520 * 521 * @param array Post IDs to be merged 522 * @param int Thread ID (Set to 0 if posts from multiple threads are 523 * selected) 524 * @return int ID of the post into which all other posts are merged 525 */ 526 function merge_posts($pids, $tid=0, $sep="new_line") 527 { 528 global $db, $plugins; 529 530 // Make sure we only have valid values 531 $pids = array_map('intval', $pids); 532 $tid = intval($tid); 533 534 $pidin = implode(',', $pids); 535 $attachment_count = 0; 536 537 $first = 1; 538 // Get the messages to be merged 539 $query = $db->query(" 540 SELECT p.pid, p.uid, p.fid, p.tid, p.visible, p.message, f.usepostcounts, t.visible AS threadvisible, t.replies AS threadreplies, t.firstpost AS threadfirstpost, t.unapprovedposts AS threadunapprovedposts 541 FROM ".TABLE_PREFIX."posts p 542 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 543 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 544 WHERE p.pid IN($pidin) 545 ORDER BY p.dateline ASC 546 "); 547 $num_unapproved_posts = $num_approved_posts = 0; 548 $message = ''; 549 $threads = array(); 550 while($post = $db->fetch_array($query)) 551 { 552 $threads[$post['tid']] = $post['tid']; 553 if($first == 1) 554 { // all posts will be merged into this one 555 $masterpid = $post['pid']; 556 $message = $post['message']; 557 $fid = $post['fid']; 558 $mastertid = $post['tid']; 559 $first = 0; 560 } 561 else 562 { 563 // these are the selected posts 564 if($sep == "new_line") 565 { 566 $message .= "\n\n {$post['message']}"; 567 } 568 else 569 { 570 $message .= "[hr]{$post['message']}"; 571 } 572 573 if($post['visible'] == 1 && $post['threadvisible'] == 1) 574 { 575 // Subtract 1 approved post from post's thread 576 if(!$thread_counters[$post['tid']]['replies']) 577 { 578 $thread_counters[$post['tid']]['replies'] = $post['threadreplies']; 579 } 580 --$thread_counters[$post['tid']]['replies']; 581 // Subtract 1 approved post from post's forum 582 if(!isset($forum_counters[$post['fid']]['num_posts'])) 583 { 584 $forum_counters[$post['fid']]['num_posts'] = 0; 585 } 586 --$forum_counters[$post['fid']]['num_posts']; 587 // Subtract 1 from user's post count 588 if($post['usepostcounts'] != 0) 589 { 590 // Update post count of the user of the merged posts 591 $db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true); 592 } 593 } 594 elseif($post['visible'] == 0) 595 { 596 // Subtract 1 unapproved post from post's thread 597 if(!$thread_counters[$post['tid']]['unapprovedposts']) 598 { 599 $thread_counters[$post['tid']]['unapprovedposts'] = $post['threadunapprovedposts']; 600 } 601 --$thread_counters[$post['tid']]['unapprovedposts']; 602 // Subtract 1 unapproved post from post's forum 603 if(!isset($forum_counters[$post['fid']]['unapprovedposts'])) 604 { 605 $forum_counters[$post['fid']]['unapprovedposts'] = 0; 606 } 607 --$forum_counters[$post['fid']]['unapprovedposts']; 608 } 609 } 610 } 611 612 // Update the message 613 $mergepost = array( 614 "message" => $db->escape_string($message), 615 ); 616 $db->update_query("posts", $mergepost, "pid = '{$masterpid}'"); 617 618 // Delete the extra posts 619 $db->delete_query("posts", "pid IN({$pidin}) AND pid != '{$masterpid}'"); 620 // Update pid for attachments 621 622 $mergepost2 = array( 623 "pid" => $masterpid, 624 ); 625 $db->update_query("attachments", $mergepost2, "pid IN({$pidin})"); 626 627 // If the first post of a thread is merged out, the thread should be deleted 628 $query = $db->simple_select("threads", "tid, fid, visible", "firstpost IN({$pidin}) AND firstpost != '{$masterpid}'"); 629 while($thread = $db->fetch_array($query)) 630 { 631 $this->delete_thread($thread['tid']); 632 // Subtract 1 thread from the forum's stats 633 if($thread['visible']) 634 { 635 if(!isset($forum_counters[$thread['fid']]['threads'])) 636 { 637 $forum_counters[$thread['fid']]['threads'] = 0; 638 } 639 --$forum_counters[$thread['fid']]['threads']; 640 } 641 else 642 { 643 if(!isset($forum_counters[$thread['fid']]['unapprovedthreads'])) 644 { 645 $forum_counters[$thread['fid']]['unapprovedthreads'] = 0; 646 } 647 --$forum_counters[$thread['fid']]['unapprovedthreads']; 648 } 649 } 650 651 $arguments = array("pids" => $pids, "tid" => $tid); 652 $plugins->run_hooks("class_moderation_merge_posts", $arguments); 653 654 if(is_array($thread_counters)) 655 { 656 foreach($thread_counters as $tid => $counters) 657 { 658 $db->update_query("threads", $counters, "tid='{$tid}'"); 659 660 update_thread_data($tid); 661 } 662 } 663 664 update_thread_data($mastertid); 665 666 update_forum_lastpost($fid); 667 668 foreach($threads as $tid) 669 { 670 $count = array(); 671 // Attachment count 672 $query = $db->query(" 673 SELECT COUNT(aid) AS attachment_count 674 FROM ".TABLE_PREFIX."attachments a 675 LEFT JOIN ".TABLE_PREFIX."posts p ON (a.pid=p.pid) 676 WHERE p.tid='$tid' 677 "); 678 $count['attachmentcount'] = $db->fetch_field($query, "attachment_count"); 679 680 if(!$count['attachmentcount']) 681 { 682 $count['attachmentcount'] = 0; 683 } 684 685 update_thread_counters($tid, $count); 686 } 687 688 if(is_array($forum_counters)) 689 { 690 foreach($forum_counters as $fid => $counters) 691 { 692 $updated_forum_stats = array( 693 'posts' => signed($counters['num_posts']), 694 'unapprovedposts' => signed($counters['unapprovedposts']), 695 'threads' => signed($counters['threads']), 696 ); 697 update_forum_counters($fid, $updated_forum_stats); 698 } 699 } 700 701 return $masterpid; 702 } 703 704 /** 705 * Move/copy thread 706 * 707 * @param int Thread to be moved 708 * @param int Destination forum 709 * @param string Method of movement (redirect, copy, move) 710 * @param int Expiry timestamp for redirect 711 * @return int Thread ID 712 */ 713 function move_thread($tid, $new_fid, $method="redirect", $redirect_expire=0) 714 { 715 global $db, $plugins; 716 717 // Get thread info 718 $tid = intval($tid); 719 $new_fid = intval($new_fid); 720 $redirect_expire = intval($redirect_expire); 721 722 $thread = get_thread($tid, true); 723 $newforum = get_forum($new_fid); 724 $fid = $thread['fid']; 725 $forum = get_forum($fid); 726 727 $num_threads = $num_unapproved_threads = $num_posts = $num_unapproved_threads = 0; 728 switch($method) 729 { 730 case "redirect": // move (and leave redirect) thread 731 $arguments = array("tid" => $tid, "new_fid" => $new_fid); 732 $plugins->run_hooks("class_moderation_move_thread_redirect", $arguments); 733 734 if($thread['visible'] == 1) 735 { 736 $num_threads++; 737 $num_posts = $thread['replies']+1; 738 } 739 else 740 { 741 $num_unapproved_threads++; 742 // Implied forum unapproved count for unapproved threads 743 $num_unapproved_posts = $thread['replies']+1; 744 } 745 746 $num_unapproved_posts += $thread['unapprovedposts']; 747 748 $db->delete_query("threads", "closed='moved|$tid' AND fid='$new_fid'"); 749 $changefid = array( 750 "fid" => $new_fid, 751 ); 752 $db->update_query("threads", $changefid, "tid='$tid'"); 753 $db->update_query("posts", $changefid, "tid='$tid'"); 754 755 // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix 756 if($thread['prefix'] != 0) 757 { 758 $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'"); 759 if($db->fetch_field($query, "num_prefixes") == 0) 760 { 761 $sqlarray = array( 762 "prefix" => 0, 763 ); 764 $db->update_query("threads", $sqlarray, "tid='$tid'"); 765 } 766 } 767 768 $threadarray = array( 769 "fid" => $thread['fid'], 770 "subject" => $db->escape_string($thread['subject']), 771 "icon" => $thread['icon'], 772 "uid" => $thread['uid'], 773 "username" => $db->escape_string($thread['username']), 774 "dateline" => $thread['dateline'], 775 "lastpost" => $thread['lastpost'], 776 "lastposteruid" => $thread['lastposteruid'], 777 "lastposter" => $db->escape_string($thread['lastposter']), 778 "views" => 0, 779 "replies" => 0, 780 "closed" => "moved|$tid", 781 "sticky" => $thread['sticky'], 782 "visible" => intval($thread['visible']), 783 "notes" => '' 784 ); 785 $redirect_tid = $db->insert_query("threads", $threadarray); 786 if($redirect_expire) 787 { 788 $this->expire_thread($redirect_tid, $redirect_expire); 789 } 790 791 // If we're moving back to a forum where we left a redirect, delete the rediect 792 $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|".intval($tid)."' AND fid='".intval($new_fid)."'"); 793 while($movedthread = $db->fetch_array($query)) 794 { 795 $db->delete_query("threads", "tid='".intval($movedthread['tid'])."'", 1); 796 } 797 break; 798 case "copy":// copy thread 799 800 $threadarray = array( 801 "fid" => $new_fid, 802 "subject" => $db->escape_string($thread['subject']), 803 "icon" => $thread['icon'], 804 "uid" => $thread['uid'], 805 "username" => $db->escape_string($thread['username']), 806 "dateline" => $thread['dateline'], 807 "firstpost" => 0, 808 "lastpost" => $thread['lastpost'], 809 "lastposteruid" => $thread['lastposteruid'], 810 "lastposter" => $db->escape_string($thread['lastposter']), 811 "views" => $thread['views'], 812 "replies" => $thread['replies'], 813 "closed" => $thread['closed'], 814 "sticky" => $thread['sticky'], 815 "visible" => intval($thread['visible']), 816 "unapprovedposts" => $thread['unapprovedposts'], 817 "attachmentcount" => $thread['attachmentcount'], 818 "prefix" => $thread['prefix'], 819 "notes" => '' 820 ); 821 822 if($thread['visible'] == 1) 823 { 824 ++$num_threads; 825 $num_posts = $thread['replies']+1; 826 827 // Fetch count of unapproved posts in this thread 828 $query = $db->simple_select("posts", "COUNT(pid) AS unapproved", "tid='{$thread['tid']}' AND visible=0"); 829 $num_unapproved_posts = $db->fetch_field($query, "unapproved"); 830 831 } 832 else 833 { 834 $num_unapproved_threads++; 835 $num_unapproved_posts = $thread['replies']+1; 836 } 837 838 $arguments = array("tid" => $tid, "new_fid" => $new_fid); 839 $plugins->run_hooks("class_moderation_copy_thread", $arguments); 840 841 // If the thread has a prefix and the destination forum doesn't accept that prefix, don't copy the prefix 842 if($threadarray['prefix'] != 0) 843 { 844 $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'"); 845 if($db->fetch_field($query, "num_prefixes") == 0) 846 { 847 $threadarray['prefix'] = 0; 848 } 849 } 850 851 $newtid = $db->insert_query("threads", $threadarray); 852 853 if($thread['poll'] != 0) 854 { 855 $query = $db->simple_select("polls", "*", "tid = '{$thread['tid']}'"); 856 $poll = $db->fetch_array($query); 857 858 $poll_array = array( 859 'tid' => $newtid, 860 'question' => $db->escape_string($poll['question']), 861 'dateline' => $poll['dateline'], 862 'options' => $db->escape_string($poll['options']), 863 'votes' => $poll['votes'], 864 'numoptions' => $poll['numoptions'], 865 'numvotes' => $poll['numvotes'], 866 'timeout' => $poll['timeout'], 867 'closed' => $poll['closed'], 868 'multiple' => $poll['multiple'], 869 'public' => $poll['public'] 870 ); 871 $new_pid = $db->insert_query("polls", $poll_array); 872 873 $query = $db->simple_select("pollvotes", "*", "pid = '{$poll['pid']}'"); 874 while($pollvote = $db->fetch_array($query)) 875 { 876 $pollvote_array = array( 877 'pid' => $new_pid, 878 'uid' => $pollvote['uid'], 879 'voteoption' => $pollvote['voteoption'], 880 'dateline' => $pollvote['dateline'], 881 ); 882 $db->insert_query("pollvotes", $pollvote_array); 883 } 884 885 $db->update_query("threads", array('poll' => $new_pid), "tid='{$newtid}'"); 886 } 887 888 $query = $db->simple_select("posts", "*", "tid = '{$thread['tid']}'"); 889 while($post = $db->fetch_array($query)) 890 { 891 $post_array = array( 892 'tid' => $newtid, 893 'fid' => $new_fid, 894 'subject' => $db->escape_string($post['subject']), 895 'icon' => $post['icon'], 896 'uid' => $post['uid'], 897 'username' => $db->escape_string($post['username']), 898 'dateline' => $post['dateline'], 899 'ipaddress' => $post['ipaddress'], 900 'includesig' => $post['includesig'], 901 'smilieoff' => $post['smilieoff'], 902 'edituid' => $post['edituid'], 903 'edittime' => $post['edittime'], 904 'visible' => $post['visible'], 905 'message' => $db->escape_string($post['message']), 906 ); 907 $pid = $db->insert_query("posts", $post_array); 908 909 // Properly set our new firstpost in our new thread 910 if($thread['firstpost'] == $post['pid']) 911 { 912 $db->update_query("threads", array('firstpost' => $pid), "tid='{$newtid}'"); 913 } 914 915 // Insert attachments for this post 916 $query2 = $db->simple_select("attachments", "*", "pid = '{$post['pid']}'"); 917 while($attachment = $db->fetch_array($query2)) 918 { 919 $attachment_array = array( 920 'pid' => $pid, 921 'uid' => $attachment['uid'], 922 'filename' => $db->escape_string($attachment['filename']), 923 'filetype' => $attachment['filetype'], 924 'filesize' => $attachment['filesize'], 925 'attachname' => $attachment['attachname'], 926 'downloads' => $attachment['downloads'], 927 'visible' => $attachment['visible'], 928 'thumbnail' => $attachment['thumbnail'] 929 ); 930 $new_aid = $db->insert_query("attachments", $attachment_array); 931 932 $post['message'] = str_replace("[attachment={$attachment['aid']}]", "[attachment={$new_aid}]", $post['message']); 933 } 934 935 if(strpos($post['message'], "[attachment=") !== false) 936 { 937 $db->update_query("posts", array('message' => $db->escape_string($post['message'])), "pid='{$pid}'"); 938 } 939 } 940 941 update_thread_data($newtid); 942 943 $the_thread = $newtid; 944 break; 945 default: 946 case "move": // plain move thread 947 $arguments = array("tid" => $tid, "new_fid" => $new_fid); 948 $plugins->run_hooks("class_moderation_move_simple", $arguments); 949 950 if($thread['visible'] == 1) 951 { 952 $num_threads++; 953 $num_posts = $thread['replies']+1; 954 } 955 else 956 { 957 $num_unapproved_threads++; 958 // Implied forum unapproved count for unapproved threads 959 $num_unapproved_posts = $thread['replies']+1; 960 } 961 962 $num_unapproved_posts = $thread['unapprovedposts']; 963 964 $sqlarray = array( 965 "fid" => $new_fid, 966 ); 967 $db->update_query("threads", $sqlarray, "tid='$tid'"); 968 $db->update_query("posts", $sqlarray, "tid='$tid'"); 969 970 // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix 971 if($thread['prefix'] != 0) 972 { 973 $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'"); 974 if($db->fetch_field($query, "num_prefixes") == 0) 975 { 976 $sqlarray = array( 977 "prefix" => 0, 978 ); 979 $db->update_query("threads", $sqlarray, "tid='$tid'"); 980 } 981 } 982 983 // If we're moving back to a forum where we left a redirect, delete the rediect 984 $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|".intval($tid)."' AND fid='".intval($new_fid)."'"); 985 while($movedthread = $db->fetch_array($query)) 986 { 987 $db->delete_query("threads", "tid='".intval($movedthread['tid'])."'", 1); 988 } 989 break; 990 } 991 992 // Do post count changes if changing between countable and non-countable forums 993 $query = $db->query(" 994 SELECT COUNT(p.pid) AS posts, u.uid, p.visible 995 FROM ".TABLE_PREFIX."posts p 996 LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid) 997 WHERE tid='$tid' 998 GROUP BY u.uid, p.visible 999 ORDER BY posts DESC 1000 "); 1001 while($posters = $db->fetch_array($query)) 1002 { 1003 $pcount = ""; 1004 if($forum['usepostcounts'] == 1 && $newforum['usepostcounts'] == 0 && $posters['visible'] == 1) 1005 { 1006 $pcount = "-{$posters['posts']}"; 1007 } 1008 else if($forum['usepostcounts'] == 0 && $newforum['userpostcounts'] == 1 && $posters['visible'] == 1) 1009 { 1010 $pcount = "+{$posters['posts']}"; 1011 } 1012 1013 if(!empty($pcount)) 1014 { 1015 $db->update_query("users", array("postnum" => "postnum{$pcount}"), "uid='{$posters['uid']}'", 1, true); 1016 } 1017 } 1018 1019 // Update forum counts 1020 $update_array = array( 1021 "threads" => "+{$num_threads}", 1022 "unapprovedthreads" => "+{$num_unapproved_threads}", 1023 "posts" => "+{$num_posts}", 1024 "unapprovedposts" => "+{$num_unapproved_posts}" 1025 ); 1026 update_forum_counters($new_fid, $update_array); 1027 1028 if($method != "copy") 1029 { 1030 $update_array = array( 1031 "threads" => "-{$num_threads}", 1032 "unapprovedthreads" => "-{$num_unapproved_threads}", 1033 "posts" => "-{$num_posts}", 1034 "unapprovedposts" => "-{$num_unapproved_posts}" 1035 ); 1036 update_forum_counters($fid, $update_array); 1037 } 1038 1039 if(isset($newtid)) 1040 { 1041 return $newtid; 1042 } 1043 else 1044 { 1045 // Remove thread subscriptions for the users who no longer have permission to view the thread 1046 $this->remove_thread_subscriptions($tid, false, $new_fid); 1047 1048 return $tid; 1049 } 1050 } 1051 1052 /** 1053 * Merge one thread into another 1054 * 1055 * @param int Thread that will be merged into destination 1056 * @param int Destination thread 1057 * @param string New thread subject 1058 * @return boolean true 1059 */ 1060 function merge_threads($mergetid, $tid, $subject) 1061 { 1062 global $db, $mybb, $mergethread, $thread, $plugins; 1063 1064 $mergetid = intval($mergetid); 1065 $tid = intval($tid); 1066 1067 if(!isset($mergethread['tid']) || $mergethread['tid'] != $mergetid) 1068 { 1069 $query = $db->simple_select("threads", "*", "tid='{$mergetid}'"); 1070 $mergethread = $db->fetch_array($query); 1071 } 1072 if(!isset($thread['tid']) || $thread['tid'] != $tid) 1073 { 1074 $query = $db->simple_select("threads", "*", "tid='{$tid}'"); 1075 $thread = $db->fetch_array($query); 1076 } 1077 1078 $pollsql = ''; 1079 if($mergethread['poll']) 1080 { 1081 $pollsql['poll'] = $mergethread['poll']; 1082 $sqlarray = array( 1083 "tid" => $tid, 1084 ); 1085 $db->update_query("polls", $sqlarray, "tid='".intval($mergethread['tid'])."'"); 1086 } 1087 else 1088 { 1089 $query = $db->simple_select("threads", "*", "poll='{$mergethread['poll']}' AND tid != '{$mergetid}'"); 1090 $pollcheck = $db->fetch_array($query); 1091 if(!$pollcheck['poll']) 1092 { 1093 $db->delete_query("polls", "pid='{$mergethread['poll']}'"); 1094 $db->delete_query("pollvotes", "pid='{$mergethread['poll']}'"); 1095 } 1096 } 1097 1098 $subject = $db->escape_string($subject); 1099 1100 $sqlarray = array( 1101 "tid" => $tid, 1102 "fid" => $thread['fid'], 1103 "replyto" => 0, 1104 ); 1105 $db->update_query("posts", $sqlarray, "tid='{$mergetid}'"); 1106 1107 $pollsql['subject'] = $subject; 1108 $db->update_query("threads", $pollsql, "tid='{$tid}'"); 1109 $sqlarray = array( 1110 "closed" => "moved|{$tid}", 1111 ); 1112 $db->update_query("threads", $sqlarray, "closed='moved|{$mergetid}'"); 1113 $sqlarray = array( 1114 "tid" => $tid, 1115 ); 1116 1117 // Update the thread ratings 1118 $new_numrating = $thread['numratings'] + $mergethread['numratings']; 1119 $new_threadrating = $thread['totalratings'] + $mergethread['totalratings']; 1120 1121 $sqlarray = array( 1122 "numratings" => $new_numrating, 1123 "totalratings" => $new_threadrating 1124 ); 1125 1126 $db->update_query("threads", $sqlarray, "tid = '{$tid}'"); 1127 1128 // Check if we have a thread subscription already for our new thread 1129 $subscriptions = array( 1130 $tid => array(), 1131 $mergetid => array() 1132 ); 1133 1134 $query = $db->simple_select("threadsubscriptions", "tid, uid", "tid='{$mergetid}' OR tid='{$tid}'"); 1135 while($subscription = $db->fetch_array($query)) 1136 { 1137 $subscriptions[$subscription['tid']][] = $subscription['uid']; 1138 } 1139 1140 // Update any subscriptions for the merged thread 1141 if(is_array($subscriptions[$mergetid])) 1142 { 1143 $update_users = array(); 1144 foreach($subscriptions[$mergetid] as $user) 1145 { 1146 if(!in_array($user, $subscriptions[$tid])) 1147 { 1148 // User doesn't have a $tid subscription 1149 $update_users[] = $user; 1150 } 1151 } 1152 1153 if(!empty($update_users)) 1154 { 1155 $update_array = array( 1156 "tid" => $tid 1157 ); 1158 1159 $update_users = implode(",", $update_users); 1160 $db->update_query("threadsubscriptions", $update_array, "tid = '{$mergetid}' AND uid IN ({$update_users})"); 1161 } 1162 } 1163 1164 // Remove source thread subscriptions 1165 $db->delete_query("threadsubscriptions", "tid = '{$mergetid}'"); 1166 1167 update_first_post($tid); 1168 1169 $arguments = array("mergetid" => $mergetid, "tid" => $tid, "subject" => $subject); 1170 $plugins->run_hooks("class_moderation_merge_threads", $arguments); 1171 1172 $this->delete_thread($mergetid); 1173 1174 // In some cases the thread we may be merging with may cause us to have a new firstpost if it is an older thread 1175 // Therefore resync the visible field to make sure they're the same if they're not 1176 $query = $db->simple_select("posts", "pid, visible", "tid='{$tid}'", array('order_by' => 'dateline', 'order_dir' => 'asc', 'limit' => 1)); 1177 $new_firstpost = $db->fetch_array($query); 1178 if($thread['visible'] != $new_firstpost['visible']) 1179 { 1180 $db->update_query("posts", array('visible' => $thread['visible']), "pid='{$new_firstpost['pid']}'"); 1181 $mergethread['visible'] = $thread['visible']; 1182 } 1183 1184 $updated_stats = array( 1185 "replies" => '+'.($mergethread['replies']+1), 1186 "attachmentcount" => "+{$mergethread['attachmentcount']}", 1187 "unapprovedposts" => "+{$mergethread['unapprovedposts']}" 1188 ); 1189 update_thread_counters($tid, $updated_stats); 1190 1191 // Thread is not in current forum 1192 if($mergethread['fid'] != $thread['fid']) 1193 { 1194 // If new thread is unapproved, implied counter comes in to effect 1195 if($thread['visible'] == 0 || $mergethread['visible'] == 0) 1196 { 1197 $updated_stats = array( 1198 "unapprovedposts" => '+'.($mergethread['replies']+1+$mergethread['unapprovedposts']) 1199 ); 1200 } 1201 else 1202 { 1203 $updated_stats = array( 1204 "posts" => '+'.($mergethread['replies']+1), 1205 "unapprovedposts" => "+{$mergethread['unapprovedposts']}" 1206 ); 1207 } 1208 update_forum_counters($thread['fid'], $updated_stats); 1209 1210 // If old thread is unapproved, implied counter comes in to effect 1211 if($mergethread['visible'] == 0) 1212 { 1213 $updated_stats = array( 1214 "unapprovedposts" => '-'.($mergethread['replies']+1+$mergethread['unapprovedposts']) 1215 ); 1216 } 1217 else 1218 { 1219 $updated_stats = array( 1220 "posts" => '-'.($mergethread['replies']+1), 1221 "unapprovedposts" => "-{$mergethread['unapprovedposts']}" 1222 ); 1223 } 1224 update_forum_counters($mergethread['fid'], $updated_stats); 1225 } 1226 // If we're in the same forum we need to at least update the last post information 1227 else 1228 { 1229 update_forum_lastpost($thread['fid']); 1230 } 1231 return true; 1232 } 1233 1234 /** 1235 * Split posts into a new/existing thread 1236 * 1237 * @param array PIDs of posts to split 1238 * @param int Original thread ID (this is only used as a base for the new 1239 * thread; it can be set to 0 when the posts specified are coming from more 1240 * than 1 thread) 1241 * @param int Destination forum 1242 * @param string New thread subject 1243 * @param int TID if moving into existing thread 1244 * @return int New thread ID 1245 */ 1246 function split_posts($pids, $tid, $moveto, $newsubject, $destination_tid=0) 1247 { 1248 global $db, $thread, $plugins; 1249 1250 $tid = intval($tid); 1251 $moveto = intval($moveto); 1252 $newtid = intval($destination_tid); 1253 1254 // Get forum infos 1255 $query = $db->simple_select("forums", "fid, usepostcounts, posts, threads, unapprovedposts, unapprovedthreads"); 1256 while($forum = $db->fetch_array($query)) 1257 { 1258 $forum_cache[$forum['fid']] = $forum; 1259 } 1260 1261 // Make sure we only have valid values 1262 $pids = array_map('intval', $pids); 1263 1264 $pids_list = implode(',', $pids); 1265 1266 // Get the icon for the first split post 1267 $query = $db->simple_select("posts", "icon, visible", "pid=".intval($pids[0])); 1268 $post_info = $db->fetch_array($query); 1269 1270 $icon = $post_info['icon']; 1271 $visible = $post_info['visible']; 1272 1273 if($destination_tid == 0) 1274 { 1275 // Splitting into a new thread 1276 $thread = get_thread($tid); 1277 // Create the new thread 1278 $newsubject = $db->escape_string($newsubject); 1279 $query = array( 1280 "fid" => $moveto, 1281 "subject" => $newsubject, 1282 "icon" => intval($icon), 1283 "uid" => intval($thread['uid']), 1284 "username" => $db->escape_string($thread['username']), 1285 "dateline" => intval($thread['dateline']), 1286 "lastpost" => intval($thread['lastpost']), 1287 "lastposter" => $db->escape_string($thread['lastposter']), 1288 "replies" => count($pids)-1, 1289 "visible" => intval($visible), 1290 "notes" => '' 1291 ); 1292 $newtid = $db->insert_query("threads", $query); 1293 1294 $forum_counters[$moveto]['threads'] = $forum_cache[$moveto]['threads']; 1295 $forum_counters[$moveto]['unapprovedthreads'] = $forum_cache[$moveto]['unapprovedthreads']; 1296 if($visible) 1297 { 1298 ++$forum_counters[$moveto]['threads']; 1299 } 1300 else 1301 { 1302 // Unapproved thread? 1303 ++$forum_counters[$moveto]['unapprovedthreads']; 1304 } 1305 } 1306 1307 // Get attachment counts for each post 1308 /*$query = $db->simple_select("attachments", "COUNT(aid) as count, pid", "pid IN ($pids_list)"); 1309 $query = $db->query(" 1310 SELECT COUNT(aid) as count, p.pid, 1311 "); 1312 $attachment_sum = 0; 1313 while($attachment = $db->fetch_array($query)) 1314 { 1315 $attachments[$attachment['pid']] = $attachment['count']; 1316 $attachment_sum += $attachment['count']; 1317 } 1318 $thread_counters[$newtid]['attachmentcount'] = '+'.$attachment_sum;*/ 1319 1320 // Get selected posts before moving forums to keep old fid 1321 //$original_posts_query = $db->simple_select("posts", "fid, visible, pid", "pid IN ($pids_list)"); 1322 $original_posts_query = $db->query(" 1323 SELECT p.pid, p.tid, p.fid, p.visible, p.uid, t.visible as threadvisible, t.replies as threadreplies, t.unapprovedposts as threadunapprovedposts, t.attachmentcount as threadattachmentcount, COUNT(a.aid) as postattachmentcount 1324 FROM ".TABLE_PREFIX."posts p 1325 LEFT JOIN ".TABLE_PREFIX."threads t ON (p.tid=t.tid) 1326 LEFT JOIN ".TABLE_PREFIX."attachments a ON (a.pid=p.pid) 1327 WHERE p.pid IN ($pids_list) 1328 GROUP BY p.pid, p.tid, p.fid, p.visible, p.uid, t.visible, t.replies, t.unapprovedposts,t.attachmentcount 1329 "); 1330 1331 // Move the selected posts over 1332 $sqlarray = array( 1333 "tid" => $newtid, 1334 "fid" => $moveto, 1335 "replyto" => 0 1336 ); 1337 $db->update_query("posts", $sqlarray, "pid IN ($pids_list)"); 1338 1339 // Get posts being merged 1340 while($post = $db->fetch_array($original_posts_query)) 1341 { 1342 if($post['visible'] == 1) 1343 { 1344 // Modify users' post counts 1345 if($forum_cache[$post['fid']]['usepostcounts'] == 1 && $forum_cache[$moveto]['usepostcounts'] == 0) 1346 { 1347 // Moving into a forum that doesn't count post counts 1348 if(!isset($user_counters[$post['uid']])) 1349 { 1350 $user_counters[$post['uid']] = 0; 1351 } 1352 --$user_counters[$post['uid']]; 1353 } 1354 elseif($forum_cache[$post['fid']]['usepostcounts'] == 0 && $forum_cache[$moveto]['usepostcounts'] == 1) 1355 { 1356 // Moving into a forum that does count post counts 1357 if(!isset($user_counters[$post['uid']])) 1358 { 1359 $user_counters[$post['uid']] = 0; 1360 } 1361 ++$user_counters[$post['uid']]; 1362 } 1363 1364 // Subtract 1 from the old thread's replies 1365 if(!isset($thread_counters[$post['tid']]['replies'])) 1366 { 1367 $thread_counters[$post['tid']]['replies'] = $post['threadreplies']; 1368 } 1369 --$thread_counters[$post['tid']]['replies']; 1370 1371 // Add 1 to the new thread's replies 1372 ++$thread_counters[$newtid]['replies']; 1373 1374 if($moveto != $post['fid']) 1375 { 1376 // Only need to change forum info if the old forum is different from new forum 1377 // Subtract 1 from the old forum's posts 1378 if(!isset($forum_counters[$post['fid']]['posts'])) 1379 { 1380 $forum_counters[$post['fid']]['posts'] = $forum_cache[$post['fid']]['posts']; 1381 } 1382 --$forum_counters[$post['fid']]['posts']; 1383 // Add 1 to the new forum's posts 1384 if(!isset($forum_counters[$moveto]['posts'])) 1385 { 1386 $forum_counters[$moveto]['posts'] = $forum_cache[$moveto]['posts']; 1387 } 1388 ++$forum_counters[$moveto]['posts']; 1389 } 1390 1391 } 1392 elseif($post['visible'] == 0) 1393 { 1394 // Unapproved post 1395 // Subtract 1 from the old thread's unapproved posts 1396 if(!isset($thread_counters[$post['tid']]['unapprovedposts'])) 1397 { 1398 $thread_counters[$post['tid']]['unapprovedposts'] = $post['threadunapprovedposts']; 1399 } 1400 --$thread_counters[$post['tid']]['unapprovedposts']; 1401 1402 // Add 1 to the new thread's unapproved posts 1403 ++$thread_counters[$newtid]['unapprovedposts']; 1404 1405 if($moveto != $post['fid']) 1406 { 1407 // Only need to change forum info if the old forum is different from new forum 1408 // Subtract 1 from the old forum's unapproved posts 1409 if(!isset($forum_counters[$post['fid']]['unapprovedposts'])) 1410 { 1411 $forum_counters[$post['fid']]['unapprovedposts'] = $forum_cache[$post['fid']]['unapprovedposts']; 1412 } 1413 --$forum_counters[$post['fid']]['unapprovedposts']; 1414 // Add 1 to the new forum's unapproved posts 1415 if(!isset($forum_counters[$moveto]['unapprovedposts'])) 1416 { 1417 $forum_counters[$moveto]['unapprovedposts'] = $forum_cache[$moveto]['unapprovedposts']; 1418 } 1419 ++$forum_counters[$moveto]['unapprovedposts']; 1420 } 1421 } 1422 1423 // Subtract attachment counts from old thread and add to new thread (which are counted regardless of post or attachment unapproval at time of coding) 1424 if(!isset($thread_counters[$post['tid']]['attachmentcount'])) 1425 { 1426 $thread_counters[$post['tid']]['attachmentcount'] = $post['threadattachmentcount']; 1427 } 1428 $thread_counters[$post['tid']]['attachmentcount'] -= $post['postattachmentcount']; 1429 $thread_counters[$newtid]['attachmentcount'] += $post['postattachmentcount']; 1430 } 1431 if($destination_tid == 0 && $thread_counters[$newtid]['replies'] > 0) 1432 { 1433 // If splitting into a new thread, subtract one from the thread's reply count to compensate for the original post 1434 --$thread_counters[$newtid]['replies']; 1435 } 1436 1437 $arguments = array("pids" => $pids, "tid" => $tid, "moveto" => $moveto, "newsubject" => $newsubject, "destination_tid" => $destination_tid); 1438 $plugins->run_hooks("class_moderation_split_posts", $arguments); 1439 1440 // Update user post counts 1441 if(is_array($user_counters)) 1442 { 1443 foreach($user_counters as $uid => $change) 1444 { 1445 if($change >= 0) 1446 { 1447 $change = '+'.$change; // add the addition operator for query 1448 } 1449 $db->update_query("users", array("postnum" => "postnum{$change}"), "uid='{$uid}'", 1, true); 1450 } 1451 } 1452 1453 // Update thread counters 1454 if(is_array($thread_counters)) 1455 { 1456 foreach($thread_counters as $tid => $counters) 1457 { 1458 if($tid == $newtid) 1459 { 1460 // Update the subject of the first post in the new thread 1461 $query = $db->simple_select("posts", "pid", "tid='$newtid'", array('order_by' => 'dateline', 'limit' => 1)); 1462 $newthread = $db->fetch_array($query); 1463 $sqlarray = array( 1464 "subject" => $newsubject, 1465 "replyto" => 0 1466 ); 1467 $db->update_query("posts", $sqlarray, "pid='{$newthread['pid']}'"); 1468 } 1469 else 1470 { 1471 // Update the subject of the first post in the old thread 1472 $query = $db->query(" 1473 SELECT p.pid, t.subject 1474 FROM ".TABLE_PREFIX."posts p 1475 LEFT JOIN ".TABLE_PREFIX."threads t ON (p.tid=t.tid) 1476 WHERE p.tid='{$tid}' 1477 ORDER BY p.dateline ASC 1478 LIMIT 1 1479 "); 1480 $oldthread = $db->fetch_array($query); 1481 $sqlarray = array( 1482 "subject" => $db->escape_string($oldthread['subject']), 1483 "replyto" => 0 1484 ); 1485 $db->update_query("posts", $sqlarray, "pid='{$oldthread['pid']}'"); 1486 } 1487 1488 $db->update_query("threads", $counters, "tid='{$tid}'"); 1489 1490 update_thread_data($tid); 1491 1492 // Update first post columns 1493 update_first_post($tid); 1494 } 1495 } 1496 update_thread_data($newtid); 1497 1498 update_first_post($newtid); 1499 1500 // Update forum counters 1501 if(is_array($forum_counters)) 1502 { 1503 foreach($forum_counters as $fid => $counters) 1504 { 1505 update_forum_counters($fid, $counters); 1506 } 1507 } 1508 1509 return $newtid; 1510 } 1511 1512 /** 1513 * Move multiple threads to new forum 1514 * 1515 * @param array Thread IDs 1516 * @param int Destination forum 1517 * @return boolean true 1518 */ 1519 function move_threads($tids, $moveto) 1520 { 1521 global $db, $plugins; 1522 1523 // Make sure we only have valid values 1524 $tids = array_map('intval', $tids); 1525 1526 $tid_list = implode(',', $tids); 1527 1528 $moveto = intval($moveto); 1529 1530 $newforum = get_forum($moveto); 1531 1532 $total_posts = $total_unapproved_posts = $total_threads = $total_unapproved_threads = 0; 1533 $query = $db->simple_select("threads", "fid, visible, replies, unapprovedposts, tid", "tid IN ($tid_list)"); 1534 while($thread = $db->fetch_array($query)) 1535 { 1536 $forum = get_forum($thread['fid']); 1537 1538 $total_posts += $thread['replies']+1; 1539 $total_unapproved_posts += $thread['unapprovedposts']; 1540 1541 $forum_counters[$thread['fid']]['posts'] += $thread['replies']+1; 1542 $forum_counters[$thread['fid']]['unapprovedposts'] += $thread['unapprovedposts']; 1543 1544 if($thread['visible'] == 1) 1545 { 1546 $forum_counters[$thread['fid']]['threads']++; 1547 ++$total_threads; 1548 } 1549 else 1550 { 1551 $forum_counters[$thread['fid']]['unapprovedthreads']++; 1552 $forum_counters[$thread['fid']]['unapprovedposts'] += $thread['replies']; // Implied unapproved posts counter for unapproved threads 1553 ++$total_unapproved_threads; 1554 } 1555 1556 $query1 = $db->query(" 1557 SELECT COUNT(p.pid) AS posts, p.visible, u.uid 1558 FROM ".TABLE_PREFIX."posts p 1559 LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid) 1560 WHERE p.tid = '{$thread['tid']}' 1561 GROUP BY p.visible, u.uid 1562 ORDER BY posts DESC 1563 "); 1564 while($posters = $db->fetch_array($query1)) 1565 { 1566 $pcount = ""; 1567 if($newforum['usepostcounts'] != 0 && $forum['usepostcounts'] == 0 && $posters['visible'] != 0) 1568 { 1569 $pcount = "+{$posters['posts']}"; 1570 } 1571 else if($newforum['usepostcounts'] == 0 && $forum['usepostcounts'] != 0 && $posters['visible'] != 0) 1572 { 1573 $pcount = "-{$posters['posts']}"; 1574 } 1575 1576 if(!empty($pcount)) 1577 { 1578 $db->update_query("users", array("postnum" => "postnum{$pcount}"), "uid='{$posters['uid']}'", 1, true); 1579 } 1580 } 1581 } 1582 1583 $sqlarray = array( 1584 "fid" => $moveto, 1585 ); 1586 $db->update_query("threads", $sqlarray, "tid IN ($tid_list)"); 1587 $db->update_query("posts", $sqlarray, "tid IN ($tid_list)"); 1588 1589 // If any of the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix 1590 $query = $db->simple_select("threads", "tid, prefix", "tid IN ($tid_list) AND prefix != 0"); 1591 while($thread = $db->fetch_array($query)) 1592 { 1593 $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$moveto,%' OR forums='-1') AND pid='".$thread['prefix']."'"); 1594 if($db->fetch_field($query, "num_prefixes") == 0) 1595 { 1596 $sqlarray = array( 1597 "prefix" => 0, 1598 ); 1599 $db->update_query("threads", $sqlarray, "tid = '{$thread['tid']}'"); 1600 } 1601 } 1602 1603 $arguments = array("tids" => $tids, "moveto" => $moveto); 1604 $plugins->run_hooks("class_moderation_move_threads", $arguments); 1605 1606 if(is_array($forum_counters)) 1607 { 1608 foreach($forum_counters as $fid => $counter) 1609 { 1610 $updated_count = array( 1611 "posts" => "-{$counter['posts']}", 1612 "unapprovedposts" => "-{$counter['unapprovedposts']}" 1613 ); 1614 if($counter['threads']) 1615 { 1616 $updated_count['threads'] = "-{$counter['threads']}"; 1617 } 1618 if($counter['unapprovedthreads']) 1619 { 1620 $updated_count['unapprovedthreads'] = "-{$counter['unapprovedthreads']}"; 1621 } 1622 update_forum_counters($fid, $updated_count); 1623 } 1624 } 1625 1626 $updated_count = array( 1627 "threads" => "+{$total_threads}", 1628 "unapprovedthreads" => "+{$total_unapproved_threads}", 1629 "posts" => "+{$total_posts}", 1630 "unapprovedposts" => "+{$total_unapproved_posts}" 1631 ); 1632 1633 update_forum_counters($moveto, $updated_count); 1634 1635 // Remove thread subscriptions for the users who no longer have permission to view the thread 1636 $this->remove_thread_subscriptions($tid_list, false, $moveto); 1637 1638 return true; 1639 } 1640 1641 /** 1642 * Approve multiple posts 1643 * 1644 * @param array PIDs 1645 * @return boolean true 1646 */ 1647 function approve_posts($pids) 1648 { 1649 global $db, $cache; 1650 1651 $num_posts = 0; 1652 1653 // Make sure we only have valid values 1654 $pids = array_map('intval', $pids); 1655 1656 $pid_list = implode(',', $pids); 1657 $pids = $threads_to_update = array(); 1658 1659 // Make visible 1660 $approve = array( 1661 "visible" => 1, 1662 ); 1663 1664 // We have three cases we deal with in these code segments: 1665 // 1) We're approving specific unapproved posts 1666 // 1.1) if the thread is approved 1667 // 1.2) if the thread is unapproved 1668 // 2) We're approving the firstpost of the thread, therefore approving the thread itself 1669 // 3) We're doing both 1 and 2 1670 $query = $db->query(" 1671 SELECT p.tid 1672 FROM ".TABLE_PREFIX."posts p 1673 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1674 WHERE p.pid IN ($pid_list) AND p.visible = '0' AND t.firstpost = p.pid AND t.visible = 0 1675 "); 1676 while($post = $db->fetch_array($query)) 1677 { 1678 // This is the first post in the thread so we're approving the whole thread. 1679 $threads_to_update[] = $post['tid']; 1680 } 1681 1682 if(!empty($threads_to_update)) 1683 { 1684 $this->approve_threads($threads_to_update); 1685 } 1686 1687 $query = $db->query(" 1688 SELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, t.visible AS threadvisible 1689 FROM ".TABLE_PREFIX."posts p 1690 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1691 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 1692 WHERE p.pid IN ($pid_list) AND p.visible = '0' AND t.firstpost != p.pid 1693 "); 1694 while($post = $db->fetch_array($query)) 1695 { 1696 $pids[] = $post['pid']; 1697 1698 ++$thread_counters[$post['tid']]['unapprovedposts']; 1699 ++$thread_counters[$post['tid']]['replies']; 1700 1701 // If the thread of this post is unapproved then we've already taken into account this counter as implied. 1702 // Updating it again would cause it to double count 1703 if($post['threadvisible'] != 0) 1704 { 1705 ++$forum_counters[$post['fid']]['num_posts']; 1706 } 1707 1708 // If post counts enabled in this forum and the thread is approved, add 1 1709 if($post['usepostcounts'] != 0 && $post['threadvisible'] == 1) 1710 { 1711 $db->update_query("users", array("postnum" => "postnum+1"), "uid='{$post['uid']}'", 1, true); 1712 } 1713 } 1714 1715 if(empty($pids) && empty($threads_to_update)) 1716 { 1717 return false; 1718 } 1719 1720 if(!empty($pids)) 1721 { 1722 $where = "pid IN (".implode(',', $pids).")"; 1723 $db->update_query("posts", $approve, $where); 1724 } 1725 1726 if(is_array($thread_counters)) 1727 { 1728 foreach($thread_counters as $tid => $counters) 1729 { 1730 $counters_update = array( 1731 "unapprovedposts" => "-".$counters['unapprovedposts'], 1732 "replies" => "+".$counters['replies'] 1733 ); 1734 update_thread_counters($tid, $counters_update); 1735 1736 update_thread_data($tid); 1737 } 1738 } 1739 1740 if(is_array($forum_counters)) 1741 { 1742 foreach($forum_counters as $fid => $counters) 1743 { 1744 $updated_forum_stats = array( 1745 "posts" => "+{$counters['num_posts']}", 1746 "unapprovedposts" => "-{$counters['num_posts']}", 1747 "threads" => "+{$counters['num_threads']}", 1748 "unapprovedthreads" => "-{$counters['num_threads']}" 1749 ); 1750 update_forum_counters($fid, $updated_forum_stats); 1751 } 1752 } 1753 1754 return true; 1755 } 1756 1757 /** 1758 * Unapprove multiple posts 1759 * 1760 * @param array PIDs 1761 * @return boolean true 1762 */ 1763 function unapprove_posts($pids) 1764 { 1765 global $db, $cache; 1766 1767 // Make sure we only have valid values 1768 $pids = array_map('intval', $pids); 1769 1770 $pid_list = implode(',', $pids); 1771 $pids = $threads_to_update = array(); 1772 1773 // Make invisible 1774 $approve = array( 1775 "visible" => 0, 1776 ); 1777 1778 // We have three cases we deal with in these code segments: 1779 // 1) We're unapproving specific approved posts 1780 // 1.1) if the thread is approved 1781 // 1.2) if the thread is unapproved 1782 // 2) We're unapproving the firstpost of the thread, therefore unapproving the thread itself 1783 // 3) We're doing both 1 and 2 1784 $query = $db->query(" 1785 SELECT p.tid 1786 FROM ".TABLE_PREFIX."posts p 1787 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1788 WHERE p.pid IN ($pid_list) AND p.visible = '1' AND t.firstpost = p.pid AND t.visible = 1 1789 "); 1790 while($post = $db->fetch_array($query)) 1791 { 1792 // This is the first post in the thread so we're unapproving the whole thread. 1793 $threads_to_update[] = $post['tid']; 1794 } 1795 1796 if(!empty($threads_to_update)) 1797 { 1798 $this->unapprove_threads($threads_to_update); 1799 } 1800 1801 $thread_counters = array(); 1802 $forum_counters = array(); 1803 1804 $query = $db->query(" 1805 SELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, t.visible AS threadvisible 1806 FROM ".TABLE_PREFIX."posts p 1807 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1808 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 1809 WHERE p.pid IN ($pid_list) AND p.visible = '1' AND t.firstpost != p.pid 1810 "); 1811 while($post = $db->fetch_array($query)) 1812 { 1813 $pids[] = $post['pid']; 1814 1815 ++$thread_counters[$post['tid']]['unapprovedposts']; 1816 ++$thread_counters[$post['tid']]['replies']; 1817 1818 // If the thread of this post is unapproved then we've already taken into account this counter as implied. 1819 // Updating it again would cause it to double count 1820 if($post['threadvisible'] != 0) 1821 { 1822 ++$forum_counters[$post['fid']]['num_posts']; 1823 } 1824 1825 // If post counts enabled in this forum and the thread is approved, subtract 1 1826 if($post['usepostcounts'] != 0 && $post['threadvisible'] == 1) 1827 { 1828 $db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true); 1829 } 1830 } 1831 1832 if(empty($pids) && empty($threads_to_update)) 1833 { 1834 return false; 1835 } 1836 1837 if(!empty($pids)) 1838 { 1839 $where = "pid IN (".implode(',', $pids).")"; 1840 $db->update_query("posts", $approve, $where); 1841 } 1842 1843 if(is_array($thread_counters)) 1844 { 1845 foreach($thread_counters as $tid => $counters) 1846 { 1847 $counters_update = array( 1848 "unapprovedposts" => "+".$counters['unapprovedposts'], 1849 "replies" => "-".$counters['replies'] 1850 ); 1851 1852 update_thread_counters($tid, $counters_update); 1853 1854 update_thread_data($tid); 1855 } 1856 } 1857 1858 if(is_array($forum_counters)) 1859 { 1860 foreach($forum_counters as $fid => $counters) 1861 { 1862 $updated_forum_stats = array( 1863 "posts" => "-{$counters['num_posts']}", 1864 "unapprovedposts" => "+{$counters['num_posts']}", 1865 "threads" => "-{$counters['num_threads']}", 1866 "unapprovedthreads" => "+{$counters['num_threads']}" 1867 ); 1868 1869 update_forum_counters($fid, $updated_forum_stats); 1870 } 1871 } 1872 1873 return true; 1874 } 1875 1876 /** 1877 * Change thread subject 1878 * 1879 * @param mixed Thread ID(s) 1880 * @param string Format of new subject (with {subject}) 1881 * @return boolean true 1882 */ 1883 function change_thread_subject($tids, $format) 1884 { 1885 global $db, $mybb, $plugins; 1886 1887 // Get tids into list 1888 if(!is_array($tids)) 1889 { 1890 $tids = array(intval($tids)); 1891 } 1892 1893 1894 // Make sure we only have valid values 1895 $tids = array_map('intval', $tids); 1896 1897 $tid_list = implode(',', $tids); 1898 1899 // Get original subject 1900 $query = $db->simple_select("threads", "subject, tid", "tid IN ($tid_list)"); 1901 while($thread = $db->fetch_array($query)) 1902 { 1903 // Update threads and first posts with new subject 1904 $subject = str_replace('{username}', $mybb->user['username'], $format); 1905 $subject = str_replace('{subject}', $thread['subject'], $subject); 1906 $new_subject = array( 1907 "subject" => $db->escape_string($subject) 1908 ); 1909 $db->update_query("threads", $new_subject, "tid='{$thread['tid']}'", 1); 1910 $db->update_query("posts", $new_subject, "tid='{$thread['tid']}' AND replyto='0'", 1); 1911 } 1912 1913 $arguments = array("tids" => $tids, "format" => $format); 1914 $plugins->run_hooks("class_moderation_change_thread_subject", $arguments); 1915 1916 return true; 1917 } 1918 1919 /** 1920 * Add thread expiry 1921 * 1922 * @param int Thread ID 1923 * @param int Timestamp when the thread is deleted 1924 * @return boolean true 1925 */ 1926 function expire_thread($tid, $deletetime) 1927 { 1928 global $db, $plugins; 1929 1930 $tid = intval($tid); 1931 1932 $update_thread = array( 1933 "deletetime" => intval($deletetime) 1934 ); 1935 $db->update_query("threads", $update_thread, "tid='{$tid}'"); 1936 1937 $arguments = array("tid" => $tid, "deletetime" => $deletetime); 1938 $plugins->run_hooks("class_moderation_expire_thread", $arguments); 1939 1940 return true; 1941 } 1942 1943 /** 1944 * Toggle post visibility (approved/unapproved) 1945 * 1946 * @param array Post IDs 1947 * @param int Thread ID 1948 * @param int Forum ID 1949 * @return boolean true 1950 */ 1951 function toggle_post_visibility($pids) 1952 { 1953 global $db; 1954 1955 // Make sure we only have valid values 1956 $pids = array_map('intval', $pids); 1957 1958 $pid_list = implode(',', $pids); 1959 $query = $db->simple_select("posts", 'pid, visible', "pid IN ($pid_list)"); 1960 while($post = $db->fetch_array($query)) 1961 { 1962 if($post['visible'] == 1) 1963 { 1964 $unapprove[] = $post['pid']; 1965 } 1966 else 1967 { 1968 $approve[] = $post['pid']; 1969 } 1970 } 1971 if(is_array($unapprove)) 1972 { 1973 $this->unapprove_posts($unapprove); 1974 } 1975 if(is_array($approve)) 1976 { 1977 $this->approve_posts($approve); 1978 } 1979 return true; 1980 } 1981 1982 /** 1983 * Toggle thread visibility (approved/unapproved) 1984 * 1985 * @param array Thread IDs 1986 * @param int Forum ID 1987 * @return boolean true 1988 */ 1989 function toggle_thread_visibility($tids, $fid) 1990 { 1991 global $db; 1992 1993 // Make sure we only have valid values 1994 $tids = array_map('intval', $tids); 1995 $fid = intval($fid); 1996 1997 $tid_list = implode(',', $tids); 1998 $query = $db->simple_select("threads", 'tid, visible', "tid IN ($tid_list)"); 1999 while($thread = $db->fetch_array($query)) 2000 { 2001 if($thread['visible'] == 1) 2002 { 2003 $unapprove[] = $thread['tid']; 2004 } 2005 else 2006 { 2007 $approve[] = $thread['tid']; 2008 } 2009 } 2010 if(is_array($unapprove)) 2011 { 2012 $this->unapprove_threads($unapprove, $fid); 2013 } 2014 if(is_array($approve)) 2015 { 2016 $this->approve_threads($approve, $fid); 2017 } 2018 return true; 2019 } 2020 2021 /** 2022 * Toggle threads open/closed 2023 * 2024 * @param array Thread IDs 2025 * @return boolean true 2026 */ 2027 function toggle_thread_status($tids) 2028 { 2029 global $db; 2030 2031 // Make sure we only have valid values 2032 $tids = array_map('intval', $tids); 2033 2034 $tid_list = implode(',', $tids); 2035 $query = $db->simple_select("threads", 'tid, closed', "tid IN ($tid_list)"); 2036 while($thread = $db->fetch_array($query)) 2037 { 2038 if($thread['closed'] == 1) 2039 { 2040 $open[] = $thread['tid']; 2041 } 2042 elseif($thread['closed'] == 0) 2043 { 2044 $close[] = $thread['tid']; 2045 } 2046 } 2047 if(is_array($open)) 2048 { 2049 $this->open_threads($open); 2050 } 2051 if(is_array($close)) 2052 { 2053 $this->close_threads($close); 2054 } 2055 return true; 2056 } 2057 2058 /** 2059 * Remove thread subscriptions (from one or multiple threads in the same forum) 2060 * 2061 * @param int $tids Thread ID, or an array of thread IDs from the same forum. 2062 * @param boolean $all True (default) to delete all subscriptions, false to only delete subscriptions from users with no permission to read the thread 2063 * @param int $fid (Only applies if $all is false) The forum ID of the thread 2064 * @return boolean true 2065 */ 2066 function remove_thread_subscriptions($tids, $all = true, $fid = 0) 2067 { 2068 global $db, $plugins; 2069 2070 // Format thread IDs 2071 if(!is_array($tids)) 2072 { 2073 $tids = array($tids); 2074 } 2075 2076 // Make sure we only have valid values 2077 $tids = array_map('intval', $tids); 2078 $fid = intval($fid); 2079 2080 $tids_csv = implode(',', $tids); 2081 2082 // Delete only subscriptions from users who no longer have permission to read the thread. 2083 if(!$all) 2084 { 2085 // Get groups that cannot view the forum or its threads 2086 $forum_parentlist = get_parent_list($fid); 2087 $query = $db->simple_select("forumpermissions", "gid", "fid IN ({$forum_parentlist}) AND (canview=0 OR canviewthreads=0)"); 2088 $groups = array(); 2089 while($group = $db->fetch_array($query)) 2090 { 2091 $groups[] = $group['gid']; 2092 switch($db->type) 2093 { 2094 case "pgsql": 2095 case "sqlite": 2096 $additional_groups .= " OR ','||u.additionalgroups||',' LIKE ',{$group['gid']},'"; 2097 break; 2098 default: 2099 $additional_groups .= " OR CONCAT(',',u.additionalgroups,',') LIKE ',{$group['gid']},'"; 2100 } 2101 } 2102 // If there are groups found, delete subscriptions from users in these groups 2103 if(count($groups) > 0) 2104 { 2105 $groups_csv = implode(',', $groups); 2106 $query = $db->query(" 2107 SELECT s.tid, u.uid 2108 FROM ".TABLE_PREFIX."threadsubscriptions s 2109 LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=s.uid) 2110 WHERE s.tid IN ({$tids_csv}) 2111 AND (u.usergroup IN ({$groups_csv}){$additional_groups}) 2112 "); 2113 while($subscription = $db->fetch_array($query)) 2114 { 2115 $db->delete_query("threadsubscriptions", "uid='{$subscription['uid']}' AND tid='{$subscription['tid']}'"); 2116 } 2117 } 2118 } 2119 // Delete all subscriptions of this thread 2120 else 2121 { 2122 $db->delete_query("threadsubscriptions", "tid IN ({$tids_csv})"); 2123 } 2124 2125 $arguments = array("tids" => $tids, "all" => $all, "fid" => $fid); 2126 $plugins->run_hooks("class_moderation_remove_thread_subscriptions", $arguments); 2127 2128 return true; 2129 } 2130 2131 /** 2132 * Apply a thread prefix (to one or multiple threads in the same forum) 2133 * 2134 * @param int $tids Thread ID, or an array of thread IDs from the same forum. 2135 * @param int $prefix Prefix ID to apply to the threads 2136 */ 2137 function apply_thread_prefix($tids, $prefix = 0) 2138 { 2139 global $db, $plugins; 2140 2141 // Format thread IDs 2142 if(!is_array($tids)) 2143 { 2144 $tids = array($tids); 2145 } 2146 2147 // Make sure we only have valid values 2148 $tids = array_map('intval', $tids); 2149 $tids_csv = implode(',', $tids); 2150 2151 $update_thread = array('prefix' => intval($prefix)); 2152 $db->update_query('threads', $update_thread, "tid IN ({$tids_csv})"); 2153 2154 $arguments = array('tids' => $tids, 'prefix' => $prefix); 2155 2156 $plugins->run_hooks('class_moderation_apply_thread_prefix', $arguments); 2157 2158 return true; 2159 } 2160 } 2161 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |