/**
  * @see Form::save()
  */
 public function save()
 {
     // set the language temporarily to the thread language
     if ($this->thread->languageID && $this->thread->languageID != WCF::getLanguage()->getLanguageID()) {
         $this->setLanguage($this->thread->languageID);
     }
     MessageForm::save();
     if ($this->thread->isDisabled) {
         $this->disablePost = 1;
     }
     // search for double posts
     if ($postID = PostEditor::test($this->subject, $this->text, WCF::getUser()->userID, $this->username, $this->threadID)) {
         HeaderUtil::redirect('index.php?page=Thread&postID=' . $postID . SID_ARG_2ND_NOT_ENCODED . '#post' . $postID);
         exit;
     }
     // save poll
     if ($this->showPoll) {
         $this->pollEditor->save();
     }
     // save post in database
     $this->newPost = PostEditor::create($this->thread->threadID, $this->subject, $this->text, WCF::getUser()->userID, $this->username, $this->getOptions(), $this->attachmentListEditor, $this->pollEditor, null, intval($this->disablePost || !$this->board->getPermission('canReplyThreadWithoutModeration')));
     // reset language
     if ($this->userInterfaceLanguageID !== null) {
         $this->setLanguage($this->userInterfaceLanguageID, true);
     }
     // remove quotes
     $sessionVars = WCF::getSession()->getVars();
     if (isset($sessionVars['quotes'][$this->threadID])) {
         unset($sessionVars['quotes'][$this->threadID]);
         WCF::getSession()->register('quotes', $sessionVars['quotes']);
     }
     if (!$this->disablePost && $this->board->getPermission('canReplyThreadWithoutModeration')) {
         // refresh thread
         $this->thread->addPost($this->newPost, $this->closeThread);
         // update subscription
         $this->thread->setSubscription($this->subscription);
         // update user posts
         if (WCF::getUser()->userID && $this->board->countUserPosts) {
             WBBUser::updateUserPosts(WCF::getUser()->userID, 1);
             if (ACTIVITY_POINTS_PER_POST) {
                 require_once WCF_DIR . 'lib/data/user/rank/UserRank.class.php';
                 UserRank::updateActivityPoints(ACTIVITY_POINTS_PER_POST);
             }
         }
         // refresh counter and last post
         $this->board->addPosts();
         $this->board->setLastPost($this->thread);
         // close / open thread
         if (!$this->thread->isClosed && $this->closeThread) {
             $this->thread->close();
         } else {
             if ($this->thread->isClosed && !$this->closeThread) {
                 $this->thread->open();
             }
         }
         // mark as done
         if ($this->markAsDone == 1) {
             $this->thread->markAsDone();
         } else {
             if (MODULE_THREAD_MARKING_AS_DONE && $this->board->enableMarkingAsDone && $this->thread->isDone && WCF::getUser()->userID && WCF::getUser()->userID == $this->thread->userID) {
                 $this->thread->markAsUndone();
             }
         }
         // reset stat cache
         WCF::getCache()->clearResource('stat');
         WCF::getCache()->clearResource('boardData');
         // send notifications
         $this->newPost->sendNotification($this->thread, $this->board, $this->attachmentListEditor);
         $this->saved();
         // forward to post
         $url = 'index.php?page=Thread&postID=' . $this->newPost->postID . SID_ARG_2ND_NOT_ENCODED . '#post' . $this->newPost->postID;
         HeaderUtil::redirect($url);
     } else {
         $this->saved();
         if ($this->disablePost) {
             HeaderUtil::redirect('index.php?page=Thread&postID=' . $this->newPost->postID . SID_ARG_2ND_NOT_ENCODED . '#post' . $this->newPost->postID);
         } else {
             WCF::getTPL()->assign(array('url' => 'index.php?page=Thread&threadID=' . $this->threadID . SID_ARG_2ND_NOT_ENCODED, 'message' => WCF::getLanguage()->get('wbb.postAdd.moderation.redirect'), 'wait' => 5));
             WCF::getTPL()->display('redirect');
         }
     }
     exit;
 }
 /**
  * Creates a new thread with the given data in the database.
  * Returns a ThreadEditor object of the new thread.
  * 
  * @param	integer				$boardID							
  * @param	string				$subject		subject of the new thread
  * @param	string				$text			text of the first post in the new thread
  * @param	integer				$authorID		user id of the author of the new thread
  * @param	string				$author			username of the author of the new thread
  * @param	integer				$sticky			true (1), if it is a sticky thread
  * @param	integer				$isClosed		true (1), if it is a closed thread					
  * @param	array				$options		options of the new thread
  * @param	integer				$subscription		type of notifation on the new thread for the active user					
  * @param	AttachmentsEditor		$attachmentsEditor
  * @param	PollEditor			$pollEditor
  * 
  * @return	ThreadEditor						the new thread		
  */
 public static function create($boardID, $languageID, $prefix, $subject, $text, $userID, $username, $sticky = 0, $announcement = 0, $closed = 0, $options = array(), $subscription = 0, $attachments = null, $poll = null, $disabled = 0)
 {
     $attachmentsAmount = $attachments != null ? count($attachments->getAttachments()) : 0;
     $polls = $poll != null && $poll->pollID ? 1 : 0;
     // insert thread
     $threadID = self::insert($subject, $boardID, array('languageID' => $languageID, 'userID' => $userID, 'username' => $username, 'prefix' => $prefix, 'time' => TIME_NOW, 'lastPostTime' => TIME_NOW, 'lastPosterID' => $userID, 'lastPoster' => $username, 'attachments' => $attachmentsAmount, 'polls' => $polls, 'isSticky' => $sticky, 'isAnnouncement' => $announcement, 'isClosed' => $closed, 'isDisabled' => $disabled, 'everEnabled' => $disabled ? 0 : 1));
     // create post
     $post = PostEditor::create($threadID, $subject, $text, $userID, $username, $options, $attachments, $poll, null, $disabled, true);
     // update first post id
     $sql = "UPDATE\twbb" . WBB_N . "_thread\n\t\t\tSET\tfirstPostID = " . $post->postID . "\n\t\t\tWHERE\tthreadID = " . $threadID;
     WCF::getDB()->sendQuery($sql);
     // update first post preview
     PostEditor::updateFirstPostPreview($threadID, $post->postID, $text, $options);
     // get thread object
     $thread = new ThreadEditor($threadID);
     // update subscription
     $thread->setSubscription($subscription);
     // get similar threads
     self::updateSimilarThreads($threadID, $subject, $boardID);
     return $thread;
 }
 /**
  * @see Form::save()
  */
 public function save()
 {
     if (!$this->canEditPost()) {
         throw new PermissionDeniedException();
     }
     // set the language temporarily to the thread language
     if ($this->thread->languageID && $this->thread->languageID != WCF::getLanguage()->getLanguageID()) {
         $this->setLanguage($this->thread->languageID);
     }
     MessageForm::save();
     // update subscription
     $this->thread->setSubscription($this->subscription);
     // save poll
     if ($this->showPoll) {
         $this->pollEditor->save();
     }
     // add edit note
     $postData = array();
     if (!$this->hideEditNote && (WCF::getUser()->userID != $this->post->userID || $this->post->time <= TIME_NOW - POST_EDIT_HIDE_EDIT_NOTE_PERIOD * 60)) {
         $postData['editor'] = WCF::getUser()->username;
         $postData['editorID'] = WCF::getUser()->userID;
         $postData['lastEditTime'] = TIME_NOW;
         $postData['editCount'] = $this->post->editCount + 1;
         $postData['editReason'] = $this->editReason;
     } else {
         if (!empty($this->editReason)) {
             $postData['editReason'] = $this->editReason;
         }
     }
     // update database entry
     $this->post->update($this->subject, $this->text, $this->getOptions(), $this->attachmentListEditor, $this->pollEditor, $postData);
     // reset language
     if ($this->userInterfaceLanguageID !== null) {
         $this->setLanguage($this->userInterfaceLanguageID, true);
     }
     $threadData = array();
     if ($this->thread->firstPostID == $this->post->postID) {
         // update thread topic
         if (!empty($this->subject)) {
             $threadData['topic'] = $this->subject;
         }
         // update thread prefix
         if ($this->board->getPermission('canUsePrefix')) {
             $threadData['prefix'] = $this->prefix;
         }
         // save tags
         if (MODULE_TAGGING && THREAD_ENABLE_TAGS && $this->board->getPermission('canSetTags')) {
             $this->thread->updateTags(TaggingUtil::splitString($this->tags));
         }
         // announcement
         if ($this->board->getModeratorPermission('canStartAnnouncement')) {
             if ($this->thread->isAnnouncement) {
                 $this->thread->removeAssignedBoards();
             }
             if ($this->isImportant == 2) {
                 $this->thread->assignBoards($this->boardIDs);
             }
             $threadData['isAnnouncement'] = intval($this->isImportant == 2);
         }
         // pin thread
         if ($this->board->getModeratorPermission('canPinThread')) {
             $threadData['isSticky'] = intval($this->isImportant == 1);
         }
         // set language
         if ($this->languageID != $this->thread->languageID) {
             $threadData['languageID'] = $this->languageID;
         }
     }
     // close / open thread
     if ($this->board->getModeratorPermission('canCloseThread')) {
         if (!$this->thread->isClosed && $this->closeThread) {
             $threadData['isClosed'] = 1;
         } else {
             if ($this->thread->isClosed && !$this->closeThread) {
                 $threadData['isClosed'] = 0;
             }
         }
     }
     // update thread
     $this->thread->update($threadData);
     // update last posts
     if ($this->thread->firstPostID == $this->post->postID && $this->languageID != $this->thread->languageID) {
         $this->board->setLastPosts();
         WCF::getCache()->clearResource('boardData');
     }
     $this->saved();
     // forward to post
     $url = 'index.php?page=Thread&postID=' . $this->postID . SID_ARG_2ND_NOT_ENCODED . '#post' . $this->postID;
     HeaderUtil::redirect($url);
     exit;
 }