[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/datahandlers/ -> post.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$
  10   */
  11  
  12  // Disallow direct access to this file for security reasons
  13  if(!defined("IN_MYBB"))
  14  {
  15      die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
  16  }
  17  
  18  /*
  19  EXAMPLE USE:
  20  
  21  $post = get from POST data
  22  $thread = get from DB using POST data id
  23  
  24  $postHandler = new postDataHandler();
  25  if($postHandler->validate_post($post))
  26  {
  27      $postHandler->insert_post($post);
  28  }
  29  
  30  */
  31  
  32  /**
  33   * Post handling class, provides common structure to handle post data.
  34   *
  35   */
  36  class PostDataHandler extends DataHandler
  37  {
  38      /**
  39      * The language file used in the data handler.
  40      *
  41      * @var string
  42      */
  43      public $language_file = 'datahandler_post';
  44  
  45      /**
  46      * The prefix for the language variables used in the data handler.
  47      *
  48      * @var string
  49      */
  50      public $language_prefix = 'postdata';
  51  
  52      /**
  53       * What are we performing?
  54       * post = New post
  55       * thread = New thread
  56       * edit = Editing a thread or post
  57       */
  58      public $action;
  59  
  60      /**
  61       * Array of data inserted in to a post.
  62       *
  63       * @var array
  64       */
  65      public $post_insert_data = array();
  66  
  67      /**
  68       * Array of data used to update a post.
  69       *
  70       * @var array
  71       */
  72      public $post_update_data = array();
  73  
  74      /**
  75       * Post ID currently being manipulated by the datahandlers.
  76       *
  77       * @var int
  78       */
  79      public $pid = 0;
  80  
  81      /**
  82       * Array of data inserted in to a thread.
  83       *
  84       * @var array
  85       */
  86      public $thread_insert_data = array();
  87  
  88      /**
  89       * Array of data used to update a thread.
  90       *
  91       * @var array
  92       */
  93      public $thread_update_data = array();
  94  
  95      /**
  96       * Thread ID currently being manipulated by the datahandlers.
  97       *
  98       * @var int
  99       */
 100      public $tid = 0;
 101  
 102      /**
 103       * Verifies the author of a post and fetches the username if necessary.
 104       *
 105       * @return boolean True if the author information is valid, false if invalid.
 106       */
 107  	function verify_author()
 108      {
 109          global $mybb;
 110  
 111          $post = &$this->data;
 112  
 113          // Don't have a user ID at all - not good (note, a user id of 0 will still work).
 114          if(!isset($post['uid']))
 115          {
 116              $this->set_error("invalid_user_id");
 117              return false;
 118          }
 119          // If we have a user id but no username then fetch the username.
 120          else if($post['uid'] > 0 && $post['username'] == '')
 121          {
 122              $user = get_user($post['uid']);
 123              $post['username'] = $user['username'];
 124          }
 125  
 126          // After all of this, if we still don't have a username, force the username as "Guest" (Note, this is not translatable as it is always a fallback)
 127          if(!$post['username'])
 128          {
 129              $post['username'] = "Guest";
 130          }
 131  
 132          // Sanitize the username
 133          $post['username'] = htmlspecialchars_uni($post['username']);
 134          return true;
 135      }
 136  
 137      /**
 138       * Verifies a post subject.
 139       *
 140       * @param string True if the subject is valid, false if invalid.
 141       * @return boolean True when valid, false when not valid.
 142       */
 143  	function verify_subject()
 144      {
 145          global $db;
 146          $post = &$this->data;
 147          $subject = &$post['subject'];
 148          $subject = trim_blank_chrs($subject);
 149          $subject = utf8_handle_4byte_string($subject);
 150  
 151          // Are we editing an existing thread or post?
 152          if($this->method == "update" && $post['pid'])
 153          {
 154              if(!$post['tid'])
 155              {
 156                  $query = $db->simple_select("posts", "tid", "pid='".intval($post['pid'])."'");
 157                  $post['tid'] = $db->fetch_field($query, "tid");
 158              }
 159              // Here we determine if we're editing the first post of a thread or not.
 160              $options = array(
 161                  "limit" => 1,
 162                  "limit_start" => 0,
 163                  "order_by" => "dateline",
 164                  "order_dir" => "asc"
 165              );
 166              $query = $db->simple_select("posts", "pid", "tid='".$post['tid']."'", $options);
 167              $first_check = $db->fetch_array($query);
 168              if($first_check['pid'] == $post['pid'])
 169              {
 170                  $first_post = true;
 171              }
 172              else
 173              {
 174                  $first_post = false;
 175              }
 176  
 177              // If this is the first post there needs to be a subject, else make it the default one.
 178              if(my_strlen($subject) == 0 && $first_post)
 179              {
 180                  $this->set_error("firstpost_no_subject");
 181                  return false;
 182              }
 183              elseif(my_strlen($subject) == 0)
 184              {
 185                  $thread = get_thread($post['tid']);
 186                  $subject = "RE: ".$thread['subject'];
 187              }
 188          }
 189  
 190          // This is a new post
 191          else if($this->action == "post")
 192          {
 193              if(my_strlen($subject) == 0)
 194              {
 195                  $thread = get_thread($post['tid']);
 196                  $subject = "RE: ".$thread['subject'];
 197              }
 198          }
 199  
 200          // This is a new thread and we require that a subject is present.
 201          else
 202          {
 203              if(my_strlen($subject) == 0)
 204              {
 205                  $this->set_error("missing_subject");
 206                  return false;
 207              }
 208          }
 209  
 210          // If post is reply and begins with "RE: ", remove 4 from subject length.
 211          $subject_length = my_strlen($subject);
 212          if($this->action == "post")
 213          {
 214              $position_re = my_strpos($subject, "RE: ");
 215              if($position_re !== false && $position_re == 0)
 216              {
 217                  $subject_length = $subject_length - 4;
 218              }
 219          }
 220  
 221          if($subject_length > 85)
 222          {
 223              // Subject is too long
 224              $this->set_error('subject_too_long', my_strlen($subject));
 225              return false;
 226          }
 227  
 228          // Subject is valid - return true.
 229          return true;
 230      }
 231  
 232      /**
 233       * Verifies a post message.
 234       *
 235       * @param string The message content.
 236       */
 237  	function verify_message()
 238      {
 239          global $mybb;
 240  
 241          $post = &$this->data;
 242          $post['message'] = trim_blank_chrs($post['message']);
 243          $post['message'] = utf8_handle_4byte_string($post['message']);
 244  
 245          // Do we even have a message at all?
 246          if(my_strlen($post['message']) == 0)
 247          {
 248              $this->set_error("missing_message");
 249              return false;
 250          }
 251  
 252          // If this board has a maximum message length check if we're over it. Use strlen because SQL limits are in bytes
 253          else if(strlen($post['message']) > $mybb->settings['maxmessagelength'] && $mybb->settings['maxmessagelength'] > 0 && !is_moderator($post['fid'], "", $post['uid']))
 254          {
 255              $this->set_error("message_too_long", array($mybb->settings['maxmessagelength'], strlen($post['message'])));
 256              return false;
 257          }
 258  
 259          // And if we've got a minimum message length do we meet that requirement too?
 260          else if(my_strlen($post['message']) < $mybb->settings['minmessagelength'] && $mybb->settings['minmessagelength'] > 0 && !is_moderator($post['fid'], "", $post['uid']))
 261          {
 262              $this->set_error("message_too_short", array($mybb->settings['minmessagelength']));
 263              return false;
 264          }
 265          return true;
 266      }
 267  
 268      /**
 269       * Verifies the specified post options are correct.
 270       *
 271       * @return boolean True
 272       */
 273  	function verify_options()
 274      {
 275          $options = &$this->data['options'];
 276  
 277          // Verify yes/no options.
 278          $this->verify_yesno_option($options, 'signature', 0);
 279          $this->verify_yesno_option($options, 'disablesmilies', 0);
 280  
 281          return true;
 282      }
 283  
 284      /**
 285      * Verify that the user is not flooding the system.
 286      *
 287      * @return boolean True
 288      */
 289  	function verify_post_flooding()
 290      {
 291          global $mybb;
 292  
 293          $post = &$this->data;
 294  
 295          // Check if post flooding is enabled within MyBB or if the admin override option is specified.
 296          if($mybb->settings['postfloodcheck'] == 1 && $post['uid'] != 0 && $this->admin_override == false)
 297          {
 298              if($this->verify_post_merge(true) !== true)
 299              {
 300                  return true;
 301              }
 302  
 303              // Fetch the user information for this post - used to check their last post date.
 304              $user = get_user($post['uid']);
 305  
 306              // A little bit of calculation magic and moderator status checking.
 307              if(TIME_NOW-$user['lastpost'] <= $mybb->settings['postfloodsecs'] && !is_moderator($post['fid'], "", $user['uid']))
 308              {
 309                  // Oops, user has been flooding - throw back error message.
 310                  $time_to_wait = ($mybb->settings['postfloodsecs'] - (TIME_NOW-$user['lastpost'])) + 1;
 311                  if($time_to_wait == 1)
 312                  {
 313                      $this->set_error("post_flooding_one_second");
 314                  }
 315                  else
 316                  {
 317                      $this->set_error("post_flooding", array($time_to_wait));
 318                  }
 319                  return false;
 320              }
 321          }
 322          // All is well that ends well - return true.
 323          return true;
 324      }
 325  
 326  	function verify_post_merge($simple_mode=false)
 327      {
 328          global $mybb, $db, $session;
 329  
 330          $post = &$this->data;
 331  
 332          // Are we starting a new thread?
 333          if(!$post['tid'])
 334          {
 335              return true;
 336          }
 337  
 338          // Are we even turned on?
 339          if(empty($mybb->settings['postmergemins']))
 340          {
 341              return true;
 342          }
 343  
 344          // Assign a default separator if none is specified
 345          if(trim($mybb->settings['postmergesep']) == "")
 346          {
 347              $mybb->settings['postmergesep'] = "[hr]";
 348          }
 349  
 350          // Check to see if this person is in a usergroup that is excluded
 351          if(trim($mybb->settings['postmergeuignore']) != "")
 352          {
 353              $gids = explode(',', $mybb->settings['postmergeuignore']);
 354              $gids = array_map('intval', $gids);
 355  
 356  
 357              $user_usergroups = explode(',', $mybb->user['usergroup'].",".$mybb->user['additionalgroups']);
 358              if(count(array_intersect($user_usergroups, $gids)) > 0)
 359              {
 360                  return true;
 361              }
 362          }
 363  
 364          // Select the lastpost and fid information for this thread
 365          $query = $db->simple_select("threads", "lastpost,fid", "lastposteruid='".$post['uid']."' AND tid='".$post['tid']."'", array('limit' => '1'));
 366          $thread = $db->fetch_array($query);
 367  
 368          // Check to see if the same author has posted within the merge post time limit
 369          if((intval($mybb->settings['postmergemins']) != 0 && trim($mybb->settings['postmergemins']) != "") && (TIME_NOW-$thread['lastpost']) > (intval($mybb->settings['postmergemins'])*60))
 370          {
 371              return true;
 372          }
 373  
 374          if(strstr($mybb->settings['postmergefignore'], ','))
 375          {
 376              $fids = explode(',', $mybb->settings['postmergefignore']);
 377              foreach($fids as $key => $forumid)
 378              {
 379                  $fid[] = intval($forumid);
 380              }
 381  
 382              if(in_array($thread['fid'], $fid))
 383              {
 384                  return true;
 385              }
 386  
 387          }
 388          else if(trim($mybb->settings['postmergefignore']) != "" && $thread['fid'] == intval($mybb->settings['postmergefignore']))
 389          {
 390              return true;
 391          }
 392  
 393          if($simple_mode == true)
 394          {
 395              return false;
 396          }
 397  
 398          if($post['uid'])
 399          {
 400              $user_check = "uid='".$post['uid']."'";
 401          }
 402          else
 403          {
 404              $user_check = "ipaddress='".$db->escape_string($session->ipaddress)."'";
 405          }
 406  
 407          $query = $db->simple_select("posts", "pid,message,visible", "{$user_check} AND tid='".$post['tid']."' AND dateline='".$thread['lastpost']."'", array('order_by' => 'pid', 'order_dir' => 'DESC', 'limit' => 1));
 408          return $db->fetch_array($query);
 409      }
 410  
 411      /**
 412      * Verifies the image count.
 413      *
 414      * @return boolean True when valid, false when not valid.
 415      */
 416  	function verify_image_count()
 417      {
 418          global $mybb, $db;
 419  
 420          $post = &$this->data;
 421  
 422          // Get the permissions of the user who is making this post or thread
 423          $permissions = user_permissions($post['uid']);
 424  
 425          // Fetch the forum this post is being made in
 426          if(!$post['fid'])
 427          {
 428              $query = $db->simple_select('posts', 'fid', "pid = '{$post['pid']}'");
 429              $post['fid'] = $db->fetch_field($query, 'fid');
 430          }
 431          $forum = get_forum($post['fid']);
 432  
 433          // Check if this post contains more images than the forum allows
 434          if($post['savedraft'] != 1 && $mybb->settings['maxpostimages'] != 0 && $permissions['cancp'] != 1)
 435          {
 436              require_once  MYBB_ROOT."inc/class_parser.php";
 437              $parser = new postParser;
 438  
 439              // Parse the message.
 440              $parser_options = array(
 441                  "allow_html" => $forum['allowhtml'],
 442                  "allow_mycode" => $forum['allowmycode'],
 443                  "allow_imgcode" => $forum['allowimgcode'],
 444                  "allow_videocode" => $forum['allowvideocode'],
 445                  "filter_badwords" => 1
 446              );
 447  
 448              if($post['options']['disablesmilies'] != 1)
 449              {
 450                  $parser_options['allow_smilies'] = $forum['allowsmilies'];
 451              }
 452              else
 453              {
 454                  $parser_options['allow_smilies'] = 0;
 455              }
 456  
 457              $image_check = $parser->parse_message($post['message'], $parser_options);
 458  
 459              // And count the number of image tags in the message.
 460              $image_count = substr_count($image_check, "<img");
 461              if($image_count > $mybb->settings['maxpostimages'])
 462              {
 463                  // Throw back a message if over the count with the number of images as well as the maximum number of images per post.
 464                  $this->set_error("too_many_images", array(1 => $image_count, 2 => $mybb->settings['maxpostimages']));
 465                  return false;
 466              }
 467          }
 468      }
 469  
 470      /**
 471      * Verifies the video count.
 472      *
 473      * @return boolean True when valid, false when not valid.
 474      */
 475  	function verify_video_count()
 476      {
 477          global $mybb, $db;
 478  
 479          $post = &$this->data;
 480  
 481          // Get the permissions of the user who is making this post or thread
 482          $permissions = user_permissions($post['uid']);
 483  
 484          // Check if this post contains more videos than the forum allows
 485          if($post['savedraft'] != 1 && $mybb->settings['maxpostvideos'] != 0 && $permissions['cancp'] != 1)
 486          {
 487              // And count the number of video tags in the message.
 488              $video_count = substr_count($post['message'], "[video=");
 489              if($video_count > $mybb->settings['maxpostvideos'])
 490              {
 491                  // Throw back a message if over the count with the number of images as well as the maximum number of images per post.
 492                  $this->set_error("too_many_videos", array(1 => $video_count, 2 => $mybb->settings['maxpostvideos']));
 493                  return false;
 494              }
 495          }
 496      }
 497  
 498      /**
 499      * Verify the reply-to post.
 500      *
 501      * @return boolean True when valid, false when not valid.
 502      */
 503  	function verify_reply_to()
 504      {
 505          global $db;
 506          $post = &$this->data;
 507  
 508          // Check if the post being replied to actually exists in this thread.
 509          if($post['replyto'])
 510          {
 511              $query = $db->simple_select("posts", "pid", "pid='".intval($post['replyto'])."'");
 512              $valid_post = $db->fetch_array($query);
 513              if(!$valid_post['pid'])
 514              {
 515                  $post['replyto'] = 0;
 516              }
 517              else
 518              {
 519                  return true;
 520              }
 521          }
 522  
 523          // If this post isn't a reply to a specific post, attach it to the first post.
 524          if(!$post['replyto'])
 525          {
 526              $options = array(
 527                  "limit_start" => 0,
 528                  "limit" => 1,
 529                  "order_by" => "dateline",
 530                  "order_dir" => "asc"
 531              );
 532              $query = $db->simple_select("posts", "pid", "tid='{$post['tid']}'", $options);
 533              $reply_to = $db->fetch_array($query);
 534              $post['replyto'] = $reply_to['pid'];
 535          }
 536  
 537          return true;
 538      }
 539  
 540      /**
 541      * Verify the post icon.
 542      *
 543      * @return boolean True when valid, false when not valid.
 544      */
 545  	function verify_post_icon()
 546      {
 547          global $cache;
 548  
 549          $post = &$this->data;
 550  
 551          // If we don't assign it as 0.
 552          if(!$post['icon'] || $post['icon'] < 0)
 553          {
 554              $post['icon'] = 0;
 555          }
 556          return true;
 557      }
 558  
 559      /**
 560      * Verify the dateline.
 561      *
 562      * @return boolean True when valid, false when not valid.
 563      */
 564  	function verify_dateline()
 565      {
 566          $dateline = &$this->data['dateline'];
 567  
 568          // The date has to be numeric and > 0.
 569          if($dateline < 0 || is_numeric($dateline) == false)
 570          {
 571              $dateline = TIME_NOW;
 572          }
 573      }
 574  
 575      /**
 576       * Verify thread prefix.
 577       *
 578       * @return boolean True when valid, false when not valid.
 579       */
 580  	function verify_prefix()
 581      {
 582          $prefix = &$this->data['prefix'];
 583  
 584          // If a valid prefix isn't supplied, don't assign one.
 585          if(!$prefix || $prefix < 1)
 586          {
 587              $prefix = 0;
 588          }
 589  
 590          return true;
 591      }
 592  
 593      /**
 594       * Validate a post.
 595       *
 596       * @return boolean True when valid, false when invalid.
 597       */
 598  	function validate_post()
 599      {
 600          global $mybb, $db, $plugins;
 601  
 602          $post = &$this->data;
 603          $time = TIME_NOW;
 604  
 605          $this->action = "post";
 606  
 607          if($this->method != "update" && !$post['savedraft'])
 608          {
 609              $this->verify_post_flooding();
 610          }
 611  
 612          // Verify all post assets.
 613  
 614          if($this->method == "insert" || array_key_exists('uid', $post))
 615          {
 616              $this->verify_author();
 617          }
 618  
 619          if($this->method == "insert" || array_key_exists('subject', $post))
 620          {
 621              $this->verify_subject();
 622          }
 623  
 624          if($this->method == "insert" || array_key_exists('message', $post))
 625          {
 626              $this->verify_message();
 627              $this->verify_image_count();
 628              $this->verify_video_count();
 629          }
 630  
 631          if($this->method == "insert" || array_key_exists('dateline', $post))
 632          {
 633              $this->verify_dateline();
 634          }
 635  
 636          if($this->method == "insert" || array_key_exists('replyto', $post))
 637          {
 638              $this->verify_reply_to();
 639          }
 640  
 641          if($this->method == "insert" || array_key_exists('icon', $post))
 642          {
 643              $this->verify_post_icon();
 644          }
 645  
 646          if($this->method == "insert" || array_key_exists('options', $post))
 647          {
 648              $this->verify_options();
 649          }
 650  
 651          $plugins->run_hooks("datahandler_post_validate_post", $this);
 652  
 653          // We are done validating, return.
 654          $this->set_validated(true);
 655          if(count($this->get_errors()) > 0)
 656          {
 657              return false;
 658          }
 659          else
 660          {
 661              return true;
 662          }
 663      }
 664  
 665  
 666      /**
 667       * Insert a post into the database.
 668       *
 669       * @return array Array of new post details, pid and visibility.
 670       */
 671  	function insert_post()
 672      {
 673          global $db, $mybb, $plugins, $cache, $lang;
 674  
 675          $post = &$this->data;
 676  
 677          // Yes, validating is required.
 678          if(!$this->get_validated())
 679          {
 680              die("The post needs to be validated before inserting it into the DB.");
 681          }
 682          if(count($this->get_errors()) > 0)
 683          {
 684              die("The post is not valid.");
 685          }
 686  
 687          // Fetch the thread
 688          $thread = get_thread($post['tid']);
 689  
 690          // This post is being saved as a draft.
 691          if($post['savedraft'])
 692          {
 693              $visible = -2;
 694          }
 695  
 696          // Otherwise this post is being made now and we have a bit to do.
 697          else
 698          {
 699              // Automatic subscription to the thread
 700              if($post['options']['subscriptionmethod'] != "" && $post['uid'] > 0)
 701              {
 702                  switch($post['options']['subscriptionmethod'])
 703                  {
 704                      case "instant":
 705                          $notification = 1;
 706                          break;
 707                      default:
 708                          $notification = 0;
 709                  }
 710  
 711                  require_once  MYBB_ROOT."inc/functions_user.php";
 712                  add_subscribed_thread($post['tid'], $notification, $post['uid']);
 713              }
 714  
 715              // Perform any selected moderation tools.
 716              if(is_moderator($post['fid'], "", $post['uid']))
 717              {
 718                  $lang->load($this->language_file, true);
 719  
 720                  $modoptions = $post['modoptions'];
 721                  $modlogdata['fid'] = $thread['fid'];
 722                  $modlogdata['tid'] = $thread['tid'];
 723  
 724                  // Close the thread.
 725                  if($modoptions['closethread'] == 1 && $thread['closed'] != 1)
 726                  {
 727                      $newclosed = "closed=1";
 728                      log_moderator_action($modlogdata, $lang->thread_closed);
 729                  }
 730  
 731                  // Open the thread.
 732                  if($modoptions['closethread'] != 1 && $thread['closed'] == 1)
 733                  {
 734                      $newclosed = "closed=0";
 735                      log_moderator_action($modlogdata, $lang->thread_opened);
 736                  }
 737  
 738                  // Stick the thread.
 739                  if($modoptions['stickthread'] == 1 && $thread['sticky'] != 1)
 740                  {
 741                      $newstick = "sticky='1'";
 742                      log_moderator_action($modlogdata, $lang->thread_stuck);
 743                  }
 744  
 745                  // Unstick the thread.
 746                  if($modoptions['stickthread'] != 1 && $thread['sticky'])
 747                  {
 748                      $newstick = "sticky='0'";
 749                      log_moderator_action($modlogdata, $lang->thread_unstuck);
 750                  }
 751  
 752                  // Execute moderation options.
 753                  if($newstick && $newclosed)
 754                  {
 755                      $sep = ",";
 756                  }
 757                  if($newstick || $newclosed)
 758                  {
 759                      $db->write_query("
 760                          UPDATE ".TABLE_PREFIX."threads
 761                          SET {$newclosed}{$sep}{$newstick}
 762                          WHERE tid='{$thread['tid']}'
 763                      ");
 764                  }
 765              }
 766  
 767              // Fetch the forum this post is being made in
 768              $forum = get_forum($post['fid']);
 769  
 770              // Decide on the visibility of this post.
 771              if($forum['modposts'] == 1 && !is_moderator($thread['fid'], "", $post['uid']))
 772              {
 773                  $visible = 0;
 774              }
 775              else
 776              {
 777                  $visible = 1;
 778              }
 779  
 780              // Are posts from this user being moderated? Change visibility
 781              if($mybb->user['uid'] == $post['uid'] && $mybb->user['moderateposts'] == 1)
 782              {
 783                  $visible = 0;
 784              }
 785          }
 786  
 787          $post['pid'] = intval($post['pid']);
 788          $post['uid'] = intval($post['uid']);
 789  
 790          if($post['pid'] > 0)
 791          {
 792              $query = $db->simple_select("posts", "tid", "pid='{$post['pid']}' AND uid='{$post['uid']}' AND visible='-2'");
 793              $draft_check = $db->fetch_field($query, "tid");
 794          }
 795          else
 796          {
 797              $draft_check = false;
 798          }
 799  
 800          if($this->method != "update" && $visible == 1)
 801          {
 802              $double_post = $this->verify_post_merge();
 803  
 804              // Only combine if they are both invisible (mod queue'd forum) or both visible
 805              if($double_post !== true && $double_post['visible'] == $visible)
 806              {
 807                  $this->pid = $double_post['pid'];
 808  
 809                  $post['message'] = $double_post['message'] .= "\n".$mybb->settings['postmergesep']."\n".$post['message'];
 810                  $update_query = array(
 811                      "message" => $db->escape_string($double_post['message'])
 812                  );
 813                  $update_query['edituid'] = intval($post['uid']);
 814                  $update_query['edittime'] = TIME_NOW;
 815                  $query = $db->update_query("posts", $update_query, "pid='".$double_post['pid']."'");
 816  
 817                  if($draft_check)
 818                  {
 819                      $db->delete_query("posts", "pid='".$post['pid']."'");
 820                  }
 821  
 822                  if($post['posthash'])
 823                  {
 824                      // Assign any uploaded attachments with the specific posthash to the merged post.
 825                      $post['posthash'] = $db->escape_string($post['posthash']);
 826  
 827                      $query = $db->simple_select("attachments", "COUNT(aid) AS attachmentcount", "pid='0' AND visible='1' AND posthash='{$post['posthash']}'");
 828                      $attachmentcount = $db->fetch_field($query, "attachmentcount");
 829  
 830                      if($attachmentcount > 0)
 831                      {
 832                          // Update forum count
 833                          update_thread_counters($post['tid'], array('attachmentcount' => "+{$attachmentcount}"));
 834                      }
 835  
 836                      $attachmentassign = array(
 837                          "pid" => $double_post['pid'],
 838                          "posthash" => ''
 839                      );
 840                      $db->update_query("attachments", $attachmentassign, "posthash='{$post['posthash']}' AND pid='0'");
 841                  }
 842  
 843                  // Return the post's pid and whether or not it is visible.
 844                  return array(
 845                      "pid" => $double_post['pid'],
 846                      "visible" => $visible
 847                  );
 848              }
 849          }
 850  
 851          if($visible == 1 && $thread['visible'] == 1)
 852          {
 853              $now = TIME_NOW;
 854  
 855              // Yes, the value to the lastpost key in this array has single quotes within double quotes. It's not a bug.
 856              $update_array = array(
 857                  'lastpost' => "'{$now}'"
 858              );
 859              if($forum['usepostcounts'] != 0)
 860              {
 861                  $update_array['postnum'] = 'postnum+1';
 862              }
 863  
 864              $db->update_query("users", $update_array, "uid='{$post['uid']}'", 1, true);
 865          }
 866  
 867          // Are we updating a post which is already a draft? Perhaps changing it into a visible post?
 868          if($draft_check)
 869          {
 870              // Update a post that is a draft
 871              $this->post_update_data = array(
 872                  "subject" => $db->escape_string($post['subject']),
 873                  "icon" => intval($post['icon']),
 874                  "uid" => $post['uid'],
 875                  "username" => $db->escape_string($post['username']),
 876                  "dateline" => intval($post['dateline']),
 877                  "message" => $db->escape_string($post['message']),
 878                  "ipaddress" => $db->escape_string($post['ipaddress']),
 879                  "longipaddress" => intval(my_ip2long($post['ipaddress'])),
 880                  "includesig" => $post['options']['signature'],
 881                  "smilieoff" => $post['options']['disablesmilies'],
 882                  "visible" => $visible
 883              );
 884  
 885              $plugins->run_hooks("datahandler_post_insert_post", $this);
 886  
 887              $db->update_query("posts", $this->post_update_data, "pid='{$post['pid']}'");
 888              $this->pid = $post['pid'];
 889          }
 890          else
 891          {
 892              // Insert the post.
 893              $this->post_insert_data = array(
 894                  "tid" => intval($post['tid']),
 895                  "replyto" => intval($post['replyto']),
 896                  "fid" => intval($post['fid']),
 897                  "subject" => $db->escape_string($post['subject']),
 898                  "icon" => intval($post['icon']),
 899                  "uid" => $post['uid'],
 900                  "username" => $db->escape_string($post['username']),
 901                  "dateline" => $post['dateline'],
 902                  "message" => $db->escape_string($post['message']),
 903                  "ipaddress" => $db->escape_string($post['ipaddress']),
 904                  "longipaddress" => intval(my_ip2long($post['ipaddress'])),
 905                  "includesig" => $post['options']['signature'],
 906                  "smilieoff" => $post['options']['disablesmilies'],
 907                  "visible" => $visible
 908              );
 909  
 910              $plugins->run_hooks("datahandler_post_insert_post", $this);
 911  
 912              $this->pid = $db->insert_query("posts", $this->post_insert_data);
 913          }
 914  
 915          // Assign any uploaded attachments with the specific posthash to the newly created post.
 916          if($post['posthash'])
 917          {
 918              $post['posthash'] = $db->escape_string($post['posthash']);
 919              $attachmentassign = array(
 920                  "pid" => $this->pid,
 921                  "posthash" => ''
 922              );
 923              $db->update_query("attachments", $attachmentassign, "posthash='{$post['posthash']}' AND pid='0'");
 924          }
 925  
 926          if($visible == 1 && $thread['visible'] == 1)
 927          {
 928              $thread = get_thread($post['tid']);
 929              require_once  MYBB_ROOT.'inc/class_parser.php';
 930              $parser = new Postparser;
 931  
 932              $done_users = array();
 933  
 934              $subject = $parser->parse_badwords($thread['subject']);
 935              $excerpt = $parser->text_parse_message($post['message'], array('me_username' => $post['username'], 'filter_badwords' => 1, 'safe_html' => 1));
 936              $excerpt = my_substr($excerpt, 0, $mybb->settings['subscribeexcerpt']).$lang->emailbit_viewthread;
 937  
 938              // Fetch any users subscribed to this thread receiving instant notification and queue up their subscription notices
 939              $query = $db->query("
 940                  SELECT u.username, u.email, u.uid, u.language, u.loginkey, u.salt, u.regdate, s.subscriptionkey
 941                  FROM ".TABLE_PREFIX."threadsubscriptions s
 942                  LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=s.uid)
 943                  WHERE s.notification='1' AND s.tid='{$post['tid']}'
 944                  AND s.uid != '{$post['uid']}'
 945                  AND u.lastactive>'{$thread['lastpost']}'
 946              ");
 947              while($subscribedmember = $db->fetch_array($query))
 948              {
 949                  if($done_users[$subscribedmember['uid']])
 950                  {
 951                      continue;
 952                  }
 953                  $done_users[$subscribedmember['uid']] = 1;
 954  
 955                  $forumpermissions = forum_permissions($thread['fid'], $subscribedmember['uid']);
 956                  if($forumpermissions['canview'] == 0 || $forumpermissions['canviewthreads'] == 0)
 957                  {
 958                      continue;
 959                  }
 960  
 961                  if($thread['uid'] != $subscribedmember['uid'] && $forumpermissions['canonlyviewownthread'] == 1 && !is_moderator($thread['fid'], "", $subscribedmember['uid']))
 962                  {
 963                      // User isn't a moderator or the author of the thread...
 964                      continue;
 965                  }
 966  
 967                  if($subscribedmember['language'] != '' && $lang->language_exists($subscribedmember['language']))
 968                  {
 969                      $uselang = $subscribedmember['language'];
 970                  }
 971                  elseif($mybb->settings['orig_bblanguage'])
 972                  {
 973                      $uselang = $mybb->settings['orig_bblanguage'];
 974                  }
 975                  else
 976                  {
 977                      $uselang = "english";
 978                  }
 979  
 980                  if($uselang == $mybb->settings['bblanguage'])
 981                  {
 982                      $emailsubject = $lang->emailsubject_subscription;
 983                      $emailmessage = $lang->email_subscription;
 984                  }
 985                  else
 986                  {
 987                      if(!isset($langcache[$uselang]['emailsubject_subscription']))
 988                      {
 989                          $userlang = new MyLanguage;
 990                          $userlang->set_path(MYBB_ROOT."inc/languages");
 991                          $userlang->set_language($uselang);
 992                          $userlang->load("messages");
 993                          $langcache[$uselang]['emailsubject_subscription'] = $userlang->emailsubject_subscription;
 994                          $langcache[$uselang]['email_subscription'] = $userlang->email_subscription;
 995                          unset($userlang);
 996                      }
 997                      $emailsubject = $langcache[$uselang]['emailsubject_subscription'];
 998                      $emailmessage = $langcache[$uselang]['email_subscription'];
 999                  }
1000                  $emailsubject = $lang->sprintf($emailsubject, $subject);
1001  
1002                  $post_code = md5($subscribedmember['loginkey'].$subscribedmember['salt'].$subscribedmember['regdate']);
1003                  $emailmessage = $lang->sprintf($emailmessage, $subscribedmember['username'], $post['username'], $mybb->settings['bbname'], $subject, $excerpt, $mybb->settings['bburl'], str_replace("&amp;", "&", get_thread_link($thread['tid'], 0, "newpost")), $thread['tid'], $subscribedmember['subscriptionkey'], $post_code);
1004                  $new_email = array(
1005                      "mailto" => $db->escape_string($subscribedmember['email']),
1006                      "mailfrom" => '',
1007                      "subject" => $db->escape_string($emailsubject),
1008                      "message" => $db->escape_string($emailmessage),
1009                      "headers" => ''
1010                  );
1011                  $db->insert_query("mailqueue", $new_email);
1012                  unset($userlang);
1013                  $queued_email = 1;
1014              }
1015              // Have one or more emails been queued? Update the queue count
1016              if($queued_email == 1)
1017              {
1018                  $cache->update_mailqueue();
1019              }
1020              $thread_update['replies'] = "+1";
1021  
1022              // Update forum count
1023              update_thread_counters($post['tid'], $thread_update);
1024              update_forum_counters($post['fid'], array("posts" => "+1"));
1025          }
1026          // Post is stuck in moderation queue
1027          else if($visible == 0)
1028          {
1029              // Update the unapproved posts count for the current thread and current forum
1030              update_thread_counters($post['tid'], array("unapprovedposts" => "+1"));
1031              update_forum_counters($post['fid'], array("unapprovedposts" => "+1"));
1032          }
1033          else if($thread['visible'] == 0)
1034          {
1035              // Update the unapproved posts count for the current forum
1036              update_thread_counters($post['tid'], array("replies" => "+1"));
1037              update_forum_counters($post['fid'], array("unapprovedposts" => "+1"));
1038          }
1039  
1040          $query = $db->simple_select("attachments", "COUNT(aid) AS attachmentcount", "pid='{$this->pid}' AND visible='1'");
1041          $attachmentcount = $db->fetch_field($query, "attachmentcount");
1042          if($attachmentcount > 0)
1043          {
1044              update_thread_counters($post['tid'], array("attachmentcount" => "+{$attachmentcount}"));
1045          }
1046  
1047          // Return the post's pid and whether or not it is visible.
1048          return array(
1049              "pid" => $this->pid,
1050              "visible" => $visible
1051          );
1052      }
1053  
1054      /**
1055       * Validate a thread.
1056       *
1057       * @return boolean True when valid, false when invalid.
1058       */
1059  	function validate_thread()
1060      {
1061          global $mybb, $db, $plugins;
1062  
1063          $thread = &$this->data;
1064  
1065          // Validate all thread assets.
1066  
1067          if(!$thread['savedraft'])
1068          {
1069              $this->verify_post_flooding();
1070          }
1071  
1072          if($this->method == "insert" || array_key_exists('uid', $thread))
1073          {
1074              $this->verify_author();
1075          }
1076  
1077          if($this->method == "insert" || array_key_exists('prefix', $thread))
1078          {
1079              $this->verify_prefix();
1080          }
1081  
1082          if($this->method == "insert" || array_key_exists('subject', $thread))
1083          {
1084              $this->verify_subject();
1085          }
1086  
1087          if($this->method == "insert" || array_key_exists('message', $thread))
1088          {
1089              $this->verify_message();
1090              $this->verify_image_count();
1091              $this->verify_video_count();
1092          }
1093  
1094          if($this->method == "insert" || array_key_exists('dateline', $thread))
1095          {
1096              $this->verify_dateline();
1097          }
1098  
1099          if($this->method == "insert" || array_key_exists('icon', $thread))
1100          {
1101              $this->verify_post_icon();
1102          }
1103  
1104          if($this->method == "insert" || array_key_exists('options', $thread))
1105          {
1106              $this->verify_options();
1107          }
1108  
1109          $plugins->run_hooks("datahandler_post_validate_thread", $this);
1110  
1111          // We are done validating, return.
1112          $this->set_validated(true);
1113          if(count($this->get_errors()) > 0)
1114          {
1115              return false;
1116          }
1117          else
1118          {
1119              return true;
1120          }
1121      }
1122  
1123      /**
1124       * Insert a thread into the database.
1125       *
1126       * @return array Array of new thread details, tid and visibility.
1127       */
1128  	function insert_thread()
1129      {
1130          global $db, $mybb, $plugins, $cache, $lang;
1131  
1132          // Yes, validating is required.
1133          if(!$this->get_validated())
1134          {
1135              die("The thread needs to be validated before inserting it into the DB.");
1136          }
1137          if(count($this->get_errors()) > 0)
1138          {
1139              die("The thread is not valid.");
1140          }
1141  
1142          $thread = &$this->data;
1143  
1144          // Fetch the forum this thread is being made in
1145          $forum = get_forum($thread['fid']);
1146  
1147          // This thread is being saved as a draft.
1148          if($thread['savedraft'])
1149          {
1150              $visible = -2;
1151          }
1152  
1153          // Thread is being made now and we have a bit to do.
1154          else
1155          {
1156  
1157              // Decide on the visibility of this post.
1158              if(($forum['modthreads'] == 1 || $forum['modposts'] == 1) && !is_moderator($thread['fid'], "", $thread['uid']))
1159              {
1160                  $visible = 0;
1161              }
1162              else
1163              {
1164                  $visible = 1;
1165              }
1166  
1167              // Are posts from this user being moderated? Change visibility
1168              if($mybb->user['uid'] == $thread['uid'] && $mybb->user['moderateposts'] == 1)
1169              {
1170                  $visible = 0;
1171              }
1172          }
1173  
1174          // Have a post ID but not a thread ID - fetch thread ID
1175          if($thread['pid'] && !$thread['tid'])
1176          {
1177              $query = $db->simple_select("posts", "tid", "pid='{$thread['pid']}");
1178              $thread['tid'] = $db->fetch_field($query, "tid");
1179          }
1180  
1181          if($thread['pid'] > 0)
1182          {
1183              $query = $db->simple_select("posts", "pid", "pid='{$thread['pid']}' AND uid='{$thread['uid']}' AND visible='-2'");
1184              $draft_check = $db->fetch_field($query, "pid");
1185          }
1186          else
1187          {
1188              $draft_check = false;
1189          }
1190  
1191          // Are we updating a post which is already a draft? Perhaps changing it into a visible post?
1192          if($draft_check)
1193          {
1194              $this->thread_insert_data = array(
1195                  "subject" => $db->escape_string($thread['subject']),
1196                  "icon" => intval($thread['icon']),
1197                  "username" => $db->escape_string($thread['username']),
1198                  "dateline" => intval($thread['dateline']),
1199                  "lastpost" => intval($thread['dateline']),
1200                  "lastposter" => $db->escape_string($thread['username']),
1201                  "visible" => $visible
1202              );
1203  
1204              $plugins->run_hooks("datahandler_post_insert_thread", $this);
1205  
1206              $db->update_query("threads", $this->thread_insert_data, "tid='{$thread['tid']}'");
1207  
1208              $this->post_insert_data = array(
1209                  "subject" => $db->escape_string($thread['subject']),
1210                  "icon" => intval($thread['icon']),
1211                  "username" => $db->escape_string($thread['username']),
1212                  "dateline" => intval($thread['dateline']),
1213                  "message" => $db->escape_string($thread['message']),
1214                  "ipaddress" => $db->escape_string(get_ip()),
1215                  "includesig" => $thread['options']['signature'],
1216                  "smilieoff" => $thread['options']['disablesmilies'],
1217                  "visible" => $visible
1218              );
1219              $plugins->run_hooks("datahandler_post_insert_thread_post", $this);
1220  
1221              $db->update_query("posts", $this->post_insert_data, "pid='{$thread['pid']}'");
1222              $this->tid = $thread['tid'];
1223              $this->pid = $thread['pid'];
1224          }
1225  
1226          // Inserting a new thread into the database.
1227          else
1228          {
1229              $this->thread_insert_data = array(
1230                  "fid" => $thread['fid'],
1231                  "subject" => $db->escape_string($thread['subject']),
1232                  "prefix" => intval($thread['prefix']),
1233                  "icon" => intval($thread['icon']),
1234                  "uid" => $thread['uid'],
1235                  "username" => $db->escape_string($thread['username']),
1236                  "dateline" => intval($thread['dateline']),
1237                  "lastpost" => intval($thread['dateline']),
1238                  "lastposter" => $db->escape_string($thread['username']),
1239                  "views" => 0,
1240                  "replies" => 0,
1241                  "visible" => $visible,
1242                  "notes" => ''
1243              );
1244  
1245              $plugins->run_hooks("datahandler_post_insert_thread", $this);
1246  
1247              $this->tid = $db->insert_query("threads", $this->thread_insert_data);
1248  
1249              $this->post_insert_data = array(
1250                  "tid" => $this->tid,
1251                  "fid" => $thread['fid'],
1252                  "subject" => $db->escape_string($thread['subject']),
1253                  "icon" => intval($thread['icon']),
1254                  "uid" => $thread['uid'],
1255                  "username" => $db->escape_string($thread['username']),
1256                  "dateline" => intval($thread['dateline']),
1257                  "message" => $db->escape_string($thread['message']),
1258                  "ipaddress" => $db->escape_string(get_ip()),
1259                  "longipaddress" => intval(my_ip2long(get_ip())),
1260                  "includesig" => $thread['options']['signature'],
1261                  "smilieoff" => $thread['options']['disablesmilies'],
1262                  "visible" => $visible
1263              );
1264              $plugins->run_hooks("datahandler_post_insert_thread_post", $this);
1265  
1266              $this->pid = $db->insert_query("posts", $this->post_insert_data);
1267  
1268              // Now that we have the post id for this first post, update the threads table.
1269              $firstpostup = array("firstpost" => $this->pid);
1270              $db->update_query("threads", $firstpostup, "tid='{$this->tid}'");
1271          }
1272  
1273          // If we're not saving a draft there are some things we need to check now
1274          if(!$thread['savedraft'])
1275          {
1276              if($thread['options']['subscriptionmethod'] != "" && $thread['uid'] > 0)
1277              {
1278                  switch($thread['options']['subscriptionmethod'])
1279                  {
1280                      case "instant":
1281                          $notification = 1;
1282                          break;
1283                      default:
1284                          $notification = 0;
1285                  }
1286  
1287                  require_once  MYBB_ROOT."inc/functions_user.php";
1288                  add_subscribed_thread($this->tid, $notification, $thread['uid']);
1289              }
1290  
1291              // Perform any selected moderation tools.
1292              if(is_moderator($thread['fid'], "", $thread['uid']) && is_array($thread['modoptions']))
1293              {
1294                  $lang->load($this->language_file, true);
1295  
1296                  $modoptions = $thread['modoptions'];
1297                  $modlogdata['fid'] = $this->tid;
1298                  $modlogdata['tid'] = $thread['tid'];
1299  
1300                  // Close the thread.
1301                  if($modoptions['closethread'] == 1)
1302                  {
1303                      $newclosed = "closed=1";
1304                      log_moderator_action($modlogdata, $lang->thread_closed);
1305                  }
1306  
1307                  // Stick the thread.
1308                  if($modoptions['stickthread'] == 1)
1309                  {
1310                      $newstick = "sticky='1'";
1311                      log_moderator_action($modlogdata, $lang->thread_stuck);
1312                  }
1313  
1314                  // Execute moderation options.
1315                  if($newstick && $newclosed)
1316                  {
1317                      $sep = ",";
1318                  }
1319                  if($newstick || $newclosed)
1320                  {
1321                      $db->write_query("
1322                          UPDATE ".TABLE_PREFIX."threads
1323                          SET $newclosed$sep$newstick
1324                          WHERE tid='{$this->tid}'
1325                      ");
1326                  }
1327              }
1328              if($visible == 1)
1329              {
1330                  // If we have a registered user then update their post count and last post times.
1331                  if($thread['uid'] > 0)
1332                  {
1333                      $user = get_user($thread['uid']);
1334                      $update_query = array();
1335                      // Only update the lastpost column of the user if the date of the thread is newer than their last post.
1336                      if($thread['dateline'] > $user['lastpost'])
1337                      {
1338                          // Yes this has a single quote within a double quote. It's not a bug.
1339                          $update_query['lastpost'] = "'{$thread['dateline']}'";
1340                      }
1341                      // Update the post count if this forum allows post counts to be tracked
1342                      if($forum['usepostcounts'] != 0)
1343                      {
1344                          $update_query['postnum'] = "postnum+1";
1345                      }
1346  
1347                      // Only update the table if we need to.
1348                      if(!empty($update_query))
1349                      {
1350                          $db->update_query("users", $update_query, "uid='{$thread['uid']}'", 1, true);
1351                      }
1352                  }
1353  
1354                  if(!$forum['lastpost'])
1355                  {
1356                      $forum['lastpost'] = 0;
1357                  }
1358  
1359                  $done_users = array();
1360  
1361                  // Queue up any forum subscription notices to users who are subscribed to this forum.
1362                  $excerpt = my_substr($thread['message'], 0, $mybb->settings['subscribeexcerpt']).$lang->emailbit_viewthread;
1363  
1364                  // Parse badwords
1365                  require_once  MYBB_ROOT."inc/class_parser.php";
1366                  $parser = new postParser;
1367                  $excerpt = $parser->parse_badwords($excerpt);
1368  
1369                  $query = $db->query("
1370                      SELECT u.username, u.email, u.uid, u.language, u.loginkey, u.salt, u.regdate
1371                      FROM ".TABLE_PREFIX."forumsubscriptions fs
1372                      LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=fs.uid)
1373                      LEFT JOIN ".TABLE_PREFIX."usergroups g ON (g.gid=u.usergroup)
1374                      WHERE fs.fid='".intval($thread['fid'])."'
1375                      AND fs.uid != '".intval($thread['uid'])."'
1376                      AND u.lastactive > '{$forum['lastpost']}'
1377                      AND g.isbannedgroup != 1
1378                  ");
1379                  while($subscribedmember = $db->fetch_array($query))
1380                  {
1381                      if($done_users[$subscribedmember['uid']])
1382                      {
1383                          continue;
1384                      }
1385                      $done_users[$subscribedmember['uid']] = 1;
1386  
1387                      $forumpermissions = forum_permissions($thread['fid'], $subscribedmember['uid']);
1388                      if($forumpermissions['canview'] == 0 || $forumpermissions['canviewthreads'] == 0)
1389                      {
1390                          continue;
1391                      }
1392  
1393                      if(!is_moderator($thread['fid'], "", $subscribedmember['uid']) && $forumpermissions['canonlyviewownthreads'] == 1)
1394                      {
1395                          // In a 'view own only' forum and not a moderator
1396                          continue;
1397                      }
1398  
1399                      // Determine the language pack we'll be using to send this email in and load it if it isn't already.
1400                      if($subscribedmember['language'] != '' && $lang->language_exists($subscribedmember['language']))
1401                      {
1402                          $uselang = $subscribedmember['language'];
1403                      }
1404                      else if($mybb->settings['bblanguage'])
1405                      {
1406                          $uselang = $mybb->settings['bblanguage'];
1407                      }
1408                      else
1409                      {
1410                          $uselang = "english";
1411                      }
1412  
1413                      if($uselang == $mybb->settings['bblanguage'])
1414                      {
1415                          $emailsubject = $lang->emailsubject_forumsubscription;
1416                          $emailmessage = $lang->email_forumsubscription;
1417                      }
1418                      else
1419                      {
1420                          if(!isset($langcache[$uselang]['emailsubject_forumsubscription']))
1421                          {
1422                              $userlang = new MyLanguage;
1423                              $userlang->set_path(MYBB_ROOT."inc/languages");
1424                              $userlang->set_language($uselang);
1425                              $userlang->load("messages");
1426                              $langcache[$uselang]['emailsubject_forumsubscription'] = $userlang->emailsubject_forumsubscription;
1427                              $langcache[$uselang]['email_forumsubscription'] = $userlang->email_forumsubscription;
1428                              unset($userlang);
1429                          }
1430                          $emailsubject = $langcache[$uselang]['emailsubject_forumsubscription'];
1431                          $emailmessage = $langcache[$uselang]['email_forumsubscription'];
1432                      }
1433                      $emailsubject = $lang->sprintf($emailsubject, $forum['name']);
1434  
1435                      $post_code = md5($subscribedmember['loginkey'].$subscribedmember['salt'].$subscribedmember['regdate']);
1436                      $emailmessage = $lang->sprintf($emailmessage, $subscribedmember['username'], $thread['username'], $forum['name'], $mybb->settings['bbname'], $thread['subject'], $excerpt, $mybb->settings['bburl'], get_thread_link($this->tid), $thread['fid'], $post_code);
1437                      $new_email = array(
1438                          "mailto" => $db->escape_string($subscribedmember['email']),
1439                          "mailfrom" => '',
1440                          "subject" => $db->escape_string($emailsubject),
1441                          "message" => $db->escape_string($emailmessage),
1442                          "headers" => ''
1443                      );
1444                      $db->insert_query("mailqueue", $new_email);
1445                      unset($userlang);
1446                      $queued_email = 1;
1447                  }
1448                  // Have one or more emails been queued? Update the queue count
1449                  if($queued_email == 1)
1450                  {
1451                      $cache->update_mailqueue();
1452                  }
1453              }
1454          }
1455  
1456          // Assign any uploaded attachments with the specific posthash to the newly created post.
1457          if($thread['posthash'])
1458          {
1459              $thread['posthash'] = $db->escape_string($thread['posthash']);
1460              $attachmentassign = array(
1461                  "pid" => $this->pid,
1462                  "posthash" => ''
1463              );
1464              $db->update_query("attachments", $attachmentassign, "posthash='{$thread['posthash']}' AND pid='0'");
1465          }
1466  
1467          if($visible == 1)
1468          {
1469              update_thread_data($this->tid);
1470              update_forum_counters($thread['fid'], array("threads" => "+1", "posts" => "+1"));
1471          }
1472          else if($visible == 0)
1473          {
1474              update_thread_data($this->tid);
1475              update_thread_counters($this->tid, array("replies" => 0));
1476              update_forum_counters($thread['fid'], array("unapprovedthreads" => "+1", "unapprovedposts" => "+1"));
1477          }
1478  
1479          $query = $db->simple_select("attachments", "COUNT(aid) AS attachmentcount", "pid='{$this->pid}' AND visible='1'");
1480          $attachmentcount = $db->fetch_field($query, "attachmentcount");
1481          if($attachmentcount > 0)
1482          {
1483              update_thread_counters($this->tid, array("attachmentcount" => "+{$attachmentcount}"));
1484          }
1485  
1486          // Return the post's pid and whether or not it is visible.
1487          return array(
1488              "pid" => $this->pid,
1489              "tid" => $this->tid,
1490              "visible" => $visible
1491          );
1492      }
1493  
1494      /**
1495       * Updates a post that is already in the database.
1496       *
1497       */
1498  	function update_post()
1499      {
1500          global $db, $mybb, $plugins;
1501  
1502          // Yes, validating is required.
1503          if($this->get_validated() != true)
1504          {
1505              die("The post needs to be validated before inserting it into the DB.");
1506          }
1507          if(count($this->get_errors()) > 0)
1508          {
1509              die("The post is not valid.");
1510          }
1511  
1512          $post = &$this->data;
1513  
1514          $post['pid'] = intval($post['pid']);
1515  
1516          $existing_post = get_post($post['pid']);
1517          $post['tid'] = $existing_post['tid'];
1518          $post['fid'] = $existing_post['fid'];
1519  
1520          $forum = get_forum($post['fid']);
1521  
1522          // Decide on the visibility of this post.
1523          if(isset($post['visible']) && $post['visible'] != $existing_post['visible'])
1524          {
1525              if($forum['mod_edit_posts'] == 1 && !is_moderator($post['fid'], "", $post['uid']))
1526              {
1527                  if($existing_post['visible'] == 1)
1528                  {
1529                      update_thread_data($existing_post['tid']);
1530                      update_thread_counters($existing_post['tid'], array('replies' => '-1', 'unapprovedposts' => '+1'));
1531                      update_forum_counters($existing_post['fid'], array('unapprovedthreads' => '+1', 'unapprovedposts' => '+1'));
1532  
1533                      // Subtract from the users post count
1534                      // Update the post count if this forum allows post counts to be tracked
1535                      if($forum['usepostcounts'] != 0)
1536                      {
1537                          $db->write_query("UPDATE ".TABLE_PREFIX."users SET postnum=postnum-1 WHERE uid='{$existing_post['uid']}'");
1538                      }
1539                  }
1540                  $visible = 0;
1541              }
1542              else
1543              {
1544                  if($existing_post['visible'] == 0)
1545                  {
1546                      update_thread_data($existing_post['tid']);
1547                      update_thread_counters($existing_post['tid'], array('replies' => '+1', 'unapprovedposts' => '-1'));
1548                      update_forum_counters($existing_post['fid'], array('unapprovedthreads' => '-1', 'unapprovedposts' => '-1'));
1549  
1550                      // Update the post count if this forum allows post counts to be tracked
1551                      if($forum['usepostcounts'] != 0)
1552                      {
1553                          $db->write_query("UPDATE ".TABLE_PREFIX."users SET postnum=postnum+1 WHERE uid='{$existing_post['uid']}'");
1554                      }
1555                  }
1556                  $visible = 1;
1557              }
1558          }
1559          else
1560          {
1561              $visible = 0;
1562              if($forum['mod_edit_posts'] != 1 || is_moderator($post['fid'], "", $post['uid']))
1563              {
1564                  $visible = 1;
1565              }
1566          }
1567  
1568          // Check if this is the first post in a thread.
1569          $options = array(
1570              "order_by" => "dateline",
1571              "order_dir" => "asc",
1572              "limit_start" => 0,
1573              "limit" => 1
1574          );
1575          $query = $db->simple_select("posts", "pid", "tid='".intval($post['tid'])."'", $options);
1576          $first_post_check = $db->fetch_array($query);
1577          if($first_post_check['pid'] == $post['pid'])
1578          {
1579              $first_post = true;
1580          }
1581          else
1582          {
1583              $first_post = false;
1584          }
1585  
1586          if($existing_post['visible'] == 0)
1587          {
1588              $visible = 0;
1589          }
1590  
1591          // Update the thread details that might have been changed first.
1592          if($first_post)
1593          {
1594              $this->tid = $post['tid'];
1595  
1596              $this->thread_update_data['visible'] = $visible;
1597  
1598              if(isset($post['prefix']))
1599              {
1600                  $this->thread_update_data['prefix'] = intval($post['prefix']);
1601              }
1602  
1603              if(isset($post['subject']))
1604              {
1605                  $this->thread_update_data['subject'] = $db->escape_string($post['subject']);
1606              }
1607  
1608              if(isset($post['icon']))
1609              {
1610                  $this->thread_update_data['icon'] = intval($post['icon']);
1611              }
1612              if(count($this->thread_update_data) > 0)
1613              {
1614                  $plugins->run_hooks("datahandler_post_update_thread", $this);
1615  
1616                  $db->update_query("threads", $this->thread_update_data, "tid='".intval($post['tid'])."'");
1617              }
1618          }
1619  
1620          // Prepare array for post updating.
1621  
1622          $this->pid = $post['pid'];
1623  
1624          if(isset($post['subject']))
1625          {
1626              $this->post_update_data['subject'] = $db->escape_string($post['subject']);
1627          }
1628  
1629          if(isset($post['message']))
1630          {
1631              $this->post_update_data['message'] = $db->escape_string($post['message']);
1632          }
1633  
1634          if(isset($post['icon']))
1635          {
1636              $this->post_update_data['icon'] = intval($post['icon']);
1637          }
1638  
1639          if(isset($post['options']))
1640          {
1641              if(isset($post['options']['disablesmilies']))
1642              {
1643                  $this->post_update_data['smilieoff'] = $db->escape_string($post['options']['disablesmilies']);
1644              }
1645              if(isset($post['options']['signature']))
1646              {
1647                  $this->post_update_data['includesig'] = $db->escape_string($post['options']['signature']);
1648              }
1649          }
1650  
1651          // If we need to show the edited by, let's do so.
1652          if(($mybb->settings['showeditedby'] == 1 && !is_moderator($post['fid'], "caneditposts", $post['edit_uid'])) || ($mybb->settings['showeditedbyadmin'] == 1 && is_moderator($post['fid'], "caneditposts", $post['edit_uid'])))
1653          {
1654              $this->post_update_data['edituid'] = intval($post['edit_uid']);
1655              $this->post_update_data['edittime'] = TIME_NOW;
1656          }
1657  
1658          $this->post_update_data['visible'] = $visible;
1659  
1660          $plugins->run_hooks("datahandler_post_update", $this);
1661  
1662          $db->update_query("posts", $this->post_update_data, "pid='".intval($post['pid'])."'");
1663  
1664          // Automatic subscription to the thread
1665          if($post['options']['subscriptionmethod'] != "" && $post['uid'] > 0)
1666          {
1667              switch($post['options']['subscriptionmethod'])
1668              {
1669                  case "instant":
1670                      $notification = 1;
1671                      break;
1672                  default:
1673                      $notification = 0;
1674              }
1675              require_once  MYBB_ROOT."inc/functions_user.php";
1676              add_subscribed_thread($post['tid'], $notification, $post['uid']);
1677          }
1678          else
1679          {
1680              $db->delete_query("threadsubscriptions", "uid='".intval($post['uid'])."' AND tid='".intval($post['tid'])."'");
1681          }
1682  
1683          update_forum_lastpost($post['fid']);
1684  
1685          return array(
1686              'visible' => $visible,
1687              'first_post' => $first_post
1688          );
1689      }
1690  }
1691  ?>


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1