Beispiel #1
0
function isReservedName($name, $current_ID_MEMBER = 0, $is_name = true, $fatal = true)
{
    global $modSettings, $context;
    // No cheating with entities please.
    $replaceEntities = create_function('$string', '
		$num = substr($string, 0, 1) === \'x\' ? hexdec(substr($string, 1)) : (int) $string;
		if ($num === 0x202E || $num === 0x202D) return \'\'; if (in_array($num, array(0x22, 0x26, 0x27, 0x3C, 0x3E))) return \'&#\' . $num . \';\';' . 'return $num < 0x20 || $num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) ? \'\' : ($num < 0x80 ? chr($num) : ($num < 0x800 ? chr(192 | $num >> 6) . chr(128 | $num & 63) : ($num < 0x10000 ? chr(224 | $num >> 12) . chr(128 | $num >> 6 & 63) . chr(128 | $num & 63) : chr(240 | $num >> 18) . chr(128 | $num >> 12 & 63) . chr(128 | $num >> 6 & 63) . chr(128 | $num & 63))));');
    $name = preg_replace('~(&#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~e', '$replaceEntities(\'\\2\')', $name);
    $checkName = commonAPI::strtolower($name);
    // Administrators are never restricted ;).
    if (!allowedTo('moderate_forum') && (!empty($modSettings['reserveName']) && $is_name || !empty($modSettings['reserveUser']) && !$is_name)) {
        $reservedNames = explode("\n", $modSettings['reserveNames']);
        // Case sensitive check?
        $checkMe = empty($modSettings['reserveCase']) ? $checkName : $name;
        // Check each name in the list...
        foreach ($reservedNames as $reserved) {
            if ($reserved == '') {
                continue;
            }
            // The admin might've used entities too, level the playing field.
            $reservedCheck = preg_replace('~(&#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~e', '$replaceEntities(\'\\2\')', $reserved);
            // Case sensitive name?
            if (empty($modSettings['reserveCase'])) {
                $reservedCheck = commonAPI::strtolower($reservedCheck);
            }
            // If it's not just entire word, check for it in there somewhere...
            if ($checkMe == $reservedCheck || commonAPI::strpos($checkMe, $reservedCheck) !== false && empty($modSettings['reserveWord'])) {
                if ($fatal) {
                    fatal_lang_error('username_reserved', 'password', array($reserved));
                } else {
                    return true;
                }
            }
        }
        $censor_name = $name;
        if (censorText($censor_name) != $name) {
            if ($fatal) {
                fatal_lang_error('name_censored', 'password', array($name));
            } else {
                return true;
            }
        }
    }
    // Characters we just shouldn't allow, regardless.
    foreach (array('*') as $char) {
        if (strpos($checkName, $char) !== false) {
            if ($fatal) {
                fatal_lang_error('username_reserved', 'password', array($char));
            } else {
                return true;
            }
        }
    }
    // Get rid of any SQL parts of the reserved name...
    $checkName = strtr($name, array('_' => '\\_', '%' => '\\%'));
    // Make sure they don't want someone else's name.
    $request = smf_db_query('
		SELECT id_member
		FROM {db_prefix}members
		WHERE ' . (empty($current_ID_MEMBER) ? '' : 'id_member != {int:current_member}
			AND ') . '(real_name LIKE {string:check_name} OR member_name LIKE {string:check_name})
		LIMIT 1', array('current_member' => $current_ID_MEMBER, 'check_name' => $checkName));
    if (mysql_num_rows($request) > 0) {
        mysql_free_result($request);
        return true;
    }
    // Does name case insensitive match a member group name?
    $request = smf_db_query('
		SELECT id_group
		FROM {db_prefix}membergroups
		WHERE group_name LIKE {string:check_name}
		LIMIT 1', array('check_name' => $checkName));
    if (mysql_num_rows($request) > 0) {
        mysql_free_result($request);
        return true;
    }
    // Okay, they passed.
    return false;
}
Beispiel #2
0
function cdata_parse($data, $ns = '')
{
    global $smcFunc, $cdata_override;
    // Are we not doing it?
    if (!empty($cdata_override)) {
        return $data;
    }
    $cdata = '<![CDATA[';
    for ($pos = 0, $n = commonAPI::strlen($data); $pos < $n; null) {
        $positions = array(commonAPI::strpos($data, '&', $pos), commonAPI::strpos($data, ']', $pos));
        if ($ns != '') {
            $positions[] = commonAPI::strpos($data, '<', $pos);
        }
        foreach ($positions as $k => $dummy) {
            if ($dummy === false) {
                unset($positions[$k]);
            }
        }
        $old = $pos;
        $pos = empty($positions) ? $n : min($positions);
        if ($pos - $old > 0) {
            $cdata .= commonAPI::substr($data, $old, $pos - $old);
        }
        if ($pos >= $n) {
            break;
        }
        if (commonAPI::substr($data, $pos, 1) == '<') {
            $pos2 = commonAPI::strpos($data, '>', $pos);
            if ($pos2 === false) {
                $pos2 = $n;
            }
            if (commonAPI::substr($data, $pos + 1, 1) == '/') {
                $cdata .= ']]></' . $ns . ':' . commonAPI::substr($data, $pos + 2, $pos2 - $pos - 1) . '<![CDATA[';
            } else {
                $cdata .= ']]><' . $ns . ':' . commonAPI::substr($data, $pos + 1, $pos2 - $pos) . '<![CDATA[';
            }
            $pos = $pos2 + 1;
        } elseif (commonAPI::substr($data, $pos, 1) == ']') {
            $cdata .= ']]>&#093;<![CDATA[';
            $pos++;
        } elseif (commonAPI::substr($data, $pos, 1) == '&') {
            $pos2 = commonAPI::strpos($data, ';', $pos);
            if ($pos2 === false) {
                $pos2 = $n;
            }
            $ent = commonAPI::substr($data, $pos + 1, $pos2 - $pos - 1);
            if (commonAPI::substr($data, $pos + 1, 1) == '#') {
                $cdata .= ']]>' . commonAPI::substr($data, $pos, $pos2 - $pos + 1) . '<![CDATA[';
            } elseif (in_array($ent, array('amp', 'lt', 'gt', 'quot'))) {
                $cdata .= ']]>' . commonAPI::substr($data, $pos, $pos2 - $pos + 1) . '<![CDATA[';
            }
            // !!! ??
            $pos = $pos2 + 1;
        }
    }
    $cdata .= ']]>';
    return strtr($cdata, array('<![CDATA[]]>' => ''));
}
Beispiel #3
0
function Post()
{
    global $txt, $scripturl, $topic, $modSettings, $board;
    global $user_info, $sc, $board_info, $context, $settings;
    global $sourcedir, $options, $language;
    $context['need_synhlt'] = true;
    loadLanguage('Post');
    loadLanguage('Tagging');
    $context['tagging_ui'] = '';
    $context['auto_preview'] = isset($_REQUEST['autopreview']) && $_REQUEST['autopreview'] ? 1 : 0;
    $context['can_tag_users'] = allowedTo('tag_users');
    /* todo: drafts should be a plugin
    	if(in_array('dr', $context['admin_features'])) {
    		require_once($sourcedir . '/lib/Subs-Drafts.php');
    		$context['have_drafts'] = true;
    		enqueueThemeScript('drafts', 'scripts/drafts.js', true);
    	}
    	else*/
    $context['have_drafts'] = false;
    // 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 . '/lib/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 = smf_db_query('
			SELECT id_topic
			FROM {db_prefix}messages
			WHERE id_msg = {int:msg}', array('msg' => (int) $_REQUEST['msg']));
        if (mysql_num_rows($request) != 1) {
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        } else {
            list($topic) = mysql_fetch_row($request);
        }
        mysql_free_result($request);
    }
    // Check if it's locked.  It isn't locked if no topic is specified.
    if (!empty($topic)) {
        $request = smf_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, ba.id_topic AS banned_from_topic
			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)
				LEFT JOIN {db_prefix}topicbans AS ba ON (ba.id_topic = {int:current_topic} AND ba.id_member = {int:current_member})
			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, $banned_from_topic) = mysql_fetch_row($request);
        mysql_free_result($request);
        if ($banned_from_topic && !$user_info['is_admin'] && !allowedTo('moderate_board') && !allowedTo('moderate_forum')) {
            fatal_lang_error('banned_from_topic');
        }
        // 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'])) {
            $oldTopicError = true;
        }
    } 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 . '/lib/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 = smf_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 = mysql_fetch_assoc($request);
            mysql_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 . '/lib/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 = smf_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']) = mysql_fetch_row($request);
            mysql_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'];
            }
        }
    }
    // Get a response prefix (like 'Re:') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = CacheAPI::getCache('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');
        }
        CacheAPI::putCache('response_prefix', $context['response_prefix'], 600);
    }
    $context['can_merge_with_last'] = false;
    // 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 (!isset($_REQUEST['goadvanced']) && htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['message'])) == '') {
                $context['post_error']['no_message'] = true;
            }
            if (!empty($modSettings['max_messageLength']) && commonAPI::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 (commonAPI::strlen($_REQUEST['guestname']) > 25) {
                    $context['post_error']['long_name'] = true;
                } else {
                    require_once $sourcedir . '/lib/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(commonAPI::htmlspecialchars($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $form_message = commonAPI::htmlspecialchars($_REQUEST['message'], ENT_QUOTES);
        // Make sure the subject isn't too long - taking into account special characters.
        if (commonAPI::strlen($form_subject) > 100) {
            $form_subject = commonAPI::substr($form_subject, 0, 100);
        }
        // Have we inadvertently trimmed off the subject of useful information?
        if (commonAPI::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']) ? commonAPI::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.
        // but don't show the preview when we come from hitting the "go advanced" button in inline-modify
        if ($really_previewing == true && !isset($_REQUEST['goadvanced']) || 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']);
            /*
             * tagging for formatting the preview, we don't do anything with the result...yet
             */
            if ($context['can_tag_users'] && !(isset($_REQUEST['allowtags']) && $_REQUEST['allowtags'])) {
                handleUserTags($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);
            parse_bbc_stage2($context['preview_message']);
            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[>'));
            }
        }
        $context['can_merge_with_last'] = isset($_REQUEST['want_automerge']) && $_REQUEST['want_automerge'] ? true : false;
        // 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 = smf_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, m.locked,
					IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
					a.approved AS attachment_approved, t.id_member_started AS id_member_poster, t.id_layout, t.id_prefix,
					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 (mysql_num_rows($request) == 0) {
                fatal_lang_error('no_board', false);
            }
            $row = mysql_fetch_assoc($request);
            $context['id_prefix'] = $row['id_prefix'];
            $context['first_is_sticky'] = (int) $row['id_layout'] & 0x80;
            $context['first_has_layout'] = (int) $row['id_layout'] & 0x7f;
            $context['message_locked'] = (int) $row['locked'];
            $context['can_lock_message'] = allowedTo('moderate_board') || allowedTo('moderate_forum');
            $attachment_stuff = array($row);
            while ($row2 = mysql_fetch_assoc($request)) {
                $attachment_stuff[] = $row2;
            }
            mysql_free_result($request);
            if ($row['locked'] && !(allowedTo('moderate_board') || allowedTo('moderate_forum'))) {
                fatal_lang_error('modify_message_locked', false);
            }
            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 = smf_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 = mysql_fetch_assoc($request)) {
                    if ($row['filesize'] <= 0) {
                        continue;
                    }
                    $context['current_attachments'][] = array('name' => htmlspecialchars($row['filename']), 'id' => $row['id_attach'], 'approved' => $row['approved']);
                }
                mysql_free_result($request);
            }
            // Allow moderators to change names....
            if (allowedTo('moderate_forum') && !empty($topic)) {
                $request = smf_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 = mysql_fetch_assoc($request);
                mysql_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 = smf_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, m.locked,
				IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
				a.approved AS attachment_approved, t.id_member_started AS id_member_poster, t.id_prefix, t.id_layout,
				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 (mysql_num_rows($request) == 0) {
            fatal_lang_error('no_board', false);
        }
        $row = mysql_fetch_assoc($request);
        $attachment_stuff = array($row);
        while ($row2 = mysql_fetch_assoc($request)) {
            $attachment_stuff[] = $row2;
        }
        mysql_free_result($request);
        if ($row['locked'] && !(allowedTo('moderate_board') || allowedTo('moderate_forum'))) {
            fatal_lang_error('modify_message_locked', false);
        }
        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'];
        $context['id_prefix'] = $row['id_prefix'];
        $context['first_is_sticky'] = (int) $row['id_layout'] & 0x80;
        $context['first_has_layout'] = (int) $row['id_layout'] & 0x7f;
        $context['message_locked'] = (int) $row['locked'];
        $context['can_lock_message'] = allowedTo('moderate_board') || allowedTo('moderate_forum');
    } else {
        if ($modSettings['tags_active']) {
            $context['tagging_ui'] = '
		<dt><b>' . $txt['smftags_topic'] . '</b></dt>
		<dd>
			<input type="text" name="tags"' . ' tabindex="' . $context['tabindex']++ . '" size="80" maxlength="80" />
			<br /><span class="smalltext">' . $txt['smftags_seperate'] . '</span>
		</dd>';
        }
        // By default....
        $context['use_smileys'] = true;
        $context['icon'] = 'xx';
        $context['id_prefix'] = 0;
        $context['first_is_sticky'] = $context['first_has_layout'] = 0;
        if (!$context['make_event']) {
            $request = smf_db_query('SELECT b.allow_topics, b.automerge FROM {db_prefix}boards AS b WHERE b.id_board = {int:board}', array('board' => $board));
            list($allow, $automerge) = mysql_fetch_row($request);
            mysql_free_result($request);
            if ($allow == 0) {
                fatal_lang_error('no_board', false);
            }
            $context['can_merge_with_last'] = $automerge > 0;
        }
        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 = smf_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 (mysql_num_rows($request) == 0) {
                fatal_lang_error('quoted_post_deleted', false);
            }
            list($form_subject, $mname, $mdate, $form_message) = mysql_fetch_row($request);
            mysql_free_result($request);
            // Add 'Re: ' to the front of the quoted subject.
            if (trim($context['response_prefix']) != '' && commonAPI::strpos($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the message and subject.
            censorText($form_message);
            parse_bbc_stage2($form_message, 0, true);
            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);
                //$form_message = preg_replace(array('~\n?\[quote.*?\].*\[/quote\]\n?~is', '~^\n~', '~\[/quote\]~'), '', $form_message);
                //$form_message = preg_replace(array('~\n?\[quote.*?\].+\[/quote\]\n?~is', '~^\n~', '~\[/quote\]~'), '', $form_message);
                /*$pattern = "/\[quote(.*?)\](((?R)|.)*?)\[\/quote\]/is";
                		preg_match_all($pattern, $form_message, $matches, PREG_SET_ORDER);
                		foreach ($matches as $match) {
                			$block = preg_replace(array('~\[quote(.*?)\](((?R)|.)*?)\[\/quote\]~is', '~^\n~', '~\[/quote\]~'), '', $match[2], -1, $count);
                			$form_message = str_replace($match[2], $block, $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]';
            $context['quoted_id'] = intval($_REQUEST['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 != '' && commonAPI::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 = smf_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) = mysql_fetch_row($request);
            mysql_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>');
    }
    // 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 . '/lib/Subs-Editor.php';
    // Now create the editor.
    $context['can_save_draft'] = !$context['user']['is_guest'] && $context['have_drafts'] && !empty($options['use_drafts']) && allowedTo('drafts_allow');
    $context['can_autosave_draft'] = $context['can_save_draft'] && !empty($modSettings['enableAutoSaveDrafts']) && allowedTo('drafts_autosave_allow');
    // Grab the draft id early; this way even if we come from, say, auto save into 'num replies has changed', we keep the id to kill it later, but we don't trash the contents we have in $_POST already
    if (!empty($_REQUEST['draft_id'])) {
        $_REQUEST['draft_id'] = (int) $_REQUEST['draft_id'];
        $context['draft_id'] = $_REQUEST['draft_id'];
    }
    $msgid = isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0;
    if (!empty($_REQUEST['draft_id']) && !empty($user_info['id']) && $context['can_save_draft'] && empty($_POST['subject']) && empty($_POST['message']) || !empty($user_info['id']) && $context['can_save_draft'] && 0 != $msgid && empty($_POST['message'])) {
        getDraft($user_info['id'], $board, $topic, $msgid);
    } else {
        $context['draft_locked'] = $context['locked'];
    }
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'rows' => '10', 'height' => (isset($options['editor_height']) && $options['editor_height'] > 150 && $options['editor_height'] < 800 ? $options['editor_height'] : 250) . 'px', '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;
    $context['can_stick_firstpost'] = $context['is_first_post'] && allowedTo('post_sticky');
    if ($context['is_first_post']) {
        getPrefixSelector($board, !empty($context['id_prefix']) ? $context['id_prefix'] : 0);
    }
    // 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 . '/lib/Subs-Editor.php';
        $verificationOptions = array('id' => 'post', 'skip_template' => true);
        $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 (!isset($_REQUEST['xml'])) {
        EoS_Smarty::loadTemplate('post/main');
    }
}
Beispiel #4
0
function validatePassword($password, $username, $restrict_in = array())
{
    global $modSettings, $smcFunc;
    // Perform basic requirements first.
    if (commonAPI::strlen($password) < (empty($modSettings['password_strength']) ? 4 : 8)) {
        return 'short';
    }
    // Is this enough?
    if (empty($modSettings['password_strength'])) {
        return null;
    }
    // Otherwise, perform the medium strength test - checking if password appears in the restricted string.
    if (preg_match('~\\b' . preg_quote($password, '~') . '\\b~', implode(' ', $restrict_in)) != 0) {
        return 'restricted_words';
    } elseif (commonAPI::strpos($password, $username) !== false) {
        return 'restricted_words';
    }
    // !!! If pspell is available, use it on the word, and return restricted_words if it doesn't give "bad spelling"?
    // If just medium, we're done.
    if ($modSettings['password_strength'] == 1) {
        return null;
    }
    // Otherwise, hard test next, check for numbers and letters, uppercase too.
    $good = preg_match('~(\\D\\d|\\d\\D)~', $password) != 0;
    $good &= commonAPI::strtolower($password) != $password;
    return $good ? null : 'chars';
}
Beispiel #5
0
function ReportMessage()
{
    global $txt, $context, $scripturl, $sourcedir;
    global $user_info, $language, $modSettings, $smcFunc;
    // Check that this feature is even enabled!
    if (empty($modSettings['enableReportPM']) || empty($_REQUEST['pmsg'])) {
        fatal_lang_error('no_access', false);
    }
    $pmsg = (int) $_REQUEST['pmsg'];
    if (!isAccessiblePM($pmsg, 'inbox')) {
        fatal_lang_error('no_access', false);
    }
    $context['pm_id'] = $pmsg;
    $context['page_title'] = $txt['pm_report_title'];
    // If we're here, just send the user to the template, with a few useful context bits.
    if (!isset($_POST['report'])) {
        EoS_Smarty::loadTemplate('pm/base');
        EoS_Smarty::getConfigInstance()->registerHookTemplate('pm_content_area', 'pm/report');
        // !!! I don't like being able to pick who to send it to.  Favoritism, etc. sucks.
        // Now, get all the administrators.
        $request = smf_db_query('
			SELECT id_member, real_name
			FROM {db_prefix}members
			WHERE id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0
			ORDER BY real_name', array('admin_group' => 1));
        $context['admins'] = array();
        while ($row = mysql_fetch_assoc($request)) {
            $context['admins'][$row['id_member']] = $row['real_name'];
        }
        mysql_free_result($request);
        // How many admins in total?
        $context['admin_count'] = count($context['admins']);
    } else {
        // Check the session before proceeding any further!
        checkSession('post');
        // First, pull out the message contents, and verify it actually went to them!
        $request = smf_db_query('
			SELECT pm.subject, pm.body, pm.msgtime, pm.id_member_from, IFNULL(m.real_name, pm.from_name) AS sender_name
			FROM {db_prefix}personal_messages AS pm
				INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)
				LEFT JOIN {db_prefix}members AS m ON (m.id_member = pm.id_member_from)
			WHERE pm.id_pm = {int:id_pm}
				AND pmr.id_member = {int:current_member}
				AND pmr.deleted = {int:not_deleted}
			LIMIT 1', array('current_member' => $user_info['id'], 'id_pm' => $context['pm_id'], 'not_deleted' => 0));
        // Can only be a hacker here!
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('no_access', false);
        }
        list($subject, $body, $time, $memberFromID, $memberFromName) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Remove the line breaks...
        $body = preg_replace('~<br ?/?' . '>~i', "\n", $body);
        // Get any other recipients of the email.
        $request = smf_db_query('
			SELECT mem_to.id_member AS id_member_to, mem_to.real_name AS to_name, pmr.bcc
			FROM {db_prefix}pm_recipients AS pmr
				LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member)
			WHERE pmr.id_pm = {int:id_pm}
				AND pmr.id_member != {int:current_member}', array('current_member' => $user_info['id'], 'id_pm' => $context['pm_id']));
        $recipients = array();
        $hidden_recipients = 0;
        while ($row = mysql_fetch_assoc($request)) {
            // If it's hidden still don't reveal their names - privacy after all ;)
            if ($row['bcc']) {
                $hidden_recipients++;
            } else {
                $recipients[] = '[url=' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . ']' . $row['to_name'] . '[/url]';
            }
        }
        mysql_free_result($request);
        if ($hidden_recipients) {
            $recipients[] = sprintf($txt['pm_report_pm_hidden'], $hidden_recipients);
        }
        // Now let's get out and loop through the admins.
        $request = smf_db_query('
			SELECT id_member, real_name, lngfile
			FROM {db_prefix}members
			WHERE (id_group = {int:admin_id} OR FIND_IN_SET({int:admin_id}, additional_groups) != 0)
				' . (empty($_POST['ID_ADMIN']) ? '' : 'AND id_member = {int:specific_admin}') . '
			ORDER BY lngfile', array('admin_id' => 1, 'specific_admin' => isset($_POST['ID_ADMIN']) ? (int) $_POST['ID_ADMIN'] : 0));
        // Maybe we shouldn't advertise this?
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('no_access', false);
        }
        $memberFromName = un_htmlspecialchars($memberFromName);
        // Prepare the message storage array.
        $messagesToSend = array();
        // Loop through each admin, and add them to the right language pile...
        while ($row = mysql_fetch_assoc($request)) {
            // Need to send in the correct language!
            $cur_language = empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'];
            if (!isset($messagesToSend[$cur_language])) {
                loadLanguage('PersonalMessage', $cur_language, false);
                // Make the body.
                $report_body = str_replace(array('{REPORTER}', '{SENDER}'), array(un_htmlspecialchars($user_info['name']), $memberFromName), $txt['pm_report_pm_user_sent']);
                $report_body .= "\n" . '[b]' . $_POST['reason'] . '[/b]' . "\n\n";
                if (!empty($recipients)) {
                    $report_body .= $txt['pm_report_pm_other_recipients'] . ' ' . implode(', ', $recipients) . "\n\n";
                }
                $report_body .= $txt['pm_report_pm_unedited_below'] . "\n" . '[quote author=' . (empty($memberFromID) ? '&quot;' . $memberFromName . '&quot;' : $memberFromName . ' link=action=profile;u=' . $memberFromID . ' date=' . $time) . ']' . "\n" . un_htmlspecialchars($body) . '[/quote]';
                // Plonk it in the array ;)
                $messagesToSend[$cur_language] = array('subject' => (commonAPI::strpos($subject, $txt['pm_report_pm_subject']) === false ? $txt['pm_report_pm_subject'] : '') . un_htmlspecialchars($subject), 'body' => $report_body, 'recipients' => array('to' => array(), 'bcc' => array()));
            }
            // Add them to the list.
            $messagesToSend[$cur_language]['recipients']['to'][$row['id_member']] = $row['id_member'];
        }
        mysql_free_result($request);
        // Send a different email for each language.
        foreach ($messagesToSend as $lang => $message) {
            sendpm($message['recipients'], $message['subject'], $message['body']);
        }
        // Give the user their own language back!
        if (!empty($modSettings['userLanguage'])) {
            loadLanguage('PersonalMessage', '', false);
        }
        EoS_Smarty::loadTemplate('pm/base');
        EoS_Smarty::getConfigInstance()->registerHookTemplate('pm_content_area', 'pm/report_done');
    }
}