[ Index ]

PHP Cross Reference of MyBB 1.6.0

title

Body

[close]

/inc/ -> class_moderation.php (source)

   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 5145 2010-07-30 21:30:51Z RyanGordon $
  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          $plugins->run_hooks_by_ref("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          // Get lastpost pid to check if we're merging a post that is on the lastpost info
 610          $query = $db->simple_select("posts", "pid", "tid = '{$post['tid']}'", array('order_by' => 'dateline', 'order_dir' => 'desc', 'limit' => '1'));
 611          $lastpostpid = $db->fetch_field($query, 'pid');
 612          
 613          $query2 = $db->simple_select("attachments", "COUNT(aid) as count", "pid IN({$pidin}) AND visible='1'");
 614          $attachment_count = $db->fetch_field($query2, "count");
 615          
 616          $db->update_query("threads", array("attachmentcount" => $attachment_count), "tid = '{$mastertid}'");
 617  
 618          // Update the message
 619          $mergepost = array(
 620              "message" => $db->escape_string($message),
 621          );
 622          $db->update_query("posts", $mergepost, "pid = '{$masterpid}'");
 623          
 624          // Delete the extra posts
 625          $db->delete_query("posts", "pid IN({$pidin}) AND pid != '{$masterpid}'");
 626          // Update pid for attachments
 627          
 628          $mergepost2 = array(
 629              "pid" => $masterpid,
 630          );
 631          $db->update_query("attachments", $mergepost2, "pid IN({$pidin})");
 632          
 633          // If the first post of a thread is merged out, the thread should be deleted
 634          $query = $db->simple_select("threads", "tid, fid, visible", "firstpost IN({$pidin}) AND firstpost != '{$masterpid}'");
 635          while($thread = $db->fetch_array($query))
 636          {
 637              $this->delete_thread($thread['tid']);
 638              // Subtract 1 thread from the forum's stats
 639              if($thread['visible'])
 640              {
 641                  if(!isset($forum_counters[$thread['fid']]['threads']))
 642                  {
 643                      $forum_counters[$thread['fid']]['threads'] = 0;
 644                  }
 645                  --$forum_counters[$thread['fid']]['threads'];
 646              }
 647              else
 648              {
 649                  if(!isset($forum_counters[$thread['fid']]['unapprovedthreads']))
 650                  {
 651                      $forum_counters[$thread['fid']]['unapprovedthreads'] = 0;
 652                  }
 653                  --$forum_counters[$thread['fid']]['unapprovedthreads'];
 654              }
 655          }
 656  
 657          $arguments = array("pids" => $pids, "tid" => $tid);
 658          $plugins->run_hooks("class_moderation_merge_posts", $arguments);
 659  
 660          if(is_array($thread_counters))
 661          {
 662              foreach($thread_counters as $tid => $counters)
 663              {
 664                  $db->update_query("threads", $counters, "tid='{$tid}'");
 665  
 666                  update_thread_data($tid);
 667              }
 668          }
 669          
 670          update_thread_data($mastertid);
 671          
 672          update_forum_lastpost($fid);
 673  
 674          if(is_array($forum_counters))
 675          {
 676              foreach($forum_counters as $fid => $counters)
 677              {
 678                  $updated_forum_stats = array(
 679                      'posts' => signed($counters['num_posts']),
 680                      'unapprovedposts' => signed($counters['unapprovedposts']),
 681                      'threads' => signed($counters['threads']),
 682                  );
 683                  update_forum_counters($fid, $updated_forum_stats);
 684              }
 685          }
 686  
 687          return $masterpid;
 688      }
 689  
 690      /**
 691       * Move/copy thread
 692       *
 693       * @param int Thread to be moved
 694       * @param int Destination forum
 695       * @param string Method of movement (redirect, copy, move)
 696       * @param int Expiry timestamp for redirect
 697       * @return int Thread ID
 698       */
 699  	function move_thread($tid, $new_fid, $method="redirect", $redirect_expire=0)
 700      {
 701          global $db, $plugins;
 702  
 703          // Get thread info
 704          $tid = intval($tid);
 705          $new_fid = intval($new_fid);
 706          $redirect_expire = intval($redirect_expire);
 707  
 708          $thread = get_thread($tid, true);
 709          $newforum = get_forum($new_fid);
 710          $fid = $thread['fid'];
 711          $forum = get_forum($fid);
 712  
 713          $num_threads = $num_unapproved_threads = $num_posts = $num_unapproved_threads = 0;
 714          switch($method)
 715          {
 716              case "redirect": // move (and leave redirect) thread
 717                  $arguments = array("tid" => $tid, "new_fid" => $new_fid);
 718                  $plugins->run_hooks("class_moderation_move_thread_redirect", $arguments);
 719  
 720                  if($thread['visible'] == 1)
 721                  {
 722                      $num_threads++;
 723                      $num_posts = $thread['replies']+1;
 724                  }
 725                  else
 726                  {
 727                      $num_unapproved_threads++;
 728                      // Implied forum unapproved count for unapproved threads
 729                       $num_unapproved_posts = $thread['replies']+1;
 730                  }
 731                  
 732                  $num_unapproved_posts += $thread['unapprovedposts'];
 733  
 734                  $db->delete_query("threads", "closed='moved|$tid' AND fid='$new_fid'");
 735                  $changefid = array(
 736                      "fid" => $new_fid,
 737                  );
 738                  $db->update_query("threads", $changefid, "tid='$tid'");
 739                  $db->update_query("posts", $changefid, "tid='$tid'");
 740                  
 741                  // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix
 742                  if($thread['prefix'] != 0)
 743                  {
 744                      $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'");
 745                      if($db->fetch_field($query, "num_prefixes") == 0)
 746                      {
 747                          $sqlarray = array(
 748                              "prefix" => 0,
 749                          );
 750                          $db->update_query("threads", $sqlarray, "tid='$tid'");
 751                      }
 752                  }
 753                  
 754                  $threadarray = array(
 755                      "fid" => $thread['fid'],
 756                      "subject" => $db->escape_string($thread['subject']),
 757                      "icon" => $thread['icon'],
 758                      "uid" => $thread['uid'],
 759                      "username" => $db->escape_string($thread['username']),
 760                      "dateline" => $thread['dateline'],
 761                      "lastpost" => $thread['lastpost'],
 762                      "lastposteruid" => $thread['lastposteruid'],
 763                      "lastposter" => $db->escape_string($thread['lastposter']),
 764                      "views" => 0,
 765                      "replies" => 0,
 766                      "closed" => "moved|$tid",
 767                      "sticky" => $thread['sticky'],
 768                      "visible" => $thread['visible'],
 769                      "notes" => ''
 770                  );
 771                  $redirect_tid = $db->insert_query("threads", $threadarray);
 772                  if($redirect_expire)
 773                  {
 774                      $this->expire_thread($redirect_tid, $redirect_expire);
 775                  }
 776                  
 777                  // If we're moving back to a forum where we left a redirect, delete the rediect
 778                  $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|".intval($tid)."' AND fid='".intval($new_fid)."'");
 779                  while($movedthread = $db->fetch_array($query))
 780                  {
 781                      $db->delete_query("threads", "tid='".intval($movedthread['tid'])."'", 1);
 782                  }                
 783                   break;
 784              case "copy":// copy thread
 785  
 786                  $threadarray = array(
 787                      "fid" => $new_fid,
 788                      "subject" => $db->escape_string($thread['subject']),
 789                      "icon" => $thread['icon'],
 790                      "uid" => $thread['uid'],
 791                      "username" => $db->escape_string($thread['username']),
 792                      "dateline" => $thread['dateline'],
 793                      "firstpost" => 0,
 794                      "lastpost" => $thread['lastpost'],
 795                      "lastposteruid" => $thread['lastposteruid'],
 796                      "lastposter" => $db->escape_string($thread['lastposter']),
 797                      "views" => $thread['views'],
 798                      "replies" => $thread['replies'],
 799                      "closed" => $thread['closed'],
 800                      "sticky" => $thread['sticky'],
 801                      "visible" => $thread['visible'],
 802                      "unapprovedposts" => $thread['unapprovedposts'],
 803                      "attachmentcount" => $thread['attachmentcount'],
 804                      "prefix" => $thread['prefix'],
 805                      "notes" => ''
 806                  );
 807  
 808                  if($thread['visible'] == 1)
 809                  {
 810                      ++$num_threads;
 811                      $num_posts = $thread['replies']+1;
 812  
 813                      // Fetch count of unapproved posts in this thread
 814                      $query = $db->simple_select("posts", "COUNT(pid) AS unapproved", "tid='{$thread['tid']}' AND visible=0");
 815                      $num_unapproved_posts = $db->fetch_field($query, "unapproved");
 816  
 817                  }
 818                  else
 819                  {
 820                      $num_unapproved_threads++;
 821                      $num_unapproved_posts = $thread['replies']+1;
 822                  }
 823  
 824                  $arguments = array("tid" => $tid, "new_fid" => $new_fid);
 825                  $plugins->run_hooks("class_moderation_copy_thread", $arguments);
 826                  
 827                  // If the thread has a prefix and the destination forum doesn't accept that prefix, don't copy the prefix
 828                  if($threadarray['prefix'] != 0)
 829                  {
 830                      $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'");
 831                      if($db->fetch_field($query, "num_prefixes") == 0)
 832                      {
 833                          $threadarray['prefix'] = 0;
 834                      }
 835                  }
 836  
 837                  $newtid = $db->insert_query("threads", $threadarray);
 838  
 839                  if($thread['poll'] != 0)
 840                  {
 841                      $query = $db->simple_select("polls", "*", "tid = '{$thread['tid']}'");
 842                      $poll = $db->fetch_array($query);
 843  
 844                      $poll_array = array(
 845                          'tid' => $newtid,
 846                          'question' => $db->escape_string($poll['question']),
 847                          'dateline' => $poll['dateline'],
 848                          'options' => $db->escape_string($poll['options']),
 849                          'votes' => $poll['votes'],
 850                          'numoptions' => $poll['numoptions'],
 851                          'numvotes' => $poll['numvotes'],
 852                          'timeout' => $poll['timeout'],
 853                          'closed' => $poll['closed'],
 854                          'multiple' => $poll['multiple'],
 855                          'public' => $poll['public']
 856                      );
 857                      $new_pid = $db->insert_query("polls", $poll_array);
 858  
 859                      $query = $db->simple_select("pollvotes", "*", "pid = '{$poll['pid']}'");
 860                      while($pollvote = $db->fetch_array($query))
 861                      {
 862                          $pollvote_array = array(
 863                              'pid' => $new_pid,
 864                              'uid' => $pollvote['uid'],
 865                              'voteoption' => $pollvote['voteoption'],
 866                              'dateline' => $pollvote['dateline'],
 867                          );
 868                          $db->insert_query("pollvotes", $pollvote_array);
 869                      }
 870  
 871                      $db->update_query("threads", array('poll' => $new_pid), "tid='{$newtid}'");
 872                  }
 873  
 874                  $query = $db->simple_select("posts", "*", "tid = '{$thread['tid']}'");
 875                  while($post = $db->fetch_array($query))
 876                  {
 877                      $post_array = array(
 878                          'tid' => $newtid,
 879                          'fid' => $new_fid,
 880                          'subject' => $db->escape_string($post['subject']),
 881                          'icon' => $post['icon'],
 882                          'uid' => $post['uid'],
 883                          'username' => $db->escape_string($post['username']),
 884                          'dateline' => $post['dateline'],
 885                          'ipaddress' => $post['ipaddress'],
 886                          'includesig' => $post['includesig'],
 887                          'smilieoff' => $post['smilieoff'],
 888                          'edituid' => $post['edituid'],
 889                          'edittime' => $post['edittime'],
 890                          'visible' => $post['visible'],
 891                          'message' => $db->escape_string($post['message']),
 892                      );
 893                      $pid = $db->insert_query("posts", $post_array);
 894                      
 895                      // Properly set our new firstpost in our new thread
 896                      if($thread['firstpost'] == $post['pid'])
 897                      {
 898                          $db->update_query("threads", array('firstpost' => $pid), "tid='{$newtid}'");
 899                      }
 900  
 901                      // Insert attachments for this post
 902                      $query2 = $db->simple_select("attachments", "*", "pid = '{$post['pid']}'");
 903                      while($attachment = $db->fetch_array($query2))
 904                      {
 905                          $attachment_array = array(
 906                              'pid' => $pid,
 907                              'posthash' => $db->escape_string($attachment['posthash']),
 908                              'uid' => $attachment['uid'],
 909                              'filename' => $db->escape_string($attachment['filename']),
 910                              'filetype' => $attachment['filetype'],
 911                              'filesize' => $attachment['filesize'],
 912                              'attachname' => $attachment['attachname'],
 913                              'downloads' => $attachment['downloads'],
 914                              'visible' => $attachment['visible'],
 915                              'thumbnail' => $attachment['thumbnail']
 916                          );
 917                          $new_aid = $db->insert_query("attachments", $attachment_array);
 918                          
 919                          $post['message'] = str_replace("[attachment={$attachment['aid']}]", "[attachment={$new_aid}]", $post['message']);
 920                      }
 921                      
 922                      if(strpos($post['message'], "[attachment=") !== false)
 923                      {
 924                          $db->update_query("posts", array('message' => $db->escape_string($post['message'])), "pid='{$pid}'");
 925                      }
 926                  }
 927  
 928                  update_thread_data($newtid);
 929  
 930                  $the_thread = $newtid;
 931                  break;
 932              default:
 933              case "move": // plain move thread
 934                  $arguments = array("tid" => $tid, "new_fid" => $new_fid);
 935                  $plugins->run_hooks("class_moderation_move_simple", $arguments);
 936  
 937                  if($thread['visible'] == 1)
 938                  {
 939                      $num_threads++;
 940                      $num_posts = $thread['replies']+1;
 941                  }
 942                  else
 943                  {
 944                      $num_unapproved_threads++;
 945                      // Implied forum unapproved count for unapproved threads
 946                       $num_unapproved_posts = $thread['replies']+1;
 947                  }
 948  
 949                  $num_unapproved_posts = $thread['unapprovedposts'];
 950  
 951                  $sqlarray = array(
 952                      "fid" => $new_fid,
 953                  );
 954                  $db->update_query("threads", $sqlarray, "tid='$tid'");
 955                  $db->update_query("posts", $sqlarray, "tid='$tid'");
 956                  
 957                  // If the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix
 958                  if($thread['prefix'] != 0)
 959                  {
 960                      $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'");
 961                      if($db->fetch_field($query, "num_prefixes") == 0)
 962                      {
 963                          $sqlarray = array(
 964                              "prefix" => 0,
 965                          );
 966                          $db->update_query("threads", $sqlarray, "tid='$tid'");
 967                      }
 968                  }
 969                  
 970                  // If we're moving back to a forum where we left a redirect, delete the rediect
 971                  $query = $db->simple_select("threads", "tid", "closed LIKE 'moved|".intval($tid)."' AND fid='".intval($new_fid)."'");
 972                  while($movedthread = $db->fetch_array($query))
 973                  {
 974                      $db->delete_query("threads", "tid='".intval($movedthread['tid'])."'", 1);
 975                  }
 976                  break;
 977          }
 978  
 979          // Do post count changes if changing between countable and non-countable forums
 980          $query = $db->query("
 981              SELECT COUNT(p.pid) AS posts, u.uid, p.visible
 982              FROM ".TABLE_PREFIX."posts p
 983              LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid)
 984              WHERE tid='$tid'
 985              GROUP BY u.uid, p.visible
 986              ORDER BY posts DESC
 987          ");
 988          while($posters = $db->fetch_array($query))
 989          {
 990              $pcount = "";
 991              if($forum['usepostcounts'] == 1 && $newforum['usepostcounts'] == 0 && $posters['visible'] == 1)
 992              {
 993                  $pcount = "-{$posters['posts']}";
 994              }
 995              else if($forum['usepostcounts'] == 0 && $newforum['userpostcounts'] == 1 && $posters['visible'] == 1)
 996              {
 997                  $pcount = "+{$posters['posts']}";
 998              }
 999              
1000              if(!empty($pcount))
1001              {
1002                  $db->update_query("users", array("postnum" => "postnum{$pcount}"), "uid='{$posters['uid']}'", 1, true);
1003              }
1004          }
1005  
1006          // Update forum counts
1007          $update_array = array(
1008              "threads" => "+{$num_threads}",
1009              "unapprovedthreads" => "+{$num_unapproved_threads}",
1010              "posts" => "+{$num_posts}",
1011              "unapprovedposts" => "+{$num_unapproved_posts}"
1012          );
1013          update_forum_counters($new_fid, $update_array);
1014  
1015          if($method != "copy")
1016          {
1017              $update_array = array(
1018                  "threads" => "-{$num_threads}",
1019                  "unapprovedthreads" => "-{$num_unapproved_threads}",
1020                  "posts" => "-{$num_posts}",
1021                  "unapprovedposts" => "-{$num_unapproved_posts}"
1022              );
1023              update_forum_counters($fid, $update_array);
1024          }
1025  
1026          if(isset($newtid))
1027          {
1028              return $newtid;
1029          }
1030          else
1031          {
1032              // Remove thread subscriptions for the users who no longer have permission to view the thread
1033              $this->remove_thread_subscriptions($tid, false, $new_fid);
1034  
1035              return $tid;
1036          }
1037      }
1038  
1039      /**
1040       * Merge one thread into another
1041       *
1042       * @param int Thread that will be merged into destination
1043       * @param int Destination thread
1044       * @param string New thread subject
1045       * @return boolean true
1046       */
1047  	function merge_threads($mergetid, $tid, $subject)
1048      {
1049          global $db, $mybb, $mergethread, $thread, $plugins;
1050  
1051          $mergetid = intval($mergetid);
1052          $tid = intval($tid);
1053  
1054          if(!isset($mergethread['tid']) || $mergethread['tid'] != $mergetid)
1055          {
1056              $query = $db->simple_select("threads", "*", "tid='{$mergetid}'");
1057              $mergethread = $db->fetch_array($query);
1058          }
1059          if(!isset($thread['tid']) || $thread['tid'] != $tid)
1060          {
1061              $query = $db->simple_select("threads", "*", "tid='{$tid}'");
1062              $thread = $db->fetch_array($query);
1063          }
1064  
1065          $pollsql = '';
1066          if($mergethread['poll'])
1067          {
1068              $pollsql['poll'] = $mergethread['poll'];
1069              $sqlarray = array(
1070                  "tid" => $tid,
1071              );
1072              $db->update_query("polls", $sqlarray, "tid='".intval($mergethread['tid'])."'");
1073          }
1074          else
1075          {
1076              $query = $db->simple_select("threads", "*", "poll='{$mergethread['poll']}' AND tid != '{$mergetid}'");
1077              $pollcheck = $db->fetch_array($query);
1078              if(!$pollcheck['poll'])
1079              {
1080                  $db->delete_query("polls", "pid='{$mergethread['poll']}'");
1081                  $db->delete_query("pollvotes", "pid='{$mergethread['poll']}'");
1082              }
1083          }
1084  
1085          $subject = $db->escape_string($subject);
1086  
1087          $sqlarray = array(
1088              "tid" => $tid,
1089              "fid" => $thread['fid'],
1090              "replyto" => 0,
1091              "visible" => $mergethread['visible'],
1092          );
1093          $db->update_query("posts", $sqlarray, "tid='{$mergetid}'");
1094  
1095          $pollsql['subject'] = $subject;
1096          $db->update_query("threads", $pollsql, "tid='{$tid}'");
1097          $sqlarray = array(
1098              "closed" => "moved|{$tid}",
1099          );
1100          $db->update_query("threads", $sqlarray, "closed='moved|{$mergetid}'");
1101          $sqlarray = array(
1102              "tid" => $tid,
1103          );
1104          $db->update_query("threadsubscriptions", $sqlarray, "tid='{$mergetid}'");
1105          update_first_post($tid);
1106  
1107          $arguments = array("mergetid" => $mergetid, "tid" => $tid, "subject" => $subject);
1108          $plugins->run_hooks("class_moderation_merge_threads", $arguments);
1109  
1110          $this->delete_thread($mergetid);
1111          
1112          // In some cases the thread we may be merging with may cause us to have a new firstpost if it is an older thread
1113          // Therefore resync the visible field to make sure they're the same if they're not
1114          $query = $db->simple_select("posts", "pid, visible", "tid='{$tid}'", array('order_by' => 'dateline', 'order_dir' => 'asc', 'limit' => 1));
1115          $new_firstpost = $db->fetch_array($query);
1116          if($thread['visible'] != $new_firstpost['visible'])
1117          {
1118              $db->update_query("posts", array('visible' => $thread['visible']), "pid='{$new_firstpost['pid']}'");
1119              $mergethread['visible'] = $thread['visible'];
1120          }
1121  
1122          $updated_stats = array(
1123              "replies" => '+'.($mergethread['replies']+1),
1124              "attachmentcount" => "+{$mergethread['attachmentcount']}",
1125              "unapprovedposts" => "+{$mergethread['unapprovedposts']}"
1126          );
1127          update_thread_counters($tid, $updated_stats);
1128  
1129          // Thread is not in current forum
1130          if($mergethread['fid'] != $thread['fid'])
1131          {
1132              // If new thread is unapproved, implied counter comes in to effect
1133              if($thread['visible'] == 0 || $mergethread['visible'] == 0)
1134              {
1135                  $updated_stats = array(
1136                      "unapprovedposts" => '+'.($mergethread['replies']+1+$mergethread['unapprovedposts'])
1137                  );
1138              }
1139              else
1140              {
1141                  $updated_stats = array(
1142                      "posts" => '+'.($mergethread['replies']+1),
1143                      "unapprovedposts" => "+{$mergethread['unapprovedposts']}"
1144                  );
1145              }
1146              update_forum_counters($thread['fid'], $updated_stats);
1147              
1148              // If old thread is unapproved, implied counter comes in to effect
1149              if($mergethread['visible'] == 0)
1150              {
1151                  $updated_stats = array(
1152                      "unapprovedposts" => '-'.($mergethread['replies']+1+$mergethread['unapprovedposts'])
1153                  );
1154              }
1155              else
1156              {
1157                  $updated_stats = array(
1158                      "posts" => '-'.($mergethread['replies']+1),
1159                      "unapprovedposts" => "-{$mergethread['unapprovedposts']}"
1160                  );
1161              }
1162              update_forum_counters($mergethread['fid'], $updated_stats);
1163          }
1164          // If we're in the same forum we need to at least update the last post information
1165          else
1166          {
1167              update_forum_lastpost($thread['fid']);
1168          }
1169          return true;
1170      }
1171  
1172      /**
1173       * Split posts into a new/existing thread
1174       *
1175       * @param array PIDs of posts to split
1176       * @param int Original thread ID (this is only used as a base for the new
1177       * thread; it can be set to 0 when the posts specified are coming from more
1178       * than 1 thread)
1179       * @param int Destination forum
1180       * @param string New thread subject
1181       * @param int TID if moving into existing thread
1182       * @return int New thread ID
1183       */
1184  	function split_posts($pids, $tid, $moveto, $newsubject, $destination_tid=0)
1185      {
1186          global $db, $thread, $plugins;
1187  
1188          $tid = intval($tid);
1189          $moveto = intval($moveto);
1190          $newtid = intval($destination_tid);
1191          
1192          // Get forum infos
1193          $query = $db->simple_select("forums", "fid, usepostcounts, posts, threads, unapprovedposts, unapprovedthreads");
1194          while($forum = $db->fetch_array($query))
1195          {
1196              $forum_cache[$forum['fid']] = $forum;
1197          }
1198  
1199          // Make sure we only have valid values
1200          $pids = array_map('intval', $pids);
1201  
1202          $pids_list = implode(',', $pids);
1203  
1204          // Get the icon for the first split post
1205          $query = $db->simple_select("posts", "icon", "pid=".intval($pids[0]));
1206          $icon = $db->fetch_array($query);
1207  
1208          if($destination_tid == 0)
1209          {
1210              // Splitting into a new thread
1211              $thread = get_thread($tid);
1212              // Create the new thread
1213              $newsubject = $db->escape_string($newsubject);
1214              $query = array(
1215                  "fid" => $moveto,
1216                  "subject" => $newsubject,
1217                  "icon" => intval($icon['icon']),
1218                  "uid" => intval($thread['uid']),
1219                  "username" => $db->escape_string($thread['username']),
1220                  "dateline" => intval($thread['dateline']),
1221                  "lastpost" => intval($thread['lastpost']),
1222                  "lastposter" => $db->escape_string($thread['lastposter']),
1223                  "replies" => count($pids)-1,
1224                  "visible" => 1,
1225                  "notes" => ''
1226              );
1227              $newtid = $db->insert_query("threads", $query);
1228              
1229              $forum_counters[$moveto]['threads'] = $forum_cache[$moveto]['threads'];
1230              ++$forum_counters[$moveto]['threads'];
1231          }
1232  
1233          // Get attachment counts for each post
1234          /*$query = $db->simple_select("attachments", "COUNT(aid) as count, pid", "pid IN ($pids_list)");
1235          $query = $db->query("
1236              SELECT COUNT(aid) as count, p.pid,
1237              ");
1238          $attachment_sum = 0;
1239          while($attachment = $db->fetch_array($query))
1240          {
1241              $attachments[$attachment['pid']] = $attachment['count'];
1242              $attachment_sum += $attachment['count'];
1243          }
1244          $thread_counters[$newtid]['attachmentcount'] = '+'.$attachment_sum;*/
1245  
1246          // Get selected posts before moving forums to keep old fid
1247          //$original_posts_query = $db->simple_select("posts", "fid, visible, pid", "pid IN ($pids_list)");
1248          $original_posts_query = $db->query("
1249              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
1250              FROM ".TABLE_PREFIX."posts p
1251              LEFT JOIN ".TABLE_PREFIX."threads t ON (p.tid=t.tid)
1252              LEFT JOIN ".TABLE_PREFIX."attachments a ON (a.pid=p.pid)
1253              WHERE p.pid IN ($pids_list)
1254              GROUP BY p.pid, p.tid, p.fid, p.visible, p.uid, t.visible, t.replies, t.unapprovedposts,t.attachmentcount
1255          ");
1256  
1257          // Move the selected posts over
1258          $sqlarray = array(
1259              "tid" => $newtid,
1260              "fid" => $moveto,
1261              "replyto" => 0
1262          );
1263          $db->update_query("posts", $sqlarray, "pid IN ($pids_list)");
1264  
1265          // Get posts being merged
1266          while($post = $db->fetch_array($original_posts_query))
1267          {
1268              if($post['visible'] == 1)
1269              {
1270                  // Modify users' post counts
1271                  if($forum_cache[$post['fid']]['usepostcounts'] == 1 && $forum_cache[$moveto]['usepostcounts'] == 0)
1272                  {
1273                      // Moving into a forum that doesn't count post counts
1274                      if(!isset($user_counters[$post['uid']]))
1275                      {
1276                          $user_counters[$post['uid']] = 0;
1277                      }
1278                      --$user_counters[$post['uid']];
1279                  }
1280                  elseif($forum_cache[$post['fid']]['usepostcounts'] == 0 && $forum_cache[$moveto]['usepostcounts'] == 1)
1281                  {
1282                      // Moving into a forum that does count post counts
1283                      if(!isset($user_counters[$post['uid']]))
1284                      {
1285                          $user_counters[$post['uid']] = 0;
1286                      }
1287                      ++$user_counters[$post['uid']];
1288                  }
1289  
1290                  // Subtract 1 from the old thread's replies
1291                  if(!isset($thread_counters[$post['tid']]['replies']))
1292                  {
1293                      $thread_counters[$post['tid']]['replies'] = $post['threadreplies'];
1294                  }
1295                  --$thread_counters[$post['tid']]['replies'];
1296  
1297                  // Add 1 to the new thread's replies
1298                  ++$thread_counters[$newtid]['replies'];
1299  
1300                  if($moveto != $post['fid'])
1301                  {
1302                      // Only need to change forum info if the old forum is different from new forum
1303                      // Subtract 1 from the old forum's posts
1304                      if(!isset($forum_counters[$post['fid']]['posts']))
1305                      {
1306                          $forum_counters[$post['fid']]['posts'] = $forum_cache[$post['fid']]['posts'];
1307                      }
1308                      --$forum_counters[$post['fid']]['posts'];
1309                      // Add 1 to the new forum's posts
1310                      if(!isset($forum_counters[$moveto]['posts']))
1311                      {
1312                          $forum_counters[$moveto]['posts'] = $forum_cache[$moveto]['posts'];
1313                      }
1314                      ++$forum_counters[$moveto]['posts'];
1315                  }
1316  
1317              }
1318              elseif($post['visible'] == 0)
1319              {
1320                  // Unapproved post
1321                  // Subtract 1 from the old thread's unapproved posts
1322                  if(!isset($thread_counters[$post['tid']]['unapprovedposts']))
1323                  {
1324                      $thread_counters[$post['tid']]['unapprovedposts'] = $post['threadunapprovedposts'];
1325                  }
1326                  --$thread_counters[$post['tid']]['unapprovedposts'];
1327  
1328                  // Add 1 to the new thread's unapproved posts
1329                  ++$thread_counters[$newtid]['unapprovedposts'];
1330  
1331                  if($moveto != $post['fid'])
1332                  {
1333                      // Only need to change forum info if the old forum is different from new forum
1334                      // Subtract 1 from the old forum's unapproved posts
1335                      if(!isset($forum_counters[$post['fid']]['unapprovedposts']))
1336                      {
1337                          $forum_counters[$post['fid']]['unapprovedposts'] = $forum_cache[$post['fid']]['unapprovedposts'];
1338                      }
1339                      --$forum_counters[$post['fid']]['posts'];
1340                      // Add 1 to the new forum's unapproved posts
1341                      if(!isset($forum_counters[$moveto]['unapprovedposts']))
1342                      {
1343                          $forum_counters[$moveto]['unapprovedposts'] = $forum_cache[$moveto]['unapprovedposts'];
1344                      }
1345                      ++$forum_counters[$moveto]['unapprovedposts'];
1346                  }
1347              }
1348  
1349              // Subtract attachment counts from old thread and add to new thread (which are counted regardless of post or attachment unapproval at time of coding)
1350              if(!isset($thread_counters[$post['tid']]['attachmentcount']))
1351              {
1352                  $thread_counters[$post['tid']]['attachmentcount'] = $post['threadattachmentcount'];
1353              }
1354              $thread_counters[$post['tid']]['attachmentcount'] -= $post['postattachmentcount'];
1355              $thread_counters[$newtid]['attachmentcount'] += $post['postattachmentcount'];
1356          }
1357          if($destination_tid == 0 && $thread_counters[$newtid]['replies'] > 0)
1358          {
1359              // If splitting into a new thread, subtract one from the thread's reply count to compensate for the original post
1360              --$thread_counters[$newtid]['replies'];
1361          }
1362  
1363          $arguments = array("pids" => $pids, "tid" => $tid, "moveto" => $moveto, "newsubject" => $newsubject, "destination_tid" => $destination_tid);
1364          $plugins->run_hooks("class_moderation_split_posts", $arguments);
1365  
1366          // Update user post counts
1367          if(is_array($user_counters))
1368          {
1369              foreach($user_counters as $uid => $change)
1370              {
1371                  if($change >= 0)
1372                  {
1373                      $change = '+'.$change; // add the addition operator for query
1374                  }
1375                  $db->update_query("users", array("postnum" => "postnum{$change}"), "uid='{$uid}'", 1, true);
1376              }
1377          }
1378  
1379          // Update thread counters
1380          if(is_array($thread_counters))
1381          {
1382              foreach($thread_counters as $tid => $counters)
1383              {
1384                  if($tid == $newtid)
1385                  {
1386                      // Update the subject of the first post in the new thread
1387                      $query = $db->simple_select("posts", "pid", "tid='$newtid'", array('order_by' => 'dateline', 'limit' => 1));
1388                      $newthread = $db->fetch_array($query);
1389                      $sqlarray = array(
1390                          "subject" => $newsubject,
1391                          "replyto" => 0
1392                      );
1393                      $db->update_query("posts", $sqlarray, "pid='{$newthread['pid']}'");
1394                  }
1395                  else
1396                  {
1397                      // Update the subject of the first post in the old thread
1398                      $query = $db->query("
1399                          SELECT p.pid, t.subject
1400                          FROM ".TABLE_PREFIX."posts p
1401                          LEFT JOIN ".TABLE_PREFIX."threads t ON (p.tid=t.tid)
1402                          WHERE p.tid='{$tid}'
1403                          ORDER BY p.dateline ASC
1404                          LIMIT 1
1405                      ");
1406                      $oldthread = $db->fetch_array($query);
1407                      $sqlarray = array(
1408                          "subject" => $db->escape_string($oldthread['subject']),
1409                          "replyto" => 0
1410                      );
1411                      $db->update_query("posts", $sqlarray, "pid='{$oldthread['pid']}'");
1412                  }
1413  
1414                  $db->update_query("threads", $counters, "tid='{$tid}'");
1415  
1416                  update_thread_data($tid);
1417  
1418                  // Update first post columns
1419                  update_first_post($tid);
1420              }
1421          }
1422          update_thread_data($newtid);
1423          
1424          update_first_post($newtid);
1425  
1426          // Update forum counters
1427          if(is_array($forum_counters))
1428          {
1429              foreach($forum_counters as $fid => $counters)
1430              {
1431                  update_forum_counters($fid, $counters);
1432              }
1433          }
1434  
1435          return $newtid;
1436      }
1437  
1438      /**
1439       * Move multiple threads to new forum
1440       *
1441       * @param array Thread IDs
1442       * @param int Destination forum
1443       * @return boolean true
1444       */
1445  	function move_threads($tids, $moveto)
1446      {
1447          global $db, $plugins;
1448  
1449          // Make sure we only have valid values
1450          $tids = array_map('intval', $tids);
1451  
1452          $tid_list = implode(',', $tids);
1453  
1454          $moveto = intval($moveto);
1455  
1456          $newforum = get_forum($moveto);
1457  
1458          $total_posts = $total_unapproved_posts = $total_threads = $total_unapproved_threads = 0;
1459          $query = $db->simple_select("threads", "fid, visible, replies, unapprovedposts, tid", "tid IN ($tid_list)");
1460          while($thread = $db->fetch_array($query))
1461          {
1462              $forum = get_forum($thread['fid']);
1463  
1464              $total_posts += $thread['replies']+1;
1465              $total_unapproved_posts += $thread['unapprovedposts'];
1466  
1467              $forum_counters[$thread['fid']]['posts'] += $thread['replies']+1;
1468              $forum_counters[$thread['fid']]['unapprovedposts'] += $thread['unapprovedposts'];
1469  
1470              if($thread['visible'] == 1)
1471              {
1472                  $forum_counters[$thread['fid']]['threads']++;
1473                  ++$total_threads;
1474              }
1475              else
1476              {
1477                  $forum_counters[$thread['fid']]['unapprovedthreads']++;
1478                  $forum_counters[$thread['fid']]['unapprovedposts'] += $thread['replies']; // Implied unapproved posts counter for unapproved threads
1479                  ++$total_unapproved_threads;
1480              }
1481  
1482              $query1 = $db->query("
1483                  SELECT COUNT(p.pid) AS posts, u.uid
1484                  FROM ".TABLE_PREFIX."posts p
1485                  LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid)
1486                  WHERE tid='{$thread['tid']}'
1487                  GROUP BY u.uid
1488                  ORDER BY posts DESC
1489              ");
1490              while($posters = $db->fetch_array($query1))
1491              {
1492                  $pcount = "";
1493                  if($newforum['usepostcounts'] != 0 && $forum['usepostcounts'] == 0 && $posters['visible'] != 0)
1494                  {
1495                      $pcount = "+{$posters['posts']}";
1496                  }
1497                  else if($newforum['usepostcounts'] == 0 && $forum['usepostcounts'] != 0 && $posters['visible'] != 0)
1498                  {
1499                      $pcount = "-{$posters['posts']}";
1500                  }
1501  
1502                  if(!empty($pcount))
1503                  {
1504                      $db->update_query("users", array("postnum" => "postnum{$pcount}"), "uid='{$posters['uid']}'", 1, true);
1505                  }
1506              }
1507          }
1508  
1509          $sqlarray = array(
1510              "fid" => $moveto,
1511          );
1512          $db->update_query("threads", $sqlarray, "tid IN ($tid_list)");
1513          $db->update_query("posts", $sqlarray, "tid IN ($tid_list)");
1514          
1515          // If any of the thread has a prefix and the destination forum doesn't accept that prefix, remove the prefix
1516          $query = $db->simple_select("threads", "tid, prefix", "tid IN ($tid_list) AND prefix != 0");
1517          while($thread = $db->fetch_array($query))
1518          {
1519              $query = $db->simple_select("threadprefixes", "COUNT(*) as num_prefixes", "(CONCAT(',',forums,',') LIKE '%,$new_fid,%' OR forums='-1') AND pid='".$thread['prefix']."'");
1520              if($db->fetch_field($query, "num_prefixes") == 0)
1521              {
1522                  $sqlarray = array(
1523                      "prefix" => 0,
1524                  );
1525                  $db->update_query("threads", $sqlarray, "tid = '{$thread['tid']}'");
1526              }
1527          }
1528  
1529          $arguments = array("tids" => $tids, "moveto" => $moveto);
1530          $plugins->run_hooks("class_moderation_move_threads", $arguments);
1531          
1532          if(is_array($forum_counters))
1533          {
1534              foreach($forum_counters as $fid => $counter)
1535              {
1536                  $updated_count = array(
1537                      "posts" => "-{$counter['posts']}",
1538                      "unapprovedposts" => "-{$counter['unapprovedposts']}"
1539                  );
1540                  if($counter['threads'])
1541                  {
1542                      $updated_count['threads'] = "-{$counter['threads']}";
1543                  }
1544                  if($counter['unapprovedthreads'])
1545                  {
1546                      $updated_count['unapprovedthreads'] = "-{$counter['unapprovedthreads']}";
1547                  }
1548                  update_forum_counters($fid, $updated_count);
1549              }
1550          }
1551  
1552          $updated_count = array(
1553              "threads" => "+{$total_threads}",
1554              "unapprovedthreads" => "+{$total_unapproved_threads}",
1555              "posts" => "+{$total_posts}",
1556              "unapprovedposts" => "+{$total_unapproved_posts}"
1557          );
1558  
1559          update_forum_counters($moveto, $updated_count);
1560  
1561          // Remove thread subscriptions for the users who no longer have permission to view the thread
1562          $this->remove_thread_subscriptions($tid_list, false, $moveto);
1563  
1564          return true;
1565      }
1566  
1567      /**
1568       * Approve multiple posts
1569       *
1570       * @param array PIDs
1571       * @return boolean true
1572       */
1573  	function approve_posts($pids)
1574      {
1575          global $db, $cache;
1576  
1577          $num_posts = 0;
1578  
1579          // Make sure we only have valid values
1580          $pids = array_map('intval', $pids);
1581  
1582          $pid_list = implode(',', $pids);
1583          $pids = $threads_to_update = array();
1584  
1585          // Make visible
1586          $approve = array(
1587              "visible" => 1,
1588          );
1589  
1590          // We have three cases we deal with in these code segments:
1591          // 1) We're approving specific unapproved posts
1592          // 1.1) if the thread is approved
1593          // 1.2) if the thread is unapproved
1594          // 2) We're approving the firstpost of the thread, therefore approving the thread itself
1595          // 3) We're doing both 1 and 2
1596          $query = $db->query("
1597              SELECT p.tid
1598              FROM ".TABLE_PREFIX."posts p
1599              LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
1600              WHERE p.pid IN ($pid_list) AND p.visible = '0' AND t.firstpost = p.pid AND t.visible = 0
1601          ");
1602          while($post = $db->fetch_array($query))
1603          {
1604              // This is the first post in the thread so we're approving the whole thread.
1605              $threads_to_update[] = $post['tid'];
1606          }
1607          
1608          if(!empty($threads_to_update))
1609          {
1610              $this->approve_threads($threads_to_update);
1611          }
1612          
1613          $query = $db->query("
1614              SELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, t.visible AS threadvisible
1615              FROM ".TABLE_PREFIX."posts p
1616              LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
1617              LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid)
1618              WHERE p.pid IN ($pid_list) AND p.visible = '0' AND t.firstpost != p.pid
1619          ");
1620          while($post = $db->fetch_array($query))
1621          {
1622              $pids[] = $post['pid'];
1623              
1624              ++$thread_counters[$post['tid']]['unapprovedposts'];
1625              ++$thread_counters[$post['tid']]['replies'];
1626              
1627              // If the thread of this post is unapproved then we've already taken into account this counter as implied.
1628              // Updating it again would cause it to double count
1629              if($post['threadvisible'] != 0)
1630              {
1631                  ++$forum_counters[$post['fid']]['num_posts'];
1632              }
1633              
1634              // If post counts enabled in this forum and the thread is approved, add 1
1635              if($post['usepostcounts'] != 0 && $post['threadvisible'] == 1)
1636              {
1637                  $db->update_query("users", array("postnum" => "postnum+1"), "uid='{$post['uid']}'", 1, true);
1638              }
1639          }
1640          
1641          if(empty($pids) && empty($threads_to_update))
1642          {
1643              return false;
1644          }
1645  
1646          if(!empty($pids))
1647          {
1648              $where = "pid IN (".implode(',', $pids).")";
1649              $db->update_query("posts", $approve, $where);
1650          }
1651          
1652          if(is_array($thread_counters))
1653          {
1654              foreach($thread_counters as $tid => $counters)
1655              {
1656                  $counters_update = array(
1657                      "unapprovedposts" => "-".$counters['unapprovedposts'],
1658                      "replies" => "+".$counters['replies']
1659                  );
1660                  update_thread_counters($tid, $counters_update);
1661  
1662                  update_thread_data($tid);
1663              }
1664          }
1665          
1666          if(is_array($forum_counters))
1667          {
1668              foreach($forum_counters as $fid => $counters)
1669              {
1670                  $updated_forum_stats = array(
1671                      "posts" => "+{$counters['num_posts']}",
1672                      "unapprovedposts" => "-{$counters['num_posts']}",
1673                      "threads" => "+{$counters['num_threads']}",
1674                      "unapprovedthreads" => "-{$counters['num_threads']}"
1675                  );
1676                  update_forum_counters($fid, $updated_forum_stats);
1677              }
1678          }
1679          
1680          return true;
1681      }
1682  
1683      /**
1684       * Unapprove multiple posts
1685       *
1686       * @param array PIDs
1687       * @return boolean true
1688       */
1689  	function unapprove_posts($pids)
1690      {
1691          global $db, $cache;
1692  
1693          // Make sure we only have valid values
1694          $pids = array_map('intval', $pids);
1695  
1696          $pid_list = implode(',', $pids);
1697          $pids = $threads_to_update = array();
1698  
1699          // Make invisible
1700          $approve = array(
1701              "visible" => 0,
1702          );
1703          
1704          // We have three cases we deal with in these code segments:
1705          // 1) We're unapproving specific approved posts
1706          // 1.1) if the thread is approved
1707          // 1.2) if the thread is unapproved
1708          // 2) We're unapproving the firstpost of the thread, therefore unapproving the thread itself
1709          // 3) We're doing both 1 and 2
1710          $query = $db->query("
1711              SELECT p.tid
1712              FROM ".TABLE_PREFIX."posts p
1713              LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
1714              WHERE p.pid IN ($pid_list) AND p.visible = '1' AND t.firstpost = p.pid AND t.visible = 1
1715          ");
1716          while($post = $db->fetch_array($query))
1717          {
1718              // This is the first post in the thread so we're unapproving the whole thread.
1719              $threads_to_update[] = $post['tid'];
1720          }
1721          
1722          if(!empty($threads_to_update))
1723          {
1724              $this->unapprove_threads($threads_to_update);
1725          }
1726          
1727          $thread_counters = array();
1728          $forum_counters = array();
1729          
1730          $query = $db->query("
1731              SELECT p.pid, p.tid, f.fid, f.usepostcounts, p.uid, t.visible AS threadvisible
1732              FROM ".TABLE_PREFIX."posts p
1733              LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
1734              LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid)
1735              WHERE p.pid IN ($pid_list) AND p.visible = '1' AND t.firstpost != p.pid
1736          ");
1737          while($post = $db->fetch_array($query))
1738          {
1739              $pids[] = $post['pid'];
1740              
1741              ++$thread_counters[$post['tid']]['unapprovedposts'];
1742              ++$thread_counters[$post['tid']]['replies'];
1743              
1744              // If the thread of this post is unapproved then we've already taken into account this counter as implied.
1745              // Updating it again would cause it to double count
1746              if($post['threadvisible'] != 0)
1747              {
1748                  ++$forum_counters[$post['fid']]['num_posts'];
1749              }
1750              
1751              // If post counts enabled in this forum and the thread is approved, subtract 1
1752              if($post['usepostcounts'] != 0 && $post['threadvisible'] == 1)
1753              {
1754                  $db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true);
1755              }
1756          }
1757          
1758          if(empty($pids) && empty($threads_to_update))
1759          {
1760              return false;
1761          }
1762  
1763          if(!empty($pids))
1764          {
1765              $where = "pid IN (".implode(',', $pids).")";
1766              $db->update_query("posts", $approve, $where);
1767          }
1768          
1769          if(is_array($thread_counters))
1770          {
1771              foreach($thread_counters as $tid => $counters)
1772              {
1773                  $counters_update = array(
1774                      "unapprovedposts" => "+".$counters['unapprovedposts'],
1775                      "replies" => "-".$counters['replies']
1776                  );
1777                  
1778                  update_thread_counters($tid, $counters_update);
1779  
1780                  update_thread_data($tid);
1781              }
1782          }
1783  
1784          if(is_array($forum_counters))
1785          {
1786              foreach($forum_counters as $fid => $counters)
1787              {
1788                  $updated_forum_stats = array(
1789                      "posts" => "-{$counters['num_posts']}",
1790                      "unapprovedposts" => "+{$counters['num_posts']}",
1791                      "threads" => "-{$counters['num_threads']}",
1792                      "unapprovedthreads" => "+{$counters['num_threads']}"
1793                  );
1794                  
1795                  update_forum_counters($fid, $updated_forum_stats);
1796              }
1797          }
1798          
1799          return true;
1800      }
1801  
1802      /**
1803       * Change thread subject
1804       *
1805       * @param mixed Thread ID(s)
1806       * @param string Format of new subject (with {subject})
1807       * @return boolean true
1808       */
1809  	function change_thread_subject($tids, $format)
1810      {
1811          global $db, $mybb, $plugins;
1812  
1813          // Get tids into list
1814          if(!is_array($tids))
1815          {
1816              $tids = array(intval($tids));
1817          }
1818  
1819  
1820          // Make sure we only have valid values
1821          $tids = array_map('intval', $tids);
1822  
1823          $tid_list = implode(',', $tids);
1824  
1825          // Get original subject
1826          $query = $db->simple_select("threads", "subject, tid", "tid IN ($tid_list)");
1827          while($thread = $db->fetch_array($query))
1828          {
1829              // Update threads and first posts with new subject
1830              $subject = str_replace('{username}', $mybb->user['username'], $format);
1831              $subject = str_replace('{subject}', $thread['subject'], $subject);
1832              $new_subject = array(
1833                  "subject" => $db->escape_string($subject)
1834              );
1835              $db->update_query("threads", $new_subject, "tid='{$thread['tid']}'", 1);
1836              $db->update_query("posts", $new_subject, "tid='{$thread['tid']}' AND replyto='0'", 1);
1837          }
1838  
1839          $arguments = array("tids" => $tids, "format" => $format);
1840          $plugins->run_hooks("class_moderation_change_thread_subject", $arguments);
1841  
1842          return true;
1843      }
1844  
1845      /**
1846       * Add thread expiry
1847       *
1848       * @param int Thread ID
1849       * @param int Timestamp when the thread is deleted
1850       * @return boolean true
1851       */
1852  	function expire_thread($tid, $deletetime)
1853      {
1854          global $db, $plugins;
1855  
1856          $tid = intval($tid);
1857  
1858          $update_thread = array(
1859              "deletetime" => intval($deletetime)
1860          );
1861          $db->update_query("threads", $update_thread, "tid='{$tid}'");
1862  
1863          $arguments = array("tid" => $tid, "deletetime" => $deletetime);
1864          $plugins->run_hooks("class_moderation_expire_thread", $arguments);
1865  
1866          return true;
1867      }
1868  
1869      /**
1870       * Toggle post visibility (approved/unapproved)
1871       *
1872       * @param array Post IDs
1873       * @param int Thread ID
1874       * @param int Forum ID
1875       * @return boolean true
1876       */
1877  	function toggle_post_visibility($pids)
1878      {
1879          global $db;
1880  
1881          // Make sure we only have valid values
1882          $pids = array_map('intval', $pids);
1883  
1884          $pid_list = implode(',', $pids);
1885          $query = $db->simple_select("posts", 'pid, visible', "pid IN ($pid_list)");
1886          while($post = $db->fetch_array($query))
1887          {
1888              if($post['visible'] == 1)
1889              {
1890                  $unapprove[] = $post['pid'];
1891              }
1892              else
1893              {
1894                  $approve[] = $post['pid'];
1895              }
1896          }
1897          if(is_array($unapprove))
1898          {
1899              $this->unapprove_posts($unapprove);
1900          }
1901          if(is_array($approve))
1902          {
1903              $this->approve_posts($approve);
1904          }
1905          return true;
1906      }
1907  
1908      /**
1909       * Toggle thread visibility (approved/unapproved)
1910       *
1911       * @param array Thread IDs
1912       * @param int Forum ID
1913       * @return boolean true
1914       */
1915  	function toggle_thread_visibility($tids, $fid)
1916      {
1917          global $db;
1918  
1919          // Make sure we only have valid values
1920          $tids = array_map('intval', $tids);
1921          $fid = intval($fid);
1922  
1923          $tid_list = implode(',', $tids);
1924          $query = $db->simple_select("threads", 'tid, visible', "tid IN ($tid_list)");
1925          while($thread = $db->fetch_array($query))
1926          {
1927              if($thread['visible'] == 1)
1928              {
1929                  $unapprove[] = $thread['tid'];
1930              }
1931              else
1932              {
1933                  $approve[] = $thread['tid'];
1934              }
1935          }
1936          if(is_array($unapprove))
1937          {
1938              $this->unapprove_threads($unapprove, $fid);
1939          }
1940          if(is_array($approve))
1941          {
1942              $this->approve_threads($approve, $fid);
1943          }
1944          return true;
1945      }
1946  
1947      /**
1948       * Toggle threads open/closed
1949       *
1950       * @param array Thread IDs
1951       * @return boolean true
1952       */
1953  	function toggle_thread_status($tids)
1954      {
1955          global $db;
1956  
1957          // Make sure we only have valid values
1958          $tids = array_map('intval', $tids);
1959  
1960          $tid_list = implode(',', $tids);
1961          $query = $db->simple_select("threads", 'tid, closed', "tid IN ($tid_list)");
1962          while($thread = $db->fetch_array($query))
1963          {
1964              if($thread['closed'] == 1)
1965              {
1966                  $open[] = $thread['tid'];
1967              }
1968              elseif($thread['closed'] == 0)
1969              {
1970                  $close[] = $thread['tid'];
1971              }
1972          }
1973          if(is_array($open))
1974          {
1975              $this->open_threads($open);
1976          }
1977          if(is_array($close))
1978          {
1979              $this->close_threads($close);
1980          }
1981          return true;
1982      }
1983  
1984      /**
1985       * Remove thread subscriptions (from one or multiple threads in the same forum)
1986       *
1987       * @param int $tids Thread ID, or an array of thread IDs from the same forum.
1988       * @param boolean $all True (default) to delete all subscriptions, false to only delete subscriptions from users with no permission to read the thread
1989       * @param int $fid (Only applies if $all is false) The forum ID of the thread
1990       * @return boolean true
1991       */
1992  	function remove_thread_subscriptions($tids, $all = true, $fid = 0)
1993      {
1994          global $db, $plugins;
1995  
1996          // Format thread IDs
1997          if(!is_array($tids))
1998          {
1999              $tids = array($tids);
2000          }
2001  
2002          // Make sure we only have valid values
2003          $tids = array_map('intval', $tids);
2004          $fid = intval($fid);
2005  
2006          $tids_csv = implode(',', $tids);
2007  
2008          // Delete only subscriptions from users who no longer have permission to read the thread.
2009          if(!$all)
2010          {
2011              // Get groups that cannot view the forum or its threads
2012              $forum_parentlist = get_parent_list($fid);
2013              $query = $db->simple_select("forumpermissions", "gid", "fid IN ({$forum_parentlist}) AND (canview=0 OR canviewthreads=0)");
2014              $groups = array();
2015              while($group = $db->fetch_array($query))
2016              {
2017                  $groups[] = $group['gid'];
2018                  switch($db->type)
2019                  {
2020                      case "pgsql":
2021                      case "sqlite":
2022                          $additional_groups .= " OR ','||u.additionalgroups||',' LIKE ',{$group['gid']},'";
2023                          break;
2024                      default:
2025                          $additional_groups .= " OR CONCAT(',',u.additionalgroups,',') LIKE ',{$group['gid']},'";
2026                  }
2027              }
2028              // If there are groups found, delete subscriptions from users in these groups
2029              if(count($groups) > 0)
2030              {
2031                  $groups_csv = implode(',', $groups);
2032                  $query = $db->query("
2033                      SELECT s.tid, u.uid
2034                      FROM ".TABLE_PREFIX."threadsubscriptions s
2035                      LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=s.uid)
2036                      WHERE s.tid IN ({$tids_csv})
2037                      AND (u.usergroup IN ({$groups_csv}){$additional_groups})
2038                  ");
2039                  while($subscription = $db->fetch_array($query))
2040                  {
2041                      $db->delete_query("threadsubscriptions", "uid='{$subscription['uid']}' AND tid='{$subscription['tid']}'");
2042                  }
2043              }
2044          }
2045          // Delete all subscriptions of this thread
2046          else
2047          {
2048              $db->delete_query("threadsubscriptions", "tid IN ({$tids_csv})");
2049          }
2050      
2051          $arguments = array("tids" => $tids, "all" => $all, "fid" => $fid);
2052          $plugins->run_hooks("class_moderation_remove_thread_subscriptions", $arguments);
2053  
2054          return true;
2055      }
2056      
2057      /**
2058       * Apply a thread prefix (to one or multiple threads in the same forum)
2059       * 
2060       * @param int $tids Thread ID, or an array of thread IDs from the same forum.
2061       * @param int $prefix Prefix ID to apply to the threads
2062       */
2063  	function apply_thread_prefix($tids, $prefix = 0)
2064      {
2065          global $db, $plugins;
2066          
2067          // Format thread IDs
2068          if(!is_array($tids))
2069          {
2070              $tids = array($tids);
2071          }
2072  
2073          // Make sure we only have valid values
2074          $tids = array_map('intval', $tids);
2075          $tids_csv = implode(',', $tids);
2076          
2077          $update_thread = array('prefix' => $prefix);
2078          $db->update_query('threads', $update_thread, "tid IN ({$tids_csv})");
2079          
2080          $arguments = array('tids' => $tids, 'prefix' => $prefix);
2081          
2082          $plugins->run_hooks('class_moderation_apply_thread_prefix', $arguments);
2083          
2084          return true;
2085      }
2086  }
2087  ?>


Generated: Tue Aug 3 20:35:36 2010 Cross-referenced by PHPXref 0.7