Last active
August 29, 2015 14:24
-
-
Save joshuaadickerson/fea8b2dd1a5ca756f6a0 to your computer and use it in GitHub Desktop.
Working on refactoring. Taking a while and a lot of work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* The job of this file is to handle everything related to posting replies, | |
* new topics, quotes, and modifications to existing posts. It also handles | |
* quoting posts by way of javascript. | |
* | |
* @name ElkArte Forum | |
* @copyright ElkArte Forum contributors | |
* @license BSD http://opensource.org/licenses/BSD-3-Clause | |
* | |
* This software is a derived product, based on: | |
* | |
* Simple Machines Forum (SMF) | |
* copyright: 2011 Simple Machines (http://www.simplemachines.org) | |
* license: BSD, See included LICENSE.TXT for terms and conditions. | |
* | |
* @version 1.1 dev | |
* | |
*/ | |
if (!defined('ELK')) | |
die('No access...'); | |
/** | |
* Post Controller | |
*/ | |
class Post_Controller extends Action_Controller | |
{ | |
/** | |
* The post (messages) errors object | |
* @var null|object | |
*/ | |
protected $_post_errors = null; | |
/** | |
* The template layers object | |
* @var null|object | |
*/ | |
protected $_template_layers = null; | |
/** | |
* An array of attributes of the topic (if not new) | |
* @var mixed[] | |
*/ | |
protected $_topic_attributes = array( | |
'locked' => false, | |
'notify' => false, | |
'is_sticky' => false, | |
'id_last_msg' => 0, | |
'id_member' => 0, | |
'id_first_msg' => 0, | |
'subject' => '', | |
'last_post_time' => 0 | |
); | |
protected $msg_info = array(); | |
protected $msg_id; | |
protected $topic_info = array(); | |
protected $topic_id; | |
protected $becomes_approved = true; | |
protected $max_subject_length = 100; | |
protected $previewing = false; | |
/** | |
* Sets up common stuff for all or most of the actions. | |
*/ | |
public function pre_dispatch() | |
{ | |
global $context; | |
$this->_post_errors = Error_Context::context('post', 1); | |
$this->_template_layers = Template_Layers::getInstance(); | |
require_once(SUBSDIR . '/Post.subs.php'); | |
require_once(SUBSDIR . '/Messages.subs.php'); | |
require_once(SUBSDIR . '/Topic.subs.php'); | |
$this->topic_id = isset($GLOBALS['topic']) ?: (int) $GLOBALS['topic']; | |
$this->msg_id = empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg']; | |
// No need! | |
$context['robot_no_index'] = true; | |
} | |
/** | |
* Dispatch to the right action method for the request. | |
* | |
* @see Action_Controller::action_index() | |
*/ | |
public function action_index() | |
{ | |
// Figure out the right action to do. | |
// hint: I'm post controller. :P | |
$this->action_post(); | |
} | |
/** | |
* Handles showing the post screen, loading the post to be modified, and loading any post quoted. | |
* | |
* - additionally handles previews of posts. | |
* - requires different permissions depending on the actions, but most notably post_new, post_reply_own, and post_reply_any. | |
* - shows options for the editing and posting of calendar events and attachments, as well as the posting of polls (using modules). | |
* - accessed from ?action=post. | |
* | |
* @uses the Post template and language file, main sub template. | |
*/ | |
public function action_post() | |
{ | |
global $txt, $modSettings, $board, $user_info, $context; | |
loadLanguage('Post'); | |
loadLanguage('Errors'); | |
$this->_template_layers->add('postarea'); | |
$this->_events->trigger('prepare_post', array('topic_attributes' => &$this->_topic_attributes)); | |
// You must be posting to *some* board. | |
if (empty($board) && !$context['make_event']) | |
{ | |
Errors::instance()->fatal_lang_error('no_board', false); | |
} | |
// All those wonderful modifiers and attachments | |
$this->_template_layers->add('additional_options', 200); | |
// @todo should this moved to a separate function and be done in pre_dispatch()? | |
// No message is complete without a topic. | |
if (empty($this->topic_id) && !empty($this->msg_id)) | |
{ | |
$this->topic_id = associatedTopic($this->msg_id); | |
if (empty($this->topic_id)) | |
{ | |
unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']); | |
} | |
} | |
$context['becomes_approved'] = $this->setBecomesApproved(); | |
// Check if it's locked. It isn't locked if no topic is specified. | |
if (!$this->isNewTopic()) | |
{ | |
if (empty($this->msg_id) && $user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) | |
{ | |
is_not_guest(); | |
} | |
$this->_topic_attributes = topicUserAttributes($this->topic_id, $user_info['id']); | |
$context['notify'] = $this->_topic_attributes['notify']; | |
$context['topic_last_message'] = $this->_topic_attributes['id_last_msg']; | |
$context['can_lock'] = allowedTo('lock_any') || ($user_info['id'] == $this->_topic_attributes['id_member'] && allowedTo('lock_own')); | |
} | |
else | |
{ | |
if ((!$context['make_event'] || !empty($board)) && !($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics'))) | |
{ | |
isAllowedTo('post_new'); | |
} | |
// @todo These won't work if you're making an event. | |
$context['can_lock'] = allowedTo(array('lock_any', 'lock_own')); | |
} | |
// Don't allow a post if it's locked and you aren't all powerful. | |
if ($this->_topic_attributes['locked'] && !allowedTo('moderate_board')) | |
{ | |
Errors::instance()->fatal_lang_error('topic_locked', false); | |
} | |
try | |
{ | |
$this->_events->trigger('prepare_context', array('id_member_poster' => $this->_topic_attributes['id_member'])); | |
} | |
catch (Controller_Redirect_Exception $e) | |
{ | |
return $e->doRedirect($this); | |
} | |
// See if any new replies have come along. | |
if ($this->isNewReply() && $this->hasNewRepliesSincePosting()) | |
{ | |
$this->newRepliesContext(); | |
} | |
$context['destination'] = 'post2;start=' . $_REQUEST['start']; | |
// Previewing, modifying, or posting? | |
// Do we have a body, but an error happened. | |
if (isset($_REQUEST['message']) || $this->_post_errors->hasErrors()) | |
{ | |
// Set up the inputs for the form. | |
$form_subject = $this->getSubject(false); | |
$form_message = $this->getBody(false); | |
// Validate inputs. | |
if (!$this->_post_errors->hasErrors()) | |
{ | |
// This means they didn't click Post and get an error. | |
$this->previewing = true; | |
} | |
else | |
{ | |
// They are previewing if they asked to preview (i.e. came from quick reply). | |
$this->previewing = !empty($_REQUEST['preview']) || isset($_REQUEST['xml']); | |
} | |
$this->setupPreview(); | |
if (!$this->isModifyingMessage() && isset($_REQUEST['last_msg'])) | |
{ | |
list ($form_subject,) = getFormMsgSubject($this->getEditingCase(), $this->topic_id, $this->_topic_attributes['subject']); | |
} | |
} | |
// Editing a message... | |
elseif ($this->isModifyingMessage()) | |
{ | |
$message = getFormMsgSubject(1, $this->topic_id, '', $this->msg_id); | |
// The message they were trying to edit was most likely deleted. | |
if ($message === false) | |
{ | |
Errors::instance()->fatal_lang_error('no_message', false); | |
} | |
$this->_events->trigger('prepare_editing', array('topic' => $this->topic_id, 'message' => &$message)); | |
if (!empty($message['errors'])) | |
{ | |
foreach ($message['errors'] as $error) | |
{ | |
$this->_post_errors->addError($error); | |
} | |
} | |
censorText($message['message']['subject']); | |
censorText(un_preparsecode($message['message']['body'])); | |
// Get the stuff ready for the form. | |
$form_subject = $message['message']['subject']; | |
$form_message = $message['message']['body']; | |
// Check the boxes that should be checked. | |
$context['use_smileys'] = !empty($message['message']['smileys_enabled']); | |
$context['icon'] = $message['message']['icon']; | |
// Set the destination. | |
$context['destination'] .= ';msg=' . $this->msg_id . ';' . $context['session_var'] . '=' . $context['session_id']; | |
$context['submit_label'] = $txt['save']; | |
} | |
// Posting... | |
else | |
{ | |
// By default.... | |
$context['use_smileys'] = true; | |
if ($user_info['is_guest']) | |
{ | |
$context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : ''; | |
$context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : ''; | |
} | |
$this->_events->trigger('prepare_posting'); | |
$context['submit_label'] = $txt['post']; | |
list ($form_subject, $form_message) = getFormMsgSubject($this->getEditingCase(), $this->topic_id, $this->_topic_attributes['subject']); | |
} | |
// Check whether this is a really old post being bumped... | |
$this->isOldPost(); | |
$this->_events->trigger('post_errors'); | |
// Any errors occurred? | |
$context['post_error'] = array( | |
'errors' => $this->_post_errors->prepareErrors(), | |
'type' => $this->_post_errors->getErrorType() == 0 ? 'minor' : 'serious', | |
'title' => $this->_post_errors->getErrorType() == 0 ? $txt['warning_while_submitting'] : $txt['error_while_submitting'], | |
); | |
// Update the topic summary, needed to show new posts in a preview | |
if (!$this->isNewTopic() && !empty($modSettings['topicSummaryPosts'])) | |
{ | |
$this->getPreviousPosts(); | |
} | |
// Just ajax previewing then lets stop now | |
if (isset($_REQUEST['xml'])) | |
{ | |
$context['sub_template'] = 'post'; | |
// Just in case of an earlier error... | |
$context['preview_message'] = ''; | |
$context['preview_subject'] = ''; | |
obExit(); | |
} | |
$this->postPageContext($form_subject, $form_message); | |
// Register this form in the session variables. | |
checkSubmitOnce('register'); | |
// Finally, load the template. | |
loadTemplate('Post'); | |
$context['sub_template'] = 'post_page'; | |
} | |
/** | |
* Posts or saves the message composed with Post(). | |
* | |
* requires various permissions depending on the action. | |
* handles attachment, post, and calendar saving. | |
* sends off notifications, and allows for announcements and moderation. | |
* accessed from ?action=post2. | |
*/ | |
public function action_post2() | |
{ | |
global $board, $context, $user_settings; | |
global $user_info, $board_info, $modSettings; | |
// Sneaking off, are we? | |
if (empty($_POST) && $this->isNewTopic()) | |
{ | |
if (empty($_SERVER['CONTENT_LENGTH'])) | |
{ | |
redirectexit('action=post;board=' . $board . '.0'); | |
} | |
else | |
{ | |
Errors::instance()->fatal_lang_error('post_upload_error', false); | |
} | |
} | |
elseif (empty($_POST) && !$this->isNewTopic()) | |
{ | |
redirectexit('action=post;topic=' . $this->topic_id . '.0'); | |
} | |
// We are now in post2 action | |
$context['current_action'] = 'post2'; | |
// If the session has timed out, let the user re-submit their form. | |
if (checkSession('post', '', false) != '') | |
{ | |
$this->_post_errors->addError('session_timeout'); | |
// Disable the preview so that any potentially malicious code is not executed | |
$_REQUEST['preview'] = false; | |
return $this->action_post(); | |
} | |
// Previewing? Go back to start. | |
if (isset($_REQUEST['preview'])) | |
{ | |
return $this->action_post(); | |
} | |
require_once(SUBSDIR . '/Boards.subs.php'); | |
loadLanguage('Post'); | |
// Prevent double submission of this form. | |
checkSubmitOnce('check'); | |
// If this isn't a new topic load the topic info that we need. | |
if (!$this->isNewTopic()) | |
{ | |
$this->getTopicInfo(); | |
if (!empty($this->topic_info['locked']) && !allowedTo('moderate_board')) | |
{ | |
Errors::instance()->fatal_lang_error('topic_locked', false); | |
} | |
// Replying to a topic? | |
if ($this->isNewReply()) | |
{ | |
$this->newReply(); | |
} | |
// Modifying an existing message. | |
elseif ($this->isModifyingMessage()) | |
{ | |
$this->msg_info = basicMessageInfo($this->msg_id, true); | |
if (empty($this->msg_info)) | |
{ | |
Errors::instance()->fatal_lang_error('cant_find_messages', false); | |
} | |
$this->modifyMessage(); | |
} | |
} | |
// Posting a new topic. | |
else | |
{ | |
$this->newTopic(); | |
// If the number of replies has changed, if the setting is enabled, go back to action_post() - which handles the error. | |
if ($this->hasNewRepliesSincePosting()) | |
{ | |
return $this->action_post(); | |
} | |
} | |
// If the poster is a guest evaluate the legality of name and email. | |
if ($this->posterIsGuest()) | |
{ | |
$email = $this->getGuestEmail(); | |
$guestname = $this->getGuestName(); | |
} | |
try | |
{ | |
$this->_events->trigger('before_save_post', array('post_errors' => $this->_post_errors, 'topic_info' => &$this->topic_info)); | |
} | |
catch (Controller_Redirect_Exception $e) | |
{ | |
return $e->doRedirect($this); | |
} | |
// Check the subject and message. | |
$subject = $this->getSubject(); | |
$body = $this->getBody(); | |
// if new message | |
if (empty($this->msg_id)) | |
{ | |
$guestname = $user_info['username']; | |
$email = $user_info['email']; | |
} | |
// Posting somewhere else? Are we sure you can? | |
if (!empty($_REQUEST['post_in_board'])) | |
{ | |
$new_board = (int) $_REQUEST['post_in_board']; | |
if (!allowedTo('post_new', $new_board)) | |
{ | |
$post_in_board = boardInfo($new_board); | |
if (!empty($post_in_board)) | |
{ | |
$this->_post_errors->addError(array('post_new_board', array($post_in_board['name']))); | |
} | |
else | |
{ | |
$this->_post_errors->addError('post_new'); | |
} | |
} | |
} | |
// Any mistakes? | |
if ($this->_post_errors->hasErrors()) | |
{ | |
return $this->action_post(); | |
} | |
// Make sure the user isn't spamming the board. | |
if (!$this->isModifyingMessage()) | |
{ | |
spamProtection('post'); | |
} | |
// At about this point, we're posting and that's that. | |
ignore_user_abort(true); | |
setTimeLimit(300); | |
$msgOptions = $this->getMessageOptions($subject, $body); | |
$topicOptions = $this->getTopicOptions(true); | |
$posterOptions = $this->getPosterOptions($guestname, $email); | |
// @todo move this up higher so the get*Options() requests can load everything? | |
// We also have to fake the board: | |
// if it's valid and it's not the current, let's forget about the "current" and load the new one | |
if (empty($this->msg_id) && !empty($_REQUEST['post_in_board'])) | |
{ | |
$new_board = (int) $_REQUEST['post_in_board']; | |
if (!empty($new_board) && $board !== $new_board) | |
{ | |
$board = $new_board; | |
loadBoard(); | |
// Some details changed | |
$topicOptions['board'] = $board; | |
$topicOptions['is_approved'] = !$modSettings['postmod_active'] || empty($this->topic_id) || !empty($board_info['cur_topic_approved']); | |
$posterOptions['update_post_count'] = !$user_info['is_guest'] && empty($this->msg_id) && $board_info['posts_count']; | |
} | |
} | |
$this->savePost($msgOptions, $topicOptions, $posterOptions); | |
// Marking boards as read. | |
// (You just posted and they will be unread.) | |
if (!$user_info['is_guest']) | |
{ | |
$board_list = !empty($board_info['parent_boards']) ? array_keys($board_info['parent_boards']) : array(); | |
// Returning to the topic? | |
if (!empty($_REQUEST['goback'])) | |
{ | |
$board_list[] = $board; | |
} | |
if (!empty($board_list)) | |
{ | |
markBoardsRead($board_list, false, false); | |
} | |
} | |
// Turn notification on or off. | |
if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) | |
{ | |
setTopicNotification($user_info['id'], $this->topic_id, true); | |
} | |
elseif (!$this->isNewTopic()) | |
{ | |
setTopicNotification($user_info['id'], $this->topic_id, false); | |
} | |
// Log an act of moderation - modifying. | |
if (!empty($this->moderationAction)) | |
{ | |
logAction('modify', array('topic' => $this->topic_id, 'message' => (int) $this->msg_id, 'member' => $this->msg_info['id_member'], 'board' => $board)); | |
} | |
if (isset($_POST['lock']) && $_POST['lock'] != 2) | |
{ | |
logAction(empty($_POST['lock']) ? 'unlock' : 'lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board'])); | |
} | |
if (isset($_POST['sticky'])) | |
{ | |
logAction(empty($_POST['sticky']) ? 'unsticky' : 'sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board'])); | |
} | |
// Notify any members who have notification turned on for this topic/board - only do this if it's going to be approved(!) | |
if ($this->becomes_approved) | |
{ | |
require_once(SUBSDIR . '/Notification.subs.php'); | |
if ($this->isNewTopic()) | |
{ | |
$notifyData = array( | |
'body' => $body, | |
'subject' => $subject, | |
'name' => $user_info['name'], | |
'poster' => $user_info['id'], | |
'msg' => $msgOptions['id'], | |
'board' => $board, | |
'topic' => $this->topic_id, | |
'signature' => (isset($user_settings['signature']) ? $user_settings['signature'] : ''), | |
); | |
sendBoardNotifications($notifyData); | |
} | |
elseif (empty($this->msg_id)) | |
{ | |
// Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it. | |
if ($this->topic_info['approved']) | |
{ | |
sendNotifications($this->topic_id, 'reply'); | |
} | |
else | |
{ | |
sendNotifications($this->topic_id, 'reply', array(), $this->topic_info['id_member_started']); | |
} | |
} | |
} | |
if ($board_info['num_topics'] == 0) | |
{ | |
cache_put_data('board-' . $board, null, 120); | |
} | |
// Now, where do we exit to? | |
if (!empty($_POST['announce_topic'])) | |
{ | |
redirectexit('action=announce;sa=selectgroup;topic=' . $this->topic_id . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback')); | |
} | |
if (!empty($_POST['move']) && allowedTo('move_any')) | |
{ | |
redirectexit('action=movetopic;topic=' . $this->topic_id . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback')); | |
} | |
// Return to post if the mod is on. | |
if (isset($this->msg_id) && !empty($_REQUEST['goback'])) | |
{ | |
redirectexit('topic=' . $this->topic_id . '.msg' . $this->msg_id . '#msg' . $this->msg_id, isBrowser('ie')); | |
} | |
elseif (!empty($_REQUEST['goback'])) | |
{ | |
redirectexit('topic=' . $this->topic_id . '.new#new', isBrowser('ie')); | |
} | |
// Dut-dut-duh-duh-DUH-duh-dut-duh-duh! *dances to the Final Fantasy Fanfare...* | |
else | |
{ | |
redirectexit('board=' . $board . '.0'); | |
} | |
} | |
/** | |
* Loads a post and inserts it into the current editing text box. | |
* Used to quick edit a post as well as to quote a post and place it in the quick reply box | |
* Can be used to quick edit just the subject from the topic listing | |
* | |
* uses the Post language file. | |
* uses special (sadly browser dependent) javascript to parse entities for internationalization reasons. | |
* accessed with ?action=quotefast and ?action=quotefast;modify | |
*/ | |
public function action_quotefast() | |
{ | |
global $user_info, $context; | |
loadLanguage('Post'); | |
// @todo check that $_GET['quote'] exists | |
// Where we going if we need to? | |
$context['post_box_name'] = isset($_GET['pb']) ? $_GET['pb'] : ''; | |
$row = quoteMessageInfo((int) $_GET['quote'], isset($_GET['modify'])); | |
$context['sub_template'] = 'quotefast'; | |
if (!empty($row)) | |
{ | |
$can_view_post = $row['approved'] || ($row['id_member'] != 0 && $row['id_member'] == $user_info['id']) || allowedTo('approve_posts', $row['id_board']); | |
} | |
if (!empty($can_view_post)) | |
{ | |
// Remove special formatting we don't want anymore. | |
$row['body'] = un_preparsecode($row['body']); | |
// Censor the message! | |
censorText($row['body']); | |
$row['body'] = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']); | |
// Want to modify a single message by double clicking it? | |
if (isset($_GET['modify'])) | |
{ | |
censorText($row['subject']); | |
$context['sub_template'] = 'modifyfast'; | |
$context['message'] = array( | |
'id' => $_GET['quote'], | |
'body' => $row['body'], | |
'subject' => addcslashes($row['subject'], '"'), | |
); | |
return; | |
} | |
// Remove any nested quotes. | |
$row['body'] = $this->removeNestedQuotes($row['body']); | |
// Add a quote string on the front and end. | |
$context['quote']['xml'] = '[quote author=' . $row['poster_name'] . ' link=msg=' . (int) $_GET['quote'] . ' date=' . $row['poster_time'] . "]\n" . $row['body'] . "\n[/quote]"; | |
$context['quote']['text'] = strtr(un_htmlspecialchars($context['quote']['xml']), array('\'' => '\\\'', '\\' => '\\\\', "\n" => '\\n', '</script>' => '</\' + \'script>')); | |
$context['quote']['xml'] = strtr($context['quote']['xml'], array(' ' => ' ', '<' => '<', '>' => '>')); | |
$context['quote']['mozilla'] = strtr(Util::htmlspecialchars($context['quote']['text']), array('"' => '"')); | |
} | |
//@todo Needs a nicer interface. | |
// In case our message has been removed in the meantime. | |
elseif (isset($_GET['modify'])) | |
{ | |
$context['sub_template'] = 'modifyfast'; | |
$context['message'] = array( | |
'id' => 0, | |
'body' => '', | |
'subject' => '', | |
); | |
} | |
else | |
{ | |
$context['quote'] = array( | |
'xml' => '', | |
'mozilla' => '', | |
'text' => '', | |
); | |
} | |
} | |
/** | |
* Used to edit the body or subject of a message inline | |
* called from action=jsmodify from script and topic js | |
*/ | |
public function action_jsmodify() | |
{ | |
global $board, $user_info, $context; | |
// We have to have a topic! | |
if (empty($this->topic_id)) | |
{ | |
obExit(false); | |
} | |
checkSession('get'); | |
$this->topic_info = getTopicInfoByMsg($this->topic_id, empty($this->msg_id) ? 0 : (int) $this->msg_id); | |
if (empty($this->topic_info)) | |
{ | |
Errors::instance()->fatal_lang_error('no_board', false); | |
} | |
// Since getTopicInfoByMsg() has all of the msg_info in it, this saves space. | |
$this->msg_info = $this->topic_info; | |
// Change either body or subject requires permissions to modify messages. | |
if (isset($_POST['message']) || isset($_POST['subject']) || isset($_REQUEST['icon'])) | |
{ | |
$this->modifyMessage(); | |
} | |
$subject = $this->getSubject(); | |
$body = $this->getBody(); | |
if (!$this->_post_errors->hasErrors()) | |
{ | |
$msgOptions = $this->getMessageOptions($subject, $body); | |
$topicOptions = $this->getTopicOptions(false); | |
$posterOptions = array(); | |
// Only consider marking as editing if they have edited the subject, message or icon. | |
if ((!empty($subject) && $subject != $this->topic_info['subject']) || (!empty($body) && $body != $this->topic_info['body']) || (isset($_REQUEST['icon']) && $_REQUEST['icon'] != $this->topic_info['icon'])) | |
{ | |
// // And even then only if the time has passed... | |
// if (time() - $this->topic_info['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $this->topic_info['id_member']) | |
// { | |
// $msgOptions['modify_time'] = time(); | |
// $msgOptions['modify_name'] = $user_info['name']; | |
// } | |
} | |
// If nothing was changed there's no need to add an entry to the moderation log. | |
if (!(!empty($subject) && $subject != $this->topic_info['subject']) || (!empty($body) && $body != $this->topic_info['body']) || (isset($_REQUEST['icon']) && $_REQUEST['icon'] != $this->topic_info['icon'])) | |
{ | |
$this->moderationAction = false; | |
} | |
modifyPost($msgOptions, $topicOptions, $posterOptions); | |
// If we didn't change anything this time but had before put back the old info. | |
if (!isset($msgOptions['modify_time']) && !empty($this->topic_info['modified_time'])) | |
{ | |
$msgOptions['modify_time'] = $this->topic_info['modified_time']; | |
$msgOptions['modify_name'] = $this->topic_info['modified_name']; | |
} | |
// Changing the first subject updates other subjects to 'Re: new_subject'. | |
if (!empty($subject) && isset($_REQUEST['change_all_subjects']) && $this->topic_info['id_first_msg'] == $this->topic_info['id_msg'] && !empty($this->topic_info['num_replies']) && (allowedTo('modify_any') || ($this->topic_info['id_member_started'] == $user_info['id'] && allowedTo('modify_replies')))) | |
{ | |
// Get the proper (default language) response prefix first. | |
$context['response_prefix'] = response_prefix(); | |
topicSubject(array('id_topic' => $this->topic_id, 'id_first_msg' => $this->topic_info['id_first_msg']), $subject, $context['response_prefix'], true); | |
} | |
if (!empty($this->moderationAction)) | |
{ | |
logAction('modify', array('topic' => $this->topic_id, 'message' => $this->topic_info['id_msg'], 'member' => $this->topic_info['id_member'], 'board' => $board)); | |
} | |
} | |
if (isset($_REQUEST['xml'])) | |
{ | |
$this->jsmodifyXMLContext($msgOptions); | |
} | |
else | |
{ | |
obExit(false); | |
} | |
} | |
protected function jsmodifyXMLContext($msgOptions) | |
{ | |
$context['sub_template'] = 'modifydone'; | |
if (!$this->_post_errors->hasErrors() && isset($msgOptions['subject']) && isset($msgOptions['body'])) | |
{ | |
$context['message'] = array( | |
'id' => $this->topic_info['id_msg'], | |
'modified' => array( | |
'time' => isset($msgOptions['modify_time']) ? standardTime($msgOptions['modify_time']) : '', | |
'html_time' => isset($msgOptions['modify_time']) ? htmlTime($msgOptions['modify_time']) : '', | |
'timestamp' => isset($msgOptions['modify_time']) ? forum_time(true, $msgOptions['modify_time']) : 0, | |
'name' => isset($msgOptions['modify_time']) ? $msgOptions['modify_name'] : '', | |
), | |
'subject' => $msgOptions['subject'], | |
'first_in_topic' => $this->topic_info['id_msg'] == $this->topic_info['id_first_msg'], | |
'body' => strtr($msgOptions['body'], array(']]>' => ']]]]><![CDATA[>')), | |
); | |
censorText($context['message']['subject']); | |
censorText($context['message']['body']); | |
$context['message']['body'] = parse_bbc($context['message']['body'], $this->topic_info['smileys_enabled'], $this->topic_info['id_msg']); | |
} | |
// Topic? | |
elseif (!$this->_post_errors->hasErrors()) | |
{ | |
$context['sub_template'] = 'modifytopicdone'; | |
$context['message'] = array( | |
'id' => $this->topic_info['id_msg'], | |
'modified' => array( | |
'time' => isset($msgOptions['modify_time']) ? standardTime($msgOptions['modify_time']) : '', | |
'html_time' => isset($msgOptions['modify_time']) ? htmlTime($msgOptions['modify_time']) : '', | |
'timestamp' => isset($msgOptions['modify_time']) ? forum_time(true, $msgOptions['modify_time']) : 0, | |
'name' => isset($msgOptions['modify_time']) ? $msgOptions['modify_name'] : '', | |
), | |
'subject' => isset($msgOptions['subject']) ? $msgOptions['subject'] : '', | |
); | |
censorText($context['message']['subject']); | |
} | |
else | |
{ | |
$context['message'] = array( | |
'id' => $this->topic_info['id_msg'], | |
'errors' => array(), | |
'error_in_subject' => $this->_post_errors->hasError('no_subject'), | |
'error_in_body' => $this->_post_errors->hasError('no_message') || $this->_post_errors->hasError('long_message'), | |
); | |
$context['message']['errors'] = $this->_post_errors->prepareErrors(); | |
} | |
} | |
protected function _checkLocked($lock) | |
{ | |
global $user_info; | |
// A new topic | |
if (empty($this->topic_info)) | |
{ | |
// New topics are by default not locked. | |
if (empty($lock)) | |
{ | |
return; | |
} | |
// Besides, you need permission. | |
elseif (!allowedTo(array('lock_any', 'lock_own'))) | |
{ | |
return; | |
} | |
// A moderator-lock (1) can override a user-lock (2). | |
else | |
{ | |
return allowedTo('lock_any') ? 1 : 2; | |
} | |
} | |
// Nothing changes to the lock status. | |
if ((empty($lock) && empty($this->topic_info['locked'])) || (!empty($lock) && !empty($this->topic_info['locked']))) | |
{ | |
return; | |
} | |
// You're simply not allowed to (un)lock this. | |
elseif (!allowedTo(array('lock_any', 'lock_own')) || (!allowedTo('lock_any') && $user_info['id'] != $this->topic_info['id_member_started'])) | |
{ | |
return; | |
} | |
// You're only allowed to lock your own topics. | |
elseif (!allowedTo('lock_any')) | |
{ | |
// You're not allowed to break a moderator's lock. | |
if ($this->topic_info['locked'] == 1) | |
{ | |
return; | |
} | |
// Lock it with a soft lock or unlock it. | |
else | |
{ | |
$lock = empty($lock) ? 0 : 2; | |
} | |
} | |
// You must be the moderator. | |
else | |
{ | |
$lock = empty($lock) ? 0 : 1; | |
} | |
return $lock; | |
} | |
protected function newTopic() | |
{ | |
// Now don't be silly, new topics will get their own id_msg soon enough. | |
unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']); | |
// Do like, the permissions, for safety and stuff... | |
$this->setBecomesApproved(); | |
$this->_events->trigger('save_new_topic', array('becomes_approved' => &$this->becomes_approved)); | |
} | |
protected function newReply() | |
{ | |
$this->setBecomesApproved(); | |
// So you wanna (un)sticky this...let's see. | |
if (isset($_POST['sticky']) && ($_POST['sticky'] == $this->topic_info['is_sticky'] || !allowedTo('make_sticky'))) | |
{ | |
unset($_POST['sticky']); | |
} | |
$this->_events->trigger('save_replying', array('topic_info' => &$this->topic_info)); | |
} | |
protected function modifyMessage() | |
{ | |
global $modSettings, $user_info; | |
$this->_events->trigger('save_modify', array('msgInfo' => &$this->msg_info)); | |
if ($this->msg_info['id_member'] == $user_info['id'] && !allowedTo('modify_any')) | |
{ | |
if ((!$modSettings['postmod_active'] || $this->msg_info['approved']) && !empty($modSettings['edit_disable_time']) && $this->msg_info['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) | |
{ | |
Errors::instance()->fatal_lang_error('modify_post_time_passed', false); | |
} | |
elseif ($this->topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) | |
{ | |
isAllowedTo('modify_replies'); | |
} | |
else | |
{ | |
isAllowedTo('modify_own'); | |
} | |
} | |
elseif ($this->topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) | |
{ | |
isAllowedTo('modify_replies'); | |
// If you're modifying a reply, I say it better be logged... | |
$this->moderationAction = true; | |
} | |
else | |
{ | |
isAllowedTo('modify_any'); | |
// Log it, assuming you're not modifying your own post. | |
if ($this->msg_info['id_member'] != $user_info['id']) | |
{ | |
$this->moderationAction = true; | |
} | |
} | |
if (!allowedTo('moderate_forum') || !$this->posterIsGuest()) | |
{ | |
$_POST['guestname'] = $this->msg_info['poster_name']; | |
$_POST['email'] = $this->msg_info['poster_email']; | |
} | |
} | |
public function isNewTopic() | |
{ | |
return empty($GLOBALS['topic']); | |
} | |
public function isNewReply() | |
{ | |
return !$this->isNewTopic() && empty($this->msg_id); | |
} | |
public function isModifyingMessage() | |
{ | |
return !empty($this->msg_id) && !$this->isNewTopic(); | |
} | |
protected function getTopicInfo() | |
{ | |
global $board; | |
$this->topic_info = getTopicInfo($this->topic_id); | |
$this->_events->trigger('prepare_save_post', array('topic_info' => &$this->topic_info)); | |
// Though the topic should be there, it might have vanished. | |
if (empty($this->topic_info)) | |
{ | |
Errors::instance()->fatal_lang_error('topic_doesnt_exist'); | |
} | |
// Did this topic suddenly move? Just checking... | |
if ($this->topic_info['id_board'] != $board) | |
{ | |
Errors::instance()->fatal_lang_error('not_a_topic'); | |
} | |
return $this->topic_info; | |
} | |
protected function getSubject($validate = true) | |
{ | |
if ($validate && (!isset($_REQUEST['subject']) || Util::htmltrim(Util::htmlspecialchars($_REQUEST['subject'])) === '')) | |
{ | |
$this->_post_errors->addError('no_subject'); | |
} | |
else | |
{ | |
$subject = !isset($_REQUEST['subject']) ? '' : $_REQUEST['subject']; | |
return $this->filterSubject($subject); | |
} | |
} | |
protected function filterSubject($subject) | |
{ | |
$subject = strtr(Util::htmlspecialchars($subject), array("\r" => '', "\n" => '', "\t" => '')); | |
// Make sure the subject isn't too long - taking into account special characters. | |
if (Util::strlen($subject) > $this->max_subject_length) | |
{ | |
$subject = Util::substr($subject, 0, $this->max_subject_length); | |
} | |
return $subject; | |
} | |
/** | |
* | |
* @return string | |
*/ | |
protected function getBody($validate = false) | |
{ | |
global $modSettings, $user_info; | |
if (!isset($_REQUEST['message'])) | |
{ | |
if ($validate) | |
{ | |
$this->_post_errors->addError('no_message'); | |
} | |
return ''; | |
} | |
$body = Util::htmltrim(Util::htmlspecialchars($_REQUEST['message'], ENT_QUOTES)); | |
if (!empty($modSettings['max_messageLength']) && Util::strlen($_REQUEST['message']) > $modSettings['max_messageLength']) | |
{ | |
if ($validate) | |
{ | |
$this->_post_errors->addError(array('long_message', array($modSettings['max_messageLength']))); | |
} | |
} | |
else | |
{ | |
// Prepare the message a bit for some additional testing. | |
//$body = Util::htmlspecialchars($_REQUEST['message'], ENT_QUOTES); | |
// Preparse code. (Zef) | |
if ($user_info['is_guest']) | |
{ | |
$user_info['name'] = $_REQUEST['guestname']; | |
} | |
preparsecode($body); | |
// Let's see if there's still some content left without the tags. | |
if ($validate && Util::htmltrim(strip_tags(parse_bbc($body, false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($body, '[html]') === false)) | |
{ | |
$this->_post_errors->addError('no_message'); | |
} | |
} | |
return $body; | |
} | |
/** | |
* | |
* @return string | |
*/ | |
protected function getGuestName($validate = true) | |
{ | |
$guestname = !isset($_REQUEST['guestname']) ? '' : Util::htmlspecialchars(trim($_REQUEST['guestname'])); | |
if ($validate) | |
{ | |
$this->validateGuestName($guestname); | |
} | |
return $guestname; | |
} | |
protected function validateGuestName($guestname) | |
{ | |
if ($guestname == '' || $guestname == '_') | |
{ | |
$this->_post_errors->addError('no_name'); | |
} | |
if (Util::strlen($guestname) > 25) | |
{ | |
$this->_post_errors->addError('long_name'); | |
} | |
// If user is a guest, make sure the chosen name isn't taken. | |
require_once(SUBSDIR . '/Members.subs.php'); | |
if (isReservedName($guestname, 0, true, false) && (!isset($this->msg_info['poster_name']) || $guestname != $this->msg_info['poster_name'])) | |
{ | |
$this->_post_errors->addError('bad_name'); | |
} | |
// In case they are making multiple posts this visit, help them along by storing their name. | |
if (!$this->_post_errors->hasErrors()) | |
{ | |
$_SESSION['guest_name'] = $guestname; | |
} | |
} | |
/** | |
* | |
* @return string | |
*/ | |
public function getGuestEmail($validate = true) | |
{ | |
global $modSettings, $txt; | |
$email = !isset($_REQUEST['email']) ? '' : Util::htmlspecialchars(trim($_REQUEST['email'])); | |
if (!$validate) | |
{ | |
return $email; | |
} | |
if (empty($modSettings['guest_post_no_email'])) | |
{ | |
// Only check if they changed it! | |
if (!isset($this->msg_info) || $this->msg_info['poster_email'] != $email) | |
{ | |
if (!allowedTo('moderate_forum') && !Data_Validator::is_valid($_POST, array('email' => 'valid_email|required'), array('email' => 'trim'))) | |
{ | |
empty($email) ? $this->_post_errors->addError('no_email') : $this->_post_errors->addError('bad_email'); | |
} | |
} | |
// Now make sure this email address is not banned from posting. | |
isBannedEmail($email, 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title'])); | |
} | |
if (!$this->_post_errors->hasErrors()) | |
{ | |
$_SESSION['guest_email'] = $email; | |
} | |
return $email; | |
} | |
/** | |
* | |
* @return bool | |
*/ | |
protected function posterIsGuest() | |
{ | |
global $user_info; | |
if ($this->isModifyingMessage()) | |
{ | |
$posterIsGuest = empty($this->msg_info['id_member']); | |
} | |
else | |
{ | |
$posterIsGuest = $user_info['is_guest']; | |
} | |
return $posterIsGuest; | |
} | |
/** | |
* | |
* @return int | |
*/ | |
protected function getEditingCase() | |
{ | |
global $modSettings; | |
// @todo: sort out what kind of combinations are actually possible | |
// Posting a quoted reply? | |
if ((!empty($this->topic_id) && !empty($_REQUEST['quote'])) || (!empty($modSettings['enableFollowup']) && !empty($_REQUEST['followup']))) | |
{ | |
$case = 2; | |
} | |
// Posting a reply without a quote? | |
elseif (!empty($this->topic_id) && empty($_REQUEST['quote'])) | |
{ | |
$case = 3; | |
} | |
else | |
{ | |
$case = 4; | |
} | |
return $case; | |
} | |
protected function getMessageOptions($subject, $body) | |
{ | |
global $modSettings, $user_info; | |
$msgOptions = array( | |
'id' => $this->msg_id, | |
'subject' => $subject, | |
'body' => $body, | |
'icon' => $this->getIcon(), | |
'smileys_enabled' => !isset($_POST['ns']), | |
'approved' => $this->becomes_approved, | |
); | |
if (!$this->isModifyingMessage()) | |
{ | |
// Have admins allowed people to hide their screwups? | |
if (time() - $this->msg_info['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $this->msg_info['id_member']) | |
{ | |
$msgOptions['modify_time'] = time(); | |
$msgOptions['modify_name'] = $user_info['name']; | |
} | |
// If we didn't change anything this time but had before put back the old info. | |
elseif (!empty($this->topic_info['modified_time'])) | |
{ | |
$msgOptions['modify_time'] = $this->topic_info['modified_time']; | |
$msgOptions['modify_name'] = $this->topic_info['modified_name']; | |
} | |
// This will save some time... | |
if ($this->msg_info['approved'] != $this->becomes_approved) | |
{ | |
unset($msgOptions['approved']); | |
} | |
} | |
return $msgOptions; | |
} | |
protected function getTopicOptions($mark_as_read) | |
{ | |
global $board, $modSettings, $board_info; | |
$lock = isset($_POST['lock']) ?: $this->_checkLocked($_POST['lock'], $this->topic_info); | |
// Sticky can be null (no change), 1 sticky, 0 not sticky | |
$sticky = null; | |
if (isset($_POST['sticky']) && allowedTo('make_sticky')) | |
{ | |
$sticky = (int) $_POST['sticky']; | |
} | |
$topicOptions = array( | |
'id' => empty($this->topic_id) ? 0 : $this->topic_id, | |
'board' => $board, | |
'lock_mode' => $lock, | |
'sticky_mode' => $sticky, | |
'mark_as_read' => $mark_as_read, | |
'is_approved' => !$modSettings['postmod_active'] || empty($this->topic_id) || !empty($board_info['cur_topic_approved']), | |
); | |
return $topicOptions; | |
} | |
public function savePost($msgOptions, $topicOptions, $posterOptions) | |
{ | |
$this->_events->trigger('pre_save_post', array('msgOptions' => &$msgOptions, 'topicOptions' => &$topicOptions, 'posterOptions' => &$posterOptions)); | |
// This is an already existing message. Edit it. | |
if (!empty($this->msg_id)) | |
{ | |
modifyPost($msgOptions, $topicOptions, $posterOptions); | |
} | |
// This is a new topic or an already existing one. Save it. | |
else | |
{ | |
createPost($msgOptions, $topicOptions, $posterOptions); | |
if (isset($topicOptions['id'])) | |
{ | |
$this->topic_id = $topicOptions['id']; | |
} | |
} | |
$this->_events->trigger('after_save_post', array('msgOptions' => $msgOptions, 'topicOptions' => $topicOptions, 'becomes_approved' => $this->becomes_approved, 'posterOptions' => $posterOptions)); | |
} | |
protected function setBecomesApproved() | |
{ | |
global $modSettings, $user_info; | |
// If no postmod, it is always approved. | |
if (!$modSettings['postmod_active']) | |
{ | |
return true; | |
} | |
if ($this->isModifyingMessage()) | |
{ | |
$this->becomes_approved = (allowedTo('approve_posts') && !$this->msgInfo['approved'] ? (!empty($_REQUEST['approve']) ? true : false) : $$this->msgInfo['approved']); | |
return $this->becomes_approved; | |
} | |
// In case we want to override | |
if (allowedTo('approve_posts')) | |
{ | |
$this->becomes_approved = !isset($_REQUEST['approve']) || !empty($_REQUEST['approve']) ? true : false; | |
return $this>becomes_approved; | |
} | |
if($this->isNewTopic()) | |
{ | |
if (!allowedTo('post_new') && allowedTo('post_unapproved_topics')) | |
{ | |
$this->becomes_approved = false; | |
} | |
else | |
{ | |
isAllowedTo('post_new'); | |
} | |
return $this->becomes_approved; | |
} | |
// Lastly, a new reply | |
if ($this->topic_info['id_member_started'] != $user_info['id']) | |
{ | |
if (allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) | |
{ | |
$this->becomes_approved = false; | |
} | |
else | |
{ | |
isAllowedTo('post_reply_any'); | |
} | |
} | |
elseif (!allowedTo('post_reply_any')) | |
{ | |
if (allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) | |
{ | |
$this->becomes_approved = false; | |
} | |
// Guests do not have post_unapproved_replies_own permission, so it's always post_unapproved_replies_any | |
elseif ($user_info['is_guest'] && allowedTo('post_unapproved_replies_any')) | |
{ | |
$this->becomes_approved = false; | |
} | |
else | |
{ | |
isAllowedTo('post_reply_own'); | |
} | |
} | |
return $this->becomes_approved; | |
} | |
/** | |
* | |
* @param string $name | |
* @param string $email | |
* @return array | |
*/ | |
protected function getPosterOptions($name, $email) | |
{ | |
global $user_info, $board_info; | |
$posterOptions = array( | |
'id' => $user_info['id'], | |
'name' => $name, | |
'email' => $email, | |
'update_post_count' => !$user_info['is_guest'] && empty($this->msg_id) && $board_info['posts_count'], | |
); | |
return $posterOptions; | |
} | |
public function removeNestedQuotes($string) | |
{ | |
global $modSettings; | |
if (!empty($modSettings['removeNestedQuotes'])) | |
{ | |
$string = preg_replace(array('~\n?\[quote.*?\].+?\[/quote\]\n?~is', '~^\n~', '~\[/quote\]~'), '', $string); | |
} | |
return $string; | |
} | |
public function isOldPost() | |
{ | |
global $modSettings; | |
if (!empty($this->topic_id) && !empty($modSettings['oldTopicDays']) && $this->_topic_attributes['last_post_time'] + $modSettings['oldTopicDays'] * 86400 < time() && empty($this->_topic_attributes['is_sticky']) && !isset($_REQUEST['subject'])) | |
{ | |
$this->_post_errors->addError(array('old_topic', array($modSettings['oldTopicDays'])), 0); | |
} | |
} | |
public function hasNewRepliesSincePosting() | |
{ | |
global $options; | |
return empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $this->topic_info['id_last_msg'] > $_REQUEST['last_msg']; | |
} | |
protected function newRepliesContext() | |
{ | |
global $context, $txt, $modSettings; | |
addInlineJavascript(' | |
$(document).ready(function () { | |
$("html,body").scrollTop($(\'.category_header:visible:first\').offset().top); | |
});' | |
); | |
$context['new_replies'] = countMessagesSince($this->topic_id, (int) $_REQUEST['last_msg'], false, $modSettings['postmod_active'] && !allowedTo('approve_posts')); | |
if (!empty($context['new_replies'])) | |
{ | |
if ($context['new_replies'] == 1) | |
{ | |
$txt['error_new_replies'] = !empty($_REQUEST['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply']; | |
} | |
else | |
{ | |
$txt['error_new_replies'] = sprintf(isset($_REQUEST['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']); | |
} | |
$this->_post_errors->addError('new_replies', 0); | |
$modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts']; | |
} | |
} | |
public function getPreviousPosts() | |
{ | |
global $context, $modSettings, $user_info; | |
if (isset($_REQUEST['xml'])) | |
{ | |
$limit = empty($context['new_replies']) ? 0 : (int) $context['new_replies']; | |
} | |
else | |
{ | |
$limit = $modSettings['topicSummaryPosts']; | |
} | |
$before = $this->isModifyingMessage() ? array('before' => (int) $this->msg_id) : array(); | |
$only_approved = $modSettings['postmod_active'] && !allowedTo('approve_posts'); | |
$counter = 0; | |
$context['previous_posts'] = empty($limit) ? array() : selectMessages($this->topic_id, 0, $limit, $before, $only_approved); | |
foreach ($context['previous_posts'] as &$post) | |
{ | |
$post['is_new'] = !empty($context['new_replies']); | |
$post['counter'] = $counter++; | |
$post['is_ignored'] = !empty($modSettings['enable_buddylist']) && in_array($post['id_poster'], $user_info['ignoreusers']); | |
if (!empty($context['new_replies'])) | |
{ | |
$context['new_replies']--; | |
} | |
} | |
} | |
protected function iconContext() | |
{ | |
global $board, $context; | |
// Message icons - customized or not, retrieve them... | |
$context['icons'] = getMessageIcons($board); | |
$context['icon_url'] = ''; | |
if (!empty($context['icons'])) | |
{ | |
$context['icons'][count($context['icons']) - 1]['is_last'] = true; | |
$context['icons'][0]['selected'] = true; | |
// $context['icon'] is set when editing a message | |
if (!isset($context['icon'])) | |
{ | |
$context['icon'] = $context['icons'][0]['value']; | |
} | |
$found = false; | |
foreach ($context['icons'] as $icon) | |
{ | |
if ($icon['value'] === $context['icon']) | |
{ | |
$found = true; | |
$context['icon_url'] = $icon['url']; | |
break; | |
} | |
} | |
// Failsafe | |
if (!$found) | |
{ | |
$context['icon'] = $context['icons'][0]['value']; | |
$context['icon_url'] = $context['icons'][0]['url']; | |
} | |
} | |
} | |
public function previewContext($subject, $body) | |
{ | |
global $context, $modSettings, $txt; | |
// Set up the preview message and subject | |
$context['preview_message'] = $body; | |
preparsecode($body, true); | |
// Do all bulletin board code thing on the message | |
preparsecode($context['preview_message']); | |
$context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1); | |
censorText($context['preview_message']); | |
// Don't forget the subject | |
$context['preview_subject'] = $subject; | |
censorText($context['preview_subject']); | |
// Any errors we should tell them about? | |
if ($subject === '') | |
{ | |
$this->_post_errors->addError('no_subject'); | |
$context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>'; | |
} | |
if ($context['preview_message'] === '') | |
{ | |
$this->_post_errors->addError('no_message'); | |
} | |
elseif (!empty($modSettings['max_messageLength']) && Util::strlen($body) > $modSettings['max_messageLength']) | |
{ | |
$this->_post_errors->addError(array('long_message', array($modSettings['max_messageLength']))); | |
} | |
// Protect any CDATA blocks. | |
if (isset($_REQUEST['xml'])) | |
{ | |
$context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>')); | |
} | |
} | |
protected function getIcon() | |
{ | |
return isset($_REQUEST['icon']) ? preg_replace('~[\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx'; | |
} | |
protected function getEditorOptions() | |
{ | |
global $context; | |
return array( | |
'id' => 'message', | |
'value' => $context['message'], | |
'labels' => array( | |
'post_button' => $context['submit_label'], | |
), | |
// add height and width for the editor | |
'height' => '275px', | |
'width' => '100%', | |
// We do XML preview here. | |
'preview_type' => 2 | |
); | |
} | |
protected function postPageContext($subject, $body) | |
{ | |
global $context, $scripturl, $txt, $modSettings; | |
// This is done for the editor | |
$context['subject'] = addcslashes($subject, '"'); | |
$context['message'] = str_replace(array('"', '<', '>', ' '), array('"', '<', '>', ' '), $body); | |
// Get a response prefix (like 'Re:') in the default forum language. | |
$context['response_prefix'] = response_prefix(); | |
// @todo These won't work if you're posting an event! | |
// Premissions | |
$context['can_notify'] = allowedTo('mark_any_notify'); | |
$context['can_move'] = allowedTo('move_any'); | |
$context['can_sticky'] = allowedTo('make_sticky'); | |
$context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved']; | |
$context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); | |
$context['move'] = !empty($_REQUEST['move']); | |
$context['announce'] = !empty($_REQUEST['announce']); | |
$context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $this->_topic_attributes['is_sticky']; | |
$context['notify'] = !empty($context['notify']); | |
// You can only announce topics that will get approved... | |
$context['locked'] = !empty($this->_topic_attributes['locked']) || !empty($_REQUEST['lock']); | |
// Generally don't show the approval box... (Assume we want things approved) | |
$context['show_approval'] = allowedTo('approve_posts') && $context['becomes_approved'] ? 2 : (allowedTo('approve_posts') ? 1 : 0); | |
// Build the link tree. | |
if (empty($this->topic_id)) | |
{ | |
$context['linktree'][] = array( | |
'name' => '<em>' . $txt['start_new_topic'] . '</em>' | |
); | |
} | |
else | |
{ | |
$context['linktree'][] = array( | |
'url' => $scripturl . '?topic=' . $this->topic_id . '.' . $_REQUEST['start'], | |
'name' => $context['subject'], | |
'extra_before' => '<span><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', | |
'extra_after' => '<span><strong class="nav"> )</strong></span>' | |
); | |
} | |
// What are you doing? Posting, modifying, previewing, new post, or reply... | |
if (empty($context['page_title'])) | |
{ | |
if ($this->isModifyingMessage()) | |
{ | |
$context['page_title'] = $txt['modify_msg']; | |
} | |
elseif (isset($_REQUEST['subject'], $context['preview_subject'])) | |
{ | |
$context['page_title'] = $txt['post_reply']; | |
} | |
elseif ($this->isNewTopic()) | |
{ | |
$context['page_title'] = $txt['start_new_topic']; | |
} | |
else | |
{ | |
$context['page_title'] = $txt['post_reply']; | |
} | |
} | |
$context['back_to_topic'] = isset($_REQUEST['goback']) || (!empty($this->msg_id) && !isset($_REQUEST['subject'])); | |
$context['is_new_topic'] = $this->isNewTopic(); | |
$context['is_new_post'] = $this->isNewReply(); | |
$context['is_first_post'] = $context['is_new_topic'] || (!empty($this->msg_id) && $this->msg_id == $this->_topic_attributes['id_first_msg']); | |
$context['current_action'] = 'post'; | |
// Needed for the editor and message icons. | |
require_once(SUBSDIR . '/Editor.subs.php'); | |
// Now create the editor. | |
$editorOptions = $this->getEditorOptions(); | |
$this->iconContext(); | |
$context['show_additional_options'] = !empty($_REQUEST['additional_options']); | |
$this->_events->trigger('finalize_post_form', array('editorOptions' => &$editorOptions)); | |
create_control_richedit($editorOptions); | |
} | |
public function setupPreview() | |
{ | |
global $context, $user_info, $txt; | |
$this->_events->trigger('prepare_modifying', array('post_errors' => $this->_post_errors, 'really_previewing' => &$this->previewing)); | |
// In order to keep the approval status flowing through, we have to pass it through the form... | |
$context['becomes_approved'] = empty($_REQUEST['not_approved']); | |
$context['show_approval'] = isset($_REQUEST['approve']) ? ($_REQUEST['approve'] ? 2 : 1) : 0; | |
$context['can_announce'] &= $context['becomes_approved']; | |
// Are you... a guest? | |
if ($user_info['is_guest']) | |
{ | |
$context['name'] = $this->getGuestName(false); | |
$context['email'] = $this->getGuestEmail(false); | |
$user_info['name'] = $context['name']; | |
} | |
// Only show the preview stuff if they hit Preview. | |
if ($this->previewing === true) | |
{ | |
$this->previewContext($form_subject, $form_message); | |
} | |
// Set up the checkboxes. | |
$context['notify'] = !empty($_REQUEST['notify']); | |
$context['use_smileys'] = !isset($_REQUEST['ns']); | |
$context['icon'] = $this->getIcon(); | |
// Set the destination action for submission. | |
$context['destination'] .= !empty($this->msg_id) ? ';msg=' . $this->msg_id . ';' . $context['session_var'] . '=' . $context['session_id'] : ''; | |
$context['submit_label'] = !empty($this->msg_id) ? $txt['save'] : $txt['post']; | |
// Previewing an edit? | |
if ($this->isModifyingMessage()) | |
{ | |
// Get the existing message. | |
$message = messageDetails((int) $this->msg_id, $this->topic_id); | |
// The message they were trying to edit was most likely deleted. | |
// @todo Change this error message? | |
if ($message === false) | |
{ | |
Errors::instance()->fatal_lang_error('no_board', false); | |
} | |
$errors = checkMessagePermissions($message['message']); | |
if (!empty($errors)) | |
{ | |
foreach ($errors as $error) | |
{ | |
$this->_post_errors->addError($error); | |
} | |
} | |
prepareMessageContext($message); | |
} | |
// No check is needed, since nothing is really posted. | |
checkSubmitOnce('free'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment