[ Index ]

PHP Cross Reference of MyBB 1.6.5

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 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  ?>


Generated: Sun Dec 11 14:16:27 2011 Cross-referenced by PHPXref 0.7.1