Exemple #1
0
function kbPreview($sub)
{
    global $context, $smcFunc, $sourcedir;
    require_once $sourcedir . '/Subs-Editor.php';
    $context['title'] = isset($_REQUEST['title']) ? $smcFunc['htmlspecialchars']($_REQUEST['title']) : '';
    $context['body'] = isset($_REQUEST['description']) ? str_replace(array('  '), array('  '), $smcFunc['htmlspecialchars']($_REQUEST['description'])) : '';
    $editorOptions = array('id' => 'description', 'value' => !empty($context['body']) ? $context['body'] : '', 'width' => '90%');
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
    $context['sub_template'] = $sub;
}
function ShowAnnouncements()
{
    global $context, $txt, $sourcedir, $ultimateportalSettings;
    if (!isset($_POST['save'])) {
        checkSession('get');
    }
    if (isset($_POST['save'])) {
        checkSession('post');
        $configUltimatePortalVar['up_news_global_announcement'] = censorText($_POST['up_news_global_announcement']);
        updateUltimatePortalSettings($configUltimatePortalVar, 'config_up_news');
    }
    // Needed for the editor and message icons.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'up_news_global_announcement', 'value' => $ultimateportalSettings['up_news_global_announcement'], 'form' => 'newsform');
    create_control_richedit($editorOptions);
    // Store the ID.
    $context['post_box_name'] = $editorOptions['id'];
    $context['sub_template'] = 'announcement';
    $context['page_title'] = $txt['ultport_admin_news_title'] . ' - ' . $txt['ultport_admin_announcements_title'] . ' - ' . $txt['ultport_admin_module_title2'];
}
Exemple #3
0
/**
 * Shows a form to edit a forum mailing and its recipients.
 * Called by ?action=admin;area=news;sa=mailingcompose.
 * Requires the send_mail permission.
 * Form is submitted to ?action=admin;area=news;sa=mailingsend.
 *
 * @uses ManageNews template, email_members_compose sub-template.
 */
function ComposeMailing()
{
    global $txt, $sourcedir, $context, $smcFunc, $scripturl, $modSettings;
    // Setup the template!
    $context['page_title'] = $txt['admin_newsletters'];
    $context['sub_template'] = 'email_members_compose';
    $context['subject'] = !empty($_POST['subject']) ? $_POST['subject'] : htmlspecialchars($context['forum_name'] . ': ' . $txt['subject']);
    $context['message'] = !empty($_POST['message']) ? $_POST['message'] : htmlspecialchars($txt['message'] . "\n\n" . $txt['regards_team'] . "\n\n" . '{$board_url}');
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'height' => '175px', 'width' => '100%', 'labels' => array('post_button' => $txt['sendtopic_send']), 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // Store the ID for old compatibility.
    $context['post_box_name'] = $editorOptions['id'];
    if (isset($context['preview'])) {
        require_once $sourcedir . '/Subs-Post.php';
        $context['recipients']['members'] = !empty($_POST['members']) ? explode(',', $_POST['members']) : array();
        $context['recipients']['exclude_members'] = !empty($_POST['exclude_members']) ? explode(',', $_POST['exclude_members']) : array();
        $context['recipients']['groups'] = !empty($_POST['groups']) ? explode(',', $_POST['groups']) : array();
        $context['recipients']['exclude_groups'] = !empty($_POST['exclude_groups']) ? explode(',', $_POST['exclude_groups']) : array();
        $context['recipients']['emails'] = !empty($_POST['emails']) ? explode(';', $_POST['emails']) : array();
        $context['email_force'] = !empty($_POST['email_force']) ? 1 : 0;
        $context['total_emails'] = !empty($_POST['total_emails']) ? (int) $_POST['total_emails'] : 0;
        $context['max_id_member'] = !empty($_POST['max_id_member']) ? (int) $_POST['max_id_member'] : 0;
        $context['send_pm'] = !empty($_POST['send_pm']) ? 1 : 0;
        $context['send_html'] = !empty($_POST['send_html']) ? '1' : '0';
        return prepareMailingForPreview();
    }
    // Start by finding any members!
    $toClean = array();
    if (!empty($_POST['members'])) {
        $toClean[] = 'members';
    }
    if (!empty($_POST['exclude_members'])) {
        $toClean[] = 'exclude_members';
    }
    if (!empty($toClean)) {
        require_once $sourcedir . '/Subs-Auth.php';
        foreach ($toClean as $type) {
            // Remove the quotes.
            $_POST[$type] = strtr($_POST[$type], array('\\"' => '"'));
            preg_match_all('~"([^"]+)"~', $_POST[$type], $matches);
            $_POST[$type] = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_POST[$type]))));
            foreach ($_POST[$type] as $index => $member) {
                if (strlen(trim($member)) > 0) {
                    $_POST[$type][$index] = $smcFunc['htmlspecialchars']($smcFunc['strtolower'](trim($member)));
                } else {
                    unset($_POST[$type][$index]);
                }
            }
            // Find the members
            $_POST[$type] = implode(',', array_keys(findMembers($_POST[$type])));
        }
    }
    if (isset($_POST['member_list']) && is_array($_POST['member_list'])) {
        $members = array();
        foreach ($_POST['member_list'] as $member_id) {
            $members[] = (int) $member_id;
        }
        $_POST['members'] = implode(',', $members);
    }
    if (isset($_POST['exclude_member_list']) && is_array($_POST['exclude_member_list'])) {
        $members = array();
        foreach ($_POST['exclude_member_list'] as $member_id) {
            $members[] = (int) $member_id;
        }
        $_POST['exclude_members'] = implode(',', $members);
    }
    // Clean the other vars.
    SendMailing(true);
    // We need a couple strings from the email template file
    loadLanguage('EmailTemplates');
    // Get a list of all full banned users.  Use their Username and email to find them.  Only get the ones that can't login to turn off notification.
    $request = $smcFunc['db_query']('', '
		SELECT DISTINCT mem.id_member
		FROM {db_prefix}ban_groups AS bg
			INNER JOIN {db_prefix}ban_items AS bi ON (bg.id_ban_group = bi.id_ban_group)
			INNER JOIN {db_prefix}members AS mem ON (bi.id_member = mem.id_member)
		WHERE (bg.cannot_access = {int:cannot_access} OR bg.cannot_login = {int:cannot_login})
			AND (bg.expire_time IS NULL OR bg.expire_time > {int:current_time})', array('cannot_access' => 1, 'cannot_login' => 1, 'current_time' => time()));
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['recipients']['exclude_members'][] = $row['id_member'];
    }
    $smcFunc['db_free_result']($request);
    $request = $smcFunc['db_query']('', '
		SELECT DISTINCT bi.email_address
		FROM {db_prefix}ban_items AS bi
			INNER JOIN {db_prefix}ban_groups AS bg ON (bg.id_ban_group = bi.id_ban_group)
		WHERE (bg.cannot_access = {int:cannot_access} OR bg.cannot_login = {int:cannot_login})
			AND (COALESCE(bg.expire_time, 1=1) OR bg.expire_time > {int:current_time})
			AND bi.email_address != {string:blank_string}', array('cannot_access' => 1, 'cannot_login' => 1, 'current_time' => time(), 'blank_string' => ''));
    $condition_array = array();
    $condition_array_params = array();
    $count = 0;
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $condition_array[] = '{string:email_' . $count . '}';
        $condition_array_params['email_' . $count++] = $row['email_address'];
    }
    $smcFunc['db_free_result']($request);
    if (!empty($condition_array)) {
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}members
			WHERE email_address IN(' . implode(', ', $condition_array) . ')', $condition_array_params);
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $context['recipients']['exclude_members'][] = $row['id_member'];
        }
        $smcFunc['db_free_result']($request);
    }
    // Did they select moderators - if so add them as specific members...
    if (!empty($context['recipients']['groups']) && in_array(3, $context['recipients']['groups']) || !empty($context['recipients']['exclude_groups']) && in_array(3, $context['recipients']['exclude_groups'])) {
        $request = $smcFunc['db_query']('', '
			SELECT DISTINCT mem.id_member AS identifier
			FROM {db_prefix}members AS mem
				INNER JOIN {db_prefix}moderators AS mods ON (mods.id_member = mem.id_member)
			WHERE mem.is_activated = {int:is_activated}', array('is_activated' => 1));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (in_array(3, $context['recipients'])) {
                $context['recipients']['exclude_members'][] = $row['identifier'];
            } else {
                $context['recipients']['members'][] = $row['identifier'];
            }
        }
        $smcFunc['db_free_result']($request);
    }
    // For progress bar!
    $context['total_emails'] = count($context['recipients']['emails']);
    $request = $smcFunc['db_query']('', '
		SELECT MAX(id_member)
		FROM {db_prefix}members', array());
    list($context['max_id_member']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Clean up the arrays.
    $context['recipients']['members'] = array_unique($context['recipients']['members']);
    $context['recipients']['exclude_members'] = array_unique($context['recipients']['exclude_members']);
}
Exemple #4
0
/**
 * An error in the message...
 *
 * @param $error_types
 * @param $named_recipients
 * @param $recipient_ids
 */
function messagePostError($error_types, $named_recipients, $recipient_ids = array())
{
    global $txt, $context, $scripturl, $modSettings;
    global $smcFunc, $user_info, $sourcedir;
    if (!isset($_REQUEST['xml'])) {
        $context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'send';
    }
    if (!WIRELESS && !isset($_REQUEST['xml'])) {
        $context['sub_template'] = 'send';
    } elseif (isset($_REQUEST['xml'])) {
        $context['sub_template'] = 'pm';
    }
    $context['page_title'] = $txt['send_message'];
    // Got some known members?
    $context['recipients'] = array('to' => array(), 'bcc' => array());
    if (!empty($recipient_ids['to']) || !empty($recipient_ids['bcc'])) {
        $allRecipients = array_merge($recipient_ids['to'], $recipient_ids['bcc']);
        $request = $smcFunc['db_query']('', '
			SELECT id_member, real_name
			FROM {db_prefix}members
			WHERE id_member IN ({array_int:member_list})', array('member_list' => $allRecipients));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $recipientType = in_array($row['id_member'], $recipient_ids['bcc']) ? 'bcc' : 'to';
            $context['recipients'][$recipientType][] = array('id' => $row['id_member'], 'name' => $row['real_name']);
        }
        $smcFunc['db_free_result']($request);
    }
    // Set everything up like before....
    $context['subject'] = isset($_REQUEST['subject']) ? $smcFunc['htmlspecialchars']($_REQUEST['subject']) : '';
    $context['message'] = isset($_REQUEST['message']) ? str_replace(array('  '), array('  '), $smcFunc['htmlspecialchars']($_REQUEST['message'])) : '';
    $context['copy_to_outbox'] = !empty($_REQUEST['outbox']);
    $context['reply'] = !empty($_REQUEST['replied_to']);
    if ($context['reply']) {
        $_REQUEST['replied_to'] = (int) $_REQUEST['replied_to'];
        $request = $smcFunc['db_query']('', '
			SELECT
				pm.id_pm, CASE WHEN pm.id_pm_head = {int:no_id_pm_head} THEN pm.id_pm ELSE pm.id_pm_head END AS pm_head,
				pm.body, pm.subject, pm.msgtime, mem.member_name, IFNULL(mem.id_member, 0) AS id_member,
				IFNULL(mem.real_name, pm.from_name) AS real_name
			FROM {db_prefix}personal_messages AS pm' . ($context['folder'] == 'sent' ? '' : '
				INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = {int:replied_to})') . '
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from)
			WHERE pm.id_pm = {int:replied_to}' . ($context['folder'] == 'sent' ? '
				AND pm.id_member_from = {int:current_member}' : '
				AND pmr.id_member = {int:current_member}') . '
			LIMIT 1', array('current_member' => $user_info['id'], 'no_id_pm_head' => 0, 'replied_to' => $_REQUEST['replied_to']));
        if ($smcFunc['db_num_rows']($request) == 0) {
            if (!isset($_REQUEST['xml'])) {
                fatal_lang_error('pm_not_yours', false);
            } else {
                $error_types[] = 'pm_not_yours';
            }
        }
        $row_quoted = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        censorText($row_quoted['subject']);
        censorText($row_quoted['body']);
        $context['quoted_message'] = array('id' => $row_quoted['id_pm'], 'pm_head' => $row_quoted['pm_head'], 'member' => array('name' => $row_quoted['real_name'], 'username' => $row_quoted['member_name'], 'id' => $row_quoted['id_member'], 'href' => !empty($row_quoted['id_member']) ? $scripturl . '?action=profile;u=' . $row_quoted['id_member'] : '', 'link' => !empty($row_quoted['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_quoted['id_member'] . '">' . $row_quoted['real_name'] . '</a>' : $row_quoted['real_name']), 'subject' => $row_quoted['subject'], 'time' => timeformat($row_quoted['msgtime']), 'timestamp' => forum_time(true, $row_quoted['msgtime']), 'body' => parse_bbc($row_quoted['body'], true, 'pm' . $row_quoted['id_pm']));
    }
    // Build the link tree....
    $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=send', 'name' => $txt['new_message']);
    // Set each of the errors for the template.
    loadLanguage('Errors');
    $context['error_type'] = 'minor';
    $context['post_error'] = array('messages' => array(), 'error_type' => '');
    foreach ($error_types as $error_type) {
        $context['post_error'][$error_type] = true;
        if (isset($txt['error_' . $error_type])) {
            if ($error_type == 'long_message') {
                $txt['error_' . $error_type] = sprintf($txt['error_' . $error_type], $modSettings['max_messageLength']);
            }
            $context['post_error']['messages'][] = $txt['error_' . $error_type];
        }
        // If it's not a minor error flag it as such.
        if (!in_array($error_type, array('new_reply', 'not_approved', 'new_replies', 'old_topic', 'need_qr_verification', 'no_subject'))) {
            $context['error_type'] = 'serious';
        }
    }
    // Need to reset draft capability once again
    $context['drafts_pm_save'] = !empty($modSettings['drafts_pm_enabled']) && allowedTo('pm_draft');
    $context['drafts_autosave'] = !empty($context['drafts_pm_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('pm_autosave_draft');
    // We need to load the editor once more.
    require_once $sourcedir . '/Subs-Editor.php';
    // Create it...
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'width' => '90%', 'labels' => array('post_button' => $txt['send_message']), 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // ... and store the ID again...
    $context['post_box_name'] = $editorOptions['id'];
    // Check whether we need to show the code again.
    $context['require_verification'] = !$user_info['is_admin'] && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification'];
    if ($context['require_verification'] && !isset($_REQUEST['xml'])) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'pm');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    $context['to_value'] = empty($named_recipients['to']) ? '' : '&quot;' . implode('&quot;, &quot;', $named_recipients['to']) . '&quot;';
    $context['bcc_value'] = empty($named_recipients['bcc']) ? '' : '&quot;' . implode('&quot;, &quot;', $named_recipients['bcc']) . '&quot;';
    // No check for the previous submission is needed.
    checkSubmitOnce('free');
    // Acquire a new form sequence number.
    checkSubmitOnce('register');
}
Exemple #5
0
function TP_prebbcbox($id, $body = '')
{
    global $sourcedir;
    require_once $sourcedir . '/Subs-Editor.php';
    $editorOptions = array('id' => $id, 'value' => $body, 'preview_type' => 2, 'height' => '300px', 'width' => '100%');
    create_control_richedit($editorOptions);
}
function getEditor($description = '')
{
    global $sourcedir, $context;
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'descript', 'value' => $description, 'width' => '97%', 'form' => 'picform', 'labels' => array('post_button' => ''));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}
/**
* load the article editor by article type.
* field: name of a input element.
* content: the content in the editor or empty.
*/
function PortaMx_EditArticle($type, $field, $content)
{
    global $context, $sourcedir, $boardurl, $modSettings, $user_info, $options, $smcFunc, $txt;
    // for html blocks
    if ($type == 'html') {
        loadJavascriptFile($boardurl . '/ckeditor/ckeditor.js', array('external' => true));
        $context['pmx']['htmledit'] = array('id' => 'content', 'content' => $content);
    } else {
        if ($type == 'script') {
            addInlineCss('
	textarea{min-height:100px;resize:vertical;}');
            $context['pmx']['script'] = array('id' => 'content', 'value' => !empty($content) ? $content : '', 'width' => '100%', 'height' => '150px');
        } elseif ($type == 'php') {
            addInlineCss('
	textarea{min-height:100px;}');
            if (preg_match('~\\[\\?pmx_initphp(.*)pmx_initphp\\?\\]~is', $content, $match)) {
                $cont = trim($match[1]);
            } else {
                $cont = '';
            }
            $context['pmx']['phpInit'] = array('id' => 'content_init', 'value' => $smcFunc['htmlspecialchars']($cont, ENT_NOQUOTES), 'width' => '100%', 'height' => '150px', 'havecont' => !empty($cont));
            if (preg_match('~\\[\\?pmx_showphp(.*)pmx_showphp\\?\\]~is', $content, $match)) {
                $cont = trim($match[1]);
            } else {
                $cont = $content;
            }
            $context['pmx']['phpShow'] = array('id' => 'content', 'value' => $smcFunc['htmlspecialchars']($cont, ENT_NOQUOTES), 'width' => '100%', 'height' => '150px', 'havecont' => !empty($cont));
        } else {
            // Let's load the SMF editor.
            require_once $sourcedir . '/Subs-Editor.php';
            $user_info['smiley_set'] = 'PortaMx';
            $modSettings['smiley_enable'] = true;
            $options['wysiwyg_default'] = true;
            $editorOptions = array('id' => 'content', 'value' => !empty($content) ? $content : '&#8;', 'width' => '100%', 'height' => '200px', 'labels' => array(), 'preview_type' => 0, 'bbc_level' => 'full', 'disable_smiley_box' => 0, 'locale' => !empty($txt['lang_locale']) && substr($txt['lang_locale'], 0, 5) != 'en_US' ? $txt['lang_locale'] : '', 'form' => 'pxmedit');
            create_control_richedit($editorOptions);
            $context['pmx']['editorID'] = $editorOptions['id'];
        }
    }
}
function char_template_edit()
{
    global $context, $txt, $sourcedir, $smcFunc;
    require_once $sourcedir . '/Subs-Post.php';
    require_once $sourcedir . '/Subs-Editor.php';
    $template_id = isset($_GET['template_id']) ? (int) $_GET['template_id'] : 0;
    $request = $smcFunc['db_query']('', '
		SELECT id_template, template_name, template
		FROM {db_prefix}character_sheet_templates
		WHERE id_template = {int:template}', ['template' => $template_id]);
    $row = $smcFunc['db_fetch_assoc']($request);
    if (empty($row)) {
        redirectexit('action=admin;area=templates');
    }
    $context['template_id'] = $template_id;
    $context['template_name'] = $row['template_name'];
    // Now create the editor.
    $editorOptions = ['id' => 'message', 'value' => un_preparsecode($row['template']), 'labels' => ['post_button' => $txt['save']], 'height' => '500px', 'width' => '100%', 'preview_type' => 0, 'required' => true];
    create_control_richedit($editorOptions);
    $context['page_title'] = $txt['char_templates_edit'];
    $context['sub_template'] = 'char_template_edit';
    loadTemplate('Admin-Chars');
}
Exemple #9
0
    /**
     * 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.
     * - accessed from ?action=post.
     *
     * @uses the Post template and language file, main sub template.
     */
    public function action_post()
    {
        global $txt, $scripturl, $topic, $modSettings, $board, $user_info, $context, $options;
        loadLanguage('Post');
        loadLanguage('Errors');
        require_once SOURCEDIR . '/AttachmentErrorContext.class.php';
        // You can't reply with a poll... hacker.
        if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) {
            unset($_REQUEST['poll']);
        }
        $post_errors = Error_Context::context('post', 1);
        $attach_errors = Attachment_Error_Context::context();
        $attach_errors->activate();
        $first_subject = '';
        // Posting an event?
        $context['make_event'] = isset($_REQUEST['calendar']);
        $context['robot_no_index'] = true;
        $template_layers = Template_Layers::getInstance();
        $template_layers->add('postarea');
        // You must be posting to *some* board.
        if (empty($board) && !$context['make_event']) {
            fatal_lang_error('no_board', false);
        }
        if ($context['make_event']) {
            $template_layers->add('make_event');
        }
        // All those wonderful modifiers and attachments
        $template_layers->add('additional_options', 200);
        require_once SUBSDIR . '/Post.subs.php';
        require_once SUBSDIR . '/Messages.subs.php';
        require_once SUBSDIR . '/Topic.subs.php';
        if (isset($_REQUEST['xml'])) {
            $context['sub_template'] = 'post';
            // Just in case of an earlier error...
            $context['preview_message'] = '';
            $context['preview_subject'] = '';
        }
        if (!empty($modSettings['mentions_enabled']) && !empty($_REQUEST['uid'])) {
            $context['member_ids'] = array_unique(array_map('intval', $_REQUEST['uid']));
        }
        // No message is complete without a topic.
        if (empty($topic) && !empty($_REQUEST['msg'])) {
            $topic = associatedTopic((int) $_REQUEST['msg']);
            if (empty($topic)) {
                unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
            }
        }
        // Check if it's locked. It isn't locked if no topic is specified.
        if (!empty($topic)) {
            list($locked, $context['notify'], $sticky, $pollID, $context['topic_last_message'], $id_member_poster, $id_first_msg, $first_subject, $lastPostTime) = array_values(topicUserAttributes($topic, $user_info['id']));
            // If this topic already has a poll, they sure can't add another.
            if (isset($_REQUEST['poll']) && $pollID > 0) {
                unset($_REQUEST['poll']);
            }
            if (empty($_REQUEST['msg'])) {
                if ($user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) {
                    is_not_guest();
                }
                // By default the reply will be approved...
                $context['becomes_approved'] = true;
                if ($id_member_poster != $user_info['id']) {
                    if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                        $context['becomes_approved'] = false;
                    } else {
                        isAllowedTo('post_reply_any');
                    }
                } elseif (!allowedTo('post_reply_any')) {
                    if ($modSettings['postmod_active']) {
                        if (allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                            $context['becomes_approved'] = false;
                        } elseif ($user_info['is_guest'] && allowedTo('post_unapproved_replies_any')) {
                            $context['becomes_approved'] = false;
                        } else {
                            isAllowedTo('post_reply_own');
                        }
                    } else {
                        isAllowedTo('post_reply_own');
                    }
                }
            } else {
                $context['becomes_approved'] = true;
            }
            $context['can_lock'] = allowedTo('lock_any') || $user_info['id'] == $id_member_poster && allowedTo('lock_own');
            $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
            $context['notify'] = !empty($context['notify']);
            $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky;
            // It's a new reply
            if (empty($_REQUEST['msg'])) {
                $context['can_add_poll'] = false;
            } else {
                $context['can_add_poll'] = (allowedTo('poll_add_any') || !empty($_REQUEST['msg']) && $id_first_msg == $_REQUEST['msg'] && allowedTo('poll_add_own')) && !empty($modSettings['pollMode']) && $pollID <= 0;
            }
        } else {
            $context['becomes_approved'] = true;
            if (!$context['make_event'] || !empty($board)) {
                if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_new');
                }
            }
            $locked = 0;
            // @todo These won't work if you're making an event.
            $context['can_lock'] = allowedTo(array('lock_any', 'lock_own'));
            $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
            $context['notify'] = !empty($context['notify']);
            $context['sticky'] = !empty($_REQUEST['sticky']);
            $context['can_add_poll'] = (allowedTo('poll_add_any') || allowedTo('poll_add_own')) && !empty($modSettings['pollMode']);
        }
        // @todo These won't work if you're posting an event!
        $context['can_notify'] = allowedTo('mark_any_notify');
        $context['can_move'] = allowedTo('move_any');
        $context['move'] = !empty($_REQUEST['move']);
        $context['announce'] = !empty($_REQUEST['announce']);
        if ($context['can_add_poll']) {
            addJavascriptVar(array('poll_remove' => $txt['poll_remove'], 'poll_add' => $txt['add_poll']), true);
        }
        // You can only announce topics that will get approved...
        $context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved'];
        $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']);
        $context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
        // 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);
        // An array to hold all the attachments for this topic.
        $context['attachments']['current'] = array();
        // Don't allow a post if it's locked and you aren't all powerful.
        if ($locked && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        // Check the users permissions - is the user allowed to add or post a poll?
        if (isset($_REQUEST['poll']) && !empty($modSettings['pollMode'])) {
            // New topic, new poll.
            if (empty($topic)) {
                isAllowedTo('poll_post');
            } elseif ($user_info['id'] == $id_member_poster && !allowedTo('poll_add_any')) {
                isAllowedTo('poll_add_own');
            } else {
                isAllowedTo('poll_add_any');
            }
            $context['can_moderate_poll'] = true;
            require_once SUBSDIR . '/Members.subs.php';
            $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
            // Set up the poll options.
            $context['poll'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide_results' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expiration' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_allowed' => in_array(-1, $allowedVoteGroups['allowed']));
            // Make all five poll choices empty.
            $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true));
            $context['last_choice_id'] = 4;
        }
        if ($context['make_event']) {
            // They might want to pick a board.
            if (!isset($context['current_board'])) {
                $context['current_board'] = 0;
            }
            // Start loading up the event info.
            $context['event'] = array();
            $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle']), ENT_COMPAT, 'UTF-8') : '';
            $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1;
            $context['event']['new'] = $context['event']['id'] == -1;
            // Permissions check!
            isAllowedTo('calendar_post');
            // Editing an event?  (but NOT previewing!?)
            if (empty($context['event']['new']) && !isset($_REQUEST['subject'])) {
                // If the user doesn't have permission to edit the post in this topic, redirect them.
                if ((empty($id_member_poster) || $id_member_poster != $user_info['id'] || !allowedTo('modify_own')) && !allowedTo('modify_any')) {
                    require_once CONTROLLERDIR . '/Calendar.controller.php';
                    $controller = new Calendar_Controller();
                    return $controller->action_post();
                }
                // Get the current event information.
                require_once SUBSDIR . '/Calendar.subs.php';
                $event_info = getEventProperties($context['event']['id']);
                // Make sure the user is allowed to edit this event.
                if ($event_info['member'] != $user_info['id']) {
                    isAllowedTo('calendar_edit_any');
                } elseif (!allowedTo('calendar_edit_any')) {
                    isAllowedTo('calendar_edit_own');
                }
                $context['event']['month'] = $event_info['month'];
                $context['event']['day'] = $event_info['day'];
                $context['event']['year'] = $event_info['year'];
                $context['event']['title'] = $event_info['title'];
                $context['event']['span'] = $event_info['span'];
            } else {
                // Posting a new event? (or preview...)
                $today = getdate();
                // You must have a month and year specified!
                if (!isset($_REQUEST['month'])) {
                    $_REQUEST['month'] = $today['mon'];
                }
                if (!isset($_REQUEST['year'])) {
                    $_REQUEST['year'] = $today['year'];
                }
                $context['event']['month'] = (int) $_REQUEST['month'];
                $context['event']['year'] = (int) $_REQUEST['year'];
                $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0);
                $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1;
                // Make sure the year and month are in the valid range.
                if ($context['event']['month'] < 1 || $context['event']['month'] > 12) {
                    fatal_lang_error('invalid_month', false);
                }
                if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) {
                    fatal_lang_error('invalid_year', false);
                }
                // Get a list of boards they can post in.
                require_once SUBSDIR . '/Boards.subs.php';
                $boards = boardsAllowedTo('post_new');
                if (empty($boards)) {
                    fatal_lang_error('cannot_post_new', 'user');
                }
                // Load a list of boards for this event in the context.
                $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'selected_board' => empty($context['current_board']) ? $modSettings['cal_defaultboard'] : $context['current_board']);
                $context += getBoardList($boardListOptions);
            }
            // Find the last day of the month.
            $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
            $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard'];
        }
        // See if any new replies have come along.
        if (empty($_REQUEST['msg']) && !empty($topic)) {
            if (empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $context['topic_last_message'] > $_REQUEST['last_msg']) {
                $context['new_replies'] = countMessagesSince($topic, (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'] = isset($_GET['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply'];
                    } else {
                        $txt['error_new_replies'] = sprintf(isset($_GET['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']);
                    }
                    $post_errors->addError('new_replies', 0);
                    $modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts'];
                }
            }
        }
        // Get a response prefix (like 'Re:') in the default forum language.
        $context['response_prefix'] = response_prefix();
        // Previewing, modifying, or posting?
        // Do we have a body, but an error happened.
        if (isset($_REQUEST['message']) || $post_errors->hasErrors() || $attach_errors->hasErrors()) {
            // Validate inputs.
            if (!$post_errors->hasErrors() && !$attach_errors->hasErrors()) {
                // This means they didn't click Post and get an error.
                $really_previewing = true;
            } else {
                if (!isset($_REQUEST['subject'])) {
                    $_REQUEST['subject'] = '';
                }
                if (!isset($_REQUEST['message'])) {
                    $_REQUEST['message'] = '';
                }
                if (!isset($_REQUEST['icon'])) {
                    $_REQUEST['icon'] = 'xx';
                }
                // They are previewing if they asked to preview (i.e. came from quick reply).
                $really_previewing = !empty($_REQUEST['preview']);
            }
            // 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'];
            // Set up the inputs for the form.
            $form_subject = strtr(Util::htmlspecialchars($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
            $form_message = Util::htmlspecialchars($_REQUEST['message'], ENT_QUOTES);
            // Make sure the subject isn't too long - taking into account special characters.
            if (Util::strlen($form_subject) > 100) {
                $form_subject = Util::substr($form_subject, 0, 100);
            }
            if (isset($_REQUEST['poll'])) {
                $context['poll']['question'] = isset($_REQUEST['question']) ? Util::htmlspecialchars(trim($_REQUEST['question'])) : '';
                $context['choices'] = array();
                $choice_id = 0;
                $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive($_POST['options']);
                foreach ($_POST['options'] as $option) {
                    if (trim($option) == '') {
                        continue;
                    }
                    $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false);
                }
                // One empty option for those with js disabled...I know are few... :P
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
                if (count($context['choices']) < 2) {
                    $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
                }
                $context['last_choice_id'] = $choice_id;
                $context['choices'][count($context['choices']) - 1]['is_last'] = true;
            }
            // Are you... a guest?
            if ($user_info['is_guest']) {
                $context['name'] = !isset($_REQUEST['guestname']) ? '' : Util::htmlspecialchars(trim($_REQUEST['guestname']));
                $context['email'] = !isset($_REQUEST['email']) ? '' : Util::htmlspecialchars(trim($_REQUEST['email']));
                $user_info['name'] = $context['name'];
            }
            // Only show the preview stuff if they hit Preview.
            if (($really_previewing === true || isset($_REQUEST['xml'])) && !isset($_REQUEST['save_draft'])) {
                // Set up the preview message and subject
                $context['preview_message'] = $form_message;
                preparsecode($form_message, 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'] = $form_subject;
                censorText($context['preview_subject']);
                // Any errors we should tell them about?
                if ($form_subject === '') {
                    $post_errors->addError('no_subject');
                    $context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>';
                }
                if ($context['preview_message'] === '') {
                    $post_errors->addError('no_message');
                } elseif (!empty($modSettings['max_messageLength']) && Util::strlen($form_message) > $modSettings['max_messageLength']) {
                    $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[>'));
                }
            }
            // Set up the checkboxes.
            $context['notify'] = !empty($_REQUEST['notify']);
            $context['use_smileys'] = !isset($_REQUEST['ns']);
            $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx';
            // Set the destination action for submission.
            $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '') . (isset($_REQUEST['poll']) ? ';poll' : '');
            $context['submit_label'] = isset($_REQUEST['msg']) ? $txt['save'] : $txt['post'];
            // Previewing an edit?
            if (isset($_REQUEST['msg']) && !empty($topic)) {
                require_once SUBSDIR . '/Messages.subs.php';
                // Get the existing message.
                $message = messageDetails((int) $_REQUEST['msg'], $topic);
                // The message they were trying to edit was most likely deleted.
                // @todo Change this error message?
                if ($message === false) {
                    fatal_lang_error('no_board', false);
                }
                $errors = checkMessagePermissions($message['message']);
                if (!empty($errors)) {
                    foreach ($errors as $error) {
                        $post_errors->addError($error);
                    }
                }
                prepareMessageContext($message);
            } elseif (isset($_REQUEST['last_msg'])) {
                list($form_subject, ) = getFormMsgSubject(false, $topic, $first_subject);
            }
            // No check is needed, since nothing is really posted.
            checkSubmitOnce('free');
        } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
            $_REQUEST['msg'] = (int) $_REQUEST['msg'];
            $message = getFormMsgSubject(true, $topic);
            if (!empty($message['errors'])) {
                foreach ($errors as $error) {
                    $post_errors->addError($error);
                }
            }
            // Get the stuff ready for the form.
            $form_subject = $message['message']['subject'];
            $form_message = un_preparsecode($message['message']['body']);
            censorText($form_message);
            censorText($form_subject);
            // 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'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] . (isset($_REQUEST['poll']) ? ';poll' : '');
            $context['submit_label'] = $txt['save'];
        } else {
            // By default....
            $context['use_smileys'] = true;
            $context['icon'] = 'xx';
            if ($user_info['is_guest']) {
                $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
                $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
            }
            $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : '');
            $context['submit_label'] = $txt['post'];
            list($form_subject, $form_message) = getFormMsgSubject(false, $topic, $first_subject);
        }
        // Check whether this is a really old post being bumped...
        if (!empty($topic) && !empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) {
            $post_errors->addError(array('old_topic', array($modSettings['oldTopicDays'])), 0);
        }
        // Are we moving a discussion to its own topic?
        if (!empty($modSettings['enableFollowup']) && !empty($_REQUEST['followup'])) {
            $context['original_post'] = isset($_REQUEST['quote']) ? (int) $_REQUEST['quote'] : (int) $_REQUEST['followup'];
            $context['show_boards_dropdown'] = true;
            require_once SUBSDIR . '/Boards.subs.php';
            $context += getBoardList(array('not_redirection' => true, 'allowed_to' => 'post_new'));
            $context['boards_current_disabled'] = false;
            if (!empty($board)) {
                foreach ($context['categories'] as $id => $values) {
                    if (isset($values['boards'][$board])) {
                        $context['categories'][$id]['boards'][$board]['selected'] = true;
                        break;
                    }
                }
            }
        }
        $context['attachments']['can']['post'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'));
        if ($context['attachments']['can']['post']) {
            // If there are attachments, calculate the total size and how many.
            $attachments = array();
            $attachments['total_size'] = 0;
            $attachments['quantity'] = 0;
            // If this isn't a new post, check the current attachments.
            if (isset($_REQUEST['msg'])) {
                $attachments['quantity'] = count($context['attachments']['current']);
                foreach ($context['attachments']['current'] as $attachment) {
                    $attachments['total_size'] += $attachment['size'];
                }
            }
            // A bit of house keeping first.
            if (!empty($_SESSION['temp_attachments']) && count($_SESSION['temp_attachments']) == 1) {
                unset($_SESSION['temp_attachments']);
            }
            if (!empty($_SESSION['temp_attachments'])) {
                // Is this a request to delete them?
                if (isset($_GET['delete_temp'])) {
                    foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                        if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false) {
                            @unlink($attachment['tmp_name']);
                        }
                    }
                    $attach_errors->addError('temp_attachments_gone');
                    $_SESSION['temp_attachments'] = array();
                } elseif ($context['current_action'] != 'post2' || !empty($_POST['from_qr'])) {
                    // Let's be nice and see if they belong here first.
                    if (empty($_REQUEST['msg']) && empty($_SESSION['temp_attachments']['post']['msg']) && $_SESSION['temp_attachments']['post']['board'] == $board || !empty($_REQUEST['msg']) && $_SESSION['temp_attachments']['post']['msg'] == $_REQUEST['msg']) {
                        // See if any files still exist before showing the warning message and the files attached.
                        foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                            if (strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                                continue;
                            }
                            if (file_exists($attachment['tmp_name'])) {
                                $attach_errors->addError('temp_attachments_new');
                                $context['files_in_session_warning'] = $txt['attached_files_in_session'];
                                unset($_SESSION['temp_attachments']['post']['files']);
                                break;
                            }
                        }
                    } else {
                        // Since, they don't belong here. Let's inform the user that they exist..
                        if (!empty($topic)) {
                            $delete_url = $scripturl . '?action=post' . (!empty($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] : '') . (!empty($_REQUEST['last_msg']) ? ';last_msg=' . $_REQUEST['last_msg'] : '') . ';topic=' . $topic . ';delete_temp';
                        } else {
                            $delete_url = $scripturl . '?action=post;board=' . $board . ';delete_temp';
                        }
                        // Compile a list of the files to show the user.
                        $file_list = array();
                        foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                            if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false) {
                                $file_list[] = $attachment['name'];
                            }
                        }
                        $_SESSION['temp_attachments']['post']['files'] = $file_list;
                        $file_list = '<div class="attachments">' . implode('<br />', $file_list) . '</div>';
                        if (!empty($_SESSION['temp_attachments']['post']['msg'])) {
                            // We have a message id, so we can link back to the old topic they were trying to edit..
                            $goback_link = '<a href="' . $scripturl . '?action=post' . (!empty($_SESSION['temp_attachments']['post']['msg']) ? ';msg=' . $_SESSION['temp_attachments']['post']['msg'] : '') . (!empty($_SESSION['temp_attachments']['post']['last_msg']) ? ';last_msg=' . $_SESSION['temp_attachments']['post']['last_msg'] : '') . ';topic=' . $_SESSION['temp_attachments']['post']['topic'] . ';additionalOptions">' . $txt['here'] . '</a>';
                            $attach_errors->addError(array('temp_attachments_found', array($delete_url, $goback_link, $file_list)));
                            $context['ignore_temp_attachments'] = true;
                        } else {
                            $attach_errors->addError(array('temp_attachments_lost', array($delete_url, $file_list)));
                            $context['ignore_temp_attachments'] = true;
                        }
                    }
                }
                foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                    // Skipping over these
                    if (isset($context['ignore_temp_attachments']) || isset($_SESSION['temp_attachments']['post']['files'])) {
                        break;
                    }
                    // Initial errors (such as missing directory), we can recover
                    if ($attachID != 'initial_error' && strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                        continue;
                    }
                    if ($attachID == 'initial_error') {
                        if ($context['current_action'] != 'post2') {
                            $txt['error_attach_initial_error'] = $txt['attach_no_upload'] . '<div class="attachmenterrors">' . (is_array($attachment) ? vsprintf($txt[$attachment[0]], $attachment[1]) : $txt[$attachment]) . '</div>';
                            $attach_errors->addError('attach_initial_error');
                        }
                        unset($_SESSION['temp_attachments']);
                        break;
                    }
                    // Show any errors which might have occurred.
                    if (!empty($attachment['errors'])) {
                        if ($context['current_action'] != 'post2') {
                            $txt['error_attach_errors'] = empty($txt['error_attach_errors']) ? '<br />' : '';
                            $txt['error_attach_errors'] .= vsprintf($txt['attach_warning'], $attachment['name']) . '<div class="attachmenterrors">';
                            foreach ($attachment['errors'] as $error) {
                                $txt['error_attach_errors'] .= (is_array($error) ? vsprintf($txt[$error[0]], $error[1]) : $txt[$error]) . '<br  />';
                            }
                            $txt['error_attach_errors'] .= '</div>';
                            $attach_errors->addError('attach_errors');
                        }
                        // Take out the trash.
                        unset($_SESSION['temp_attachments'][$attachID]);
                        @unlink($attachment['tmp_name']);
                        continue;
                    }
                    // More house keeping.
                    if (!file_exists($attachment['tmp_name'])) {
                        unset($_SESSION['temp_attachments'][$attachID]);
                        continue;
                    }
                    $attachments['quantity']++;
                    $attachments['total_size'] += $attachment['size'];
                    if (!isset($context['files_in_session_warning'])) {
                        $context['files_in_session_warning'] = $txt['attached_files_in_session'];
                    }
                    $context['attachments']['current'][] = array('name' => '<u>' . htmlspecialchars($attachment['name'], ENT_COMPAT, 'UTF-8') . '</u>', 'size' => $attachment['size'], 'id' => $attachID, 'unchecked' => false, 'approved' => 1);
                }
            }
        }
        // Do we need to show the visual verification image?
        $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
        if ($context['require_verification']) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions);
            $context['visual_verification_id'] = $verificationOptions['id'];
        }
        // If they came from quick reply, and have to enter verification details, give them some notice.
        if (!empty($_REQUEST['from_qr']) && !empty($context['require_verification'])) {
            $post_errors->addError('need_qr_verification');
        }
        // Any errors occurred?
        $context['post_error'] = array('errors' => $post_errors->prepareErrors(), 'type' => $post_errors->getErrorType() == 0 ? 'minor' : 'serious', 'title' => $post_errors->getErrorType() == 0 ? $txt['warning_while_submitting'] : $txt['error_while_submitting']);
        // If there are attachment errors. Let's show a list to the user.
        if ($attach_errors->hasErrors()) {
            loadTemplate('Errors');
            $errors = $attach_errors->prepareErrors();
            foreach ($errors as $key => $error) {
                $context['attachment_error_keys'][] = $key . '_error';
                $context[$key . '_error'] = $error;
            }
        }
        // What are you doing? Posting a poll, modifying, previewing, new post, or reply...
        if (isset($_REQUEST['poll'])) {
            $context['page_title'] = $txt['new_poll'];
        } elseif ($context['make_event']) {
            $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar_post_event'] : $txt['calendar_edit'];
        } elseif (isset($_REQUEST['msg'])) {
            $context['page_title'] = $txt['modify_msg'];
        } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) {
            $context['page_title'] = $txt['post_reply'];
        } elseif (empty($topic)) {
            $context['page_title'] = $txt['start_new_topic'];
        } else {
            $context['page_title'] = $txt['post_reply'];
        }
        // Update the topic summary, needed to show new posts in a preview
        if (!empty($topic) && !empty($modSettings['topicSummaryPosts'])) {
            $only_approved = $modSettings['postmod_active'] && !allowedTo('approve_posts');
            if (isset($_REQUEST['xml'])) {
                $limit = empty($context['new_replies']) ? 0 : (int) $context['new_replies'];
            } else {
                $limit = $modSettings['topicSummaryPosts'];
            }
            $before = isset($_REQUEST['msg']) ? array('before' => (int) $_REQUEST['msg']) : array();
            $counter = 0;
            $context['previous_posts'] = empty($limit) ? array() : selectMessages($topic, 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']--;
                }
            }
        }
        // Just ajax previewing then lets stop now
        if (isset($_REQUEST['xml'])) {
            obExit();
        }
        // Build the link tree.
        if (empty($topic)) {
            $context['linktree'][] = array('name' => '<em>' . $txt['start_new_topic'] . '</em>');
        } else {
            $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', 'extra_after' => '<span><strong class="nav"> )</strong></span>');
        }
        $context['subject'] = addcslashes($form_subject, '"');
        $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
        // Are post drafts enabled?
        $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft');
        $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
        if (!empty($modSettings['mentions_enabled'])) {
            $context['mentions_enabled'] = true;
            loadCSSFile('jquery.atwho.css');
            addInlineJavascript('
			$(document).ready(function () {
				for (var i = 0, count = all_elk_mentions.length; i < count; i++)
					all_elk_mentions[i].oMention = new elk_mentions(all_elk_mentions[i].oOptions);
			});');
        }
        // Build a list of drafts that they can load into the editor
        if (!empty($context['drafts_save'])) {
            $this->_prepareDraftsContext($user_info['id'], $topic);
            if (!empty($context['drafts'])) {
                $template_layers->add('load_drafts', 100);
            }
        }
        // Needed for the editor and message icons.
        require_once SUBSDIR . '/Editor.subs.php';
        // Now create the editor.
        $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'height' => '275px', 'width' => '100%', 'preview_type' => 2);
        create_control_richedit($editorOptions);
        $context['attached'] = '';
        $context['make_poll'] = isset($_REQUEST['poll']);
        if ($context['make_poll']) {
            loadTemplate('Poll');
            $template_layers->add('poll_edit');
        }
        // 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'];
            }
        }
        // Are we starting a poll? if set the poll icon as selected if its available
        if (isset($_REQUEST['poll'])) {
            for ($i = 0, $n = count($context['icons']); $i < $n; $i++) {
                if ($context['icons'][$i]['value'] == 'poll') {
                    $context['icons'][$i]['selected'] = true;
                    $context['icon'] = 'poll';
                    $context['icon_url'] = $context['icons'][$i]['url'];
                    break;
                }
            }
        }
        // If the user can post attachments prepare the warning labels.
        if ($context['attachments']['can']['post']) {
            // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments.
            $context['attachments']['num_allowed'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['attachments']['current']), $modSettings['attachmentNumPerPostLimit']);
            $context['attachments']['can']['post_unapproved'] = allowedTo('post_attachment');
            $context['attachments']['restrictions'] = array();
            if (!empty($modSettings['attachmentCheckExtensions'])) {
                $context['attachments']['allowed_extensions'] = strtr(strtolower($modSettings['attachmentExtensions']), array(',' => ', '));
            } else {
                $context['attachments']['allowed_extensions'] = '';
            }
            $context['attachments']['templates'] = array('add_new' => 'template_add_new_attachments', 'existing' => 'template_show_existing_attachments');
            $attachmentRestrictionTypes = array('attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit');
            foreach ($attachmentRestrictionTypes as $type) {
                if (!empty($modSettings[$type])) {
                    $context['attachments']['restrictions'][] = sprintf($txt['attach_restrict_' . $type], comma_format($modSettings[$type], 0));
                    // Show some numbers. If they exist.
                    if ($type == 'attachmentNumPerPostLimit' && $attachments['quantity'] > 0) {
                        $context['attachments']['restrictions'][] = sprintf($txt['attach_remaining'], $modSettings['attachmentNumPerPostLimit'] - $attachments['quantity']);
                    } elseif ($type == 'attachmentPostLimit' && $attachments['total_size'] > 0) {
                        $context['attachments']['restrictions'][] = sprintf($txt['attach_available'], comma_format(round(max($modSettings['attachmentPostLimit'] - $attachments['total_size'] / 1028, 0)), 0));
                    }
                }
            }
            // Load up the drag and drop attachment magic
            addInlineJavascript('
			var dropAttach = dragDropAttachment.prototype.init({
				board: ' . $board . ',
				allowedExtensions: ' . JavaScriptEscape($context['attachments']['allowed_extensions']) . ',
				totalSizeAllowed: ' . JavaScriptEscape(empty($modSettings['attachmentPostLimit']) ? '' : $modSettings['attachmentPostLimit']) . ',
				individualSizeAllowed: ' . JavaScriptEscape(empty($modSettings['attachmentSizeLimit']) ? '' : $modSettings['attachmentSizeLimit']) . ',
				numOfAttachmentAllowed: ' . $context['attachments']['num_allowed'] . ',
				totalAttachSizeUploaded: ' . (isset($context['attachments']['total_size']) && !empty($context['attachments']['total_size']) ? $context['attachments']['total_size'] : 0) . ',
				numAttachUploaded: ' . (isset($context['attachments']['quantity']) && !empty($context['attachments']['quantity']) ? $context['attachments']['quantity'] : 0) . ',
				oTxt: ({
					allowedExtensions : ' . JavaScriptEscape(sprintf($txt['cant_upload_type'], $context['attachments']['allowed_extensions'])) . ',
					totalSizeAllowed : ' . JavaScriptEscape($txt['attach_max_total_file_size']) . ',
					individualSizeAllowed : ' . JavaScriptEscape(sprintf($txt['file_too_big'], comma_format($modSettings['attachmentSizeLimit'], 0))) . ',
					numOfAttachmentAllowed : ' . JavaScriptEscape(sprintf($txt['attachments_limit_per_post'], $modSettings['attachmentNumPerPostLimit'])) . ',
					postUploadError : ' . JavaScriptEscape($txt['post_upload_error']) . ',
				}),
			});', true);
        }
        $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']);
        $context['show_additional_options'] = !empty($_POST['additional_options']) || isset($_SESSION['temp_attachments']['post']) || isset($_GET['additionalOptions']);
        $context['is_new_topic'] = empty($topic);
        $context['is_new_post'] = !isset($_REQUEST['msg']);
        $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $id_first_msg;
        $context['current_action'] = 'post';
        // Register this form in the session variables.
        checkSubmitOnce('register');
        // Finally, load the template.
        if (!isset($_REQUEST['xml'])) {
            loadTemplate('Post');
            $context['sub_template'] = 'post_page';
        }
    }
Exemple #10
0
function BlogViewPost()
{
    global $boarddir, $context, $smcFunc, $modSettings, $scripturl, $sourcedir, $txt;
    // No ID? Redirect back to the main blog page.
    if (empty($_GET['id'])) {
        redirectexit('action=blog');
    }
    // Make sure it's numeric.
    $_GET['id'] = (int) $_GET['id'];
    // We need the postbox functions.
    require_once $sourcedir . '/Subs-Post.php';
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => '', 'width' => '90%', 'form' => 'postmodify', 'labels' => array('post_button' => ''));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
    // Register the comment form in the session variables.
    checkSubmitOnce('register');
    // Make sure we have a posts per page value. If not, use a default.
    if (empty($modSettings['blog_comments_perpage'])) {
        $modSettings['blog_comments_perpage'] = 10;
    }
    // Grab the post and its replies.
    $context['blog_post'] = BlogTopic($_GET['id'], $modSettings['blog_comments_perpage'], null, 'array');
    // Construct a page index
    // !!! ssi_topic() should be fixed! :P
    $context['blog_post']['pageindex'] = constructPageIndex($scripturl . '?action=blog;sa=view_post;id=' . $_GET['id'] . (!empty($modSettings['blog_enable_rewrite']) ? ';blog_name=' . $_GET['blog_name'] : '') . ';start=%d#comments', $_REQUEST['start'], $context['blog_post']['reply_count'], $modSettings['blog_comments_perpage'], true);
    // If the blog name is passed...
    if (!empty($_GET['blog_name'])) {
        $context['blog_name'] = $_GET['blog_name'];
    }
    // Use the "view_post" template.
    $context['sub_template'] = 'view_post';
}
 /**
  * Send a new personal message?
  */
 public function action_send()
 {
     global $txt, $scripturl, $modSettings, $context, $user_info;
     // Load in some text and template dependencies
     loadLanguage('PersonalMessage');
     loadTemplate('PersonalMessage');
     // Set the template we will use
     $context['sub_template'] = 'send';
     // Extract out the spam settings - cause it's neat.
     list($modSettings['max_pm_recipients'], $modSettings['pm_posts_verification'], $modSettings['pm_posts_per_hour']) = explode(',', $modSettings['pm_spam_settings']);
     // Set up some items for the template
     $context['page_title'] = $txt['send_message'];
     $context['reply'] = isset($_REQUEST['pmsg']) || isset($_REQUEST['quote']);
     // Check whether we've gone over the limit of messages we can send per hour.
     if (!empty($modSettings['pm_posts_per_hour']) && !allowedTo(array('admin_forum', 'moderate_forum', 'send_mail')) && $user_info['mod_cache']['bq'] == '0=1' && $user_info['mod_cache']['gq'] == '0=1') {
         // How many messages have they sent this last hour?
         $pmCount = pmCount($user_info['id'], 3600);
         if (!empty($pmCount) && $pmCount >= $modSettings['pm_posts_per_hour']) {
             fatal_lang_error('pm_too_many_per_hour', true, array($modSettings['pm_posts_per_hour']));
         }
     }
     // Quoting / Replying to a message?
     if (!empty($_REQUEST['pmsg'])) {
         $pmsg = (int) $_REQUEST['pmsg'];
         // Make sure this is accessible (not deleted)
         if (!isAccessiblePM($pmsg)) {
             fatal_lang_error('no_access', false);
         }
         // Validate that this is one has been received?
         $isReceived = checkPMReceived($pmsg);
         // Get the quoted message (and make sure you're allowed to see this quote!).
         $row_quoted = loadPMQuote($pmsg, $isReceived);
         if ($row_quoted === false) {
             fatal_lang_error('pm_not_yours', false);
         }
         // Censor the message.
         censorText($row_quoted['subject']);
         censorText($row_quoted['body']);
         // Lets make sure we mark this one as read
         markMessages($pmsg);
         // Figure out which flavor or 'Re: ' to use
         $context['response_prefix'] = response_prefix();
         $form_subject = $row_quoted['subject'];
         // Add 'Re: ' to it....
         if ($context['reply'] && trim($context['response_prefix']) != '' && Util::strpos($form_subject, trim($context['response_prefix'])) !== 0) {
             $form_subject = $context['response_prefix'] . $form_subject;
         }
         // If quoting, lets clean up some things and set the quote header for the pm body
         if (isset($_REQUEST['quote'])) {
             // Remove any nested quotes and <br />...
             $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $row_quoted['body']);
             if (!empty($modSettings['removeNestedQuotes'])) {
                 $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message);
             }
             if (empty($row_quoted['id_member'])) {
                 $form_message = '[quote author=&quot;' . $row_quoted['real_name'] . '&quot;]' . "\n" . $form_message . "\n" . '[/quote]';
             } else {
                 $form_message = '[quote author=' . $row_quoted['real_name'] . ' link=action=profile;u=' . $row_quoted['id_member'] . ' date=' . $row_quoted['msgtime'] . ']' . "\n" . $form_message . "\n" . '[/quote]';
             }
         } else {
             $form_message = '';
         }
         // Do the BBC thang on the message.
         $row_quoted['body'] = parse_bbc($row_quoted['body'], true, 'pm' . $row_quoted['id_pm']);
         // Set up the quoted message array.
         $context['quoted_message'] = array('id' => $row_quoted['id_pm'], 'pm_head' => $row_quoted['pm_head'], 'member' => array('name' => $row_quoted['real_name'], 'username' => $row_quoted['member_name'], 'id' => $row_quoted['id_member'], 'href' => !empty($row_quoted['id_member']) ? $scripturl . '?action=profile;u=' . $row_quoted['id_member'] : '', 'link' => !empty($row_quoted['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_quoted['id_member'] . '">' . $row_quoted['real_name'] . '</a>' : $row_quoted['real_name']), 'subject' => $row_quoted['subject'], 'time' => standardTime($row_quoted['msgtime']), 'html_time' => htmlTime($row_quoted['msgtime']), 'timestamp' => forum_time(true, $row_quoted['msgtime']), 'body' => $row_quoted['body']);
     } else {
         $context['quoted_message'] = false;
         $form_subject = '';
         $form_message = '';
     }
     // Start of like we don't know where this is going
     $context['recipients'] = array('to' => array(), 'bcc' => array());
     // Sending by ID?  Replying to all?  Fetch the real_name(s).
     if (isset($_REQUEST['u'])) {
         // If the user is replying to all, get all the other members this was sent to..
         if ($_REQUEST['u'] == 'all' && isset($row_quoted)) {
             // Firstly, to reply to all we clearly already have $row_quoted - so have the original member from.
             if ($row_quoted['id_member'] != $user_info['id']) {
                 $context['recipients']['to'][] = array('id' => $row_quoted['id_member'], 'name' => htmlspecialchars($row_quoted['real_name'], ENT_COMPAT, 'UTF-8'));
             }
             // Now to get all the others.
             $context['recipients']['to'] = array_merge($context['recipients']['to'], isset($pmsg) ? loadPMRecipientsAll($pmsg) : array());
         } else {
             $users = array_map('intval', explode(',', $_REQUEST['u']));
             $users = array_unique($users);
             // For all the member's this is going to, get their display name.
             require_once SUBSDIR . '/Members.subs.php';
             $result = getBasicMemberData($users);
             foreach ($result as $row) {
                 $context['recipients']['to'][] = array('id' => $row['id_member'], 'name' => $row['real_name']);
             }
         }
         // Get a literal name list in case the user has JavaScript disabled.
         $names = array();
         foreach ($context['recipients']['to'] as $to) {
             $names[] = $to['name'];
         }
         $context['to_value'] = empty($names) ? '' : '&quot;' . implode('&quot;, &quot;', $names) . '&quot;';
     } else {
         $context['to_value'] = '';
     }
     // Set the defaults...
     $context['subject'] = $form_subject;
     $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
     // And build the link tree.
     $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=send', 'name' => $txt['new_message']);
     // If drafts are enabled, lets generate a list of drafts that they can load in to the editor
     if (!empty($context['drafts_pm_save'])) {
         $pm_seed = isset($_REQUEST['pmsg']) ? $_REQUEST['pmsg'] : (isset($_REQUEST['quote']) ? $_REQUEST['quote'] : 0);
         prepareDraftsContext($user_info['id'], $pm_seed);
     }
     // Needed for the editor.
     require_once SUBSDIR . '/Editor.subs.php';
     // Now create the editor.
     $editorOptions = array('id' => 'message', 'value' => $context['message'], 'height' => '250px', 'width' => '100%', 'labels' => array('post_button' => $txt['send_message']), 'preview_type' => 2);
     create_control_richedit($editorOptions);
     // No one is bcc'ed just yet
     $context['bcc_value'] = '';
     // Verification control needed for this PM?
     $context['require_verification'] = !$user_info['is_admin'] && !empty($modSettings['pm_posts_verification']) && $user_info['posts'] < $modSettings['pm_posts_verification'];
     if ($context['require_verification']) {
         require_once SUBSDIR . '/VerificationControls.class.php';
         $verificationOptions = array('id' => 'pm');
         $context['require_verification'] = create_control_verification($verificationOptions);
         $context['visual_verification_id'] = $verificationOptions['id'];
     }
     // Register this form and get a sequence number in $context.
     checkSubmitOnce('register');
 }
function shd_frontpage_options($return_config)
{
    global $context, $modSettings, $txt, $sourcedir, $smcFunc;
    // Since this is potentially dangerous, real admins only, thanks.
    isAllowedTo('admin_forum');
    $config_vars = array(array('select', 'shdp_frontpage_appear', array('always' => $txt['shdp_frontpage_appear_always'], 'firstload' => $txt['shdp_frontpage_appear_firstload'], 'firstdefault' => $txt['shdp_frontpage_appear_firstdefault'])), '', array('select', 'shdp_frontpage_type', array('php' => $txt['shdp_frontpage_type_php'], 'bbcode' => $txt['shdp_frontpage_type_bbcode'])), array('large_text', 'shdp_frontpage_content', 'size' => 30));
    $context['settings_title'] = $txt['shdp_frontpage'];
    $context['settings_icon'] = 'frontpage.png';
    // Are we actually going to display this, or bouncing it back just for admin search?
    if (!$return_config) {
        require_once $sourcedir . '/Subs-Post.php';
        require_once $sourcedir . '/Subs-Editor.php';
        loadTemplate('sd_plugins_template/SDPluginFrontPage');
        $context['sub_template'] = 'shd_frontpage_admin';
        $context['shdp_frontpage_content'] = !empty($modSettings['shdp_frontpage_content']) ? un_preparsecode($modSettings['shdp_frontpage_content']) : '';
        if (isset($_GET['save'])) {
            $_POST['shdp_frontpage_content'] = isset($_POST['shdp_frontpage_content']) ? $_POST['shdp_frontpage_content'] : '';
            if (!empty($_POST['shdp_frontpage_type']) && $_POST['shdp_frontpage_type'] == 'php') {
                $context['shdp_frontpage_content'] = $smcFunc['htmlspecialchars']($_POST['shdp_frontpage_content'], ENT_QUOTES);
            } else {
                $_POST['shdp_frontpage_content'] = $smcFunc['htmlspecialchars']($_POST['shdp_frontpage_content'], ENT_QUOTES);
                preparsecode($_POST['shdp_frontpage_content']);
                $context['shdp_frontpage_content'] = un_preparsecode($_POST['shdp_frontpage_content']);
                // So it's a known safe version.
            }
        }
        $modSettings['disable_wysiwyg'] = true;
        $editorOptions = array('id' => 'shdp_frontpage_content', 'value' => $context['shdp_frontpage_content'], 'labels' => array('post_button' => $txt['save']), 'preview_type' => 0, 'width' => '70%', 'disable_smiley_box' => false);
        create_control_richedit($editorOptions);
        $context['post_box_name'] = $editorOptions['id'];
    }
    return $config_vars;
}
 /**
  * Adding or editing a block.
  */
 public function action_sportal_admin_block_edit()
 {
     global $txt, $context, $modSettings, $boards;
     // Just in case, the admin could be doing something silly like editing a SP block while SP is disabled. ;)
     require_once SUBSDIR . '/PortalBlocks.subs.php';
     $context['SPortal']['is_new'] = empty($_REQUEST['block_id']);
     // BBC Fix move the parameter to the correct position.
     if (!empty($_POST['bbc_name'])) {
         $_POST['parameters'][$_POST['bbc_name']] = !empty($_POST[$_POST['bbc_parameter']]) ? $_POST[$_POST['bbc_parameter']] : '';
         // If we came from WYSIWYG then turn it back into BBC regardless.
         if (!empty($_REQUEST['bbc_' . $_POST['bbc_name'] . '_mode']) && isset($_POST['parameters'][$_POST['bbc_name']])) {
             require_once SUBSDIR . 'Html2BBC.class.php';
             $bbc_converter = new Convert_BBC($_POST['parameters'][$_POST['bbc_name']]);
             $_POST['parameters'][$_POST['bbc_name']] = $bbc_converter->get_bbc();
             // We need to unhtml it now as it gets done shortly.
             $_POST['parameters'][$_POST['bbc_name']] = un_htmlspecialchars($_POST['parameters'][$_POST['bbc_name']]);
         }
     }
     // Passing the selected type via $_GET instead of $_POST?
     $start_parameters = array();
     if (!empty($_GET['selected_type']) && empty($_POST['selected_type'])) {
         $_POST['selected_type'] = array($_GET['selected_type']);
         if (!empty($_GET['parameters'])) {
             foreach ($_GET['parameters'] as $param) {
                 if (isset($_GET[$param])) {
                     $start_parameters[$param] = $_GET[$param];
                 }
             }
         }
     }
     // Want use a block on the portal?
     if ($context['SPortal']['is_new'] && empty($_POST['selected_type']) && empty($_POST['add_block'])) {
         // Gather the blocks we have available
         $context['SPortal']['block_types'] = getFunctionInfo();
         // Create a list of the blocks in use
         $in_use = getBlockInfo();
         foreach ($in_use as $block) {
             $context['SPortal']['block_inuse'][$block['type']] = array('state' => $block['state'], 'column' => $block['column']);
         }
         $context['location'] = array(1 => $txt['sp-positionLeft'], $txt['sp-positionTop'], $txt['sp-positionBottom'], $txt['sp-positionRight'], $txt['sp-positionHeader'], $txt['sp-positionFooter']);
         if (!empty($_REQUEST['col'])) {
             $context['SPortal']['block']['column'] = $_REQUEST['col'];
         }
         $context['sub_template'] = 'block_select_type';
         $context['page_title'] = $txt['sp-blocksAdd'];
     } elseif ($context['SPortal']['is_new'] && !empty($_POST['selected_type'])) {
         $context['SPortal']['block'] = array('id' => 0, 'label' => $txt['sp-blocksDefaultLabel'], 'type' => $_POST['selected_type'][0], 'type_text' => !empty($txt['sp_function_' . $_POST['selected_type'][0] . '_label']) ? $txt['sp_function_' . $_POST['selected_type'][0] . '_label'] : $txt['sp_function_unknown_label'], 'column' => !empty($_POST['block_column']) ? $_POST['block_column'] : 0, 'row' => 0, 'permissions' => 3, 'state' => 1, 'force_view' => 0, 'mobile_view' => 0, 'display' => '', 'display_custom' => '', 'style' => '', 'parameters' => !empty($start_parameters) ? $start_parameters : array(), 'options' => $_POST['selected_type'][0](array(), false, true), 'list_blocks' => !empty($_POST['block_column']) ? getBlockInfo($_POST['block_column']) : array());
     } elseif (!$context['SPortal']['is_new'] && empty($_POST['add_block'])) {
         $_REQUEST['block_id'] = (int) $_REQUEST['block_id'];
         $context['SPortal']['block'] = current(getBlockInfo(null, $_REQUEST['block_id']));
         $context['SPortal']['block'] += array('options' => $context['SPortal']['block']['type'](array(), false, true), 'list_blocks' => getBlockInfo($context['SPortal']['block']['column']));
     }
     // Want to take a look at how this block will appear, well we try our best
     if (!empty($_POST['preview_block']) || isset($_SESSION['sp_error'])) {
         // An error was generated on save, lets set things up like a preview and return to the preview
         if (isset($_SESSION['sp_error'])) {
             $context['SPortal']['error'] = $_SESSION['sp_error'];
             $_POST = $_SESSION['sp_error_post'];
             $_POST['preview_block'] = true;
             // Clean up
             unset($_SESSION['sp_error'], $_SESSION['sp_error_post'], $_POST['add_block']);
         }
         // Just in case, the admin could be doing something silly like editing a SP block while SP is disabled. ;)
         require_once BOARDDIR . '/SSI.php';
         sportal_init_headers();
         loadTemplate('Portal');
         $type_parameters = $_POST['block_type'](array(), 0, true);
         if (!empty($_POST['parameters']) && is_array($_POST['parameters']) && !empty($type_parameters)) {
             foreach ($type_parameters as $name => $type) {
                 if (isset($_POST['parameters'][$name])) {
                     $this->_prepare_parameters($type, $name);
                 }
             }
         } else {
             $_POST['parameters'] = array();
         }
         // Simple is clean
         if (empty($_POST['display_advanced'])) {
             if (!empty($_POST['display_simple']) && in_array($_POST['display_simple'], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages'))) {
                 $display = $_POST['display_simple'];
             } else {
                 $display = '';
             }
             $custom = '';
         } else {
             $display = array();
             $custom = array();
             if (!empty($_POST['display_actions'])) {
                 foreach ($_POST['display_actions'] as $action) {
                     $display[] = Util::htmlspecialchars($action, ENT_QUOTES);
                 }
             }
             if (!empty($_POST['display_boards'])) {
                 foreach ($_POST['display_boards'] as $board) {
                     $display[] = 'b' . (int) substr($board, 1);
                 }
             }
             if (!empty($_POST['display_pages'])) {
                 foreach ($_POST['display_pages'] as $page) {
                     $display[] = 'p' . (int) substr($page, 1);
                 }
             }
             if (!empty($_POST['display_custom'])) {
                 $temp = explode(',', $_POST['display_custom']);
                 foreach ($temp as $action) {
                     $custom[] = Util::htmlspecialchars(Util::htmltrim($action), ENT_QUOTES);
                 }
             }
             $display = empty($display) ? '' : implode(',', $display);
             $custom = empty($custom) ? '' : implode(',', $custom);
         }
         // Create all the information we know about this block
         $context['SPortal']['block'] = array('id' => $_POST['block_id'], 'label' => Util::htmlspecialchars($_POST['block_name'], ENT_QUOTES), 'type' => $_POST['block_type'], 'type_text' => !empty($txt['sp_function_' . $_POST['block_type'] . '_label']) ? $txt['sp_function_' . $_POST['block_type'] . '_label'] : $txt['sp_function_unknown_label'], 'column' => $_POST['block_column'], 'row' => !empty($_POST['block_row']) ? $_POST['block_row'] : 0, 'placement' => !empty($_POST['placement']) && in_array($_POST['placement'], array('before', 'after')) ? $_POST['placement'] : '', 'permissions' => $_POST['permissions'], 'state' => !empty($_POST['block_active']), 'force_view' => !empty($_POST['block_force']), 'mobile_view' => !empty($_POST['block_mobile']), 'display' => $display, 'display_custom' => $custom, 'style' => sportal_parse_style('implode'), 'parameters' => !empty($_POST['parameters']) ? $_POST['parameters'] : array(), 'options' => $_POST['block_type'](array(), false, true), 'list_blocks' => getBlockInfo($_POST['block_column']), 'collapsed' => false);
         if (strpos($modSettings['leftwidth'], '%') !== false || strpos($modSettings['leftwidth'], 'px') !== false) {
             $context['widths'][1] = $modSettings['leftwidth'];
         } else {
             $context['widths'][1] = $modSettings['leftwidth'] . 'px';
         }
         if (strpos($modSettings['rightwidth'], '%') !== false || strpos($modSettings['rightwidth'], 'px') !== false) {
             $context['widths'][4] = $modSettings['rightwidth'];
         } else {
             $context['widths'][4] = $modSettings['rightwidth'] . 'px';
         }
         if (strpos($context['widths'][1], '%') !== false) {
             $context['widths'][2] = $context['widths'][3] = 100 - ($context['widths'][1] + $context['widths'][4]) . '%';
             $context['widths'][5] = $context['widths'][6] = '100%';
         } elseif (strpos($context['widths'][1], 'px') !== false) {
             $context['widths'][2] = $context['widths'][3] = 960 - ($context['widths'][1] + $context['widths'][4]) . 'px';
             $context['widths'][5] = $context['widths'][6] = '960px';
         }
         $context['SPortal']['preview'] = true;
     }
     if (!empty($_POST['selected_type']) || !empty($_POST['preview_block']) || !$context['SPortal']['is_new'] && empty($_POST['add_block'])) {
         // Only the admin can use PHP blocks
         if ($context['SPortal']['block']['type'] == 'sp_php' && !allowedTo('admin_forum')) {
             fatal_lang_error('cannot_admin_forum', false);
         }
         loadLanguage('SPortalHelp', sp_languageSelect('SPortalHelp'));
         // Load up the permissions
         $context['SPortal']['block']['permission_profiles'] = sportal_get_profiles(null, 1, 'name');
         if (empty($context['SPortal']['block']['permission_profiles'])) {
             fatal_lang_error('error_sp_no_permission_profiles', false);
         }
         $context['simple_actions'] = array('sportal' => $txt['sp-portal'], 'sforum' => $txt['sp-forum'], 'allaction' => $txt['sp-blocksOptionAllActions'], 'allboard' => $txt['sp-blocksOptionAllBoards'], 'allpages' => $txt['sp-blocksOptionAllPages'], 'all' => $txt['sp-blocksOptionEverywhere']);
         $context['display_actions'] = array('portal' => $txt['sp-portal'], 'forum' => $txt['sp-forum'], 'recent' => $txt['recent_posts'], 'unread' => $txt['unread_topics_visit'], 'unreadreplies' => $txt['unread_replies'], 'profile' => $txt['profile'], 'pm' => $txt['pm_short'], 'calendar' => $txt['calendar'], 'admin' => $txt['admin'], 'login' => $txt['login'], 'register' => $txt['register'], 'post' => $txt['post'], 'stats' => $txt['forum_stats'], 'search' => $txt['search'], 'mlist' => $txt['members_list'], 'moderate' => $txt['moderate'], 'help' => $txt['help'], 'who' => $txt['who_title']);
         // Load up boards and pages for selection in the template
         sp_block_template_helpers();
         if (empty($context['SPortal']['block']['display'])) {
             $context['SPortal']['block']['display'] = array('0');
         } else {
             $context['SPortal']['block']['display'] = explode(',', $context['SPortal']['block']['display']);
         }
         if (in_array($context['SPortal']['block']['display'][0], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages')) || $context['SPortal']['is_new'] || empty($context['SPortal']['block']['display'][0]) && empty($context['SPortal']['block']['display_custom'])) {
             $context['SPortal']['block']['display_type'] = 0;
         } else {
             $context['SPortal']['block']['display_type'] = 1;
         }
         $context['SPortal']['block']['style'] = sportal_parse_style('explode', $context['SPortal']['block']['style'], !empty($context['SPortal']['preview']));
         // Prepare the Textcontent for BBC, only the first bbc will be detected correctly!
         $firstBBCFound = false;
         foreach ($context['SPortal']['block']['options'] as $name => $type) {
             // Selectable Boards :D
             if ($type == 'board_select' || $type == 'boards') {
                 if (empty($boards)) {
                     require_once SUBSDIR . '/Boards.subs.php';
                     getBoardTree();
                 }
                 // Merge the array ;)
                 if (!isset($context['SPortal']['block']['parameters'][$name])) {
                     $context['SPortal']['block']['parameters'][$name] = array();
                 } elseif (!empty($context['SPortal']['block']['parameters'][$name]) && is_array($context['SPortal']['block']['parameters'][$name])) {
                     $context['SPortal']['block']['parameters'][$name] = implode('|', $context['SPortal']['block']['parameters'][$name]);
                 }
                 $context['SPortal']['block']['board_options'][$name] = array();
                 $config_variable = !empty($context['SPortal']['block']['parameters'][$name]) ? $context['SPortal']['block']['parameters'][$name] : array();
                 $config_variable = !is_array($config_variable) ? explode('|', $config_variable) : $config_variable;
                 $context['SPortal']['block']['board_options'][$name] = array();
                 // Create the list for this Item
                 foreach ($boards as $board) {
                     // Ignore the redirected boards :)
                     if (!empty($board['redirect'])) {
                         continue;
                     }
                     $context['SPortal']['block']['board_options'][$name][$board['id']] = array('value' => $board['id'], 'text' => $board['name'], 'selected' => in_array($board['id'], $config_variable));
                 }
             } elseif ($type === 'bbc') {
                 // ELK support only one bbc correct, multiple bbc do not work at the moment
                 if (!$firstBBCFound) {
                     $firstBBCFound = true;
                     // Start Elk BBC System :)
                     require_once SUBSDIR . '/Editor.subs.php';
                     // Prepare the output :D
                     $form_message = !empty($context['SPortal']['block']['parameters'][$name]) ? $context['SPortal']['block']['parameters'][$name] : '';
                     // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited!
                     if (strpos($form_message, '[html]') !== false) {
                         $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE);
                         for ($i = 0, $n = count($parts); $i < $n; $i++) {
                             // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat.
                             if ($i % 4 == 0) {
                                 $parts[$i] = preg_replace_callback('~\\[html\\](.+?)\\[/html\\]~is', create_function('$m', 'return "[html]" . preg_replace(\'~<br\\s?/?>~i\', \'&lt;br /&gt;<br />\', "$m[1]") . "[/html]";'), $parts[$i]);
                             }
                         }
                         $form_message = implode('', $parts);
                     }
                     $form_message = preg_replace('~<br(?: /)?' . '>~i', "\n", $form_message);
                     // Prepare the data before i want them inside the textarea
                     $form_message = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
                     $context['SPortal']['bbc'] = 'bbc_' . $name;
                     $message_data = array('id' => $context['SPortal']['bbc'], 'width' => '95%', 'height' => '200px', 'value' => $form_message, 'form' => 'sp_block');
                     // Run the ELK bbc editor routine
                     create_control_richedit($message_data);
                     // Store the updated data on the parameters
                     $context['SPortal']['block']['parameters'][$name] = $form_message;
                 } else {
                     $context['SPortal']['block']['options'][$name] = 'textarea';
                 }
             }
         }
         loadJavascriptFile('portal.js?sp24');
         $context['sub_template'] = 'block_edit';
         $context['page_title'] = $context['SPortal']['is_new'] ? $txt['sp-blocksAdd'] : $txt['sp-blocksEdit'];
     }
     // Want to add / edit a block oo the portal
     if (!empty($_POST['add_block'])) {
         checkSession();
         // Only the admin can do php here
         if ($_POST['block_type'] == 'sp_php' && !allowedTo('admin_forum')) {
             fatal_lang_error('cannot_admin_forum', false);
         }
         // Make sure the block name is something safe
         if (!isset($_POST['block_name']) || Util::htmltrim(Util::htmlspecialchars($_POST['block_name']), ENT_QUOTES) === '') {
             fatal_lang_error('error_sp_name_empty', false);
         }
         if ($_POST['block_type'] == 'sp_php' && !empty($_POST['parameters']['content']) && empty($modSettings['sp_disable_php_validation'])) {
             require_once SUBSDIR . '/DataValidator.class.php';
             $validator = new Data_Validator();
             $validator->validation_rules(array('content' => 'php_syntax'));
             $validator->validate(array('content' => $_POST['parameters']['content']));
             $error = $validator->validation_errors();
             if ($error) {
                 $_SESSION['sp_error'] = $error[0];
                 $_SESSION['sp_error_post'] = $_POST;
                 redirectexit('action=admin;area=portalblocks;sa=' . $_REQUEST['sa'] . (!empty($_REQUEST['block_id']) ? ';block_id=' . $_REQUEST['block_id'] : ''));
             }
         }
         // If we have a block ID passed, we must be editing, so the the blocks current data
         if (!empty($_REQUEST['block_id'])) {
             $current_data = current(getBlockInfo(null, $_REQUEST['block_id']));
         }
         // Where are we going to place this new block, before, after, no change
         if (!empty($_POST['placement']) && ($_POST['placement'] === 'before' || $_POST['placement'] === 'after')) {
             if (!empty($current_data)) {
                 $current_row = $current_data['row'];
             } else {
                 $current_row = null;
             }
             // Before or after the chosen block
             if ($_POST['placement'] === 'before') {
                 $row = (int) $_POST['block_row'];
             } else {
                 $row = (int) $_POST['block_row'] + 1;
             }
             if (!empty($current_row) && $row > $current_row) {
                 sp_update_block_row($current_row, $row - 1, $_POST['block_column'], true);
             } else {
                 sp_update_block_row($current_row, $row, $_POST['block_column'], false);
             }
         } elseif (!empty($_POST['placement']) && $_POST['placement'] == 'nochange') {
             $row = 0;
         } else {
             $block_id = !empty($_REQUEST['block_id']) ? (int) $_REQUEST['block_id'] : 0;
             $row = sp_block_nextrow($_POST['block_column'], $block_id);
         }
         $type_parameters = $_POST['block_type'](array(), 0, true);
         if (!empty($_POST['parameters']) && is_array($_POST['parameters']) && !empty($type_parameters)) {
             foreach ($type_parameters as $name => $type) {
                 // Prepare BBC Content for ELK
                 if (isset($_POST['parameters'][$name])) {
                     $this->_prepare_parameters($type, $name);
                 }
             }
         } else {
             $_POST['parameters'] = array();
         }
         // Standard options
         if (empty($_POST['display_advanced'])) {
             if (!empty($_POST['display_simple']) && in_array($_POST['display_simple'], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages'))) {
                 $display = $_POST['display_simple'];
             } else {
                 $display = '';
             }
             $custom = '';
         } else {
             $display = array();
             if (!empty($_POST['display_actions'])) {
                 foreach ($_POST['display_actions'] as $action) {
                     $display[] = Util::htmlspecialchars($action, ENT_QUOTES);
                 }
             }
             if (!empty($_POST['display_boards'])) {
                 foreach ($_POST['display_boards'] as $board) {
                     $display[] = 'b' . (int) substr($board, 1);
                 }
             }
             if (!empty($_POST['display_pages'])) {
                 foreach ($_POST['display_pages'] as $page) {
                     $display[] = 'p' . (int) substr($page, 1);
                 }
             }
             if (!empty($_POST['display_custom'])) {
                 $custom = array();
                 $temp = explode(',', $_POST['display_custom']);
                 foreach ($temp as $action) {
                     $custom[] = Util::htmlspecialchars(Util::htmltrim($action), ENT_QUOTES);
                 }
             }
             $display = empty($display) ? '' : implode(',', $display);
             if (!allowedTo('admin_forum') && isset($current_data['display_custom']) && substr($current_data['display_custom'], 0, 4) === '$php') {
                 $custom = $current_data['display_custom'];
             } elseif (!empty($_POST['display_custom'])) {
                 if (allowedTo('admin_forum') && substr($_POST['display_custom'], 0, 4) === '$php') {
                     $custom = Util::htmlspecialchars($_POST['display_custom'], ENT_QUOTES);
                 } else {
                     $custom = array();
                     $temp = explode(',', $_POST['display_custom']);
                     foreach ($temp as $action) {
                         $custom[] = Util::htmlspecialchars($action, ENT_QUOTES);
                     }
                     $custom = empty($custom) ? '' : implode(',', $custom);
                 }
             } else {
                 $custom = '';
             }
         }
         $blockInfo = array('id' => (int) $_POST['block_id'], 'label' => Util::htmlspecialchars($_POST['block_name'], ENT_QUOTES), 'type' => $_POST['block_type'], 'col' => $_POST['block_column'], 'row' => $row, 'permissions' => (int) $_POST['permissions'], 'state' => !empty($_POST['block_active']) ? 1 : 0, 'force_view' => !empty($_POST['block_force']) ? 1 : 0, 'mobile_view' => !empty($_POST['block_mobile']) ? 1 : 0, 'display' => $display, 'display_custom' => $custom, 'style' => sportal_parse_style('implode'));
         // Insert a new block in to the portal
         if ($context['SPortal']['is_new']) {
             unset($blockInfo['id']);
             $blockInfo['id'] = sp_block_insert($blockInfo);
         } else {
             sp_block_update($blockInfo);
         }
         // Save any parameters for the block
         if (!empty($_POST['parameters'])) {
             sp_block_insert_parameters($_POST['parameters'], $blockInfo['id']);
         }
         redirectexit('action=admin;area=portalblocks');
     }
 }
function shd_admin_canned_editreply()
{
    global $context, $smcFunc, $txt, $sourcedir, $scripturl;
    require_once $sourcedir . '/Subs-Editor.php';
    require_once $sourcedir . '/Subs-Post.php';
    $context['page_title'] = $txt['shd_admin_cannedreplies_editreply'];
    $context['sub_template'] = 'shd_edit_canned_reply';
    $_REQUEST['reply'] = isset($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0;
    $query = $smcFunc['db_query']('', '
		SELECT hdcr.title, hdcr.body, hdcr.vis_user, hdcr.vis_staff, hdcr.active, hdcr.id_cat
		FROM {db_prefix}helpdesk_cannedreplies AS hdcr
		WHERE id_reply = {int:reply}', array('reply' => $_REQUEST['reply']));
    if ($smcFunc['db_num_rows']($query) == 0) {
        $smcFunc['db_free_result']($query);
        fatal_lang_error('shd_admin_cannedreplies_thereplyisalie', false);
    }
    $row = $smcFunc['db_fetch_assoc']($query);
    $smcFunc['db_free_result']($query);
    $context['canned_reply'] = array('id' => $_REQUEST['reply'], 'title' => $row['title'], 'body' => un_preparsecode($row['body']), 'active' => !empty($row['active']), 'vis_user' => !empty($row['vis_user']), 'vis_staff' => !empty($row['vis_staff']), 'cat' => $row['id_cat'], 'depts_selected' => array(), 'depts_available' => array());
    // Now we need to get the possible departments.
    $query = $smcFunc['db_query']('', '
		SELECT id_dept, dept_name
		FROM {db_prefix}helpdesk_depts
		ORDER BY dept_order');
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $context['canned_reply']['depts_available'][$row['id_dept']] = $row['dept_name'];
    }
    $smcFunc['db_free_result']($query);
    // Now any departments this reply is attached to.
    $query = $smcFunc['db_query']('', '
		SELECT hdcrd.id_dept
		FROM {db_prefix}helpdesk_cannedreplies_depts AS hdcrd
		WHERE hdcrd.id_reply = {int:reply}', array('reply' => $_REQUEST['reply']));
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $context['canned_reply']['depts_selected'][] = $row['id_dept'];
    }
    $smcFunc['db_free_result']($query);
    checkSubmitOnce('register');
    $editorOptions = array('id' => 'shd_canned_reply', 'value' => $context['canned_reply']['body'], 'labels' => array('post_button' => $txt['shd_admin_cannedreplies_editreply']), 'preview_type' => 0, 'width' => '70%', 'disable_smiley_box' => false);
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}
    /**
     * Interface for adding/editing a page
     */
    public function action_sportal_admin_page_edit()
    {
        global $txt, $context, $options;
        $context['SPortal']['is_new'] = empty($_REQUEST['page_id']);
        $pages_errors = Error_Context::context('pages', 0);
        // Some help will be needed
        require_once SUBSDIR . '/Editor.subs.php';
        require_once SUBSDIR . '/Post.subs.php';
        // Convert this to BBC?
        if (!empty($_REQUEST['content_mode']) && $_POST['type'] === 'bbc') {
            require_once SUBSDIR . 'Html2BBC.class.php';
            $bbc_converter = new Convert_BBC($_REQUEST['content']);
            $_REQUEST['content'] = $bbc_converter->get_bbc();
            $_REQUEST['content'] = un_htmlspecialchars($_REQUEST['content']);
            $_POST['content'] = $_REQUEST['content'];
        }
        // Load in the blocks that can be used on a page
        $this->blocks = getBlockInfo();
        $context['page_blocks'] = $this->_sportal_admin_page_load_blocks();
        // Saving the work?
        if (!empty($_POST['submit']) && !$pages_errors->hasErrors()) {
            checkSession();
            $this->_sportal_admin_page_edit_save();
        }
        // Doing a quick look before you save or you messed up?
        if (!empty($_POST['preview']) || $pages_errors->hasErrors()) {
            $context['SPortal']['page'] = array('id' => $_POST['page_id'], 'page_id' => $_POST['namespace'], 'title' => Util::htmlspecialchars($_POST['title'], ENT_QUOTES), 'body' => Util::htmlspecialchars($_POST['content'], ENT_QUOTES), 'type' => $_POST['type'], 'permissions' => $_POST['permissions'], 'style' => sportal_parse_style('implode'), 'status' => !empty($_POST['status']));
            // Fix up bbc errors before we go to the preview
            if ($context['SPortal']['page']['type'] == 'bbc') {
                preparsecode($context['SPortal']['page']['body']);
            }
            loadTemplate('PortalPages');
            // Showing errors or a preview?
            if ($pages_errors->hasErrors()) {
                $context['pages_errors'] = array('errors' => $pages_errors->prepareErrors(), 'type' => $pages_errors->getErrorType() == 0 ? 'minor' : 'serious', 'title' => $txt['sp_form_errors_detected']);
            } else {
                $context['SPortal']['preview'] = true;
            }
        } elseif ($context['SPortal']['is_new']) {
            $context['SPortal']['page'] = array('id' => 0, 'page_id' => 'page' . mt_rand(1, 5000), 'title' => $txt['sp_pages_default_title'], 'body' => '', 'type' => 'bbc', 'permissions' => 3, 'style' => '', 'status' => 1);
        } else {
            $_REQUEST['page_id'] = (int) $_REQUEST['page_id'];
            $context['SPortal']['page'] = sportal_get_pages($_REQUEST['page_id']);
        }
        if ($context['SPortal']['page']['type'] === 'bbc') {
            $context['SPortal']['page']['body'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), un_preparsecode($context['SPortal']['page']['body']));
        }
        // Set up the editor, values, initial state, etc
        if ($context['SPortal']['page']['type'] !== 'bbc') {
            // No wizzy mode if they don't need it
            $temp_editor = !empty($options['wysiwyg_default']);
            $options['wysiwyg_default'] = false;
        }
        $editorOptions = array('id' => 'content', 'value' => $context['SPortal']['page']['body'], 'width' => '100%', 'height' => '225px', 'preview_type' => 2);
        create_control_richedit($editorOptions);
        $context['post_box_name'] = $editorOptions['id'];
        if (isset($temp_editor)) {
            $options['wysiwyg_default'] = $temp_editor;
        }
        // Set the editor box as needed (editor or textbox, etc)
        addInlineJavascript('
			$(window).load(function() {
				diewithfire = window.setTimeout(function() {sp_update_editor("' . $context['SPortal']['page']['type'] . '", "");}, 200);
			});
		');
        // Permissions
        $context['SPortal']['page']['permission_profiles'] = sportal_get_profiles(null, 1, 'name');
        if (empty($context['SPortal']['page']['permission_profiles'])) {
            fatal_lang_error('error_sp_no_permission_profiles', false);
        }
        // And for the template
        $context['SPortal']['page']['style'] = sportal_parse_style('explode', $context['SPortal']['page']['style'], !empty($context['SPortal']['preview']));
        $context['SPortal']['page']['body'] = sportal_parse_content($context['SPortal']['page']['body'], $context['SPortal']['page']['type'], 'return');
        $context['page_title'] = $context['SPortal']['is_new'] ? $txt['sp_admin_pages_add'] : $txt['sp_admin_pages_edit'];
        $context['sub_template'] = 'pages_edit';
    }
function char_sheet_edit()
{
    global $context, $txt, $smcFunc, $scripturl, $sourcedir;
    // First, get rid of people shouldn't have a sheet at all - the OOC characters
    if ($context['character']['is_main']) {
        redirectexit('action=profile;u=' . $context['id_member'] . ';area=characters;char=' . $context['character']['id_character']);
    }
    // Then if we're looking at a character who doesn't have an approved one
    // and the user couldn't see it... you are the weakest link, goodbye.
    if (empty($context['character']['char_sheet']) && empty($context['user']['is_owner']) && !allowedTo('admin_forum')) {
        redirectexit('action=profile;u=' . $context['id_member'] . ';area=characters;char=' . $context['character']['id_character']);
    }
    $request = $smcFunc['db_query']('', '
		SELECT id_version, sheet_text, created_time, id_approver, approved_time, approval_state
		FROM {db_prefix}character_sheet_versions
		WHERE id_character = {int:character}
		ORDER BY id_version DESC
		LIMIT 1', array('character' => $context['character']['id_character']));
    if ($smcFunc['db_num_rows']($request) > 0) {
        $context['character']['sheet_details'] = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
    }
    // Make an editor box
    require_once $sourcedir . '/Subs-Post.php';
    require_once $sourcedir . '/Subs-Editor.php';
    if (isset($_POST['message'])) {
        // Are we saving? Let's see if session's legit first.
        checkSession();
        // Then try to get some content.
        $message = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES);
        preparsecode($message);
        if (!empty($message)) {
            // So we have a character sheet. Let's do a comparison against
            // the last character sheet saved just in case the user did something
            // a little bit weird/silly.
            if (empty($context['character']['sheet_details']['sheet_text']) || $message != $context['character']['sheet_details']['sheet_text']) {
                // It's different, good. So insert it, making it await approval.
                $smcFunc['db_insert']('insert', '{db_prefix}character_sheet_versions', array('sheet_text' => 'string', 'id_character' => 'int', 'id_member' => 'int', 'created_time' => 'int', 'id_approver' => 'int', 'approved_time' => 'int', 'approval_state' => 'int'), array($message, $context['character']['id_character'], $context['user']['id'], time(), 0, 0, 0), array('id_version'));
                // Mark previous versions of the character sheet as not awaited approval.
                mark_char_sheets_unapproved($context['character']['id_character']);
            }
        }
        redirectexit('action=profile;u=' . $context['id_member'] . ';area=characters;char=' . $context['character']['id_character'] . ';sa=sheet');
    }
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => !empty($context['character']['sheet_details']['sheet_text']) ? un_preparsecode($context['character']['sheet_details']['sheet_text']) : '', 'labels' => array('post_button' => $txt['save']), 'height' => '500px', 'width' => '100%', 'preview_type' => 0, 'required' => true);
    create_control_richedit($editorOptions);
    load_char_sheet_templates();
    // Now fetch the comments
    $context['sheet_comments'] = [];
    if (!empty($context['character']['sheet_details']['created_time']) && empty($context['character']['sheet_details']['id_approver'])) {
        $request = $smcFunc['db_query']('', '
			SELECT id_comment, id_author, mem.real_name, time_posted, sheet_comment
			FROM {db_prefix}character_sheet_comments AS csc
				LEFT JOIN {db_prefix}members AS mem ON (csc.id_author = mem.id_member)
			WHERE id_character = {int:character}
				AND time_posted > {int:last_approved_time}
			ORDER BY NULL', array('character' => $context['character']['id_character'], 'last_approved_time' => $context['character']['sheet_details']['created_time']));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['real_name'])) {
                $row['real_name'] = $txt['char_unknown'];
            }
            $context['sheet_comments'][$row['id_comment']] = $row;
        }
        $smcFunc['db_free_result']($request);
        krsort($context['sheet_comments']);
    }
    $context['page_title'] = $txt['char_sheet'] . ' - ' . $context['character']['character_name'];
    $context['sub_template'] = 'char_sheet_edit';
}
Exemple #17
0
function EditTopic()
{
    global $txt, $context, $smcFunc, $mbname, $sourcedir, $modSettings;
    // Load the edit topic template
    $context['sub_template'] = 'edittopic';
    // Set the page title
    $context['page_title'] = $mbname . ' - ' . $txt['welcome_edittopic'];
    // Get the Topic ID
    $id = (int) $_REQUEST['id'];
    $request = $smcFunc['db_query']('', "\n\tSELECT \n\t\tID, welcomesubject, welcomebody\n\tFROM {db_prefix}welcome\n\tWHERE ID = {$id} LIMIT 1");
    $row = $smcFunc['db_fetch_assoc']($request);
    $context['welcome_topic'] = array('ID' => $row['ID'], 'SUBJECT' => $row['welcomesubject'], 'BODY' => $row['welcomebody']);
    $smcFunc['db_free_result']($request);
    // Check if spellchecking is both enabled and actually working.
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'topicbody', 'value' => $context['welcome_topic']['BODY'], 'width' => '90%', 'form' => 'cprofile', 'labels' => array('addtopic' => ''));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}
Exemple #18
0
function shd_postbox($id, $message, $buttons, $width = '70%')
{
    global $context, $txt, $modSettings;
    $editorOptions = array('id' => $id, 'value' => $message, 'labels' => $buttons, 'preview_type' => 0, 'width' => $width, 'disable_smiley_box' => empty($modSettings['shd_allow_ticket_bbc']) || $context['ticket_form']['disable_smileys']);
    if (empty($modSettings['shd_allow_ticket_bbc'])) {
        $modSettings['disable_wysiwyg'] = 1;
    }
    // Hide any disabled tags.
    if (!empty($modSettings['shd_enabled_bbc'])) {
        $enabled_tags = explode(',', $modSettings['shd_enabled_bbc']);
        $disabled_tags = array();
        // Loop through all the tags there are in this forum, and and each disabled tag to our 'hide-list'.
        foreach (parse_bbc(false) as $tag) {
            if (!in_array($tag['tag'], $enabled_tags) || $modSettings['shd_enabled_bbc'] == 'shd_all_tags_disabled') {
                $disabled_tags[] = $tag['tag'];
            }
        }
        // Add them to the editors hide var.
        $modSettings['disabledBBC'] = implode(',', $disabled_tags);
    }
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
    // Are there any restrictions on uploading attachments?
    $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', '));
    $context['attachment_restrictions'] = array();
    if (!empty($modSettings['attachmentNumPerPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') {
        $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentNumPerPostLimit'], $modSettings['attachmentNumPerPostLimit']);
    }
    if (!empty($modSettings['attachmentPostLimit']) && $modSettings['shd_attachments_mode'] != 'ticket') {
        $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentPostLimit'], $modSettings['attachmentPostLimit']);
    }
    if (!empty($modSettings['attachmentSizeLimit'])) {
        $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_attachmentSizeLimit'], $modSettings['attachmentSizeLimit']);
    }
}
function sportal_admin_block_edit()
{
    global $txt, $context, $modSettings, $smcFunc, $sourcedir, $boarddir, $boards;
    // Just in case, the admin could be doing something silly like editing a SP block while SP it disabled. ;)
    require_once $sourcedir . '/PortalBlocks.php';
    $context['SPortal']['is_new'] = empty($_REQUEST['block_id']);
    // BBC Fix move the parameter to the correct position.
    if (!empty($_POST['bbc_name'])) {
        $_POST['parameters'][$_POST['bbc_name']] = !empty($_POST[$_POST['bbc_parameter']]) ? $_POST[$_POST['bbc_parameter']] : '';
        // If we came from WYSIWYG then turn it back into BBC regardless.
        if (!empty($_REQUEST['bbc_' . $_POST['bbc_name'] . '_mode']) && isset($_POST['parameters'][$_POST['bbc_name']])) {
            require_once $sourcedir . '/Subs-Editor.php';
            $_POST['parameters'][$_POST['bbc_name']] = html_to_bbc($_POST['parameters'][$_POST['bbc_name']]);
            // We need to unhtml it now as it gets done shortly.
            $_POST['parameters'][$_POST['bbc_name']] = un_htmlspecialchars($_POST['parameters'][$_POST['bbc_name']]);
            // We need this for everything else.
            $_POST['parameters'][$_POST['bbc_name']] = $_POST['parameters'][$_POST['bbc_name']];
        }
    }
    // Passing the selected type via $_GET instead of $_POST?
    $start_parameters = array();
    if (!empty($_GET['selected_type']) && empty($_POST['selected_type'])) {
        $_POST['selected_type'] = array($_GET['selected_type']);
        if (!empty($_GET['parameters'])) {
            foreach ($_GET['parameters'] as $param) {
                if (isset($_GET[$param])) {
                    $start_parameters[$param] = $_GET[$param];
                }
            }
        }
    }
    if ($context['SPortal']['is_new'] && empty($_POST['selected_type']) && empty($_POST['add_block'])) {
        $context['SPortal']['block_types'] = getFunctionInfo();
        if (!empty($_REQUEST['col'])) {
            $context['SPortal']['block']['column'] = $_REQUEST['col'];
        }
        $context['sub_template'] = 'block_select_type';
        $context['page_title'] = $txt['sp-blocksAdd'];
    } elseif ($context['SPortal']['is_new'] && !empty($_POST['selected_type'])) {
        $context['SPortal']['block'] = array('id' => 0, 'label' => $txt['sp-blocksDefaultLabel'], 'type' => $_POST['selected_type'][0], 'type_text' => !empty($txt['sp_function_' . $_POST['selected_type'][0] . '_label']) ? $txt['sp_function_' . $_POST['selected_type'][0] . '_label'] : $txt['sp_function_unknown_label'], 'column' => !empty($_POST['block_column']) ? $_POST['block_column'] : 0, 'row' => 0, 'permission_set' => 3, 'groups_allowed' => array(), 'groups_denied' => array(), 'state' => 1, 'force_view' => 0, 'display' => '', 'display_custom' => '', 'style' => '', 'parameters' => !empty($start_parameters) ? $start_parameters : array(), 'options' => $_POST['selected_type'][0](array(), false, true), 'list_blocks' => !empty($_POST['block_column']) ? getBlockInfo($_POST['block_column']) : array());
    } elseif (!$context['SPortal']['is_new'] && empty($_POST['add_block'])) {
        $_REQUEST['block_id'] = (int) $_REQUEST['block_id'];
        $context['SPortal']['block'] = current(getBlockInfo(null, $_REQUEST['block_id']));
        $context['SPortal']['block'] += array('options' => $context['SPortal']['block']['type'](array(), false, true), 'list_blocks' => getBlockInfo($context['SPortal']['block']['column']));
    }
    if (!empty($_POST['preview_block'])) {
        // Just in case, the admin could be doing something silly like editing a SP block while SP it disabled. ;)
        require_once $boarddir . '/SSI.php';
        sportal_init_headers();
        loadTemplate('Portal');
        $type_parameters = $_POST['block_type'](array(), 0, true);
        if (!empty($_POST['parameters']) && is_array($_POST['parameters']) && !empty($type_parameters)) {
            foreach ($type_parameters as $name => $type) {
                if (isset($_POST['parameters'][$name])) {
                    if ($type == 'bbc') {
                        $parameter['value'] = $_POST['parameters'][$name];
                        require_once $sourcedir . '/Subs-Post.php';
                        $parameter['value'] = $smcFunc['htmlspecialchars']($parameter['value'], ENT_QUOTES);
                        preparsecode($parameter['value']);
                        $_POST['parameters'][$name] = $parameter['value'];
                    } elseif ($type == 'boards' || $type == 'board_select') {
                        $_POST['parameters'][$name] = is_array($_POST['parameters'][$name]) ? implode('|', $_POST['parameters'][$name]) : $_POST['parameters'][$name];
                    } elseif ($type == 'int' || $type == 'select') {
                        $_POST['parameters'][$name] = (int) $_POST['parameters'][$name];
                    } elseif ($type == 'text' || $type == 'textarea' || is_array($type)) {
                        $_POST['parameters'][$name] = $smcFunc['htmlspecialchars']($_POST['parameters'][$name], ENT_QUOTES);
                    } elseif ($type == 'check') {
                        $_POST['parameters'][$name] = !empty($_POST['parameters'][$name]) ? 1 : 0;
                    }
                }
            }
        } else {
            $_POST['parameters'] = array();
        }
        if (empty($_POST['display_advanced'])) {
            if (!empty($_POST['display_simple']) && in_array($_POST['display_simple'], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages'))) {
                $display = $_POST['display_simple'];
            } else {
                $display = '';
            }
            $custom = '';
        } else {
            $display = array();
            $custom = array();
            if (!empty($_POST['display_actions'])) {
                foreach ($_POST['display_actions'] as $action) {
                    $display[] = $smcFunc['htmlspecialchars']($action, ENT_QUOTES);
                }
            }
            if (!empty($_POST['display_boards'])) {
                foreach ($_POST['display_boards'] as $board) {
                    $display[] = 'b' . (int) substr($board, 1);
                }
            }
            if (!empty($_POST['display_pages'])) {
                foreach ($_POST['display_pages'] as $page) {
                    $display[] = 'p' . (int) substr($page, 1);
                }
            }
            if (!empty($_POST['display_custom'])) {
                $temp = explode(',', $_POST['display_custom']);
                foreach ($temp as $action) {
                    $custom[] = $smcFunc['htmlspecialchars']($smcFunc['htmltrim']($action), ENT_QUOTES);
                }
            }
            $display = empty($display) ? '' : implode(',', $display);
            $custom = empty($custom) ? '' : implode(',', $custom);
        }
        $permission_set = 0;
        $groups_allowed = $groups_denied = array();
        if (!empty($_POST['permission_set'])) {
            $permission_set = (int) $_POST['permission_set'];
        } elseif (!empty($_POST['membergroups']) && is_array($_POST['membergroups'])) {
            foreach ($_POST['membergroups'] as $id => $value) {
                if ($value == 1) {
                    $groups_allowed[] = (int) $id;
                } elseif ($value == -1) {
                    $groups_denied[] = (int) $id;
                }
            }
        }
        $context['SPortal']['block'] = array('id' => $_POST['block_id'], 'label' => $smcFunc['htmlspecialchars']($_POST['block_name'], ENT_QUOTES), 'type' => $_POST['block_type'], 'type_text' => !empty($txt['sp_function_' . $_POST['block_type'] . '_label']) ? $txt['sp_function_' . $_POST['block_type'] . '_label'] : $txt['sp_function_unknown_label'], 'column' => $_POST['block_column'], 'row' => !empty($_POST['block_row']) ? $_POST['block_row'] : 0, 'permission_set' => $permission_set, 'groups_allowed' => $groups_allowed, 'groups_denied' => $groups_denied, 'state' => !empty($_POST['block_active']), 'force_view' => !empty($_POST['block_force']), 'display' => $display, 'display_custom' => $custom, 'style' => sportal_parse_style('implode'), 'parameters' => !empty($_POST['parameters']) ? $_POST['parameters'] : array(), 'options' => $_POST['block_type'](array(), false, true), 'list_blocks' => getBlockInfo($_POST['block_column']), 'collapsed' => false);
        if (strpos($modSettings['leftwidth'], '%') !== false || strpos($modSettings['leftwidth'], 'px') !== false) {
            $context['widths'][1] = $modSettings['leftwidth'];
        } else {
            $context['widths'][1] = $modSettings['leftwidth'] . 'px';
        }
        if (strpos($modSettings['rightwidth'], '%') !== false || strpos($modSettings['rightwidth'], 'px') !== false) {
            $context['widths'][4] = $modSettings['rightwidth'];
        } else {
            $context['widths'][4] = $modSettings['rightwidth'] . 'px';
        }
        if (strpos($context['widths'][1], '%') !== false) {
            $context['widths'][2] = $context['widths'][3] = 100 - ($context['widths'][1] + $context['widths'][4]) . '%';
        } elseif (strpos($context['widths'][1], 'px') !== false) {
            $context['widths'][2] = $context['widths'][3] = 960 - ($context['widths'][1] + $context['widths'][4]) . 'px';
        }
        if (strpos($context['widths'][1], '%') !== false) {
            $context['widths'][2] = $context['widths'][3] = 100 - ($context['widths'][1] + $context['widths'][4]) . '%';
            $context['widths'][5] = $context['widths'][6] = '100%';
        } elseif (strpos($context['widths'][1], 'px') !== false) {
            $context['widths'][2] = $context['widths'][3] = 960 - ($context['widths'][1] + $context['widths'][4]) . 'px';
            $context['widths'][5] = $context['widths'][6] = '960px';
        }
        $context['SPortal']['preview'] = true;
    }
    if (!empty($_POST['selected_type']) || !empty($_POST['preview_block']) || !$context['SPortal']['is_new'] && empty($_POST['add_block'])) {
        if ($context['SPortal']['block']['type'] == 'sp_php' && !allowedTo('admin_forum')) {
            fatal_lang_error('cannot_admin_forum', false);
        }
        $context['html_headers'] .= '
	<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
		function sp_collapseObject(id)
		{
			mode = document.getElementById("sp_object_" + id).style.display == "" ? 0 : 1;
			document.getElementById("sp_collapse_" + id).src = smf_images_url + (mode ? "/collapse.gif" : "/expand.gif");
			document.getElementById("sp_object_" + id).style.display = mode ? "" : "none";
		}
	// ]]></script>';
        loadLanguage('SPortalHelp', sp_languageSelect('SPortalHelp'));
        $context['SPortal']['block']['groups'] = sp_load_membergroups();
        $context['simple_actions'] = array('sportal' => $txt['sp-portal'], 'sforum' => $txt['sp-forum'], 'allaction' => $txt['sp-blocksOptionAllActions'], 'allboard' => $txt['sp-blocksOptionAllBoards'], 'allpages' => $txt['sp-blocksOptionAllPages'], 'all' => $txt['sp-blocksOptionEverywhere']);
        $context['display_actions'] = array('portal' => $txt['sp-portal'], 'forum' => $txt['sp-forum'], 'recent' => $txt['recent_posts'], 'unread' => $txt['unread_topics_visit'], 'unreadreplies' => $txt['unread_replies'], 'profile' => $txt['profile'], 'pm' => $txt['pm_short'], 'calendar' => $txt['calendar'], 'admin' => $txt['admin'], 'login' => $txt['login'], 'register' => $txt['register'], 'post' => $txt['post'], 'stats' => $txt['forum_stats'], 'search' => $txt['search'], 'mlist' => $txt['members_list'], 'moderate' => $txt['moderate'], 'help' => $txt['help'], 'who' => $txt['who_title']);
        $request = $smcFunc['db_query']('', '
			SELECT id_board, name
			FROM {db_prefix}boards
			ORDER BY name DESC');
        $context['display_boards'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $context['display_boards']['b' . $row['id_board']] = $row['name'];
        }
        $smcFunc['db_free_result']($request);
        $request = $smcFunc['db_query']('', '
			SELECT id_page, title
			FROM {db_prefix}sp_pages
			ORDER BY title DESC');
        $context['display_pages'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $context['display_pages']['p' . $row['id_page']] = $row['title'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($context['SPortal']['block']['display'])) {
            $context['SPortal']['block']['display'] = array('0');
        } else {
            $context['SPortal']['block']['display'] = explode(',', $context['SPortal']['block']['display']);
        }
        if (in_array($context['SPortal']['block']['display'][0], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages')) || $context['SPortal']['is_new'] || empty($context['SPortal']['block']['display'][0]) && empty($context['SPortal']['block']['display_custom'])) {
            $context['SPortal']['block']['display_type'] = 0;
        } else {
            $context['SPortal']['block']['display_type'] = 1;
        }
        $context['SPortal']['block']['style'] = sportal_parse_style('explode', $context['SPortal']['block']['style'], !empty($context['SPortal']['preview']));
        // Prepare the Textcontent for BBC, only the first bbc will be correct detected! (SMF Support only 1 per page with the standard function)
        $firstBBCFound = false;
        foreach ($context['SPortal']['block']['options'] as $name => $type) {
            // Selectable Boards :D
            if ($type == 'board_select' || $type == 'boards') {
                if (empty($boards)) {
                    require_once $sourcedir . '/Subs-Boards.php';
                    getBoardTree();
                }
                // Merge the array ;). (Only in 2.0 needed)
                if (!isset($context['SPortal']['block']['parameters'][$name])) {
                    $context['SPortal']['block']['parameters'][$name] = array();
                } elseif (!empty($context['SPortal']['block']['parameters'][$name]) && is_array($context['SPortal']['block']['parameters'][$name])) {
                    $context['SPortal']['block']['parameters'][$name] = implode('|', $context['SPortal']['block']['parameters'][$name]);
                }
                $context['SPortal']['block']['board_options'][$name] = array();
                $config_variable = !empty($context['SPortal']['block']['parameters'][$name]) ? $context['SPortal']['block']['parameters'][$name] : array();
                $config_variable = !is_array($config_variable) ? explode('|', $config_variable) : $config_variable;
                $context['SPortal']['block']['board_options'][$name] = array();
                // Create the list for this Item
                foreach ($boards as $board) {
                    if (!empty($board['redirect'])) {
                        // Ignore the redirected boards :)
                        continue;
                    }
                    $context['SPortal']['block']['board_options'][$name][$board['id']] = array('value' => $board['id'], 'text' => $board['name'], 'selected' => in_array($board['id'], $config_variable));
                }
            } elseif ($type == 'bbc') {
                // SMF support only one bbc correct, multiple bbc do not work at the moment
                if (!$firstBBCFound) {
                    $firstBBCFound = true;
                    // Start SMF BBC Sytem :)
                    require_once $sourcedir . '/Subs-Editor.php';
                    // Prepare the output :D
                    $form_message = !empty($context['SPortal']['block']['parameters'][$name]) ? $context['SPortal']['block']['parameters'][$name] : '';
                    // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited!
                    if (strpos($form_message, '[html]') !== false) {
                        $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE);
                        for ($i = 0, $n = count($parts); $i < $n; $i++) {
                            // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat.
                            if ($i % 4 == 0) {
                                $parts[$i] = preg_replace('~\\[html\\](.+?)\\[/html\\]~ise', '\'[html]\' . preg_replace(\'~<br\\s?/?>~i\', \'&lt;br /&gt;<br />\', \'$1\') . \'[/html]\'', $parts[$i]);
                            }
                        }
                        $form_message = implode('', $parts);
                    }
                    $form_message = preg_replace('~<br(?: /)?' . '>~i', "\n", $form_message);
                    // Prepare the data before i want them inside the textarea
                    $form_message = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
                    $context['SPortal']['bbc'] = 'bbc_' . $name;
                    $message_data = array('id' => $context['SPortal']['bbc'], 'width' => '95%', 'height' => '200px', 'value' => $form_message, 'form' => 'sp_block');
                    // Run the SMF bbc editor rutine
                    create_control_richedit($message_data);
                    // Store the updated data on the parameters
                    $context['SPortal']['block']['parameters'][$name] = $form_message;
                } else {
                    $context['SPortal']['block']['options'][$name] = 'textarea';
                }
            }
        }
        $context['sub_template'] = 'block_edit';
        $context['page_title'] = $context['SPortal']['is_new'] ? $txt['sp-blocksAdd'] : $txt['sp-blocksEdit'];
    }
    if (!empty($_POST['add_block'])) {
        if ($_POST['block_type'] == 'sp_php' && !allowedTo('admin_forum')) {
            fatal_lang_error('cannot_admin_forum', false);
        }
        if (!isset($_POST['block_name']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['block_name']), ENT_QUOTES) === '') {
            fatal_lang_error('error_sp_name_empty', false);
        }
        if ($_POST['block_type'] == 'sp_php' && !empty($_POST['parameters']['content']) && empty($modSettings['sp_disable_php_validation'])) {
            $error = sp_validate_php($_POST['parameters']['content']);
            if ($error) {
                fatal_lang_error('error_sp_php_' . $error, false);
            }
        }
        if (!empty($_REQUEST['block_id'])) {
            $current_data = current(getBlockInfo(null, $_REQUEST['block_id']));
        }
        if (!empty($_POST['placement']) && ($_POST['placement'] == 'before' || $_POST['placement'] == 'after')) {
            if (!empty($current_data)) {
                $current_row = $current_data['row'];
            } else {
                $current_row = null;
            }
            if ($_POST['placement'] == 'before') {
                $row = (int) $_POST['block_row'];
            } else {
                $row = (int) $_POST['block_row'] + 1;
            }
            if (!empty($current_row) && $row > $current_row) {
                $row = $row - 1;
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}sp_blocks
					SET row = row - 1
					WHERE col = {int:col}
						AND row > {int:start}
						AND row <= {int:end}', array('col' => (int) $_POST['block_column'], 'start' => $current_row, 'end' => $row));
            } else {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}sp_blocks
					SET row = row + 1
					WHERE col = {int:col}
						AND row >= {int:start}' . (!empty($current_row) ? '
						AND row < {int:end}' : ''), array('col' => (int) $_POST['block_column'], 'start' => $row, 'end' => !empty($current_row) ? $current_row : 0));
            }
        } elseif (!empty($_POST['placement']) && $_POST['placement'] == 'nochange') {
            $row = 0;
        } else {
            $request = $smcFunc['db_query']('', '
				SELECT row
				FROM {db_prefix}sp_blocks
				WHERE col = {int:col}' . (!empty($_REQUEST['block_id']) ? '
					AND id_block != {int:current_id}' : '') . '
				ORDER BY row DESC
				LIMIT 1', array('col' => $_POST['block_column'], 'current_id' => $_REQUEST['block_id']));
            list($row) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            $row = $row + 1;
        }
        $type_parameters = $_POST['block_type'](array(), 0, true);
        if (!empty($_POST['parameters']) && is_array($_POST['parameters']) && !empty($type_parameters)) {
            foreach ($type_parameters as $name => $type) {
                if (isset($_POST['parameters'][$name])) {
                    // Prepare BBC Content for SMF 2 special case =D
                    if ($type == 'bbc') {
                        $parameter['value'] = $_POST['parameters'][$name];
                        require_once $sourcedir . '/Subs-Post.php';
                        // Prepare the message a bit for some additional testing.
                        $parameter['value'] = $smcFunc['htmlspecialchars']($parameter['value'], ENT_QUOTES);
                        preparsecode($parameter['value']);
                        //Store now the correct and fixed value ;)
                        $_POST['parameters'][$name] = $parameter['value'];
                    } elseif ($type == 'boards' || $type == 'board_select') {
                        $_POST['parameters'][$name] = is_array($_POST['parameters'][$name]) ? implode('|', $_POST['parameters'][$name]) : $_POST['parameters'][$name];
                    } elseif ($type == 'int' || $type == 'select') {
                        $_POST['parameters'][$name] = (int) $_POST['parameters'][$name];
                    } elseif ($type == 'text' || $type == 'textarea' || is_array($type)) {
                        $_POST['parameters'][$name] = $smcFunc['htmlspecialchars']($_POST['parameters'][$name], ENT_QUOTES);
                    } elseif ($type == 'check') {
                        $_POST['parameters'][$name] = !empty($_POST['parameters'][$name]) ? 1 : 0;
                    }
                }
            }
        } else {
            $_POST['parameters'] = array();
        }
        $permission_set = 0;
        $groups_allowed = $groups_denied = '';
        if (!empty($_POST['permission_set'])) {
            $permission_set = (int) $_POST['permission_set'];
        } elseif (!empty($_POST['membergroups']) && is_array($_POST['membergroups'])) {
            $groups_allowed = $groups_denied = array();
            foreach ($_POST['membergroups'] as $id => $value) {
                if ($value == 1) {
                    $groups_allowed[] = (int) $id;
                } elseif ($value == -1) {
                    $groups_denied[] = (int) $id;
                }
            }
            $groups_allowed = implode(',', $groups_allowed);
            $groups_denied = implode(',', $groups_denied);
        }
        if (empty($_POST['display_advanced'])) {
            if (!empty($_POST['display_simple']) && in_array($_POST['display_simple'], array('all', 'sportal', 'sforum', 'allaction', 'allboard', 'allpages'))) {
                $display = $_POST['display_simple'];
            } else {
                $display = '';
            }
            $custom = '';
        } else {
            $display = array();
            if (!empty($_POST['display_actions'])) {
                foreach ($_POST['display_actions'] as $action) {
                    $display[] = $smcFunc['htmlspecialchars']($action, ENT_QUOTES);
                }
            }
            if (!empty($_POST['display_boards'])) {
                foreach ($_POST['display_boards'] as $board) {
                    $display[] = 'b' . (int) substr($board, 1);
                }
            }
            if (!empty($_POST['display_pages'])) {
                foreach ($_POST['display_pages'] as $page) {
                    $display[] = 'p' . (int) substr($page, 1);
                }
            }
            if (!empty($_POST['display_custom'])) {
                $temp = explode(',', $_POST['display_custom']);
                foreach ($temp as $action) {
                    $custom[] = $smcFunc['htmlspecialchars']($smcFunc['htmltrim']($action), ENT_QUOTES);
                }
            }
            $display = empty($display) ? '' : implode(',', $display);
            if (!allowedTo('admin_forum') && isset($current_data['display_custom']) && substr($current_data['display_custom'], 0, 4) === '$php') {
                $custom = $current_data['display_custom'];
            } elseif (!empty($_POST['display_custom'])) {
                if (allowedTo('admin_forum') && substr($_POST['display_custom'], 0, 4) === '$php') {
                    $custom = $smcFunc['htmlspecialchars']($_POST['display_custom'], ENT_QUOTES);
                } else {
                    $custom = array();
                    $temp = explode(',', $_POST['display_custom']);
                    foreach ($temp as $action) {
                        $custom[] = $smcFunc['htmlspecialchars']($action, ENT_QUOTES);
                    }
                    $custom = empty($custom) ? '' : implode(',', $custom);
                }
            } else {
                $custom = '';
            }
        }
        $blockInfo = array('id' => (int) $_POST['block_id'], 'label' => $smcFunc['htmlspecialchars']($_POST['block_name'], ENT_QUOTES), 'type' => $_POST['block_type'], 'col' => $_POST['block_column'], 'row' => $row, 'permission_set' => $permission_set, 'groups_allowed' => $groups_allowed, 'groups_denied' => $groups_denied, 'state' => !empty($_POST['block_active']) ? 1 : 0, 'force_view' => !empty($_POST['block_force']) ? 1 : 0, 'display' => $display, 'display_custom' => $custom, 'style' => sportal_parse_style('implode'));
        if ($context['SPortal']['is_new']) {
            unset($blockInfo['id']);
            $smcFunc['db_insert']('', '{db_prefix}sp_blocks', array('label' => 'string', 'type' => 'string', 'col' => 'int', 'row' => 'int', 'permission_set' => 'int', 'groups_allowed' => 'string', 'groups_denied' => 'string', 'state' => 'int', 'force_view' => 'int', 'display' => 'string', 'display_custom' => 'string', 'style' => 'string'), $blockInfo, array('id_block'));
            $blockInfo['id'] = $smcFunc['db_insert_id']('{db_prefix}sp_blocks', 'id_block');
        } else {
            $block_fields = array("label = {string:label}", "permission_set = {int:permission_set}", "groups_allowed = {string:groups_allowed}", "groups_denied = {string:groups_denied}", "state = {int:state}", "force_view = {int:force_view}", "display = {string:display}", "display_custom = {string:display_custom}", "style = {string:style}");
            if (!empty($blockInfo['row'])) {
                $block_fields[] = "row = {int:row}";
            } else {
                unset($blockInfo['row']);
            }
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}sp_blocks
				SET ' . implode(', ', $block_fields) . '
				WHERE id_block = {int:id}', $blockInfo);
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}sp_parameters
				WHERE id_block = {int:id}', array('id' => $blockInfo['id']));
        }
        if (!empty($_POST['parameters'])) {
            $parameters = array();
            foreach ($_POST['parameters'] as $variable => $value) {
                $parameters[] = array('id_block' => $blockInfo['id'], 'variable' => $variable, 'value' => $value);
            }
            $smcFunc['db_insert']('', '{db_prefix}sp_parameters', array('id_block' => 'int', 'variable' => 'string', 'value' => 'string'), $parameters, array());
        }
        redirectexit('action=admin;area=portalblocks');
    }
}
    /**
     * The central part of the board - topic display.
     *
     * What it does:
     * - This function loads the posts in a topic up so they can be displayed.
     * - It uses the main sub template of the Display template.
     * - It requires a topic, and can go to the previous or next topic from it.
     * - It jumps to the correct post depending on a number/time/IS_MSG passed.
     * - It depends on the messages_per_page, defaultMaxMessages and enableAllMessages settings.
     * - It is accessed by ?topic=id_topic.START.
     */
    public function action_display()
    {
        global $scripturl, $txt, $modSettings, $context, $settings;
        global $options, $user_info, $board_info, $topic, $board;
        global $attachments, $messages_request;
        // What are you gonna display if these are empty?!
        if (empty($topic)) {
            fatal_lang_error('no_board', false);
        }
        // Load the template
        loadTemplate('Display');
        $context['sub_template'] = 'messages';
        // And the topic functions
        require_once SUBSDIR . '/Topic.subs.php';
        require_once SUBSDIR . '/Messages.subs.php';
        // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            @ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        // How much are we sticking on each page?
        $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        $template_layers = Template_Layers::getInstance();
        $template_layers->addEnd('messages_informations');
        $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
        // Let's do some work on what to search index.
        if (count($_GET) > 2) {
            foreach ($_GET as $k => $v) {
                if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                    $context['robot_no_index'] = true;
                }
            }
        }
        if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
            $context['robot_no_index'] = true;
        }
        // Find the previous or next topic.  Make a fuss if there are no more.
        if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
            // No use in calculating the next topic if there's only one.
            if ($board_info['num_topics'] > 1) {
                $includeStickies = !empty($modSettings['enableStickyTopics']);
                $topic = $_REQUEST['prev_next'] === 'prev' ? previousTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies) : nextTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies);
                $context['current_topic'] = $topic;
            }
            // Go to the newest message on this topic.
            $_REQUEST['start'] = 'new';
        }
        // Add 1 to the number of views of this topic (except for robots).
        if (!$user_info['possibly_robot'] && (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic)) {
            increaseViewCounter($topic);
            $_SESSION['last_read_topic'] = $topic;
        }
        $topic_selects = array();
        $topic_tables = array();
        $topic_parameters = array('topic' => $topic, 'member' => $user_info['id'], 'board' => (int) $board);
        // Allow addons to add additional details to the topic query
        call_integration_hook('integrate_topic_query', array(&$topic_selects, &$topic_tables, &$topic_parameters));
        // Load the topic details
        $topicinfo = getTopicInfo($topic_parameters, 'all', $topic_selects, $topic_tables);
        if (empty($topicinfo)) {
            fatal_lang_error('not_a_topic', false);
        }
        // Is this a moved topic that we are redirecting to?
        if (!empty($topicinfo['id_redirect_topic']) && !isset($_GET['noredir'])) {
            markTopicsRead(array($user_info['id'], $topic, $topicinfo['id_last_msg'], 0), $topicinfo['new_from'] !== 0);
            redirectexit('topic=' . $topicinfo['id_redirect_topic'] . '.0;redirfrom=' . $topicinfo['id_topic']);
        }
        $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
        $context['topic_first_message'] = $topicinfo['id_first_msg'];
        $context['topic_last_message'] = $topicinfo['id_last_msg'];
        $context['topic_unwatched'] = isset($topicinfo['unwatched']) ? $topicinfo['unwatched'] : 0;
        if (isset($_GET['redirfrom'])) {
            $redir_topics = topicsList(array((int) $_GET['redirfrom']));
            if (!empty($redir_topics[(int) $_GET['redirfrom']])) {
                $context['topic_redirected_from'] = $redir_topics[(int) $_GET['redirfrom']];
                $context['topic_redirected_from']['redir_href'] = $scripturl . '?topic=' . $context['topic_redirected_from']['id_topic'] . '.0;noredir';
            }
        }
        // Add up unapproved replies to get real number of replies...
        if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
            $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
        }
        // If this topic was derived from another, set the followup details
        if (!empty($topicinfo['derived_from'])) {
            require_once SUBSDIR . '/FollowUps.subs.php';
            $context['topic_derived_from'] = topicStartedHere($topic, $includeUnapproved);
        }
        // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
        if (!$includeUnapproved && $topicinfo['unapproved_posts'] && !$user_info['is_guest']) {
            $myUnapprovedPosts = unapprovedPosts($topic, $user_info['id']);
            $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
        } elseif ($user_info['is_guest']) {
            $context['total_visible_posts'] = $context['num_replies'] + ($topicinfo['approved'] ? 1 : 0);
        } else {
            $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
        }
        // When was the last time this topic was replied to?  Should we warn them about it?
        if (!empty($modSettings['oldTopicDays'])) {
            $mgsOptions = basicMessageInfo($topicinfo['id_last_msg'], true);
            $context['oldTopicError'] = $mgsOptions['poster_time'] + $modSettings['oldTopicDays'] * 86400 < time() && empty($topicinfo['is_sticky']);
        } else {
            $context['oldTopicError'] = false;
        }
        // The start isn't a number; it's information about what to do, where to go.
        if (!is_numeric($_REQUEST['start'])) {
            // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
            if ($_REQUEST['start'] == 'new') {
                // Guests automatically go to the last post.
                if ($user_info['is_guest']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                    $_REQUEST['start'] = $context['start_from'];
                } else {
                    // Fall through to the next if statement.
                    $_REQUEST['start'] = 'msg' . $topicinfo['new_from'];
                }
            }
            // Start from a certain time index, not a message.
            if (substr($_REQUEST['start'], 0, 4) == 'from') {
                $timestamp = (int) substr($_REQUEST['start'], 4);
                if ($timestamp === 0) {
                    $_REQUEST['start'] = 0;
                } else {
                    // Find the number of messages posted before said time...
                    $context['start_from'] = countNewPosts($topic, $topicinfo, $timestamp);
                    $_REQUEST['start'] = $context['start_from'];
                }
            } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
                $virtual_msg = (int) substr($_REQUEST['start'], 3);
                if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                    $context['start_from'] = 0;
                } else {
                    $only_approved = $modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts');
                    $context['start_from'] = countMessagesBefore($topic, $virtual_msg, false, $only_approved, !$user_info['is_guest']);
                }
                // We need to reverse the start as well in this case.
                $_REQUEST['start'] = $context['start_from'];
            }
        }
        // Mark the mention as read if requested
        if (isset($_REQUEST['mentionread']) && !empty($virtual_msg)) {
            require_once CONTROLLERDIR . '/Mentions.controller.php';
            $mentions = new Mentions_Controller();
            $mentions->setData(array('id_mention' => $_REQUEST['item'], 'mark' => $_REQUEST['mark']));
            $mentions->action_markread();
        }
        // Create a previous next string if the selected theme has it as a selected option.
        if ($modSettings['enablePreviousNext']) {
            $context['links'] += array('go_prev' => $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new', 'go_next' => $scripturl . '?topic=' . $topic . '.0;prev_next=next#new');
        }
        // Derived from, set the link back
        if (!empty($context['topic_derived_from'])) {
            $context['links']['derived_from'] = $scripturl . '?msg=' . $context['topic_derived_from']['derived_from'];
        }
        // Check if spellchecking is both enabled and actually working. (for quick reply.)
        $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
        if ($context['show_spellchecking']) {
            loadJavascriptFile('spellcheck.js', array('defer' => true));
        }
        // Do we need to show the visual verification image?
        $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
        if ($context['require_verification']) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions);
            $context['visual_verification_id'] = $verificationOptions['id'];
        }
        // Are we showing signatures - or disabled fields?
        $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
        $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
        // Censor the title...
        censorText($topicinfo['subject']);
        $context['page_title'] = $topicinfo['subject'];
        // Is this topic sticky, or can it even be?
        $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
        // Allow addons access to the topicinfo array
        call_integration_hook('integrate_display_topic', array($topicinfo));
        // Default this topic to not marked for notifications... of course...
        $context['is_marked_notify'] = false;
        // Did we report a post to a moderator just now?
        $context['report_sent'] = isset($_GET['reportsent']);
        if ($context['report_sent']) {
            $template_layers->add('report_sent');
        }
        // Let's get nosey, who is viewing this topic?
        if (!empty($settings['display_who_viewing'])) {
            require_once SUBSDIR . '/Who.subs.php';
            formatViewers($topic, 'topic');
        }
        // If all is set, but not allowed... just unset it.
        $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
        if (isset($_REQUEST['all']) && !$can_show_all) {
            unset($_REQUEST['all']);
        } elseif (isset($_REQUEST['all'])) {
            $_REQUEST['start'] = -1;
        }
        // Construct the page index, allowing for the .START method...
        $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true, array('all' => $can_show_all, 'all_selected' => isset($_REQUEST['all'])));
        $context['start'] = $_REQUEST['start'];
        // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
        // Figure out all the link to the next/prev
        $context['links'] += array('prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '');
        // If they are viewing all the posts, show all the posts, otherwise limit the number.
        if ($can_show_all && isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        }
        // Build the link tree.
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject']);
        // Build a list of this board's moderators.
        $context['moderators'] =& $board_info['moderators'];
        $context['link_moderators'] = array();
        // Information about the current topic...
        $context['is_locked'] = $topicinfo['locked'];
        $context['is_sticky'] = $topicinfo['is_sticky'];
        $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
        $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
        $context['is_approved'] = $topicinfo['approved'];
        $context['is_poll'] = $topicinfo['id_poll'] > 0 && !empty($modSettings['pollMode']) && allowedTo('poll_view');
        determineTopicClass($context);
        // Did this user start the topic or not?
        $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
        $context['topic_starter_id'] = $topicinfo['id_member_started'];
        // Set the topic's information for the template.
        $context['subject'] = $topicinfo['subject'];
        $context['num_views'] = $topicinfo['num_views'];
        $context['num_views_text'] = $context['num_views'] == 1 ? $txt['read_one_time'] : sprintf($txt['read_many_times'], $context['num_views']);
        $context['mark_unread_time'] = !empty($virtual_msg) ? $virtual_msg : $topicinfo['new_from'];
        // Set a canonical URL for this page.
        $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
        // For quick reply we need a response prefix in the default forum language.
        $context['response_prefix'] = response_prefix();
        // If we want to show event information in the topic, prepare the data.
        if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
            // We need events details and all that jazz
            require_once SUBSDIR . '/Calendar.subs.php';
            // First, try create a better time format, ignoring the "time" elements.
            if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
                $date_string = $user_info['time_format'];
            } else {
                $date_string = $matches[0];
            }
            // Get event information for this topic.
            $events = eventInfoForTopic($topic);
            $context['linked_calendar_events'] = array();
            foreach ($events as $event) {
                // Prepare the dates for being formatted.
                $start_date = sscanf($event['start_date'], '%04d-%02d-%02d');
                $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
                $end_date = sscanf($event['end_date'], '%04d-%02d-%02d');
                $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
                $context['linked_calendar_events'][] = array('id' => $event['id_event'], 'title' => $event['title'], 'can_edit' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'can_export' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => standardTime($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => standardTime($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
            }
            if (!empty($context['linked_calendar_events'])) {
                $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
                $template_layers->add('display_calendar');
            }
        }
        // Create the poll info if it exists.
        if ($context['is_poll']) {
            $template_layers->add('display_poll');
            require_once SUBSDIR . '/Poll.subs.php';
            loadPollContext($topicinfo['id_poll']);
            // Build the poll moderation button array.
            $context['poll_buttons'] = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'allow_poll_view', 'text' => 'poll_results', 'image' => 'poll_results.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start'] . ';viewresults'), 'change_vote' => array('test' => 'allow_change_vote', 'text' => 'poll_change_vote', 'image' => 'poll_change_vote.png', 'lang' => true, 'url' => $scripturl . '?action=poll;sa=vote;topic=' . $context['current_topic'] . '.' . $context['start'] . ';poll=' . $context['poll']['id'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'allow_lock_poll', 'text' => !$context['poll']['is_locked'] ? 'poll_lock' : 'poll_unlock', 'image' => 'poll_lock.png', 'lang' => true, 'url' => $scripturl . '?action=lockvoting;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'edit' => array('test' => 'allow_edit_poll', 'text' => 'poll_edit', 'image' => 'poll_edit.png', 'lang' => true, 'url' => $scripturl . '?action=editpoll;topic=' . $context['current_topic'] . '.' . $context['start']), 'remove_poll' => array('test' => 'can_remove_poll', 'text' => 'poll_remove', 'image' => 'admin_remove_poll.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['poll_remove_warn'] . '\');"', 'url' => $scripturl . '?action=poll;sa=remove;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']));
            // Allow mods to add additional buttons here
            call_integration_hook('integrate_poll_buttons');
        }
        // Calculate the fastest way to get the messages!
        $ascending = true;
        $start = $_REQUEST['start'];
        $limit = $context['messages_per_page'];
        $firstIndex = 0;
        if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
            $ascending = !$ascending;
            $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
            $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
            $firstIndex = $limit - 1;
        }
        // Taking care of member specific settings
        $limit_settings = array('messages_per_page' => $context['messages_per_page'], 'start' => $start, 'offset' => $limit);
        // Get each post and poster in this topic.
        $topic_details = getTopicsPostsAndPoster($topic, $limit_settings, $ascending);
        $messages = $topic_details['messages'];
        $posters = array_unique($topic_details['all_posters']);
        $all_posters = $topic_details['all_posters'];
        unset($topic_details);
        call_integration_hook('integrate_display_message_list', array(&$messages, &$posters));
        // Guests can't mark topics read or for notifications, just can't sorry.
        if (!$user_info['is_guest'] && !empty($messages)) {
            $mark_at_msg = max($messages);
            if ($mark_at_msg >= $topicinfo['id_last_msg']) {
                $mark_at_msg = $modSettings['maxMsgID'];
            }
            if ($mark_at_msg >= $topicinfo['new_from']) {
                markTopicsRead(array($user_info['id'], $topic, $mark_at_msg, $topicinfo['unwatched']), $topicinfo['new_from'] !== 0);
            }
            updateReadNotificationsFor($topic, $board);
            // Have we recently cached the number of new topics in this board, and it's still a lot?
            if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
                $_SESSION['topicseen_cache'][$board]--;
            } elseif (isset($_REQUEST['topicseen'])) {
                // Use the mark read tables... and the last visit to figure out if this should be read or not.
                $numNewTopics = getUnreadCountSince($board, empty($_SESSION['id_msg_last_visit']) ? 0 : $_SESSION['id_msg_last_visit']);
                // If there're no real new topics in this board, mark the board as seen.
                if (empty($numNewTopics)) {
                    $_REQUEST['boardseen'] = true;
                } else {
                    $_SESSION['topicseen_cache'][$board] = $numNewTopics;
                }
            } elseif (isset($_SESSION['topicseen_cache'][$board])) {
                $_SESSION['topicseen_cache'][$board]--;
            }
            // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
            if (isset($_REQUEST['boardseen'])) {
                require_once SUBSDIR . '/Boards.subs.php';
                markBoardsRead($board, false, false);
            }
        }
        $attachments = array();
        // If there _are_ messages here... (probably an error otherwise :!)
        if (!empty($messages)) {
            require_once SUBSDIR . '/Attachments.subs.php';
            // Fetch attachments.
            $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
            if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
                $attachments = getAttachments($messages, $includeUnapproved, 'filter_accessible_attachment', $all_posters);
            }
            $msg_parameters = array('message_list' => $messages, 'new_from' => $topicinfo['new_from']);
            $msg_selects = array();
            $msg_tables = array();
            call_integration_hook('integrate_message_query', array(&$msg_selects, &$msg_tables, &$msg_parameters));
            // What?  It's not like it *couldn't* be only guests in this topic...
            if (!empty($posters)) {
                loadMemberData($posters);
            }
            // Load in the likes for this group of messages
            if (!empty($modSettings['likes_enabled'])) {
                require_once SUBSDIR . '/Likes.subs.php';
                $context['likes'] = loadLikes($messages, true);
                // ajax controller for likes
                loadJavascriptFile('like_posts.js', array('defer' => true));
                loadLanguage('Errors');
                // Initiate likes and the tooltips for likes
                addInlineJavascript('
				$(document).ready(function () {
					var likePostInstance = likePosts.prototype.init({
						oTxt: ({
							btnText : ' . JavaScriptEscape($txt['ok_uppercase']) . ',
							likeHeadingError : ' . JavaScriptEscape($txt['like_heading_error']) . ',
							error_occurred : ' . JavaScriptEscape($txt['error_occurred']) . '
						}),
					});

					$(".like_button, .unlike_button").SiteTooltip({
						hoverIntent: {
							sensitivity: 10,
							interval: 150,
							timeout: 50
						}
					});
				});', true);
            }
            $messages_request = loadMessageRequest($msg_selects, $msg_tables, $msg_parameters);
            if (!empty($modSettings['enableFollowup'])) {
                require_once SUBSDIR . '/FollowUps.subs.php';
                $context['follow_ups'] = followupTopics($messages, $includeUnapproved);
            }
            // Go to the last message if the given time is beyond the time of the last message.
            if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
                $context['start_from'] = $topicinfo['num_replies'];
            }
            // Since the anchor information is needed on the top of the page we load these variables beforehand.
            $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $messages_request = false;
            $context['first_message'] = 0;
            $context['first_new_message'] = false;
        }
        $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&')), ENT_COMPAT, 'UTF-8'), 'child_level' => $board_info['child_level']);
        // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
        // This will be called from the template.
        $context['get_message'] = array($this, 'prepareDisplayContext_callback');
        // Now set all the wonderful, wonderful permissions... like moderation ones...
        $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_send_email' => 'send_email_to_members', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
        foreach ($common_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm);
        }
        // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
        $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
        foreach ($anyown_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
        }
        // Cleanup all the permissions with extra stuff...
        $context['can_mark_notify'] &= !$context['user']['is_guest'];
        $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
        $context['calendar_post'] &= !empty($modSettings['cal_enabled']) && (allowedTo('modify_any') || $context['user']['started'] && allowedTo('modify_own'));
        $context['can_add_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] <= 0;
        $context['can_remove_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] > 0;
        $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
        $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
        $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && !empty($modSettings['warning_enable']);
        // Handle approval flags...
        $context['can_reply_approved'] = $context['can_reply'];
        $context['can_reply'] |= $context['can_reply_unapproved'];
        $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
        $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
        $context['can_unwatch'] = !$user_info['is_guest'] && $modSettings['enable_unwatch'];
        $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
        $context['can_print'] = empty($modSettings['disable_print_topic']);
        // Start this off for quick moderation - it will be or'd for each post.
        $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
        // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
        $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
        $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
        $context['can_follow_up'] = !empty($modSettings['enableFollowup']) && boardsallowedto('post_new') !== array();
        // Check if the draft functions are enabled and that they have permission to use them (for quick reply.)
        $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft') && $context['can_reply'];
        $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
        if (!empty($context['drafts_save'])) {
            loadLanguage('Drafts');
        }
        if (!empty($context['drafts_autosave']) && empty($options['use_editor_quick_reply'])) {
            loadJavascriptFile('drafts.js');
        }
        if (!empty($modSettings['mentions_enabled'])) {
            $context['mentions_enabled'] = true;
            // Just using the plain text quick reply and not the editor
            if (empty($options['use_editor_quick_reply'])) {
                loadJavascriptFile(array('jquery.atwho.js', 'jquery.caret.min.js', 'mentioning.js'));
            }
            loadCSSFile('jquery.atwho.css');
            addInlineJavascript('
			$(document).ready(function () {
				for (var i = 0, count = all_elk_mentions.length; i < count; i++)
					all_elk_mentions[i].oMention = new elk_mentions(all_elk_mentions[i].oOptions);
			});');
        }
        // Load up the Quick ModifyTopic and Quick Reply scripts
        loadJavascriptFile('topic.js');
        // Auto video embeding enabled?
        if (!empty($modSettings['enableVideoEmbeding'])) {
            addInlineJavascript('
		$(document).ready(function() {
			$().linkifyvideo(oEmbedtext);
		});');
        }
        // Load up the "double post" sequencing magic.
        if (!empty($options['display_quick_reply'])) {
            checkSubmitOnce('register');
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
            if (!empty($options['use_editor_quick_reply']) && $context['can_reply']) {
                // Needed for the editor and message icons.
                require_once SUBSDIR . '/Editor.subs.php';
                // Now create the editor.
                $editorOptions = array('id' => 'message', 'value' => '', 'labels' => array('post_button' => $txt['post']), 'height' => '250px', 'width' => '100%', 'preview_type' => 0);
                create_control_richedit($editorOptions);
                $context['attached'] = '';
                $context['make_poll'] = isset($_REQUEST['poll']);
                // Message icons - customized icons are off?
                $context['icons'] = getMessageIcons($board);
                if (!empty($context['icons'])) {
                    $context['icons'][count($context['icons']) - 1]['is_last'] = true;
                }
            }
        }
        addJavascriptVar(array('notification_topic_notice' => $context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']), true);
        if ($context['can_send_topic']) {
            addJavascriptVar(array('sendtopic_cancel' => $txt['modify_cancel'], 'sendtopic_back' => $txt['back'], 'sendtopic_close' => $txt['find_close'], 'sendtopic_error' => $txt['send_error_occurred'], 'required_field' => $txt['require_field']), true);
        }
        // Build the normal button array.
        $context['normal_buttons'] = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'image' => 'reply.png', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return notifyButton(this);"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'unwatch' => array('test' => 'can_unwatch', 'text' => ($context['topic_unwatched'] ? '' : 'un') . 'watch', 'image' => ($context['topic_unwatched'] ? '' : 'un') . 'watched.png', 'lang' => true, 'custom' => 'onclick="return unwatchButton(this);"', 'url' => $scripturl . '?action=unwatchtopic;topic=' . $context['current_topic'] . '.' . $context['start'] . ';sa=' . ($context['topic_unwatched'] ? 'off' : 'on') . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0', 'custom' => 'onclick="return sendtopicOverlayDiv(this.href, \'' . $txt['send_topic'] . '\');"'), 'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="nofollow"', 'class' => 'new_win', 'url' => $scripturl . '?action=topic;sa=printpage;topic=' . $context['current_topic'] . '.0'));
        // Build the mod button array
        $context['mod_buttons'] = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.png', 'lang' => true, 'url' => $scripturl . '?action=movetopic;current_board=' . $context['current_board'] . ';topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', 'url' => $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=lock;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'sticky' => array('test' => 'can_sticky', 'text' => empty($context['is_sticky']) ? 'set_sticky' : 'set_nonsticky', 'image' => 'admin_sticky.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.png', 'lang' => true, 'url' => $scripturl . '?action=mergetopics;board=' . $context['current_board'] . '.0;from=' . $context['current_topic']), 'calendar' => array('test' => 'calendar_post', 'text' => 'calendar_link', 'image' => 'linktocal.png', 'lang' => true, 'url' => $scripturl . '?action=post;calendar;msg=' . $context['topic_first_message'] . ';topic=' . $context['current_topic'] . '.0'));
        // Restore topic. eh?  No monkey business.
        if ($context['can_restore_topic']) {
            $context['mod_buttons'][] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']);
        }
        if ($context['can_reply'] && !empty($options['display_quick_reply'])) {
            $template_layers->add('quickreply');
        }
        $template_layers->add('pages_and_buttons');
        // Allow adding new buttons easily.
        call_integration_hook('integrate_display_buttons');
        call_integration_hook('integrate_mod_buttons');
    }
    /**
     * Edits an existing or adds a new article to the system
     * Handles the previewing of an article
     */
    public function action_sportal_admin_article_edit()
    {
        global $context, $options, $txt;
        $this->_is_new = empty($_REQUEST['article_id']);
        $article_errors = Error_Context::context('article', 0);
        // Going to use editor and post functions
        require_once SUBSDIR . '/Post.subs.php';
        require_once SUBSDIR . '/Editor.subs.php';
        // Convert this to BBC?
        if (!empty($_REQUEST['content_mode']) && $_POST['type'] == 'bbc') {
            $convert = $_REQUEST['content'];
            require_once SUBSDIR . '/Html2BBC.class.php';
            $bbc_converter = new Convert_BBC($convert);
            $convert = $bbc_converter->get_bbc();
            $convert = un_htmlspecialchars($convert);
            $_POST['content'] = $convert;
        }
        // Saving the work?
        if (!empty($_POST['submit']) && !$article_errors->hasErrors()) {
            checkSession();
            $this->_sportal_admin_article_edit_save();
        }
        // Just taking a look before you save?
        if (!empty($_POST['preview']) || $article_errors->hasErrors()) {
            $context['article'] = $this->_sportal_admin_article_preview();
            // Fix any bbc errors they have created
            if ($context['article']['type'] == 'bbc') {
                preparsecode($context['article']['body']);
            }
            loadTemplate('PortalArticles');
            // Showing errors or a preview?
            if ($article_errors->hasErrors()) {
                $context['article_errors'] = array('errors' => $article_errors->prepareErrors(), 'type' => $article_errors->getErrorType() == 0 ? 'minor' : 'serious', 'title' => $txt['sp_form_errors_detected']);
            } else {
                $context['preview'] = true;
            }
        } elseif ($this->_is_new) {
            $context['article'] = array('id' => 0, 'article_id' => 'article' . mt_rand(1, 5000), 'category' => array('id' => 0), 'title' => $txt['sp_articles_default_title'], 'body' => '', 'type' => 'bbc', 'permissions' => 3, 'status' => 1);
        } else {
            $_REQUEST['article_id'] = (int) $_REQUEST['article_id'];
            $context['article'] = sportal_get_articles($_REQUEST['article_id']);
        }
        if ($context['article']['type'] === 'bbc') {
            $context['article']['body'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), un_preparsecode($context['article']['body']));
        }
        // On to the editor
        if ($context['article']['type'] !== 'bbc') {
            // Override user prefs for wizzy mode if they don't need it
            $temp_editor = !empty($options['wysiwyg_default']);
            $options['wysiwyg_default'] = false;
        }
        // Fire up the editor with the values
        $editor_options = array('id' => 'content', 'value' => $context['article']['body'], 'width' => '100%', 'height' => '225px', 'preview_type' => 2);
        create_control_richedit($editor_options);
        $context['post_box_name'] = $editor_options['id'];
        // Restore their settings
        if (isset($temp_editor)) {
            $options['wysiwyg_default'] = $temp_editor;
        }
        // Set the editor box to the right mode based on type (bbc, html, php)
        addInlineJavascript('
			$(window).load(function() {
				diewithfire = window.setTimeout(function() {sp_update_editor("' . $context['article']['type'] . '", "");}, 200);
			});
		');
        // Final bits for the template, category's and permission settings
        $context['article']['permission_profiles'] = sportal_get_profiles(null, 1, 'name');
        if (empty($context['article']['permission_profiles'])) {
            fatal_lang_error('error_sp_no_permission_profiles', false);
        }
        $context['article']['categories'] = sportal_get_categories();
        if (empty($context['article']['categories'])) {
            fatal_lang_error('error_sp_no_category', false);
        }
        // Page out values
        $context['is_new'] = $this->_is_new;
        $context['article']['body'] = sportal_parse_content($context['article']['body'], $context['article']['type'], 'return');
        $context['page_title'] = $this->_is_new ? $txt['sp_admin_articles_add'] : $txt['sp_admin_articles_edit'];
        $context['sub_template'] = 'articles_edit';
    }
Exemple #22
0
function Post()
{
    global $txt, $scripturl, $topic, $modSettings, $board;
    global $user_info, $sc, $board_info, $context, $settings;
    global $sourcedir, $options, $smcFunc, $language;
    loadLanguage('Post');
    // You can't reply with a poll... hacker.
    if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) {
        unset($_REQUEST['poll']);
    }
    // Posting an event?
    $context['make_event'] = isset($_REQUEST['calendar']);
    $context['robot_no_index'] = true;
    // You must be posting to *some* board.
    if (empty($board) && !$context['make_event']) {
        fatal_lang_error('no_board', false);
    }
    require_once $sourcedir . '/Subs-Post.php';
    if (isset($_REQUEST['xml'])) {
        $context['sub_template'] = 'post';
        // Just in case of an earlier error...
        $context['preview_message'] = '';
        $context['preview_subject'] = '';
    }
    // No message is complete without a topic.
    if (empty($topic) && !empty($_REQUEST['msg'])) {
        $request = $smcFunc['db_query']('', '
			SELECT id_topic
			FROM {db_prefix}messages
			WHERE id_msg = {int:msg}', array('msg' => (int) $_REQUEST['msg']));
        if ($smcFunc['db_num_rows']($request) != 1) {
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        } else {
            list($topic) = $smcFunc['db_fetch_row']($request);
        }
        $smcFunc['db_free_result']($request);
    }
    // Check if it's locked.  It isn't locked if no topic is specified.
    if (!empty($topic)) {
        $request = $smcFunc['db_query']('', '
			SELECT
				t.locked, IFNULL(ln.id_topic, 0) AS notify, t.is_sticky, t.id_poll, t.id_last_msg, mf.id_member,
				t.id_first_msg, mf.subject,
				CASE WHEN ml.poster_time > ml.modified_time THEN ml.poster_time ELSE ml.modified_time END AS last_post_time
			FROM {db_prefix}topics AS t
				LEFT JOIN {db_prefix}log_notify AS ln ON (ln.id_topic = t.id_topic AND ln.id_member = {int:current_member})
				LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
			WHERE t.id_topic = {int:current_topic}
			LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic));
        list($locked, $context['notify'], $sticky, $pollID, $context['topic_last_message'], $id_member_poster, $id_first_msg, $first_subject, $lastPostTime) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // If this topic already has a poll, they sure can't add another.
        if (isset($_REQUEST['poll']) && $pollID > 0) {
            unset($_REQUEST['poll']);
        }
        if (empty($_REQUEST['msg'])) {
            if ($user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) {
                is_not_guest();
            }
            // By default the reply will be approved...
            $context['becomes_approved'] = true;
            if ($id_member_poster != $user_info['id']) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_any');
                }
            } elseif (!allowedTo('post_reply_any')) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_own');
                }
            }
        } else {
            $context['becomes_approved'] = true;
        }
        $context['can_lock'] = allowedTo('lock_any') || $user_info['id'] == $id_member_poster && allowedTo('lock_own');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky;
    } else {
        $context['becomes_approved'] = true;
        if (!$context['make_event'] || !empty($board)) {
            if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                $context['becomes_approved'] = false;
            } else {
                isAllowedTo('post_new');
            }
        }
        $locked = 0;
        // !!! These won't work if you're making an event.
        $context['can_lock'] = allowedTo(array('lock_any', 'lock_own'));
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = !empty($_REQUEST['sticky']);
    }
    // !!! These won't work if you're posting an event!
    $context['can_notify'] = allowedTo('mark_any_notify');
    $context['can_move'] = allowedTo('move_any');
    $context['move'] = !empty($_REQUEST['move']);
    $context['announce'] = !empty($_REQUEST['announce']);
    // You can only announce topics that will get approved...
    $context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved'];
    $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']);
    $context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    // Generally don't show the approval box... (Assume we want things approved)
    $context['show_approval'] = false;
    // An array to hold all the attachments for this topic.
    $context['current_attachments'] = array();
    // Don't allow a post if it's locked and you aren't all powerful.
    if ($locked && !allowedTo('moderate_board')) {
        fatal_lang_error('topic_locked', false);
    }
    // Check the users permissions - is the user allowed to add or post a poll?
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        // New topic, new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $id_member_poster && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        require_once $sourcedir . '/Subs-Members.php';
        $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
        // Set up the poll options.
        $context['poll_options'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expire' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_enabled' => in_array(-1, $allowedVoteGroups['allowed']));
        // Make all five poll choices empty.
        $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true));
    }
    if ($context['make_event']) {
        // They might want to pick a board.
        if (!isset($context['current_board'])) {
            $context['current_board'] = 0;
        }
        // Start loading up the event info.
        $context['event'] = array();
        $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : '';
        $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1;
        $context['event']['new'] = $context['event']['id'] == -1;
        // Permissions check!
        isAllowedTo('calendar_post');
        // Editing an event?  (but NOT previewing!?)
        if (!$context['event']['new'] && !isset($_REQUEST['subject'])) {
            // If the user doesn't have permission to edit the post in this topic, redirect them.
            if ((empty($id_member_poster) || $id_member_poster != $user_info['id'] || !allowedTo('modify_own')) && !allowedTo('modify_any')) {
                require_once $sourcedir . '/Calendar.php';
                return CalendarPost();
            }
            // Get the current event information.
            $request = $smcFunc['db_query']('', '
				SELECT
					id_member, title, MONTH(start_date) AS month, DAYOFMONTH(start_date) AS day,
					YEAR(start_date) AS year, (TO_DAYS(end_date) - TO_DAYS(start_date)) AS span
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}
				LIMIT 1', array('id_event' => $context['event']['id']));
            $row = $smcFunc['db_fetch_assoc']($request);
            $smcFunc['db_free_result']($request);
            // Make sure the user is allowed to edit this event.
            if ($row['id_member'] != $user_info['id']) {
                isAllowedTo('calendar_edit_any');
            } elseif (!allowedTo('calendar_edit_any')) {
                isAllowedTo('calendar_edit_own');
            }
            $context['event']['month'] = $row['month'];
            $context['event']['day'] = $row['day'];
            $context['event']['year'] = $row['year'];
            $context['event']['title'] = $row['title'];
            $context['event']['span'] = $row['span'] + 1;
        } else {
            $today = getdate();
            // You must have a month and year specified!
            if (!isset($_REQUEST['month'])) {
                $_REQUEST['month'] = $today['mon'];
            }
            if (!isset($_REQUEST['year'])) {
                $_REQUEST['year'] = $today['year'];
            }
            $context['event']['month'] = (int) $_REQUEST['month'];
            $context['event']['year'] = (int) $_REQUEST['year'];
            $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0);
            $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1;
            // Make sure the year and month are in the valid range.
            if ($context['event']['month'] < 1 || $context['event']['month'] > 12) {
                fatal_lang_error('invalid_month', false);
            }
            if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) {
                fatal_lang_error('invalid_year', false);
            }
            // Get a list of boards they can post in.
            $boards = boardsAllowedTo('post_new');
            if (empty($boards)) {
                fatal_lang_error('cannot_post_new', 'user');
            }
            // Load a list of boards for this event in the context.
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($context['current_board']) ? $modSettings['cal_defaultboard'] : $context['current_board']);
            $context['event']['categories'] = getBoardList($boardListOptions);
        }
        // Find the last day of the month.
        $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
        $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard'];
    }
    if (empty($context['post_errors'])) {
        $context['post_errors'] = array();
    }
    // See if any new replies have come along.
    if (empty($_REQUEST['msg']) && !empty($topic)) {
        if (empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $context['topic_last_message'] > $_REQUEST['last_msg']) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}messages
				WHERE id_topic = {int:current_topic}
					AND id_msg > {int:last_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND approved = {int:approved}') . '
				LIMIT 1', array('current_topic' => $topic, 'last_msg' => (int) $_REQUEST['last_msg'], 'approved' => 1));
            list($context['new_replies']) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            if (!empty($context['new_replies'])) {
                if ($context['new_replies'] == 1) {
                    $txt['error_new_reply'] = isset($_GET['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply'];
                } else {
                    $txt['error_new_replies'] = sprintf(isset($_GET['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']);
                }
                // If they've come from the display page then we treat the error differently....
                if (isset($_GET['last_msg'])) {
                    $newRepliesError = $context['new_replies'];
                } else {
                    $context['post_error'][$context['new_replies'] == 1 ? 'new_reply' : 'new_replies'] = true;
                }
                $modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts'];
            }
        }
        // Check whether this is a really old post being bumped...
        if (!empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) {
            $oldTopicError = true;
        }
    }
    // Get a response prefix (like 'Re:') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // Previewing, modifying, or posting?
    if (isset($_REQUEST['message']) || !empty($context['post_error'])) {
        // Validate inputs.
        if (empty($context['post_error'])) {
            if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['subject'])) == '') {
                $context['post_error']['no_subject'] = true;
            }
            if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['message'])) == '') {
                $context['post_error']['no_message'] = true;
            }
            if (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_REQUEST['message']) > $modSettings['max_messageLength']) {
                $context['post_error']['long_message'] = true;
            }
            // Are you... a guest?
            if ($user_info['is_guest']) {
                $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']);
                $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']);
                // Validate the name and email.
                if (!isset($_REQUEST['guestname']) || trim(strtr($_REQUEST['guestname'], '_', ' ')) == '') {
                    $context['post_error']['no_name'] = true;
                } elseif ($smcFunc['strlen']($_REQUEST['guestname']) > 25) {
                    $context['post_error']['long_name'] = true;
                } else {
                    require_once $sourcedir . '/Subs-Members.php';
                    if (isReservedName(htmlspecialchars($_REQUEST['guestname']), 0, true, false)) {
                        $context['post_error']['bad_name'] = true;
                    }
                }
                if (empty($modSettings['guest_post_no_email'])) {
                    if (!isset($_REQUEST['email']) || $_REQUEST['email'] == '') {
                        $context['post_error']['no_email'] = true;
                    } elseif (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_REQUEST['email']) == 0) {
                        $context['post_error']['bad_email'] = true;
                    }
                }
            }
            // This is self explanatory - got any questions?
            if (isset($_REQUEST['question']) && trim($_REQUEST['question']) == '') {
                $context['post_error']['no_question'] = true;
            }
            // This means they didn't click Post and get an error.
            $really_previewing = true;
        } else {
            if (!isset($_REQUEST['subject'])) {
                $_REQUEST['subject'] = '';
            }
            if (!isset($_REQUEST['message'])) {
                $_REQUEST['message'] = '';
            }
            if (!isset($_REQUEST['icon'])) {
                $_REQUEST['icon'] = 'xx';
            }
            // They are previewing if they asked to preview (i.e. came from quick reply).
            $really_previewing = !empty($_POST['preview']);
        }
        // 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'];
        // Set up the inputs for the form.
        $form_subject = strtr($smcFunc['htmlspecialchars']($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $form_message = $smcFunc['htmlspecialchars']($_REQUEST['message'], ENT_QUOTES);
        // Make sure the subject isn't too long - taking into account special characters.
        if ($smcFunc['strlen']($form_subject) > 100) {
            $form_subject = $smcFunc['substr']($form_subject, 0, 100);
        }
        // Have we inadvertently trimmed off the subject of useful information?
        if ($smcFunc['htmltrim']($form_subject) === '') {
            $context['post_error']['no_subject'] = true;
        }
        // Any errors occurred?
        if (!empty($context['post_error'])) {
            loadLanguage('Errors');
            $context['error_type'] = 'minor';
            $context['post_error']['messages'] = array();
            foreach ($context['post_error'] as $post_error => $dummy) {
                if ($post_error == 'messages') {
                    continue;
                }
                if ($post_error == 'long_message') {
                    $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']);
                }
                $context['post_error']['messages'][] = $txt['error_' . $post_error];
                // If it's not a minor error flag it as such.
                if (!in_array($post_error, array('new_reply', 'not_approved', 'new_replies', 'old_topic', 'need_qr_verification'))) {
                    $context['error_type'] = 'serious';
                }
            }
        }
        if (isset($_REQUEST['poll'])) {
            $context['question'] = isset($_REQUEST['question']) ? $smcFunc['htmlspecialchars'](trim($_REQUEST['question'])) : '';
            $context['choices'] = array();
            $choice_id = 0;
            $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive($_POST['options']);
            foreach ($_POST['options'] as $option) {
                if (trim($option) == '') {
                    continue;
                }
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false);
            }
            if (count($context['choices']) < 2) {
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
            }
            $context['choices'][count($context['choices']) - 1]['is_last'] = true;
        }
        // Are you... a guest?
        if ($user_info['is_guest']) {
            $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']);
            $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']);
            $_REQUEST['guestname'] = htmlspecialchars($_REQUEST['guestname']);
            $context['name'] = $_REQUEST['guestname'];
            $_REQUEST['email'] = htmlspecialchars($_REQUEST['email']);
            $context['email'] = $_REQUEST['email'];
            $user_info['name'] = $_REQUEST['guestname'];
        }
        // Only show the preview stuff if they hit Preview.
        if ($really_previewing == true || isset($_REQUEST['xml'])) {
            // Set up the preview message and subject and censor them...
            $context['preview_message'] = $form_message;
            preparsecode($form_message, true);
            preparsecode($context['preview_message']);
            // Do all bulletin board code tags, with or without smileys.
            $context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1);
            if ($form_subject != '') {
                $context['preview_subject'] = $form_subject;
                censorText($context['preview_subject']);
                censorText($context['preview_message']);
            } else {
                $context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>';
            }
            // Protect any CDATA blocks.
            if (isset($_REQUEST['xml'])) {
                $context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>'));
            }
        }
        // Set up the checkboxes.
        $context['notify'] = !empty($_REQUEST['notify']);
        $context['use_smileys'] = !isset($_REQUEST['ns']);
        $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx';
        // Set the destination action for submission.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '') . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = isset($_REQUEST['msg']) ? $txt['save'] : $txt['post'];
        // Previewing an edit?
        if (isset($_REQUEST['msg']) && !empty($topic)) {
            // Get the existing message.
            $request = $smcFunc['db_query']('', '
				SELECT
					m.id_member, m.modified_time, m.smileys_enabled, m.body,
					m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
					IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
					a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
					m.poster_time
			FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
					LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
				WHERE m.id_msg = {int:id_msg}
					AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg']));
            // The message they were trying to edit was most likely deleted.
            // !!! Change this error message?
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('no_board', false);
            }
            $row = $smcFunc['db_fetch_assoc']($request);
            $attachment_stuff = array($row);
            while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
                $attachment_stuff[] = $row2;
            }
            $smcFunc['db_free_result']($request);
            if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
                // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
                if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                    isAllowedTo('modify_replies');
                } else {
                    isAllowedTo('modify_own');
                }
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_any');
            }
            if (!empty($modSettings['attachmentEnable'])) {
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(size, -1) AS filesize, filename, id_attach, approved
					FROM {db_prefix}attachments
					WHERE id_msg = {int:id_msg}
						AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    if ($row['filesize'] <= 0) {
                        continue;
                    }
                    $context['current_attachments'][] = array('name' => htmlspecialchars($row['filename']), 'id' => $row['id_attach'], 'approved' => $row['approved']);
                }
                $smcFunc['db_free_result']($request);
            }
            // Allow moderators to change names....
            if (allowedTo('moderate_forum') && !empty($topic)) {
                $request = $smcFunc['db_query']('', '
					SELECT id_member, poster_name, poster_email
					FROM {db_prefix}messages
					WHERE id_msg = {int:id_msg}
						AND id_topic = {int:current_topic}
					LIMIT 1', array('current_topic' => $topic, 'id_msg' => (int) $_REQUEST['msg']));
                $row = $smcFunc['db_fetch_assoc']($request);
                $smcFunc['db_free_result']($request);
                if (empty($row['id_member'])) {
                    $context['name'] = htmlspecialchars($row['poster_name']);
                    $context['email'] = htmlspecialchars($row['poster_email']);
                }
            }
        }
        // No check is needed, since nothing is really posted.
        checkSubmitOnce('free');
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Get the existing message.
        $request = $smcFunc['db_query']('', '
			SELECT
				m.id_member, m.modified_time, m.smileys_enabled, m.body,
				m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
				IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
				a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
				m.poster_time
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
				LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
			WHERE m.id_msg = {int:id_msg}
				AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg']));
        // The message they were trying to edit was most likely deleted.
        // !!! Change this error message?
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('no_board', false);
        }
        $row = $smcFunc['db_fetch_assoc']($request);
        $attachment_stuff = array($row);
        while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
            $attachment_stuff[] = $row2;
        }
        $smcFunc['db_free_result']($request);
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
            if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
        } else {
            isAllowedTo('modify_any');
        }
        // When was it last modified?
        if (!empty($row['modified_time'])) {
            $context['last_modified'] = timeformat($row['modified_time']);
        }
        // Get the stuff ready for the form.
        $form_subject = $row['subject'];
        $form_message = un_preparsecode($row['body']);
        censorText($form_message);
        censorText($form_subject);
        // Check the boxes that should be checked.
        $context['use_smileys'] = !empty($row['smileys_enabled']);
        $context['icon'] = $row['icon'];
        // Show an "approve" box if the user can approve it, and the message isn't approved.
        if (!$row['approved'] && !$context['show_approval']) {
            $context['show_approval'] = allowedTo('approve_posts');
        }
        // Load up 'em attachments!
        foreach ($attachment_stuff as $attachment) {
            if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) {
                $context['current_attachments'][] = array('name' => htmlspecialchars($attachment['filename']), 'id' => $attachment['id_attach'], 'approved' => $attachment['attachment_approved']);
            }
        }
        // Allow moderators to change names....
        if (allowedTo('moderate_forum') && empty($row['id_member'])) {
            $context['name'] = htmlspecialchars($row['poster_name']);
            $context['email'] = htmlspecialchars($row['poster_email']);
        }
        // Set the destinaton.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['save'];
    } else {
        // By default....
        $context['use_smileys'] = true;
        $context['icon'] = 'xx';
        if ($user_info['is_guest']) {
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
        }
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['post'];
        // Posting a quoted reply?
        if (!empty($topic) && !empty($_REQUEST['quote'])) {
            // Make sure they _can_ quote this post, and if so get it.
            $request = $smcFunc['db_query']('', '
				SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
					LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
				WHERE m.id_msg = {int:id_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND m.approved = {int:is_approved}') . '
				LIMIT 1', array('id_msg' => (int) $_REQUEST['quote'], 'is_approved' => 1));
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('quoted_post_deleted', false);
            }
            list($form_subject, $mname, $mdate, $form_message) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // Add 'Re: ' to the front of the quoted subject.
            if (trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the message and subject.
            censorText($form_message);
            censorText($form_subject);
            // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited!
            if (strpos($form_message, '[html]') !== false) {
                $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE);
                for ($i = 0, $n = count($parts); $i < $n; $i++) {
                    // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat.
                    if ($i % 4 == 0) {
                        $parts[$i] = preg_replace('~\\[html\\](.+?)\\[/html\\]~ise', '\'[html]\' . preg_replace(\'~<br\\s?/?' . '>~i\', \'&lt;br /&gt;<br />\', \'$1\') . \'[/html]\'', $parts[$i]);
                    }
                }
                $form_message = implode('', $parts);
            }
            $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $form_message);
            // Remove any nested quotes, if necessary.
            if (!empty($modSettings['removeNestedQuotes'])) {
                $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message);
            }
            // Add a quote string on the front and end.
            $form_message = '[quote author=' . $mname . ' link=topic=' . $topic . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $mdate . ']' . "\n" . rtrim($form_message) . "\n" . '[/quote]';
        } elseif (!empty($topic) && empty($_REQUEST['quote'])) {
            // Get the first message's subject.
            $form_subject = $first_subject;
            // Add 'Re: ' to the front of the subject.
            if (trim($context['response_prefix']) != '' && $form_subject != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the subject.
            censorText($form_subject);
            $form_message = '';
        } else {
            $form_subject = isset($_GET['subject']) ? $_GET['subject'] : '';
            $form_message = '';
        }
    }
    // !!! This won't work if you're posting an event.
    if (allowedTo('post_attachment') || allowedTo('post_unapproved_attachments')) {
        if (empty($_SESSION['temp_attachments'])) {
            $_SESSION['temp_attachments'] = array();
        }
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            // Just use the current path for temp files.
            $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $current_attach_dir = $modSettings['attachmentUploadDir'];
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*), SUM(size)
				FROM {db_prefix}attachments
				WHERE id_msg = {int:id_msg}
					AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
            list($quantity, $total_size) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        $temp_start = 0;
        if (!empty($_SESSION['temp_attachments'])) {
            if ($context['current_action'] != 'post2' || !empty($_POST['from_qr'])) {
                $context['post_error']['messages'][] = $txt['error_temp_attachments'];
                $context['error_type'] = 'minor';
            }
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                $temp_start++;
                if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    $deleted_attachments = true;
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($current_attach_dir . '/' . $attachID);
                    continue;
                }
                $quantity++;
                $total_size += filesize($current_attach_dir . '/' . $attachID);
                $context['current_attachments'][] = array('name' => htmlspecialchars($name), 'id' => $attachID, 'approved' => 1);
            }
        }
        if (!empty($_POST['attach_del'])) {
            $del_temp = array();
            foreach ($_POST['attach_del'] as $i => $dummy) {
                $del_temp[$i] = (int) $dummy;
            }
            foreach ($context['current_attachments'] as $k => $dummy) {
                if (!in_array($dummy['id'], $del_temp)) {
                    $context['current_attachments'][$k]['unchecked'] = true;
                    $deleted_attachments = !isset($deleted_attachments) || is_bool($deleted_attachments) ? 1 : $deleted_attachments + 1;
                    $quantity--;
                }
            }
        }
        if (!empty($_FILES['attachment'])) {
            foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
                if ($_FILES['attachment']['name'][$n] == '') {
                    continue;
                }
                if (!is_uploaded_file($_FILES['attachment']['tmp_name'][$n]) || @ini_get('open_basedir') == '' && !file_exists($_FILES['attachment']['tmp_name'][$n])) {
                    fatal_lang_error('attach_timeout', 'critical');
                }
                if (!empty($modSettings['attachmentSizeLimit']) && $_FILES['attachment']['size'][$n] > $modSettings['attachmentSizeLimit'] * 1024) {
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit']));
                }
                $quantity++;
                if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                    fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
                }
                $total_size += $_FILES['attachment']['size'][$n];
                if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit']));
                }
                if (!empty($modSettings['attachmentCheckExtensions'])) {
                    if (!in_array(strtolower(substr(strrchr($_FILES['attachment']['name'][$n], '.'), 1)), explode(',', strtolower($modSettings['attachmentExtensions'])))) {
                        fatal_error($_FILES['attachment']['name'][$n] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                    }
                }
                if (!empty($modSettings['attachmentDirSizeLimit'])) {
                    // Make sure the directory isn't full.
                    $dirSize = 0;
                    $dir = @opendir($current_attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical');
                    while ($file = readdir($dir)) {
                        if ($file == '.' || $file == '..') {
                            continue;
                        }
                        if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) {
                            // Temp file is more than 5 hours old!
                            if (filemtime($current_attach_dir . '/' . $file) < time() - 18000) {
                                @unlink($current_attach_dir . '/' . $file);
                            }
                            continue;
                        }
                        $dirSize += filesize($current_attach_dir . '/' . $file);
                    }
                    closedir($dir);
                    // Too big!  Maybe you could zip it or something...
                    if ($_FILES['attachment']['size'][$n] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) {
                        fatal_lang_error('ran_out_of_space');
                    }
                }
                if (!is_writable($current_attach_dir)) {
                    fatal_lang_error('attachments_no_write', 'critical');
                }
                $attachID = 'post_tmp_' . $user_info['id'] . '_' . $temp_start++;
                $_SESSION['temp_attachments'][$attachID] = basename($_FILES['attachment']['name'][$n]);
                $context['current_attachments'][] = array('name' => htmlspecialchars(basename($_FILES['attachment']['name'][$n])), 'id' => $attachID, 'approved' => 1);
                $destName = $current_attach_dir . '/' . $attachID;
                if (!move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) {
                    fatal_lang_error('attach_timeout', 'critical');
                }
                @chmod($destName, 0644);
            }
        }
    }
    // If we are coming here to make a reply, and someone has already replied... make a special warning message.
    if (isset($newRepliesError)) {
        $context['post_error']['messages'][] = $newRepliesError == 1 ? $txt['error_new_reply'] : $txt['error_new_replies'];
        $context['error_type'] = 'minor';
    }
    if (isset($oldTopicError)) {
        $context['post_error']['messages'][] = sprintf($txt['error_old_topic'], $modSettings['oldTopicDays']);
        $context['error_type'] = 'minor';
    }
    // What are you doing?  Posting a poll, modifying, previewing, new post, or reply...
    if (isset($_REQUEST['poll'])) {
        $context['page_title'] = $txt['new_poll'];
    } elseif ($context['make_event']) {
        $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar_post_event'] : $txt['calendar_edit'];
    } elseif (isset($_REQUEST['msg'])) {
        $context['page_title'] = $txt['modify_msg'];
    } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) {
        $context['page_title'] = $txt['preview'] . ' - ' . strip_tags($context['preview_subject']);
    } elseif (empty($topic)) {
        $context['page_title'] = $txt['start_new_topic'];
    } else {
        $context['page_title'] = $txt['post_reply'];
    }
    // Build the link tree.
    if (empty($topic)) {
        $context['linktree'][] = array('name' => '<em>' . $txt['start_new_topic'] . '</em>');
    } else {
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', 'extra_after' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav"> )</strong></span>');
    }
    // Give wireless a linktree url to the post screen, so that they can switch to full version.
    if (WIRELESS) {
        $context['linktree'][count($context['linktree']) - 1]['url'] = $scripturl . '?action=post;' . (!empty($topic) ? 'topic=' . $topic : 'board=' . $board) . '.' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . (int) $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '');
    }
    // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments.
    // !!! This won't work if you're posting an event.
    $context['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['current_attachments']) + (isset($deleted_attachments) ? $deleted_attachments : 0), $modSettings['attachmentNumPerPostLimit']);
    $context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments')) && $context['num_allowed_attachments'] > 0;
    $context['can_post_attachment_unapproved'] = allowedTo('post_attachment');
    $context['subject'] = addcslashes($form_subject, '"');
    $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
    // Needed for the editor and message icons.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'height' => '175px', 'width' => '100%', 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // Store the ID.
    $context['post_box_name'] = $editorOptions['id'];
    $context['attached'] = '';
    $context['make_poll'] = isset($_REQUEST['poll']);
    // Message icons - customized icons are off?
    $context['icons'] = getMessageIcons($board);
    if (!empty($context['icons'])) {
        $context['icons'][count($context['icons']) - 1]['is_last'] = true;
    }
    $context['icon_url'] = '';
    for ($i = 0, $n = count($context['icons']); $i < $n; $i++) {
        $context['icons'][$i]['selected'] = $context['icon'] == $context['icons'][$i]['value'];
        if ($context['icons'][$i]['selected']) {
            $context['icon_url'] = $context['icons'][$i]['url'];
        }
    }
    if (empty($context['icon_url'])) {
        $context['icon_url'] = $settings[file_exists($settings['theme_dir'] . '/images/post/' . $context['icon'] . '.gif') ? 'images_url' : 'default_images_url'] . '/post/' . $context['icon'] . '.gif';
        array_unshift($context['icons'], array('value' => $context['icon'], 'name' => $txt['current_icon'], 'url' => $context['icon_url'], 'is_last' => empty($context['icons']), 'selected' => true));
    }
    if (!empty($topic) && !empty($modSettings['topicSummaryPosts'])) {
        getTopic();
    }
    // If the user can post attachments prepare the warning labels.
    if ($context['can_post_attachment']) {
        $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', '));
        $context['attachment_restrictions'] = array();
        $attachmentRestrictionTypes = array('attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit');
        foreach ($attachmentRestrictionTypes as $type) {
            if (!empty($modSettings[$type])) {
                $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_' . $type], $modSettings[$type]);
            }
        }
    }
    $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']);
    $context['show_additional_options'] = !empty($_POST['additional_options']) || !empty($_SESSION['temp_attachments']) || !empty($deleted_attachments);
    $context['is_new_topic'] = empty($topic);
    $context['is_new_post'] = !isset($_REQUEST['msg']);
    $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $id_first_msg;
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // If they came from quick reply, and have to enter verification details, give them some notice.
    if (!empty($_REQUEST['from_qr']) && !empty($context['require_verification'])) {
        $context['post_error']['messages'][] = $txt['enter_verification_details'];
        $context['error_type'] = 'minor';
    }
    // WYSIWYG only works if BBC is enabled
    $modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']);
    // Register this form in the session variables.
    checkSubmitOnce('register');
    // Finally, load the template.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_post';
    } elseif (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
}
Exemple #23
0
/**
 * Handles showing the post screen, loading the post to be modified, and loading any post quoted.
 *
 * - additionally handles previews of posts.
 * - @uses the Post template and language file, main sub template.
 * - allows wireless access using the protocol_post sub template.
 * - 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.
 * - accessed from ?action=post.
 */
function Post($post_errors = array())
{
    global $txt, $scripturl, $topic, $modSettings, $board;
    global $user_info, $sc, $board_info, $context, $settings;
    global $sourcedir, $options, $smcFunc, $language;
    loadLanguage('Post');
    // You can't reply with a poll... hacker.
    if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) {
        unset($_REQUEST['poll']);
    }
    // Posting an event?
    $context['make_event'] = isset($_REQUEST['calendar']);
    $context['robot_no_index'] = true;
    // You must be posting to *some* board.
    if (empty($board) && !$context['make_event']) {
        fatal_lang_error('no_board', false);
    }
    require_once $sourcedir . '/Subs-Post.php';
    if (isset($_REQUEST['xml'])) {
        $context['sub_template'] = 'post';
        // Just in case of an earlier error...
        $context['preview_message'] = '';
        $context['preview_subject'] = '';
    }
    // No message is complete without a topic.
    if (empty($topic) && !empty($_REQUEST['msg'])) {
        $request = $smcFunc['db_query']('', '
			SELECT id_topic
			FROM {db_prefix}messages
			WHERE id_msg = {int:msg}', array('msg' => (int) $_REQUEST['msg']));
        if ($smcFunc['db_num_rows']($request) != 1) {
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        } else {
            list($topic) = $smcFunc['db_fetch_row']($request);
        }
        $smcFunc['db_free_result']($request);
    }
    // Check if it's locked. It isn't locked if no topic is specified.
    if (!empty($topic)) {
        $request = $smcFunc['db_query']('', '
			SELECT
				t.locked, IFNULL(ln.id_topic, 0) AS notify, t.is_sticky, t.id_poll, t.id_last_msg, mf.id_member,
				t.id_first_msg, mf.subject,
				CASE WHEN ml.poster_time > ml.modified_time THEN ml.poster_time ELSE ml.modified_time END AS last_post_time
			FROM {db_prefix}topics AS t
				LEFT JOIN {db_prefix}log_notify AS ln ON (ln.id_topic = t.id_topic AND ln.id_member = {int:current_member})
				LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
			WHERE t.id_topic = {int:current_topic}
			LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic));
        list($locked, $context['notify'], $sticky, $pollID, $context['topic_last_message'], $id_member_poster, $id_first_msg, $first_subject, $lastPostTime) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // If this topic already has a poll, they sure can't add another.
        if (isset($_REQUEST['poll']) && $pollID > 0) {
            unset($_REQUEST['poll']);
        }
        if (empty($_REQUEST['msg'])) {
            if ($user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) {
                is_not_guest();
            }
            // By default the reply will be approved...
            $context['becomes_approved'] = true;
            if ($id_member_poster != $user_info['id']) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_any');
                }
            } elseif (!allowedTo('post_reply_any')) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_own');
                }
            }
        } else {
            $context['becomes_approved'] = true;
        }
        $context['can_lock'] = allowedTo('lock_any') || $user_info['id'] == $id_member_poster && allowedTo('lock_own');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky;
        // Check whether this is a really old post being bumped...
        if (!empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) {
            $post_errors[] = array('old_topic', array($modSettings['oldTopicDays']));
        }
    } else {
        $context['becomes_approved'] = true;
        if (!$context['make_event'] || !empty($board)) {
            if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                $context['becomes_approved'] = false;
            } else {
                isAllowedTo('post_new');
            }
        }
        $locked = 0;
        // @todo These won't work if you're making an event.
        $context['can_lock'] = allowedTo(array('lock_any', 'lock_own'));
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = !empty($_REQUEST['sticky']);
    }
    // @todo These won't work if you're posting an event!
    $context['can_notify'] = allowedTo('mark_any_notify');
    $context['can_move'] = allowedTo('move_any');
    $context['move'] = !empty($_REQUEST['move']);
    $context['announce'] = !empty($_REQUEST['announce']);
    // You can only announce topics that will get approved...
    $context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved'];
    $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']);
    $context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    // 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);
    // An array to hold all the attachments for this topic.
    $context['current_attachments'] = array();
    // Don't allow a post if it's locked and you aren't all powerful.
    if ($locked && !allowedTo('moderate_board')) {
        fatal_lang_error('topic_locked', false);
    }
    // Check the users permissions - is the user allowed to add or post a poll?
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        // New topic, new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $id_member_poster && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        require_once $sourcedir . '/Subs-Members.php';
        $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
        // Set up the poll options.
        $context['poll_options'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expire' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_enabled' => in_array(-1, $allowedVoteGroups['allowed']));
        // Make all five poll choices empty.
        $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true));
        $context['last_choice_id'] = 4;
    }
    if ($context['make_event']) {
        // They might want to pick a board.
        if (!isset($context['current_board'])) {
            $context['current_board'] = 0;
        }
        // Start loading up the event info.
        $context['event'] = array();
        $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : '';
        $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1;
        $context['event']['new'] = $context['event']['id'] == -1;
        // Permissions check!
        isAllowedTo('calendar_post');
        // Editing an event?  (but NOT previewing!?)
        if (empty($context['event']['new']) && !isset($_REQUEST['subject'])) {
            // If the user doesn't have permission to edit the post in this topic, redirect them.
            if ((empty($id_member_poster) || $id_member_poster != $user_info['id'] || !allowedTo('modify_own')) && !allowedTo('modify_any')) {
                require_once $sourcedir . '/Calendar.php';
                return CalendarPost();
            }
            // Get the current event information.
            $request = $smcFunc['db_query']('', '
				SELECT
					id_member, title, MONTH(start_date) AS month, DAYOFMONTH(start_date) AS day,
					YEAR(start_date) AS year, (TO_DAYS(end_date) - TO_DAYS(start_date)) AS span
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}
				LIMIT 1', array('id_event' => $context['event']['id']));
            $row = $smcFunc['db_fetch_assoc']($request);
            $smcFunc['db_free_result']($request);
            // Make sure the user is allowed to edit this event.
            if ($row['id_member'] != $user_info['id']) {
                isAllowedTo('calendar_edit_any');
            } elseif (!allowedTo('calendar_edit_any')) {
                isAllowedTo('calendar_edit_own');
            }
            $context['event']['month'] = $row['month'];
            $context['event']['day'] = $row['day'];
            $context['event']['year'] = $row['year'];
            $context['event']['title'] = $row['title'];
            $context['event']['span'] = $row['span'] + 1;
        } else {
            $today = getdate();
            // You must have a month and year specified!
            if (!isset($_REQUEST['month'])) {
                $_REQUEST['month'] = $today['mon'];
            }
            if (!isset($_REQUEST['year'])) {
                $_REQUEST['year'] = $today['year'];
            }
            $context['event']['month'] = (int) $_REQUEST['month'];
            $context['event']['year'] = (int) $_REQUEST['year'];
            $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0);
            $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1;
            // Make sure the year and month are in the valid range.
            if ($context['event']['month'] < 1 || $context['event']['month'] > 12) {
                fatal_lang_error('invalid_month', false);
            }
            if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) {
                fatal_lang_error('invalid_year', false);
            }
            // Get a list of boards they can post in.
            $boards = boardsAllowedTo('post_new');
            if (empty($boards)) {
                fatal_lang_error('cannot_post_new', 'user');
            }
            // Load a list of boards for this event in the context.
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($context['current_board']) ? $modSettings['cal_defaultboard'] : $context['current_board']);
            $context['event']['categories'] = getBoardList($boardListOptions);
        }
        // Find the last day of the month.
        $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
        $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard'];
    }
    // See if any new replies have come along.
    // Huh, $_REQUEST['msg'] is set upon submit, so this doesn't get executed at submit
    // only at preview
    if (empty($_REQUEST['msg']) && !empty($topic)) {
        if (empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $context['topic_last_message'] > $_REQUEST['last_msg']) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}messages
				WHERE id_topic = {int:current_topic}
					AND id_msg > {int:last_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND approved = {int:approved}') . '
				LIMIT 1', array('current_topic' => $topic, 'last_msg' => (int) $_REQUEST['last_msg'], 'approved' => 1));
            list($context['new_replies']) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            if (!empty($context['new_replies'])) {
                if ($context['new_replies'] == 1) {
                    $txt['error_new_replies'] = isset($_GET['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply'];
                } else {
                    $txt['error_new_replies'] = sprintf(isset($_GET['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']);
                }
                $post_errors[] = 'new_replies';
                $modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts'];
            }
        }
    }
    // Get a response prefix (like 'Re:') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // Previewing, modifying, or posting?
    // Do we have a body, but an error happened.
    if (isset($_REQUEST['message']) || !empty($context['post_error'])) {
        // Validate inputs.
        if (empty($context['post_error'])) {
            // This means they didn't click Post and get an error.
            $really_previewing = true;
        } else {
            if (!isset($_REQUEST['subject'])) {
                $_REQUEST['subject'] = '';
            }
            if (!isset($_REQUEST['message'])) {
                $_REQUEST['message'] = '';
            }
            if (!isset($_REQUEST['icon'])) {
                $_REQUEST['icon'] = 'xx';
            }
            // They are previewing if they asked to preview (i.e. came from quick reply).
            $really_previewing = !empty($_POST['preview']);
        }
        // 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'];
        // Set up the inputs for the form.
        $form_subject = strtr($smcFunc['htmlspecialchars']($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $form_message = $smcFunc['htmlspecialchars']($_REQUEST['message'], ENT_QUOTES);
        // Make sure the subject isn't too long - taking into account special characters.
        if ($smcFunc['strlen']($form_subject) > 100) {
            $form_subject = $smcFunc['substr']($form_subject, 0, 100);
        }
        if (isset($_REQUEST['poll'])) {
            $context['question'] = isset($_REQUEST['question']) ? $smcFunc['htmlspecialchars'](trim($_REQUEST['question'])) : '';
            $context['choices'] = array();
            $choice_id = 0;
            $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive($_POST['options']);
            foreach ($_POST['options'] as $option) {
                if (trim($option) == '') {
                    continue;
                }
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false);
            }
            // One empty option for those with js disabled...I know are few... :P
            $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
            if (count($context['choices']) < 2) {
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
            }
            $context['last_choice_id'] = $choice_id;
            $context['choices'][count($context['choices']) - 1]['is_last'] = true;
        }
        // Are you... a guest?
        if ($user_info['is_guest']) {
            $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']);
            $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']);
            $_REQUEST['guestname'] = htmlspecialchars($_REQUEST['guestname']);
            $context['name'] = $_REQUEST['guestname'];
            $_REQUEST['email'] = htmlspecialchars($_REQUEST['email']);
            $context['email'] = $_REQUEST['email'];
            $user_info['name'] = $_REQUEST['guestname'];
        }
        // Only show the preview stuff if they hit Preview.
        if (($really_previewing == true || isset($_REQUEST['xml'])) && !isset($_POST['id_draft'])) {
            // Set up the preview message and subject and censor them...
            $context['preview_message'] = $form_message;
            preparsecode($form_message, true);
            preparsecode($context['preview_message']);
            // Do all bulletin board code tags, with or without smileys.
            $context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1);
            censorText($context['preview_message']);
            if ($form_subject != '') {
                $context['preview_subject'] = $form_subject;
                censorText($context['preview_subject']);
            } else {
                $context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>';
            }
            // Protect any CDATA blocks.
            if (isset($_REQUEST['xml'])) {
                $context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>'));
            }
        }
        // Set up the checkboxes.
        $context['notify'] = !empty($_REQUEST['notify']);
        $context['use_smileys'] = !isset($_REQUEST['ns']);
        $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx';
        // Set the destination action for submission.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '') . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = isset($_REQUEST['msg']) ? $txt['save'] : $txt['post'];
        // Previewing an edit?
        if (isset($_REQUEST['msg']) && !empty($topic)) {
            // Get the existing message.
            $request = $smcFunc['db_query']('', '
				SELECT
					m.id_member, m.modified_time, m.smileys_enabled, m.body,
					m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
					IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
					a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
					m.poster_time, log.id_action
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
					LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
					LEFT JOIN {db_prefix}log_actions AS log ON (m.id_topic = log.id_topic AND log.action = {string:announce_action})
				WHERE m.id_msg = {int:id_msg}
					AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg'], 'announce_action' => 'announce_topic'));
            // The message they were trying to edit was most likely deleted.
            // @todo Change this error message?
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('no_board', false);
            }
            $row = $smcFunc['db_fetch_assoc']($request);
            $attachment_stuff = array($row);
            while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
                $attachment_stuff[] = $row2;
            }
            $smcFunc['db_free_result']($request);
            if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
                // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
                if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                    isAllowedTo('modify_replies');
                } else {
                    isAllowedTo('modify_own');
                }
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_any');
            }
            if (!empty($modSettings['attachmentEnable'])) {
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(size, -1) AS filesize, filename, id_attach, approved
					FROM {db_prefix}attachments
					WHERE id_msg = {int:id_msg}
						AND attachment_type = {int:attachment_type}
					ORDER BY id_attach', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    if ($row['filesize'] <= 0) {
                        continue;
                    }
                    $context['current_attachments'][] = array('name' => htmlspecialchars($row['filename']), 'size' => $row['filesize'], 'id' => $row['id_attach'], 'approved' => $row['approved']);
                }
                $smcFunc['db_free_result']($request);
            }
            if ($context['can_announce'] && !empty($row['id_action'])) {
                loadLanguage('Errors');
                $context['post_error']['messages'][] = $txt['error_topic_already_announced'];
            }
            // Allow moderators to change names....
            if (allowedTo('moderate_forum') && !empty($topic)) {
                $request = $smcFunc['db_query']('', '
					SELECT id_member, poster_name, poster_email
					FROM {db_prefix}messages
					WHERE id_msg = {int:id_msg}
						AND id_topic = {int:current_topic}
					LIMIT 1', array('current_topic' => $topic, 'id_msg' => (int) $_REQUEST['msg']));
                $row = $smcFunc['db_fetch_assoc']($request);
                $smcFunc['db_free_result']($request);
                if (empty($row['id_member'])) {
                    $context['name'] = htmlspecialchars($row['poster_name']);
                    $context['email'] = htmlspecialchars($row['poster_email']);
                }
            }
        }
        // No check is needed, since nothing is really posted.
        checkSubmitOnce('free');
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Get the existing message.
        $request = $smcFunc['db_query']('', '
			SELECT
				m.id_member, m.modified_time, m.smileys_enabled, m.body,
				m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
				IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
				a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
				m.poster_time, log.id_action
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
				LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
					LEFT JOIN {db_prefix}log_actions AS log ON (m.id_topic = log.id_topic AND log.action = {string:announce_action})
			WHERE m.id_msg = {int:id_msg}
				AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg'], 'announce_action' => 'announce_topic'));
        // The message they were trying to edit was most likely deleted.
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('no_message', false);
        }
        $row = $smcFunc['db_fetch_assoc']($request);
        $attachment_stuff = array($row);
        while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
            $attachment_stuff[] = $row2;
        }
        $smcFunc['db_free_result']($request);
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
            if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
        } else {
            isAllowedTo('modify_any');
        }
        if ($context['can_announce'] && !empty($row['id_action'])) {
            loadLanguage('Errors');
            $context['post_error']['messages'][] = $txt['error_topic_already_announced'];
        }
        // When was it last modified?
        if (!empty($row['modified_time'])) {
            $context['last_modified'] = timeformat($row['modified_time']);
        }
        // Get the stuff ready for the form.
        $form_subject = $row['subject'];
        $form_message = un_preparsecode($row['body']);
        censorText($form_message);
        censorText($form_subject);
        // Check the boxes that should be checked.
        $context['use_smileys'] = !empty($row['smileys_enabled']);
        $context['icon'] = $row['icon'];
        // Show an "approve" box if the user can approve it, and the message isn't approved.
        if (!$row['approved'] && !$context['show_approval']) {
            $context['show_approval'] = allowedTo('approve_posts');
        }
        // Sort the attachments so they are in the order saved
        $temp = array();
        foreach ($attachment_stuff as $attachment) {
            if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) {
                $temp[$attachment['id_attach']] = $attachment;
            }
        }
        ksort($temp);
        // Load up 'em attachments!
        foreach ($temp as $attachment) {
            $context['current_attachments'][] = array('name' => htmlspecialchars($attachment['filename']), 'size' => $attachment['filesize'], 'id' => $attachment['id_attach'], 'approved' => $attachment['attachment_approved']);
        }
        // Allow moderators to change names....
        if (allowedTo('moderate_forum') && empty($row['id_member'])) {
            $context['name'] = htmlspecialchars($row['poster_name']);
            $context['email'] = htmlspecialchars($row['poster_email']);
        }
        // Set the destinaton.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['save'];
    } else {
        // By default....
        $context['use_smileys'] = true;
        $context['icon'] = 'xx';
        if ($user_info['is_guest']) {
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
        }
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['post'];
        // Posting a quoted reply?
        if (!empty($topic) && !empty($_REQUEST['quote'])) {
            // Make sure they _can_ quote this post, and if so get it.
            $request = $smcFunc['db_query']('', '
				SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
					LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
				WHERE m.id_msg = {int:id_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND m.approved = {int:is_approved}') . '
				LIMIT 1', array('id_msg' => (int) $_REQUEST['quote'], 'is_approved' => 1));
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('quoted_post_deleted', false);
            }
            list($form_subject, $mname, $mdate, $form_message) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // Add 'Re: ' to the front of the quoted subject.
            if (trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the message and subject.
            censorText($form_message);
            censorText($form_subject);
            // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited!
            if (strpos($form_message, '[html]') !== false) {
                $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE);
                for ($i = 0, $n = count($parts); $i < $n; $i++) {
                    // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat.
                    if ($i % 4 == 0) {
                        $parts[$i] = preg_replace('~\\[html\\](.+?)\\[/html\\]~ise', '\'[html]\' . preg_replace(\'~<br\\s?/?' . '>~i\', \'&lt;br /&gt;<br />\', \'$1\') . \'[/html]\'', $parts[$i]);
                    }
                }
                $form_message = implode('', $parts);
            }
            $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $form_message);
            // Remove any nested quotes, if necessary.
            if (!empty($modSettings['removeNestedQuotes'])) {
                $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message);
            }
            // Add a quote string on the front and end.
            $form_message = '[quote author=' . $mname . ' link=topic=' . $topic . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $mdate . ']' . "\n" . rtrim($form_message) . "\n" . '[/quote]';
        } elseif (!empty($topic) && empty($_REQUEST['quote'])) {
            // Get the first message's subject.
            $form_subject = $first_subject;
            // Add 'Re: ' to the front of the subject.
            if (trim($context['response_prefix']) != '' && $form_subject != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the subject.
            censorText($form_subject);
            $form_message = '';
        } else {
            $form_subject = isset($_GET['subject']) ? $_GET['subject'] : '';
            $form_message = '';
        }
    }
    $context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'));
    if ($context['can_post_attachment']) {
        // If there are attachments, calculate the total size and how many.
        $context['attachments']['total_size'] = 0;
        $context['attachments']['quantity'] = 0;
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $context['attachments']['quantity'] = count($context['current_attachments']);
            foreach ($context['current_attachments'] as $attachment) {
                $context['attachments']['total_size'] += $attachment['size'];
            }
        }
        // A bit of house keeping first.
        if (!empty($_SESSION['temp_attachments']) && count($_SESSION['temp_attachments']) == 1) {
            unset($_SESSION['temp_attachments']);
        }
        if (!empty($_SESSION['temp_attachments'])) {
            // Is this a request to delete them?
            if (isset($_GET['delete_temp'])) {
                foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                    if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false) {
                        if (file_exists($attachment['tmp_name'])) {
                            unlink($attachment['tmp_name']);
                        }
                    }
                }
                $post_errors[] = 'temp_attachments_gone';
                $_SESSION['temp_attachments'] = array();
            } elseif ($context['current_action'] != 'post2' || !empty($_POST['from_qr'])) {
                // Let's be nice and see if they belong here first.
                if (empty($_REQUEST['msg']) && empty($_SESSION['temp_attachments']['post']['msg']) && $_SESSION['temp_attachments']['post']['board'] == $board || !empty($_REQUEST['msg']) && $_SESSION['temp_attachments']['post']['msg'] == $_REQUEST['msg']) {
                    // See if any files still exist before showing the warning message and the files attached.
                    foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                        if (strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                            continue;
                        }
                        if (file_exists($attachment['tmp_name'])) {
                            $post_errors[] = 'temp_attachments_new';
                            $context['files_in_session_warning'] = $txt['attached_files_in_session'];
                            unset($_SESSION['temp_attachments']['post']['files']);
                            break;
                        }
                    }
                } else {
                    // Since, they don't belong here. Let's inform the user that they exist..
                    if (!empty($topic)) {
                        $delete_link = '<a href="' . $scripturl . '?action=post' . (!empty($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] : '') . (!empty($_REQUEST['last_msg']) ? ';last_msg=' . $_REQUEST['last_msg'] : '') . ';topic=' . $topic . ';delete_temp">' . $txt['here'] . '</a>';
                    } else {
                        $delete_link = '<a href="' . $scripturl . '?action=post;board=' . $board . ';delete_temp">' . $txt['here'] . '</a>';
                    }
                    // Compile a list of the files to show the user.
                    $file_list = array();
                    foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                        if (strpos($attachID, 'post_tmp_' . $user_info['id']) !== false) {
                            $file_list[] = $attachment['name'];
                        }
                    }
                    $_SESSION['temp_attachments']['post']['files'] = $file_list;
                    $file_list = '<div class="attachments">' . implode('<br />', $file_list) . '</div>';
                    if (!empty($_SESSION['temp_attachments']['post']['msg'])) {
                        // We have a message id, so we can link back to the old topic they were trying to edit..
                        $goback_link = '<a href="' . $scripturl . '?action=post' . (!empty($_SESSION['temp_attachments']['post']['msg']) ? ';msg=' . $_SESSION['temp_attachments']['post']['msg'] : '') . (!empty($_SESSION['temp_attachments']['post']['last_msg']) ? ';last_msg=' . $_SESSION['temp_attachments']['post']['last_msg'] : '') . ';topic=' . $_SESSION['temp_attachments']['post']['topic'] . ';additionalOptions">' . $txt['here'] . '</a>';
                        $post_errors[] = array('temp_attachments_found', array($delete_link, $goback_link, $file_list));
                        $context['ignore_temp_attachments'] = true;
                    } else {
                        $post_errors[] = array('temp_attachments_lost', array($delete_link, $file_list));
                        $context['ignore_temp_attachments'] = true;
                    }
                }
            }
            if (!empty($context['we_are_history'])) {
                $post_errors[] = $context['we_are_history'];
            }
            foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                if (isset($context['ignore_temp_attachments']) || isset($_SESSION['temp_attachments']['post']['files'])) {
                    break;
                }
                if ($attachID != 'initial_error' && strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                    continue;
                }
                if ($attachID == 'initial_error') {
                    $txt['error_attach_initial_error'] = $txt['attach_no_upload'] . '<div style="padding: 0 1em;">' . (is_array($attachment) ? vsprintf($txt[$attachment[0]], $attachment[1]) : $txt[$attachment]) . '</div>';
                    $post_errors[] = 'attach_initial_error';
                    unset($_SESSION['temp_attachments']);
                    break;
                }
                // Show any errors which might of occured.
                if (!empty($attachment['errors'])) {
                    $txt['error_attach_errors'] = empty($txt['error_attach_errors']) ? '<br />' : '';
                    $txt['error_attach_errors'] .= vsprintf($txt['attach_warning'], $attachment['name']) . '<div style="padding: 0 1em;">';
                    foreach ($attachment['errors'] as $error) {
                        $txt['error_attach_errors'] .= (is_array($error) ? vsprintf($txt[$error[0]], $error[1]) : $txt[$error]) . '<br  />';
                    }
                    $txt['error_attach_errors'] .= '</div>';
                    $post_errors[] = 'attach_errors';
                    // Take out the trash.
                    unset($_SESSION['temp_attachments'][$attachID]);
                    if (file_exists($attachment['tmp_name'])) {
                        unlink($attachment['tmp_name']);
                    }
                    continue;
                }
                // More house keeping.
                if (!file_exists($attachment['tmp_name'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    continue;
                }
                $context['attachments']['quantity']++;
                $context['attachments']['total_size'] += $attachment['size'];
                if (!isset($context['files_in_session_warning'])) {
                    $context['files_in_session_warning'] = $txt['attached_files_in_session'];
                }
                $context['current_attachments'][] = array('name' => '<u>' . htmlspecialchars($attachment['name']) . '</u>', 'size' => $attachment['size'], 'id' => $attachID, 'unchecked' => false, 'approved' => 1);
            }
        }
    }
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // If they came from quick reply, and have to enter verification details, give them some notice.
    if (!empty($_REQUEST['from_qr']) && !empty($context['require_verification'])) {
        $post_errors[] = 'need_qr_verification';
    }
    /*
     * There are two error types: serious and miinor. Serious errors
     * actually tell the user that a real error has occurred, while minor
     * errors are like warnings that let them know that something with
     * their post isn't right.
     */
    $minor_errors = array('not_approved', 'new_replies', 'old_topic', 'need_qr_verification', 'no_subject');
    call_integration_hook('integrate_post_errors', array($post_errors, $minor_errors));
    // Any errors occurred?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        $context['error_type'] = 'minor';
        foreach ($post_errors as $post_error) {
            if (is_array($post_error)) {
                $post_error_id = $post_error[0];
                $context['post_error'][$post_error_id] = vsprintf($txt['error_' . $post_error_id], $post_error[1]);
                // If it's not a minor error flag it as such.
                if (!in_array($post_error_id, $minor_errors)) {
                    $context['error_type'] = 'serious';
                }
            } else {
                $context['post_error'][$post_error] = $txt['error_' . $post_error];
                // If it's not a minor error flag it as such.
                if (!in_array($post_error, $minor_errors)) {
                    $context['error_type'] = 'serious';
                }
            }
        }
    }
    // What are you doing? Posting a poll, modifying, previewing, new post, or reply...
    if (isset($_REQUEST['poll'])) {
        $context['page_title'] = $txt['new_poll'];
    } elseif ($context['make_event']) {
        $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar_post_event'] : $txt['calendar_edit'];
    } elseif (isset($_REQUEST['msg'])) {
        $context['page_title'] = $txt['modify_msg'];
    } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) {
        $context['page_title'] = $txt['preview'] . ' - ' . strip_tags($context['preview_subject']);
    } elseif (empty($topic)) {
        $context['page_title'] = $txt['start_new_topic'];
    } else {
        $context['page_title'] = $txt['post_reply'];
    }
    // Build the link tree.
    if (empty($topic)) {
        $context['linktree'][] = array('name' => '<em>' . $txt['start_new_topic'] . '</em>');
    } else {
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', 'extra_after' => '<span><strong class="nav"> )</strong></span>');
    }
    // Give wireless a linktree url to the post screen, so that they can switch to full version.
    if (WIRELESS) {
        $context['linktree'][count($context['linktree']) - 1]['url'] = $scripturl . '?action=post;' . (!empty($topic) ? 'topic=' . $topic : 'board=' . $board) . '.' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . (int) $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '');
    }
    $context['subject'] = addcslashes($form_subject, '"');
    $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
    // Are post drafts enabled?
    $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft');
    $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
    // Build a list of drafts that they can load in to the editor
    if (!empty($context['drafts_save'])) {
        require_once $sourcedir . '/Drafts.php';
        ShowDrafts($user_info['id'], $topic);
    }
    // Needed for the editor and message icons.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'height' => '275px', 'width' => '100%', 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // Store the ID.
    $context['post_box_name'] = $editorOptions['id'];
    $context['attached'] = '';
    $context['make_poll'] = isset($_REQUEST['poll']);
    // Message icons - customized icons are off?
    $context['icons'] = getMessageIcons($board);
    if (!empty($context['icons'])) {
        $context['icons'][count($context['icons']) - 1]['is_last'] = true;
    }
    // Are we starting a poll? if set the poll icon as selected if its available
    if (isset($_REQUEST['poll'])) {
        foreach ($context['icons'] as $icons) {
            if (isset($icons['value']) && $icons['value'] == 'poll') {
                // if found we are done
                $context['icon'] = 'poll';
                break;
            }
        }
    }
    $context['icon_url'] = '';
    for ($i = 0, $n = count($context['icons']); $i < $n; $i++) {
        $context['icons'][$i]['selected'] = $context['icon'] == $context['icons'][$i]['value'];
        if ($context['icons'][$i]['selected']) {
            $context['icon_url'] = $context['icons'][$i]['url'];
        }
    }
    if (empty($context['icon_url'])) {
        $context['icon_url'] = $settings[file_exists($settings['theme_dir'] . '/images/post/' . $context['icon'] . '.png') ? 'images_url' : 'default_images_url'] . '/post/' . $context['icon'] . '.png';
        array_unshift($context['icons'], array('value' => $context['icon'], 'name' => $txt['current_icon'], 'url' => $context['icon_url'], 'is_last' => empty($context['icons']), 'selected' => true));
    }
    if (!empty($topic) && !empty($modSettings['topicSummaryPosts'])) {
        getTopic();
    }
    // If the user can post attachments prepare the warning labels.
    if ($context['can_post_attachment']) {
        // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments.
        $context['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['current_attachments']), $modSettings['attachmentNumPerPostLimit']);
        $context['can_post_attachment_unapproved'] = allowedTo('post_attachment');
        $context['attachment_restrictions'] = array();
        $context['allowed_extensions'] = strtr(strtolower($modSettings['attachmentExtensions']), array(',' => ', '));
        $attachmentRestrictionTypes = array('attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit');
        foreach ($attachmentRestrictionTypes as $type) {
            if (!empty($modSettings[$type])) {
                $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_' . $type], comma_format($modSettings[$type], 0));
                // Show some numbers. If they exist.
                if ($type == 'attachmentNumPerPostLimit' && $context['attachments']['quantity'] > 0) {
                    $context['attachment_restrictions'][] = sprintf($txt['attach_remaining'], $modSettings['attachmentNumPerPostLimit'] - $context['attachments']['quantity']);
                } elseif ($type == 'attachmentPostLimit' && $context['attachments']['total_size'] > 0) {
                    $context['attachment_restrictions'][] = sprintf($txt['attach_available'], comma_format(round(max($modSettings['attachmentPostLimit'] - $context['attachments']['total_size'] / 1028, 0)), 0));
                }
            }
        }
    }
    $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']);
    $context['show_additional_options'] = !empty($_POST['additional_options']) || isset($_SESSION['temp_attachments']['post']) || isset($_GET['additionalOptions']);
    $context['is_new_topic'] = empty($topic);
    $context['is_new_post'] = !isset($_REQUEST['msg']);
    $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $id_first_msg;
    // WYSIWYG only works if BBC is enabled
    $modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']);
    // Register this form in the session variables.
    checkSubmitOnce('register');
    // Finally, load the template.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_post';
    } elseif (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
}
Exemple #24
0
function EditPost()
{
    global $txt, $mbname, $context, $smcFunc, $sourcedir, $modSettings;
    // Get the ID
    $id = (int) $_REQUEST['id'];
    if (empty($id)) {
        fatal_error($txt['postscheduler_nopostselected'], false);
    }
    require_once $sourcedir . '/Subs-Post.php';
    // Show the boards
    $context['schedule_boards'] = array('');
    $request = $smcFunc['db_query']('', "\n\tSELECT \n\t\tb.ID_BOARD, b.name AS bName, c.name AS cName \n\tFROM {db_prefix}boards AS b, {db_prefix}categories AS c \n\tWHERE b.ID_CAT = c.ID_CAT ORDER BY c.cat_order, b.board_order");
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['schedule_boards'][$row['ID_BOARD']] = $row['cName'] . ' - ' . $row['bName'];
    }
    $smcFunc['db_free_result']($request);
    // Get the Data
    $context['schedulepost'] = array();
    $request = $smcFunc['db_query']('', "\n\tSELECT \n\t\tID_POST, subject, ID_MEMBER, postername, post_time,\n\t\tmsgicon, body, locked, ID_TOPIC, ID_BOARD \n\tFROM {db_prefix}postscheduler \n\tWHERE ID_POST = {$id} LIMIT 1");
    $row = $smcFunc['db_fetch_assoc']($request);
    $context['schedulepost'] = $row;
    $smcFunc['db_free_result']($request);
    // Load Message Icons
    $context['msg_icons'] = array();
    $result = $smcFunc['db_query']('', "SELECT title, filename\n\t\t\t\tFROM {db_prefix}message_icons\n\t\t\t\t");
    while ($row = $smcFunc['db_fetch_assoc']($result)) {
        $context['msg_icons'][] = $row;
    }
    // Set the page title
    $context['page_title'] = $mbname . ' - ' . $txt['postscheduler_editpost'];
    $context['sub_template'] = 'editpost';
    // Check if spellchecking is both enabled and actually working.
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    $context['post_box_name'] = 'message';
    $context['post_form'] = 'frmfeed';
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['schedulepost']['body'], 'width' => '90%', 'form' => 'frmfeed', 'labels' => array('editpost' => $txt['postscheduler_editpost']));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}
Exemple #25
0
function EditLink()
{
    global $context, $mbname, $txt, $smcFunc, $modSettings, $sourcedir, $user_info;
    is_not_guest();
    $context['sub_template'] = 'editlink';
    //Set the page title
    $context['page_title'] = $mbname . $txt['smflinks_title'] . ' - ' . $txt['smflinks_editlink'];
    // Lookup the link and see if they can edit it.
    if (!empty($_REQUEST['id'])) {
        $id = (int) $_REQUEST['id'];
    }
    if (empty($id)) {
        fatal_error($txt['smflinks_nolinkselected']);
    }
    $context['link_id'] = $id;
    $dbresult = $smcFunc['db_query']('', '
		SELECT ID_LINK, title, ID_CAT, description, url, ID_MEMBER
		FROM {db_prefix}links
		WHERE ID_LINK = {int:this_id}
		LIMIT 1', array('this_id' => $id));
    $row = $smcFunc['db_fetch_assoc']($dbresult);
    $smcFunc['db_free_result']($dbresult);
    $context['links_link'] = $row;
    if (!allowedTo('edit_links_any') && (!allowedTo('edit_links_own') || $row['ID_MEMBER'] != $user_info['id'])) {
        fatal_error($txt['smflinks_perm_link_no_edit']);
    }
    GetCatPermission($row['ID_CAT'], 'editlink');
    $dbresult = $smcFunc['db_query']('', '
		SELECT ID_CAT, title, roworder
		FROM {db_prefix}links_cat
		ORDER BY roworder ASC');
    // Get category count
    $cat_count = $smcFunc['db_affected_rows']();
    if ($cat_count == 0) {
        fatal_error($txt['smflinks_nofirstcat'], false);
    }
    $context['links_cats'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($dbresult)) {
        $context['links_cats'][] = $row;
    }
    $smcFunc['db_free_result']($dbresult);
    // Check if spellchecking is both enabled and actually working.
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Needed for the WYSIWYG editor.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'descript', 'value' => $context['links_link']['description'], 'width' => '90%', 'form' => 'links', 'labels' => array('addlink' => ''));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}
 /**
  * Shows a form to edit a forum mailing and its recipients.
  *
  * What it does:
  * - Called by ?action=admin;area=news;sa=mailingcompose.
  * - Requires the send_mail permission.
  * - Form is submitted to ?action=admin;area=news;sa=mailingsend.
  *
  * @uses ManageNews template, email_members_compose sub-template.
  */
 public function action_mailingcompose()
 {
     global $txt, $context;
     // Setup the template!
     $context['page_title'] = $txt['admin_newsletters'];
     $context['sub_template'] = 'email_members_compose';
     $context['subject'] = !empty($_POST['subject']) ? $_POST['subject'] : $context['forum_name'] . ': ' . htmlspecialchars($txt['subject'], ENT_COMPAT, 'UTF-8');
     $context['message'] = !empty($_POST['message']) ? $_POST['message'] : htmlspecialchars($txt['message'] . "\n\n" . replaceBasicActionUrl($txt['regards_team']) . "\n\n" . '{$board_url}', ENT_COMPAT, 'UTF-8');
     // Needed for the WYSIWYG editor.
     require_once SUBSDIR . '/Editor.subs.php';
     // Now create the editor.
     $editorOptions = array('id' => 'message', 'value' => $context['message'], 'height' => '250px', 'width' => '100%', 'labels' => array('post_button' => $txt['sendtopic_send']), 'preview_type' => 2);
     create_control_richedit($editorOptions);
     if (isset($context['preview'])) {
         require_once SUBSDIR . '/Mail.subs.php';
         $context['recipients']['members'] = !empty($_POST['members']) ? explode(',', $_POST['members']) : array();
         $context['recipients']['exclude_members'] = !empty($_POST['exclude_members']) ? explode(',', $_POST['exclude_members']) : array();
         $context['recipients']['groups'] = !empty($_POST['groups']) ? explode(',', $_POST['groups']) : array();
         $context['recipients']['exclude_groups'] = !empty($_POST['exclude_groups']) ? explode(',', $_POST['exclude_groups']) : array();
         $context['recipients']['emails'] = !empty($_POST['emails']) ? explode(';', $_POST['emails']) : array();
         $context['email_force'] = !empty($_POST['email_force']) ? 1 : 0;
         $context['total_emails'] = !empty($_POST['total_emails']) ? (int) $_POST['total_emails'] : 0;
         $context['max_id_member'] = !empty($_POST['max_id_member']) ? (int) $_POST['max_id_member'] : 0;
         $context['send_pm'] = !empty($_POST['send_pm']) ? 1 : 0;
         $context['send_html'] = !empty($_POST['send_html']) ? '1' : '0';
         return prepareMailingForPreview();
     }
     // Start by finding any members!
     $toClean = array();
     if (!empty($_POST['members'])) {
         $toClean[] = 'members';
     }
     if (!empty($_POST['exclude_members'])) {
         $toClean[] = 'exclude_members';
     }
     if (!empty($toClean)) {
         require_once SUBSDIR . '/Auth.subs.php';
         foreach ($toClean as $type) {
             // Remove the quotes.
             $_POST[$type] = strtr((string) $_POST[$type], array('\\"' => '"'));
             preg_match_all('~"([^"]+)"~', $_POST[$type], $matches);
             $_POST[$type] = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_POST[$type]))));
             foreach ($_POST[$type] as $index => $member) {
                 if (strlen(trim($member)) > 0) {
                     $_POST[$type][$index] = Util::htmlspecialchars(Util::strtolower(trim($member)));
                 } else {
                     unset($_POST[$type][$index]);
                 }
             }
             // Find the members
             $_POST[$type] = implode(',', array_keys(findMembers($_POST[$type])));
         }
     }
     if (isset($_POST['member_list']) && is_array($_POST['member_list'])) {
         $members = array();
         foreach ($_POST['member_list'] as $member_id) {
             $members[] = (int) $member_id;
         }
         $_POST['members'] = implode(',', $members);
     }
     if (isset($_POST['exclude_member_list']) && is_array($_POST['exclude_member_list'])) {
         $members = array();
         foreach ($_POST['exclude_member_list'] as $member_id) {
             $members[] = (int) $member_id;
         }
         $_POST['exclude_members'] = implode(',', $members);
     }
     // Clean the other vars.
     $this->action_mailingsend(true);
     // We need a couple strings from the email template file
     loadLanguage('EmailTemplates');
     require_once SUBSDIR . '/News.subs.php';
     // Get a list of all full banned users.  Use their Username and email to find them.
     // Only get the ones that can't login to turn off notification.
     $context['recipients']['exclude_members'] = excludeBannedMembers();
     // Did they select moderators - if so add them as specific members...
     if (!empty($context['recipients']['groups']) && in_array(3, $context['recipients']['groups']) || !empty($context['recipients']['exclude_groups']) && in_array(3, $context['recipients']['exclude_groups'])) {
         $mods = getModerators();
         foreach ($mods as $row) {
             if (in_array(3, $context['recipients'])) {
                 $context['recipients']['exclude_members'][] = $row;
             } else {
                 $context['recipients']['members'][] = $row;
             }
         }
     }
     require_once SUBSDIR . '/Members.subs.php';
     // For progress bar!
     $context['total_emails'] = count($context['recipients']['emails']);
     $context['max_id_member'] = maxMemberID();
     // Clean up the arrays.
     $context['recipients']['members'] = array_unique($context['recipients']['members']);
     $context['recipients']['exclude_members'] = array_unique($context['recipients']['exclude_members']);
 }
Exemple #27
0
/**
 * The central part of the board - topic display.
 * This function loads the posts in a topic up so they can be displayed.
 * It supports wireless, using wap/wap2/imode and the Wireless templates.
 * It uses the main sub template of the Display template.
 * It requires a topic, and can go to the previous or next topic from it.
 * It jumps to the correct post depending on a number/time/IS_MSG passed.
 * It depends on the messages_per_page, defaultMaxMessages and enableAllMessages settings.
 * It is accessed by ?topic=id_topic.START.
 */
function Display()
{
    global $scripturl, $txt, $modSettings, $context, $settings;
    global $options, $sourcedir, $user_info, $board_info, $topic, $board;
    global $attachments, $messages_request, $topicinfo, $language, $smcFunc;
    // What are you gonna display if these are empty?!
    if (empty($topic)) {
        fatal_lang_error('no_board', false);
    }
    // Load the proper template and/or sub template.
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_display';
    } else {
        loadTemplate('Display');
    }
    // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Prefetch Forbidden');
        die;
    }
    // How much are we sticking on each page?
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    // Let's do some work on what to search index.
    if (count($_GET) > 2) {
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                $context['robot_no_index'] = true;
            }
        }
    }
    if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
        $context['robot_no_index'] = true;
    }
    // Find the previous or next topic.  Make a fuss if there are no more.
    if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
        // No use in calculating the next topic if there's only one.
        if ($board_info['num_topics'] > 1) {
            // Just prepare some variables that are used in the query.
            $gt_lt = $_REQUEST['prev_next'] == 'prev' ? '>' : '<';
            $order = $_REQUEST['prev_next'] == 'prev' ? '' : ' DESC';
            $request = $smcFunc['db_query']('', '
				SELECT t2.id_topic
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}topics AS t2 ON (' . (empty($modSettings['enableStickyTopics']) ? '
					t2.id_last_msg ' . $gt_lt . ' t.id_last_msg' : '
					(t2.id_last_msg ' . $gt_lt . ' t.id_last_msg AND t2.is_sticky ' . $gt_lt . '= t.is_sticky) OR t2.is_sticky ' . $gt_lt . ' t.is_sticky') . ')
				WHERE t.id_topic = {int:current_topic}
					AND t2.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND (t2.approved = {int:is_approved} OR (t2.id_member_started != {int:id_member_started} AND t2.id_member_started = {int:current_member}))') . '
				ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' t2.is_sticky' . $order . ',') . ' t2.id_last_msg' . $order . '
				LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'id_member_started' => 0));
            // No more left.
            if ($smcFunc['db_num_rows']($request) == 0) {
                $smcFunc['db_free_result']($request);
                // Roll over - if we're going prev, get the last - otherwise the first.
                $request = $smcFunc['db_query']('', '
					SELECT id_topic
					FROM {db_prefix}topics
					WHERE id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
						AND (approved = {int:is_approved} OR (id_member_started != {int:id_member_started} AND id_member_started = {int:current_member}))') . '
					ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' is_sticky' . $order . ',') . ' id_last_msg' . $order . '
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_started' => 0));
            }
            // Now you can be sure $topic is the id_topic to view.
            list($topic) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            $context['current_topic'] = $topic;
        }
        // Go to the newest message on this topic.
        $_REQUEST['start'] = 'new';
    }
    // Add 1 to the number of views of this topic (except for robots).
    if (!$user_info['possibly_robot'] && (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic)) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET num_views = num_views + 1
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic));
        $_SESSION['last_read_topic'] = $topic;
    }
    $topic_parameters = array('current_member' => $user_info['id'], 'current_topic' => $topic, 'current_board' => $board);
    $topic_selects = array();
    $topic_tables = array();
    call_integration_hook('integrate_display_topic', array(&$topic_selects, &$topic_tables, &$topic_parameters));
    // @todo Why isn't this cached?
    // @todo if we get id_board in this query and cache it, we can save a query on posting
    // Get all the important topic info.
    $request = $smcFunc['db_query']('', '
		SELECT
			t.num_replies, t.num_views, t.locked, ms.subject, t.is_sticky, t.id_poll,
			t.id_member_started, t.id_first_msg, t.id_last_msg, t.approved, t.unapproved_posts, t.id_redirect_topic,
			' . ($user_info['is_guest'] ? 't.id_last_msg + 1' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from
			' . (!empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $board ? ', id_previous_board, id_previous_topic' : '') . '
			' . (!empty($topic_selects) ? implode(',', $topic_selects) : '') . '
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)' . ($user_info['is_guest'] ? '' : '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . '
			' . (!empty($topic_tables) ? implode("\n\t", $topic_tables) : '') . '
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', $topic_parameters);
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('not_a_topic', false);
    }
    $topicinfo = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    // Is this a moved topic that we are redirecting to?
    if (!empty($topicinfo['id_redirect_topic'])) {
        redirectexit('topic=' . $topicinfo['id_redirect_topic'] . '.0');
    }
    $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
    $context['topic_first_message'] = $topicinfo['id_first_msg'];
    $context['topic_last_message'] = $topicinfo['id_last_msg'];
    // Add up unapproved replies to get real number of replies...
    if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
        $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
    }
    // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
    if ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !$user_info['is_guest'] && !allowedTo('approve_posts')) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(id_member) AS my_unapproved_posts
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND id_member = {int:current_member}
				AND approved = 0', array('current_topic' => $topic, 'current_member' => $user_info['id']));
        list($myUnapprovedPosts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
    } elseif ($user_info['is_guest']) {
        $context['total_visible_posts'] = $context['num_replies'] + ($topicinfo['approved'] ? 1 : 0);
    } else {
        $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
    }
    // When was the last time this topic was replied to?  Should we warn them about it?
    $request = $smcFunc['db_query']('', '
		SELECT poster_time
		FROM {db_prefix}messages
		WHERE id_msg = {int:id_last_msg}
		LIMIT 1', array('id_last_msg' => $topicinfo['id_last_msg']));
    list($lastPostTime) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['oldTopicError'] = !empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($topicinfo['is_sticky']);
    // The start isn't a number; it's information about what to do, where to go.
    if (!is_numeric($_REQUEST['start'])) {
        // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
        if ($_REQUEST['start'] == 'new') {
            // Guests automatically go to the last post.
            if ($user_info['is_guest']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : 0;
            } else {
                // Find the earliest unread message in the topic. (the use of topics here is just for both tables.)
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from
					FROM {db_prefix}topics AS t
						LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
						LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})
					WHERE t.id_topic = {int:current_topic}
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
                list($new_from) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Fall through to the next if statement.
                $_REQUEST['start'] = 'msg' . $new_from;
            }
        }
        // Start from a certain time index, not a message.
        if (substr($_REQUEST['start'], 0, 4) == 'from') {
            $timestamp = (int) substr($_REQUEST['start'], 4);
            if ($timestamp === 0) {
                $_REQUEST['start'] = 0;
            } else {
                // Find the number of messages posted before said time...
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE poster_time < {int:timestamp}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_topic' => $topic, 'current_member' => $user_info['id'], 'is_approved' => 1, 'timestamp' => $timestamp));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Handle view_newest_first options, and get the correct start value.
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
            }
        } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
            $virtual_msg = (int) substr($_REQUEST['start'], 3);
            if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
            } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                $context['start_from'] = 0;
            } else {
                // Find the start value for that message......
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE id_msg < {int:virtual_msg}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'virtual_msg' => $virtual_msg, 'is_approved' => 1, 'no_member' => 0));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
            }
            // We need to reverse the start as well in this case.
            $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
        }
    }
    // Create a previous next string if the selected theme has it as a selected option.
    $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> - <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
    // Check if spellchecking is both enabled and actually working. (for quick reply.)
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // Are we showing signatures - or disabled fields?
    $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
    // Censor the title...
    censorText($topicinfo['subject']);
    $context['page_title'] = $topicinfo['subject'];
    // Is this topic sticky, or can it even be?
    $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
    // Default this topic to not marked for notifications... of course...
    $context['is_marked_notify'] = false;
    // Did we report a post to a moderator just now?
    $context['report_sent'] = isset($_GET['reportsent']);
    // Let's get nosey, who is viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        // Start out with no one at all viewing it.
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        // Search for members who have this topic set in their GET data.
        $request = $smcFunc['db_query']('', '
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_id_group} THEN mem.id_post_group ELSE mem.id_group END)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_id_group' => 0, 'in_url_string' => 's:5:"topic";i:' . $topic . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            if (!empty($row['online_color'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
            }
            $is_buddy = in_array($row['id_member'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<strong>' . $link . '</strong>';
            }
            // Add them both to the list and to the more detailed list.
            if (!empty($row['show_online']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
            }
            $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        // The number of guests is equal to the rows minus the ones we actually used ;).
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Sort the list.
        krsort($context['view_members']);
        krsort($context['view_members_list']);
    }
    // If all is set, but not allowed... just unset it.
    $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
    if (isset($_REQUEST['all']) && !$can_show_all) {
        unset($_REQUEST['all']);
    } elseif (isset($_REQUEST['all'])) {
        $_REQUEST['start'] = -1;
    }
    // Construct the page index, allowing for the .START method...
    $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true);
    $context['start'] = $_REQUEST['start'];
    // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
    // Figure out all the link to the next/prev/first/last/etc. for wireless mainly.
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '', 'last' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . floor($context['total_visible_posts'] / $context['messages_per_page']) * $context['messages_per_page'] : '', 'up' => $scripturl . '?board=' . $board . '.0');
    // If they are viewing all the posts, show all the posts, otherwise limit the number.
    if ($can_show_all) {
        if (isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            $context['page_index'] .= empty($modSettings['compactTopicPagesEnable']) ? '<strong>' . $txt['all'] . '</strong> ' : '[<strong>' . $txt['all'] . '</strong>] ';
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        } else {
            $context['page_index'] .= '&nbsp;<a href="' . $scripturl . '?topic=' . $topic . '.0;all">' . $txt['all'] . '</a> ';
        }
    }
    // Build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject']);
    // Build a list of this board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        // Add a link for each moderator...
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        // And show it after the board's name.
        $context['linktree'][count($context['linktree']) - 2]['extra_after'] = '<span class="board_moderators"> (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')</span>';
    }
    // Information about the current topic...
    $context['is_locked'] = $topicinfo['locked'];
    $context['is_sticky'] = $topicinfo['is_sticky'];
    $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
    $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
    $context['is_approved'] = $topicinfo['approved'];
    // @todo Tricks? We don't want to show the poll icon in the topic class here, so pretend it's not one.
    $context['is_poll'] = false;
    determineTopicClass($context);
    $context['is_poll'] = $topicinfo['id_poll'] > 0 && $modSettings['pollMode'] == '1' && allowedTo('poll_view');
    // Did this user start the topic or not?
    $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
    $context['topic_starter_id'] = $topicinfo['id_member_started'];
    // Set the topic's information for the template.
    $context['subject'] = $topicinfo['subject'];
    $context['num_views'] = $topicinfo['num_views'];
    $context['mark_unread_time'] = !empty($virtual_msg) ? $virtual_msg : $topicinfo['new_from'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
    // For quick reply we need a response prefix in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix', 600))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // If we want to show event information in the topic, prepare the data.
    if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
        // First, try create a better time format, ignoring the "time" elements.
        if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
            $date_string = $user_info['time_format'];
        } else {
            $date_string = $matches[0];
        }
        // Any calendar information for this topic?
        $request = $smcFunc['db_query']('', '
			SELECT cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, mem.real_name
			FROM {db_prefix}calendar AS cal
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = cal.id_member)
			WHERE cal.id_topic = {int:current_topic}
			ORDER BY start_date', array('current_topic' => $topic));
        $context['linked_calendar_events'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Prepare the dates for being formatted.
            $start_date = sscanf($row['start_date'], '%04d-%02d-%02d');
            $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
            $end_date = sscanf($row['end_date'], '%04d-%02d-%02d');
            $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
            $context['linked_calendar_events'][] = array('id' => $row['id_event'], 'title' => $row['title'], 'can_edit' => allowedTo('calendar_edit_any') || $row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'can_export' => allowedTo('calendar_edit_any') || $row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => timeformat($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => timeformat($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
        }
        $smcFunc['db_free_result']($request);
        if (!empty($context['linked_calendar_events'])) {
            $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
        }
    }
    // Create the poll info if it exists.
    if ($context['is_poll']) {
        // Get the question and if it's locked.
        $request = $smcFunc['db_query']('', '
			SELECT
				p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote,
				p.guest_vote, p.id_member, IFNULL(mem.real_name, p.poster_name) AS poster_name, p.num_guest_voters, p.reset_poll
			FROM {db_prefix}polls AS p
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)
			WHERE p.id_poll = {int:id_poll}
			LIMIT 1', array('id_poll' => $topicinfo['id_poll']));
        $pollinfo = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(DISTINCT id_member) AS total
			FROM {db_prefix}log_polls
			WHERE id_poll = {int:id_poll}
				AND id_member != {int:not_guest}', array('id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        list($pollinfo['total']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Total voters needs to include guest voters
        $pollinfo['total'] += $pollinfo['num_guest_voters'];
        // Get all the options, and calculate the total votes.
        $request = $smcFunc['db_query']('', '
			SELECT pc.id_choice, pc.label, pc.votes, IFNULL(lp.id_choice, -1) AS voted_this
			FROM {db_prefix}poll_choices AS pc
				LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest})
			WHERE pc.id_poll = {int:id_poll}', array('current_member' => $user_info['id'], 'id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        $pollOptions = array();
        $realtotal = 0;
        $pollinfo['has_voted'] = false;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            censorText($row['label']);
            $pollOptions[$row['id_choice']] = $row;
            $realtotal += $row['votes'];
            $pollinfo['has_voted'] |= $row['voted_this'] != -1;
        }
        $smcFunc['db_free_result']($request);
        // If this is a guest we need to do our best to work out if they have voted, and what they voted for.
        if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote')) {
            if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $topicinfo['id_poll'] . ',') !== false) {
                // ;id,timestamp,[vote,vote...]; etc
                $guestinfo = explode(';', $_COOKIE['guest_poll_vote']);
                // Find the poll we're after.
                foreach ($guestinfo as $i => $guestvoted) {
                    $guestvoted = explode(',', $guestvoted);
                    if ($guestvoted[0] == $topicinfo['id_poll']) {
                        break;
                    }
                }
                // Has the poll been reset since guest voted?
                if ($pollinfo['reset_poll'] > $guestvoted[1]) {
                    // Remove the poll info from the cookie to allow guest to vote again
                    unset($guestinfo[$i]);
                    if (!empty($guestinfo)) {
                        $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
                    } else {
                        unset($_COOKIE['guest_poll_vote']);
                    }
                } else {
                    // What did they vote for?
                    unset($guestvoted[0], $guestvoted[1]);
                    foreach ($pollOptions as $choice => $details) {
                        $pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1;
                        $pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1;
                    }
                    unset($choice, $details, $guestvoted);
                }
                unset($guestinfo, $guestvoted, $i);
            }
        }
        // Set up the basic poll information.
        $context['poll'] = array('id' => $topicinfo['id_poll'], 'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'), 'question' => parse_bbc($pollinfo['question']), 'total_votes' => $pollinfo['total'], 'change_vote' => !empty($pollinfo['change_vote']), 'is_locked' => !empty($pollinfo['voting_locked']), 'options' => array(), 'lock' => allowedTo('poll_lock_any') || $context['user']['started'] && allowedTo('poll_lock_own'), 'edit' => allowedTo('poll_edit_any') || $context['user']['started'] && allowedTo('poll_edit_own'), 'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '', 'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(), 'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0, 'has_voted' => !empty($pollinfo['has_voted']), 'starter' => array('id' => $pollinfo['id_member'], 'name' => $row['poster_name'], 'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'], 'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'));
        // Make the lock and edit permissions defined above more directly accessible.
        $context['allow_lock_poll'] = $context['poll']['lock'];
        $context['allow_edit_poll'] = $context['poll']['edit'];
        // You're allowed to vote if:
        // 1. the poll did not expire, and
        // 2. you're either not a guest OR guest voting is enabled... and
        // 3. you're not trying to view the results, and
        // 4. the poll is not locked, and
        // 5. you have the proper permissions, and
        // 6. you haven't already voted before.
        $context['allow_vote'] = !$context['poll']['is_expired'] && (!$user_info['is_guest'] || $pollinfo['guest_vote'] && allowedTo('poll_vote')) && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && !$context['poll']['has_voted'];
        // You're allowed to view the results if:
        // 1. you're just a super-nice-guy, or
        // 2. anyone can see them (hide_results == 0), or
        // 3. you can see them after you voted (hide_results == 1), or
        // 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.)
        $context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || $pollinfo['hide_results'] == 1 && $context['poll']['has_voted'] || $context['poll']['is_expired'];
        $context['poll']['show_results'] = $context['allow_poll_view'] && (isset($_REQUEST['viewresults']) || isset($_REQUEST['viewResults']));
        $context['show_view_results_button'] = $context['allow_vote'] && (!$context['allow_poll_view'] || !$context['poll']['show_results'] || !$context['poll']['has_voted']);
        // You're allowed to change your vote if:
        // 1. the poll did not expire, and
        // 2. you're not a guest... and
        // 3. the poll is not locked, and
        // 4. you have the proper permissions, and
        // 5. you have already voted, and
        // 6. the poll creator has said you can!
        $context['allow_change_vote'] = !$context['poll']['is_expired'] && !$user_info['is_guest'] && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && $context['poll']['has_voted'] && $context['poll']['change_vote'];
        // You're allowed to return to voting options if:
        // 1. you are (still) allowed to vote.
        // 2. you are currently seeing the results.
        $context['allow_return_vote'] = $context['allow_vote'] && $context['poll']['show_results'];
        // Calculate the percentages and bar lengths...
        $divisor = $realtotal == 0 ? 1 : $realtotal;
        // Determine if a decimal point is needed in order for the options to add to 100%.
        $precision = $realtotal == 100 ? 0 : 1;
        // Now look through each option, and...
        foreach ($pollOptions as $i => $option) {
            // First calculate the percentage, and then the width of the bar...
            $bar = round($option['votes'] * 100 / $divisor, $precision);
            $barWide = $bar == 0 ? 1 : floor($bar * 8 / 3);
            // Now add it to the poll's contextual theme data.
            $context['poll']['options'][$i] = array('id' => 'options-' . $i, 'percent' => $bar, 'votes' => $option['votes'], 'voted_this' => $option['voted_this'] != -1, 'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.png" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.png" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.png" alt="" /></span>', 'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '', 'bar_width' => $barWide, 'option' => parse_bbc($option['label']), 'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '" />');
        }
        // Build the poll moderation button array.
        $context['poll_buttons'] = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'show_view_results_button', 'text' => 'poll_results', 'image' => 'poll_results.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start'] . ';viewresults'), 'change_vote' => array('test' => 'allow_change_vote', 'text' => 'poll_change_vote', 'image' => 'poll_change_vote.png', 'lang' => true, 'url' => $scripturl . '?action=vote;topic=' . $context['current_topic'] . '.' . $context['start'] . ';poll=' . $context['poll']['id'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'allow_lock_poll', 'text' => !$context['poll']['is_locked'] ? 'poll_lock' : 'poll_unlock', 'image' => 'poll_lock.png', 'lang' => true, 'url' => $scripturl . '?action=lockvoting;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'edit' => array('test' => 'allow_edit_poll', 'text' => 'poll_edit', 'image' => 'poll_edit.png', 'lang' => true, 'url' => $scripturl . '?action=editpoll;topic=' . $context['current_topic'] . '.' . $context['start']), 'remove_poll' => array('test' => 'can_remove_poll', 'text' => 'poll_remove', 'image' => 'admin_remove_poll.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['poll_remove_warn'] . '\');"', 'url' => $scripturl . '?action=removepoll;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']));
        // Allow mods to add additional buttons here
        call_integration_hook('integrate_poll_buttons');
    }
    // Calculate the fastest way to get the messages!
    $ascending = empty($options['view_newest_first']);
    $start = $_REQUEST['start'];
    $limit = $context['messages_per_page'];
    $firstIndex = 0;
    if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
        $ascending = !$ascending;
        $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
        $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
        $firstIndex = $limit - 1;
    }
    // Get each post and poster in this topic.
    $request = $smcFunc['db_query']('display_get_post_poster', '
		SELECT id_msg, id_member, approved
		FROM {db_prefix}messages
		WHERE id_topic = {int:current_topic}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : (!empty($modSettings['db_mysql_group_by_fix']) ? '' : '
		GROUP BY id_msg') . '
		HAVING (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')') . '
		ORDER BY id_msg ' . ($ascending ? '' : 'DESC') . ($context['messages_per_page'] == -1 ? '' : '
		LIMIT ' . $start . ', ' . $limit), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'blank_id_member' => 0));
    $messages = array();
    $all_posters = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        if (!empty($row['id_member'])) {
            $all_posters[$row['id_msg']] = $row['id_member'];
        }
        $messages[] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    $posters = array_unique($all_posters);
    call_integration_hook('integrate_display_message_list', array($messages, $posters));
    // Guests can't mark topics read or for notifications, just can't sorry.
    if (!$user_info['is_guest'] && !empty($messages)) {
        $mark_at_msg = max($messages);
        if ($mark_at_msg >= $topicinfo['id_last_msg']) {
            $mark_at_msg = $modSettings['maxMsgID'];
        }
        if ($mark_at_msg >= $topicinfo['new_from']) {
            $smcFunc['db_insert']($topicinfo['new_from'] == 0 ? 'ignore' : 'replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), array($user_info['id'], $topic, $mark_at_msg), array('id_member', 'id_topic'));
        }
        // Check for notifications on this topic OR board.
        $request = $smcFunc['db_query']('', '
			SELECT sent, id_topic
			FROM {db_prefix}log_notify
			WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
				AND id_member = {int:current_member}
			LIMIT 2', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
        $do_once = true;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Find if this topic is marked for notification...
            if (!empty($row['id_topic'])) {
                $context['is_marked_notify'] = true;
            }
            // Only do this once, but mark the notifications as "not sent yet" for next time.
            if (!empty($row['sent']) && $do_once) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_not_sent}
					WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_not_sent' => 0));
                $do_once = false;
            }
        }
        // Have we recently cached the number of new topics in this board, and it's still a lot?
        if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
            $_SESSION['topicseen_cache'][$board]--;
        } elseif (isset($_REQUEST['topicseen'])) {
            // Use the mark read tables... and the last visit to figure out if this should be read or not.
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}topics AS t
					LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = {int:current_board} AND lb.id_member = {int:current_member})
					LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
				WHERE t.id_board = {int:current_board}
					AND t.id_last_msg > IFNULL(lb.id_msg, 0)
					AND t.id_last_msg > IFNULL(lt.id_msg, 0)' . (empty($_SESSION['id_msg_last_visit']) ? '' : '
					AND t.id_last_msg > {int:id_msg_last_visit}'), array('current_board' => $board, 'current_member' => $user_info['id'], 'id_msg_last_visit' => (int) $_SESSION['id_msg_last_visit']));
            list($numNewTopics) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // If there're no real new topics in this board, mark the board as seen.
            if (empty($numNewTopics)) {
                $_REQUEST['boardseen'] = true;
            } else {
                $_SESSION['topicseen_cache'][$board] = $numNewTopics;
            }
        } elseif (isset($_SESSION['topicseen_cache'][$board])) {
            $_SESSION['topicseen_cache'][$board]--;
        }
        // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
        if (isset($_REQUEST['boardseen'])) {
            $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board'));
        }
    }
    $attachments = array();
    // If there _are_ messages here... (probably an error otherwise :!)
    if (!empty($messages)) {
        // Fetch attachments.
        if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
            $request = $smcFunc['db_query']('', '
				SELECT
					a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
					a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
					IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
				FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
					LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
				WHERE a.id_msg IN ({array_int:message_list})
					AND a.attachment_type = {int:attachment_type}', array('message_list' => $messages, 'attachment_type' => 0, 'is_approved' => 1));
            $temp = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id'])) {
                    continue;
                }
                $temp[$row['id_attach']] = $row;
                if (!isset($attachments[$row['id_msg']])) {
                    $attachments[$row['id_msg']] = array();
                }
            }
            $smcFunc['db_free_result']($request);
            // This is better than sorting it with the query...
            ksort($temp);
            foreach ($temp as $row) {
                $attachments[$row['id_msg']][] = $row;
            }
        }
        $msg_parameters = array('message_list' => $messages, 'new_from' => $topicinfo['new_from']);
        $msg_selects = array();
        $msg_tables = array();
        call_integration_hook('integrate_query_message', array(&$msg_selects, &$msg_tables, &$msg_parameters));
        // What?  It's not like it *couldn't* be only guests in this topic...
        if (!empty($posters)) {
            loadMemberData($posters);
        }
        $messages_request = $smcFunc['db_query']('', '
			SELECT
				id_msg, icon, subject, poster_time, poster_ip, id_member, modified_time, modified_name, body,
				smileys_enabled, poster_name, poster_email, approved,
				id_msg_modified < {int:new_from} AS is_read
				' . (!empty($msg_selects) ? implode(',', $msg_selects) : '') . '
			FROM {db_prefix}messages
				' . (!empty($msg_tables) ? implode("\n\t", $msg_tables) : '') . '
			WHERE id_msg IN ({array_int:message_list})
			ORDER BY id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'), $msg_parameters);
        // Go to the last message if the given time is beyond the time of the last message.
        if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
            $context['start_from'] = $topicinfo['num_replies'];
        }
        // Since the anchor information is needed on the top of the page we load these variables beforehand.
        $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
        if (empty($options['view_newest_first'])) {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $topicinfo['num_replies'] - $context['start_from'];
        }
    } else {
        $messages_request = false;
        $context['first_message'] = 0;
        $context['first_new_message'] = false;
    }
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&'))), 'child_level' => $board_info['child_level']);
    // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
    // This will be called from the template.
    $context['get_message'] = 'prepareDisplayContext';
    // Now set all the wonderful, wonderful permissions... like moderation ones...
    $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_send_email' => 'send_email_to_members', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
    foreach ($common_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm);
    }
    // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
    $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
    foreach ($anyown_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
    }
    // Cleanup all the permissions with extra stuff...
    $context['can_mark_notify'] &= !$context['user']['is_guest'];
    $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
    $context['calendar_post'] &= !empty($modSettings['cal_enabled']);
    $context['can_add_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] <= 0;
    $context['can_remove_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] > 0;
    $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
    $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
    $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1;
    // Handle approval flags...
    $context['can_reply_approved'] = $context['can_reply'];
    $context['can_reply'] |= $context['can_reply_unapproved'];
    $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
    $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
    $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
    $context['can_print'] = empty($modSettings['disable_print_topic']);
    // Start this off for quick moderation - it will be or'd for each post.
    $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
    // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
    $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
    $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
    // Check if the draft functions are enabled and that they have permission to use them (for quick reply.)
    $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft') && $context['can_reply'];
    $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
    if (!empty($context['drafts_save'])) {
        loadLanguage('Drafts');
    }
    // Wireless shows a "more" if you can do anything special.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['wireless_more'] = $context['can_sticky'] || $context['can_lock'] || allowedTo('modify_any');
        $context['wireless_moderate'] = isset($_GET['moderate']) ? ';moderate' : '';
    }
    // Load up the "double post" sequencing magic.
    if (!empty($options['display_quick_reply'])) {
        checkSubmitOnce('register');
        $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
        $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
        if ($options['display_quick_reply'] == 3 && $context['can_reply']) {
            // Needed for the editor and message icons.
            require_once $sourcedir . '/Subs-Editor.php';
            // Now create the editor.
            $editorOptions = array('id' => 'message', 'value' => '', 'labels' => array('post_button' => $txt['post']), 'height' => '175px', 'width' => '100%', 'preview_type' => 0);
            create_control_richedit($editorOptions);
            // Store the ID.
            $context['post_box_name'] = $editorOptions['id'];
            $context['attached'] = '';
            $context['make_poll'] = isset($_REQUEST['poll']);
            // Message icons - customized icons are off?
            $context['icons'] = getMessageIcons($board);
            if (!empty($context['icons'])) {
                $context['icons'][count($context['icons']) - 1]['is_last'] = true;
            }
        }
    }
    // Build the normal button array.
    $context['normal_buttons'] = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'image' => 'reply.png', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'add_poll' => array('test' => 'can_add_poll', 'text' => 'add_poll', 'image' => 'add_poll.png', 'lang' => true, 'url' => $scripturl . '?action=editpoll;add;topic=' . $context['current_topic'] . '.' . $context['start']), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']) . '\');"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0'), 'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="new_win nofollow"', 'url' => $scripturl . '?action=printpage;topic=' . $context['current_topic'] . '.0'));
    // Build the mod button array
    $context['mod_buttons'] = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.png', 'lang' => true, 'url' => $scripturl . '?action=movetopic;current_board=' . $context['current_board'] . ';topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', 'url' => $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.png', 'lang' => true, 'url' => $scripturl . '?action=lock;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'sticky' => array('test' => 'can_sticky', 'text' => empty($context['is_sticky']) ? 'set_sticky' : 'set_nonsticky', 'image' => 'admin_sticky.png', 'lang' => true, 'url' => $scripturl . '?action=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.png', 'lang' => true, 'url' => $scripturl . '?action=mergetopics;board=' . $context['current_board'] . '.0;from=' . $context['current_topic']), 'calendar' => array('test' => 'calendar_post', 'text' => 'calendar_link', 'image' => 'linktocal.png', 'lang' => true, 'url' => $scripturl . '?action=post;calendar;msg=' . $context['topic_first_message'] . ';topic=' . $context['current_topic'] . '.0'));
    // Restore topic. eh?  No monkey business.
    if ($context['can_restore_topic']) {
        $context['mod_buttons'][] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']);
    }
    // Allow adding new mod buttons easily.
    call_integration_hook('integrate_display_buttons');
}
function sportal_admin_page_edit()
{
    global $txt, $context, $modSettings, $smcFunc, $sourcedir, $options;
    require_once $sourcedir . '/Subs-Editor.php';
    require_once $sourcedir . '/Subs-Post.php';
    $context['SPortal']['is_new'] = empty($_REQUEST['page_id']);
    if (!empty($_REQUEST['content_mode']) && $_POST['type'] == 'bbc') {
        $_REQUEST['content'] = html_to_bbc($_REQUEST['content']);
        $_REQUEST['content'] = un_htmlspecialchars($_REQUEST['content']);
        $_POST['content'] = $_REQUEST['content'];
    }
    $context['sides'] = array(5 => $txt['sp-positionHeader'], 1 => $txt['sp-positionLeft'], 2 => $txt['sp-positionTop'], 3 => $txt['sp-positionBottom'], 4 => $txt['sp-positionRight'], 6 => $txt['sp-positionFooter']);
    $blocks = getBlockInfo();
    $context['page_blocks'] = array();
    foreach ($blocks as $block) {
        $shown = false;
        $tests = array('all', 'allpages', 'sforum');
        if (!$context['SPortal']['is_new']) {
            $tests[] = 'p' . (int) $_REQUEST['page_id'];
        }
        foreach (array('display', 'display_custom') as $field) {
            if (substr($block[$field], 0, 4) === '$php') {
                continue 2;
            }
            $block[$field] = explode(',', $block[$field]);
            if (!$context['SPortal']['is_new'] && in_array('-p' . (int) $_REQUEST['page_id'], $block[$field])) {
                continue;
            }
            foreach ($tests as $test) {
                if (in_array($test, $block[$field])) {
                    $shown = true;
                    break;
                }
            }
        }
        $context['page_blocks'][$block['column']][] = array('id' => $block['id'], 'label' => $block['label'], 'shown' => $shown);
    }
    if (!empty($_POST['submit'])) {
        checkSession();
        if (!isset($_POST['title']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['title'], ENT_QUOTES)) === '') {
            fatal_lang_error('sp_error_page_name_empty', false);
        }
        if (!isset($_POST['namespace']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['namespace'], ENT_QUOTES)) === '') {
            fatal_lang_error('sp_error_page_namespace_empty', false);
        }
        $result = $smcFunc['db_query']('', '
			SELECT id_page
			FROM {db_prefix}sp_pages
			WHERE namespace = {string:namespace}
				AND id_page != {int:current}
			LIMIT 1', array('limit' => 1, 'namespace' => $smcFunc['htmlspecialchars']($_POST['namespace'], ENT_QUOTES), 'current' => (int) $_POST['page_id']));
        list($has_duplicate) = $smcFunc['db_fetch_row']($result);
        $smcFunc['db_free_result']($result);
        if (!empty($has_duplicate)) {
            fatal_lang_error('sp_error_page_namespace_duplicate', false);
        }
        if (preg_match('~[^A-Za-z0-9_]+~', $_POST['namespace']) != 0) {
            fatal_lang_error('sp_error_page_namespace_invalid_chars', false);
        }
        if (preg_replace('~[0-9]+~', '', $_POST['namespace']) === '') {
            fatal_lang_error('sp_error_page_namespace_numeric', false);
        }
        if ($_POST['type'] == 'php' && !empty($_POST['content']) && empty($modSettings['sp_disable_php_validation'])) {
            $error = sp_validate_php($_POST['content']);
            if ($error) {
                fatal_lang_error('error_sp_php_' . $error, false);
            }
        }
        $permission_set = 0;
        $groups_allowed = $groups_denied = '';
        if (!empty($_POST['permission_set'])) {
            $permission_set = (int) $_POST['permission_set'];
        } elseif (!empty($_POST['membergroups']) && is_array($_POST['membergroups'])) {
            $groups_allowed = $groups_denied = array();
            foreach ($_POST['membergroups'] as $id => $value) {
                if ($value == 1) {
                    $groups_allowed[] = (int) $id;
                } elseif ($value == -1) {
                    $groups_denied[] = (int) $id;
                }
            }
            $groups_allowed = implode(',', $groups_allowed);
            $groups_denied = implode(',', $groups_denied);
        }
        if (!empty($_POST['blocks']) && is_array($_POST['blocks'])) {
            foreach ($_POST['blocks'] as $id => $block) {
                $_POST['blocks'][$id] = (int) $block;
            }
        } else {
            $_POST['blocks'] = array();
        }
        $fields = array('namespace' => 'string', 'title' => 'string', 'body' => 'string', 'type' => 'string', 'permission_set' => 'int', 'groups_allowed' => 'string', 'groups_denied' => 'string', 'style' => 'string', 'status' => 'int');
        $page_info = array('id' => (int) $_POST['page_id'], 'namespace' => $smcFunc['htmlspecialchars']($_POST['namespace'], ENT_QUOTES), 'title' => $smcFunc['htmlspecialchars']($_POST['title'], ENT_QUOTES), 'body' => $smcFunc['htmlspecialchars']($_POST['content'], ENT_QUOTES), 'type' => $_POST['type'], 'permission_set' => $permission_set, 'groups_allowed' => $groups_allowed, 'groups_denied' => $groups_denied, 'style' => sportal_parse_style('implode'), 'status' => !empty($_POST['status']) ? 1 : 0);
        if ($page_info['type'] == 'bbc') {
            preparsecode($page_info['body']);
        }
        if ($context['SPortal']['is_new']) {
            unset($page_info['id']);
            $smcFunc['db_insert']('', '{db_prefix}sp_pages', $fields, $page_info, array('id_page'));
            $page_info['id'] = $smcFunc['db_insert_id']('{db_prefix}sp_pages', 'id_page');
        } else {
            $update_fields = array();
            foreach ($fields as $name => $type) {
                $update_fields[] = $name . ' = {' . $type . ':' . $name . '}';
            }
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}sp_pages
				SET ' . implode(', ', $update_fields) . '
				WHERE id_page = {int:id}', $page_info);
        }
        $to_show = array();
        $not_to_show = array();
        $changes = array();
        foreach ($context['page_blocks'] as $page_blocks) {
            foreach ($page_blocks as $block) {
                if ($block['shown'] && !in_array($block['id'], $_POST['blocks'])) {
                    $not_to_show[] = $block['id'];
                } elseif (!$block['shown'] && in_array($block['id'], $_POST['blocks'])) {
                    $to_show[] = $block['id'];
                }
            }
        }
        foreach ($to_show as $id) {
            if (empty($blocks[$id]['display']) && empty($blocks[$id]['display_custom']) || $blocks[$id]['display'] == 'sportal') {
                $changes[$id] = array('display' => 'portal,p' . $page_info['id'], 'display_custom' => '');
            } elseif (in_array($blocks[$id]['display'], array('allaction', 'allboard'))) {
                $changes[$id] = array('display' => '', 'display_custom' => $blocks[$id]['display'] . ',p' . $page_info['id']);
            } elseif (in_array('-p' . $page_info['id'], explode(',', $blocks[$id]['display_custom']))) {
                $changes[$id] = array('display' => $blocks[$id]['display'], 'display_custom' => implode(',', array_diff(explode(',', $blocks[$id]['display_custom']), array('-p' . $page_info['id']))));
            } elseif (empty($blocks[$id]['display_custom'])) {
                $changes[$id] = array('display' => implode(',', array_merge(explode(',', $blocks[$id]['display']), array('p' . $page_info['id']))), 'display_custom' => '');
            } else {
                $changes[$id] = array('display' => $blocks[$id]['display'], 'display_custom' => implode(',', array_merge(explode(',', $blocks[$id]['display_custom']), array('p' . $page_info['id']))));
            }
        }
        foreach ($not_to_show as $id) {
            if (count(array_intersect(array($blocks[$id]['display'], $blocks[$id]['display_custom']), array('sforum', 'allpages', 'all'))) > 0) {
                $changes[$id] = array('display' => '', 'display_custom' => $blocks[$id]['display'] . $blocks[$id]['display_custom'] . ',-p' . $page_info['id']);
            } elseif (empty($blocks[$id]['display_custom'])) {
                $changes[$id] = array('display' => implode(',', array_diff(explode(',', $blocks[$id]['display']), array('p' . $page_info['id']))), 'display_custom' => '');
            } else {
                $changes[$id] = array('display' => implode(',', array_diff(explode(',', $blocks[$id]['display']), array('p' . $page_info['id']))), 'display_custom' => implode(',', array_diff(explode(',', $blocks[$id]['display_custom']), array('p' . $page_info['id']))));
            }
        }
        foreach ($changes as $id => $data) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}sp_blocks
				SET
					display = {string:display},
					display_custom = {string:display_custom}
				WHERE id_block = {int:id}', array('id' => $id, 'display' => $data['display'], 'display_custom' => $data['display_custom']));
        }
        redirectexit('action=admin;area=portalpages');
    }
    if (!empty($_POST['preview'])) {
        $permission_set = 0;
        $groups_allowed = $groups_denied = array();
        if (!empty($_POST['permission_set'])) {
            $permission_set = (int) $_POST['permission_set'];
        } elseif (!empty($_POST['membergroups']) && is_array($_POST['membergroups'])) {
            foreach ($_POST['membergroups'] as $id => $value) {
                if ($value == 1) {
                    $groups_allowed[] = (int) $id;
                } elseif ($value == -1) {
                    $groups_denied[] = (int) $id;
                }
            }
        }
        $context['SPortal']['page'] = array('id' => $_POST['page_id'], 'page_id' => $_POST['namespace'], 'title' => $smcFunc['htmlspecialchars']($_POST['title'], ENT_QUOTES), 'body' => $smcFunc['htmlspecialchars']($_POST['content'], ENT_QUOTES), 'type' => $_POST['type'], 'permission_set' => $permission_set, 'groups_allowed' => $groups_allowed, 'groups_denied' => $groups_denied, 'style' => sportal_parse_style('implode'), 'status' => !empty($_POST['status']));
        if ($context['SPortal']['page']['type'] == 'bbc') {
            preparsecode($context['SPortal']['page']['body']);
        }
        loadTemplate('PortalPages');
        $context['SPortal']['preview'] = true;
    } elseif ($context['SPortal']['is_new']) {
        $context['SPortal']['page'] = array('id' => 0, 'page_id' => 'page' . mt_rand(1, 5000), 'title' => $txt['sp_pages_default_title'], 'body' => '', 'type' => 'bbc', 'permission_set' => 3, 'groups_allowed' => array(), 'groups_denied' => array(), 'style' => '', 'status' => 1);
    } else {
        $_REQUEST['page_id'] = (int) $_REQUEST['page_id'];
        $context['SPortal']['page'] = sportal_get_pages($_REQUEST['page_id']);
    }
    if ($context['SPortal']['page']['type'] == 'bbc') {
        $context['SPortal']['page']['body'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), un_preparsecode($context['SPortal']['page']['body']));
    }
    if ($context['SPortal']['page']['type'] != 'bbc') {
        $temp_editor = !empty($options['wysiwyg_default']);
        $options['wysiwyg_default'] = false;
    }
    $editorOptions = array('id' => 'content', 'value' => $context['SPortal']['page']['body'], 'width' => '95%', 'height' => '200px', 'preview_type' => 0);
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
    if (isset($temp_editor)) {
        $options['wysiwyg_default'] = $temp_editor;
    }
    $context['SPortal']['page']['groups'] = sp_load_membergroups();
    $context['SPortal']['page']['style'] = sportal_parse_style('explode', $context['SPortal']['page']['style'], !empty($context['SPortal']['preview']));
    $context['page_title'] = $context['SPortal']['is_new'] ? $txt['sp_admin_pages_add'] : $txt['sp_admin_pages_edit'];
    $context['sub_template'] = 'pages_edit';
}
function ProfileComments_Edit()
{
    global $context, $mbname, $user_info, $modSettings, $sourcedir, $txt, $smcFunc;
    // Guests can't do this stuff
    is_not_guest();
    $id = (int) $_REQUEST['id'];
    if (empty($id)) {
        fatal_error($txt['pcomments_err_nocom']);
    }
    $dbresult = $smcFunc['db_query']('', "\n\tSELECT \n\t\tp.ID_COMMENT, p.ID_MEMBER, p.comment, p.subject, p.date, p.COMMENT_MEMBER_ID \n\tFROM {db_prefix}profile_comments as p \n\tWHERE p.ID_COMMENT = {$id} LIMIT 1");
    $row = $smcFunc['db_fetch_assoc']($dbresult);
    $context['profilerow'] = $row;
    $smcFunc['db_free_result']($dbresult);
    $context['sub_template'] = 'commentsedit';
    //Set the page title
    $context['page_title'] = $mbname . $txt['pcomments_edit1'];
    // Check if spellchecking is both enabled and actually working.
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Used for the editor
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'comment', 'value' => $row['comment'], 'width' => '90%', 'form' => 'cprofile', 'labels' => array('post_button' => ''));
    create_control_richedit($editorOptions);
    $context['post_box_name'] = $editorOptions['id'];
}