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