コード例 #1
0
ファイル: Xml.controller.php プロジェクト: KeiroD/Elkarte
 /**
  * Get a list of boards and categories used for the jumpto dropdown.
  */
 public function action_jumpto()
 {
     global $context;
     // Find the boards/categories they can see.
     require_once SUBSDIR . '/Boards.subs.php';
     $boardListOptions = array('selected_board' => isset($context['current_board']) ? $context['current_board'] : 0);
     $context += getBoardList($boardListOptions);
     // Make the board safe for display.
     foreach ($context['categories'] as $id_cat => $cat) {
         $context['categories'][$id_cat]['name'] = un_htmlspecialchars(strip_tags($cat['name']));
         foreach ($cat['boards'] as $id_board => $board) {
             $context['categories'][$id_cat]['boards'][$id_board]['name'] = un_htmlspecialchars(strip_tags($board['name']));
         }
     }
     $context['sub_template'] = 'jump_to';
 }
コード例 #2
0
ファイル: Xml.php プロジェクト: abdulhadikaryana/kebudayaan
function GetJumpTo()
{
    global $user_info, $context, $smcFunc, $sourcedir;
    // Find the boards/cateogories they can see.
    require_once $sourcedir . '/Subs-MessageIndex.php';
    $boardListOptions = array('use_permissions' => true, 'selected_board' => isset($context['current_board']) ? $context['current_board'] : 0);
    $context['jump_to'] = getBoardList($boardListOptions);
    // Make the board safe for display.
    foreach ($context['jump_to'] as $id_cat => $cat) {
        $context['jump_to'][$id_cat]['name'] = un_htmlspecialchars(strip_tags($cat['name']));
        foreach ($cat['boards'] as $id_board => $board) {
            $context['jump_to'][$id_cat]['boards'][$id_board]['name'] = un_htmlspecialchars(strip_tags($board['name']));
        }
    }
    $context['sub_template'] = 'jump_to';
}
コード例 #3
0
 public static function integrate_general_mod_settings(&$config_vars)
 {
     global $txt, $modSettings;
     loadLanguage('TwitterPoster');
     if (empty($modSettings['twitter_new_topic'])) {
         $modSettings['twitter_new_topic'] = $txt['twitter_new_topic_default'];
     }
     $config_vars[] = array('title', 'twitter_configs');
     $config_vars[] = array('text', 'consumer_key');
     $config_vars[] = array('text', 'consumer_secret');
     $config_vars[] = array('text', 'oauth_token');
     $config_vars[] = array('text', 'oauth_token_secret');
     $config_vars[] = array('large_text', 'twitter_new_topic', 'subtext' => $txt['twitter_new_topic_desc']);
     require_once SUBSDIR . '/Boards.subs.php';
     $boardListOpt = array('access' => '-1', 'override_permissions' => true, 'not_redirection' => true, 'ignore' => !empty($modSettings['recycle_enable']) ? array($modSettings['recycle_board']) : null);
     $boards_structure = getBoardList($boardListOpt);
     $select = array();
     foreach ($boards_structure['categories'] as $category) {
         if (empty($category['boards'])) {
             continue;
         }
         $select_tmp = array();
         foreach ($category['boards'] as $board) {
             if ($board['allow']) {
                 $select_tmp['b_' . $board['id']] = ($board['child_level'] > 0 ? str_repeat('=', $board['child_level']) . '> ' : '') . $board['name'];
             }
         }
         if (!empty($select_tmp)) {
             $select['c1_' . $category['id']] = '----------';
             $select['c2_' . $category['id']] = $category['name'];
             $select['c3_' . $category['id']] = '----------';
             $select += $select_tmp;
         }
     }
     if (empty($modSettings['twitter_select_boards'])) {
         $modSettings['twitter_select_boards'] = serialize(array());
     } elseif (!is_array($modSettings['twitter_select_boards'])) {
         $tmp = unserialize($modSettings['twitter_select_boards']);
         $tmpr = array();
         foreach ($tmp as $b) {
             $tmpr[] = 'b_' . $b;
         }
         $modSettings['twitter_select_boards'] = serialize($tmpr);
     }
     $config_vars[] = array('select', 'twitter_select_boards', $select, 'multiple' => true);
 }
コード例 #4
0
 /**
  * Browse all the reported posts...
  * @todo this needs to be given its own file?
  */
 public function action_reportedPosts()
 {
     global $txt, $context, $scripturl, $user_info;
     loadTemplate('ModerationCenter');
     require_once SUBSDIR . '/Moderation.subs.php';
     // Put the open and closed options into tabs, because we can...
     $context[$context['moderation_menu_name']]['tab_data'] = array('title' => $txt['mc_reported_posts'], 'help' => '', 'description' => $txt['mc_reported_posts_desc']);
     // This comes under the umbrella of moderating posts.
     if ($user_info['mod_cache']['bq'] == '0=1') {
         isAllowedTo('moderate_forum');
     }
     // Are they wanting to view a particular report?
     if (!empty($_REQUEST['report'])) {
         return $this->action_modReport();
     }
     // Set up the comforting bits...
     $context['page_title'] = $txt['mc_reported_posts'];
     $context['sub_template'] = 'reported_posts';
     // Are we viewing open or closed reports?
     $context['view_closed'] = isset($_GET['sa']) && $_GET['sa'] == 'closed' ? 1 : 0;
     // Are we doing any work?
     if ((isset($_GET['ignore']) || isset($_GET['close'])) && isset($_GET['rid'])) {
         checkSession('get');
         $_GET['rid'] = (int) $_GET['rid'];
         // Update the report...
         if (isset($_GET['ignore'])) {
             updateReportsStatus((int) $_GET['rid'], 'ignore', (int) $_GET['ignore']);
         } elseif (isset($_GET['close'])) {
             updateReportsStatus((int) $_GET['rid'], 'close', (int) $_GET['close']);
         }
         // Time to update.
         updateSettings(array('last_mod_report_action' => time()));
         recountOpenReports();
     } elseif (isset($_POST['close']) && isset($_POST['close_selected'])) {
         checkSession('post');
         // All the ones to update...
         $toClose = array();
         foreach ($_POST['close'] as $rid) {
             $toClose[] = (int) $rid;
         }
         if (!empty($toClose)) {
             updateReportsStatus($toClose, 'close', 1);
             // Time to update.
             updateSettings(array('last_mod_report_action' => time()));
             recountOpenReports();
         }
     }
     // How many entries are we viewing?
     $context['total_reports'] = totalReports($context['view_closed']);
     // So, that means we can page index, yes?
     $context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=reports' . ($context['view_closed'] ? ';sa=closed' : ''), $_GET['start'], $context['total_reports'], 10);
     $context['start'] = $_GET['start'];
     // By George, that means we in a position to get the reports, golly good.
     $context['reports'] = getModReports($context['view_closed'], $context['start'], 10);
     $report_ids = array_keys($context['reports']);
     $report_boards_ids = array();
     foreach ($context['reports'] as $row) {
         $context['reports'][$row['id_report']] = array('board' => $row['id_board'], 'id' => $row['id_report'], 'topic_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'report_href' => $scripturl . '?action=moderate;area=reports;report=' . $row['id_report'], 'author' => array('id' => $row['id_author'], 'name' => $row['author_name'], 'link' => $row['id_author'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_author'] . '">' . $row['author_name'] . '</a>' : $row['author_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_author']), 'comments' => array(), 'time_started' => standardTime($row['time_started']), 'last_updated' => standardTime($row['time_updated']), 'subject' => $row['subject'], 'body' => parse_bbc($row['body']), 'num_reports' => $row['num_reports'], 'closed' => $row['closed'], 'ignore' => $row['ignore_all'], 'buttons' => array('quickmod_check' => array('checkbox' => !$context['view_closed'], 'name' => 'close', 'value' => $row['id_report']), 'details' => array('href' => $scripturl . '?action=moderate;area=reports;report=' . $row['id_report'], 'text' => $txt['mc_reportedp_details']), 'ignore' => array('href' => $scripturl . '?action=moderate;area=reports' . ($context['view_closed'] ? ';sa=closed' : '') . ';ignore=' . (int) (!$row['ignore_all']) . ';rid=' . $row['id_report'] . ';start=' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'text' => $row['ignore_all'] ? $txt['mc_reportedp_unignore'] : $txt['mc_reportedp_ignore'], 'custom' => $row['ignore_all'] ? '' : 'onclick="return confirm(' . JavaScriptEscape($txt['mc_reportedp_ignore_confirm']) . ');"'), 'close' => array('href' => $scripturl . '?action=moderate;area=reports' . ($context['view_closed'] ? ';sa=closed' : '') . ';close=' . (int) (!$row['closed']) . ';rid=' . $row['id_report'] . ';start=' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'text' => $context['view_closed'] ? $txt['mc_reportedp_open'] : $txt['mc_reportedp_close'])));
         $report_boards_ids[] = $row['id_board'];
     }
     // Get the names of boards these topics are in.
     if (!empty($report_ids)) {
         require_once SUBSDIR . '/Boards.subs.php';
         $board_names = getBoardList(array('included_boards' => $report_boards_ids), true);
         // Add the board name to the report array
         foreach ($context['reports'] as $id_report => $report) {
             if (!empty($board_names[$report['board']])) {
                 $context['reports'][$id_report]['board_name'] = $board_names[$report['board']]['board_name'];
             }
         }
     }
     // Now get all the people who reported it.
     if (!empty($report_ids)) {
         $comments = getReportsUserComments($report_ids);
         foreach ($comments as $id_rep => $rows) {
             foreach ($rows as $row) {
                 $context['reports'][$id_rep]['comments'][] = array('id' => $row['id_comment'], 'message' => $row['comment'], 'raw_time' => $row['time_sent'], 'time' => standardTime($row['time_sent']), 'html_time' => htmlTime($row['time_sent']), 'timestamp' => forum_time(true, $row['time_sent']), 'member' => array('id' => $row['id_member'], 'name' => empty($row['reporter']) ? $txt['guest'] : $row['reporter'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['reporter'] . '</a>' : (empty($row['reporter']) ? $txt['guest'] : $row['reporter']), 'href' => $row['id_member'] ? $scripturl . '?action=profile;u=' . $row['id_member'] : ''));
             }
         }
     }
 }
コード例 #5
0
ファイル: Search.php プロジェクト: chenhao6593/smf
function prepareSearchContext($reset = false)
{
    global $txt, $modSettings, $scripturl, $user_info, $sourcedir;
    global $memberContext, $context, $settings, $options, $messages_request;
    global $boards_can, $participants, $smcFunc;
    // Remember which message this is.  (ie. reply #83)
    static $counter = null;
    if ($counter == null || $reset) {
        $counter = $_REQUEST['start'] + 1;
    }
    // If the query returned false, bail.
    if ($messages_request == false) {
        return false;
    }
    // Start from the beginning...
    if ($reset) {
        return @$smcFunc['db_data_seek']($messages_request, 0);
    }
    // Attempt to get the next message.
    $message = $smcFunc['db_fetch_assoc']($messages_request);
    if (!$message) {
        return false;
    }
    // Can't have an empty subject can we?
    $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject'];
    $message['first_subject'] = $message['first_subject'] != '' ? $message['first_subject'] : $txt['no_subject'];
    $message['last_subject'] = $message['last_subject'] != '' ? $message['last_subject'] : $txt['no_subject'];
    // If it couldn't load, or the user was a guest.... someday may be done with a guest table.
    if (!loadMemberContext($message['id_member'])) {
        // Notice this information isn't used anywhere else.... *cough guest table cough*.
        $memberContext[$message['id_member']]['name'] = $message['poster_name'];
        $memberContext[$message['id_member']]['id'] = 0;
        $memberContext[$message['id_member']]['group'] = $txt['guest_title'];
        $memberContext[$message['id_member']]['link'] = $message['poster_name'];
        $memberContext[$message['id_member']]['email'] = $message['poster_email'];
    }
    $memberContext[$message['id_member']]['ip'] = $message['poster_ip'];
    // Do the censor thang...
    censorText($message['body']);
    censorText($message['subject']);
    censorText($message['first_subject']);
    censorText($message['last_subject']);
    // Shorten this message if necessary.
    if ($context['compact']) {
        // Set the number of characters before and after the searched keyword.
        $charLimit = 50;
        $message['body'] = strtr($message['body'], array("\n" => ' ', '<br />' => "\n"));
        $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']);
        $message['body'] = strip_tags(strtr($message['body'], array('</div>' => '<br />', '</li>' => '<br />')), '<br>');
        if ($smcFunc['strlen']($message['body']) > $charLimit) {
            if (empty($context['key_words'])) {
                $message['body'] = $smcFunc['substr']($message['body'], 0, $charLimit) . '<strong>...</strong>';
            } else {
                $matchString = '';
                $force_partial_word = false;
                foreach ($context['key_words'] as $keyword) {
                    $keyword = preg_replace_callback('~(&amp;#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'entity_fix__callback', strtr($keyword, array('\\\'' => '\'', '&' => '&amp;')));
                    if (preg_match('~[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]$~', $keyword) != 0 || preg_match('~^[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]~', $keyword) != 0) {
                        $force_partial_word = true;
                    }
                    $matchString .= strtr(preg_quote($keyword, '/'), array('\\*' => '.+?')) . '|';
                }
                $matchString = substr($matchString, 0, -1);
                $message['body'] = un_htmlspecialchars(strtr($message['body'], array('&nbsp;' => ' ', '<br />' => "\n", '&#91;' => '[', '&#93;' => ']', '&#58;' => ':', '&#64;' => '@')));
                if (empty($modSettings['search_method']) || $force_partial_word) {
                    preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?|^)(' . $matchString . ')(.{0,' . $charLimit . '}[\\s\\W]|[^\\s\\W]{' . $charLimit . '})/is' . ($context['utf8'] ? 'u' : ''), $message['body'], $matches);
                } else {
                    preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?[\\s\\W]|^)(' . $matchString . ')([\\s\\W].{0,' . $charLimit . '}[\\s\\W]|[\\s\\W][^\\s\\W]{' . $charLimit . '})/is' . ($context['utf8'] ? 'u' : ''), $message['body'], $matches);
                }
                $message['body'] = '';
                foreach ($matches[0] as $index => $match) {
                    $match = strtr($smcFunc['htmlspecialchars']($match, ENT_QUOTES), array("\n" => '&nbsp;'));
                    $message['body'] .= '<strong>......</strong>&nbsp;' . $match . '&nbsp;<strong>......</strong>';
                }
            }
            // Re-fix the international characters.
            $message['body'] = preg_replace_callback('~(&amp;#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'entity_fix__callback', $message['body']);
        }
    } else {
        // Run BBC interpreter on the message.
        $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']);
    }
    // Make sure we don't end up with a practically empty message body.
    $message['body'] = preg_replace('~^(?:&nbsp;)+$~', '', $message['body']);
    // Sadly, we need to check the icon ain't broke.
    if (empty($modSettings['messageIconChecks_disable'])) {
        if (!isset($context['icon_sources'][$message['first_icon']])) {
            $context['icon_sources'][$message['first_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $message['first_icon'] . '.gif') ? 'images_url' : 'default_images_url';
        }
        if (!isset($context['icon_sources'][$message['last_icon']])) {
            $context['icon_sources'][$message['last_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $message['last_icon'] . '.gif') ? 'images_url' : 'default_images_url';
        }
        if (!isset($context['icon_sources'][$message['icon']])) {
            $context['icon_sources'][$message['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $message['icon'] . '.gif') ? 'images_url' : 'default_images_url';
        }
    } else {
        if (!isset($context['icon_sources'][$message['first_icon']])) {
            $context['icon_sources'][$message['first_icon']] = 'images_url';
        }
        if (!isset($context['icon_sources'][$message['last_icon']])) {
            $context['icon_sources'][$message['last_icon']] = 'images_url';
        }
        if (!isset($context['icon_sources'][$message['icon']])) {
            $context['icon_sources'][$message['icon']] = 'images_url';
        }
    }
    // Do we have quote tag enabled?
    $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    $output = array_merge($context['topics'][$message['id_msg']], array('id' => $message['id_topic'], 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($message['is_sticky']), 'is_locked' => !empty($message['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $message['id_poll'] > 0, 'is_hot' => $message['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $message['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'posted_in' => !empty($participants[$message['id_topic']]), 'views' => $message['num_views'], 'replies' => $message['num_replies'], 'can_reply' => in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any']), 'can_quote' => (in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any'])) && $quote_enabled, 'can_mark_notify' => in_array($message['id_board'], $boards_can['mark_any_notify']) || in_array(0, $boards_can['mark_any_notify']) && !$context['user']['is_guest'], 'first_post' => array('id' => $message['first_msg'], 'time' => timeformat($message['first_poster_time']), 'timestamp' => forum_time(true, $message['first_poster_time']), 'subject' => $message['first_subject'], 'href' => $scripturl . '?topic=' . $message['id_topic'] . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . $message['id_topic'] . '.0">' . $message['first_subject'] . '</a>', 'icon' => $message['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$message['first_icon']]] . '/post/' . $message['first_icon'] . '.gif', 'member' => array('id' => $message['first_member_id'], 'name' => $message['first_member_name'], 'href' => !empty($message['first_member_id']) ? $scripturl . '?action=profile;u=' . $message['first_member_id'] : '', 'link' => !empty($message['first_member_id']) ? '<a href="' . $scripturl . '?action=profile;u=' . $message['first_member_id'] . '" title="' . $txt['profile_of'] . ' ' . $message['first_member_name'] . '">' . $message['first_member_name'] . '</a>' : $message['first_member_name'])), 'last_post' => array('id' => $message['last_msg'], 'time' => timeformat($message['last_poster_time']), 'timestamp' => forum_time(true, $message['last_poster_time']), 'subject' => $message['last_subject'], 'href' => $scripturl . '?topic=' . $message['id_topic'] . ($message['num_replies'] == 0 ? '.0' : '.msg' . $message['last_msg']) . '#msg' . $message['last_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $message['id_topic'] . ($message['num_replies'] == 0 ? '.0' : '.msg' . $message['last_msg']) . '#msg' . $message['last_msg'] . '">' . $message['last_subject'] . '</a>', 'icon' => $message['last_icon'], 'icon_url' => $settings[$context['icon_sources'][$message['last_icon']]] . '/post/' . $message['last_icon'] . '.gif', 'member' => array('id' => $message['last_member_id'], 'name' => $message['last_member_name'], 'href' => !empty($message['last_member_id']) ? $scripturl . '?action=profile;u=' . $message['last_member_id'] : '', 'link' => !empty($message['last_member_id']) ? '<a href="' . $scripturl . '?action=profile;u=' . $message['last_member_id'] . '" title="' . $txt['profile_of'] . ' ' . $message['last_member_name'] . '">' . $message['last_member_name'] . '</a>' : $message['last_member_name'])), 'board' => array('id' => $message['id_board'], 'name' => $message['board_name'], 'href' => $scripturl . '?board=' . $message['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $message['id_board'] . '.0">' . $message['board_name'] . '</a>'), 'category' => array('id' => $message['id_cat'], 'name' => $message['cat_name'], 'href' => $scripturl . '#c' . $message['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $message['id_cat'] . '">' . $message['cat_name'] . '</a>')));
    determineTopicClass($output);
    if ($output['posted_in']) {
        $output['class'] = 'my_' . $output['class'];
    }
    $body_highlighted = $message['body'];
    $subject_highlighted = $message['subject'];
    if (!empty($options['display_quick_mod'])) {
        $started = $output['first_post']['member']['id'] == $user_info['id'];
        $output['quick_mod'] = array('lock' => in_array(0, $boards_can['lock_any']) || in_array($output['board']['id'], $boards_can['lock_any']) || $started && (in_array(0, $boards_can['lock_own']) || in_array($output['board']['id'], $boards_can['lock_own'])), 'sticky' => (in_array(0, $boards_can['make_sticky']) || in_array($output['board']['id'], $boards_can['make_sticky'])) && !empty($modSettings['enableStickyTopics']), 'move' => in_array(0, $boards_can['move_any']) || in_array($output['board']['id'], $boards_can['move_any']) || $started && (in_array(0, $boards_can['move_own']) || in_array($output['board']['id'], $boards_can['move_own'])), 'remove' => in_array(0, $boards_can['remove_any']) || in_array($output['board']['id'], $boards_can['remove_any']) || $started && (in_array(0, $boards_can['remove_own']) || in_array($output['board']['id'], $boards_can['remove_own'])));
        $context['can_lock'] |= $output['quick_mod']['lock'];
        $context['can_sticky'] |= $output['quick_mod']['sticky'];
        $context['can_move'] |= $output['quick_mod']['move'];
        $context['can_remove'] |= $output['quick_mod']['remove'];
        $context['can_merge'] |= in_array($output['board']['id'], $boards_can['merge_any']);
        // If we've found a message we can move, and we don't already have it, load the destinations.
        if ($options['display_quick_mod'] == 1 && !isset($context['move_to_boards']) && $context['can_move']) {
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('use_permissions' => true, 'not_redirection' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']);
            $context['move_to_boards'] = getBoardList($boardListOptions);
        }
    }
    foreach ($context['key_words'] as $query) {
        // Fix the international characters in the keyword too.
        $query = strtr($smcFunc['htmlspecialchars']($query), array('\\\'' => '\''));
        $body_highlighted = preg_replace_callback('/((<[^>]*)|' . preg_quote(strtr($query, array('\'' => '&#039;')), '/') . ')/i' . ($context['utf8'] ? 'u' : ''), 'search_highlight__preg_callback', $body_highlighted);
        $subject_highlighted = preg_replace('/(' . preg_quote($query, '/') . ')/i' . ($context['utf8'] ? 'u' : ''), '<strong class="highlight">$1</strong>', $subject_highlighted);
    }
    $output['matches'][] = array('id' => $message['id_msg'], 'attachment' => loadAttachmentContext($message['id_msg']), 'alternate' => $counter % 2, 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => $settings[$context['icon_sources'][$message['icon']]] . '/post/' . $message['icon'] . '.gif', 'subject' => $message['subject'], 'subject_highlighted' => $subject_highlighted, 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'counter' => $counter, 'modified' => array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'name' => $message['modified_name']), 'body' => $message['body'], 'body_highlighted' => $body_highlighted, 'start' => 'msg' . $message['id_msg']);
    $counter++;
    return $output;
}
コード例 #6
0
ファイル: MessageIndex.php プロジェクト: norv/EosAlpha
function MessageIndex()
{
    global $txt, $scripturl, $board, $modSettings, $context;
    global $options, $settings, $board_info, $user_info, $smcFunc, $sourcedir;
    global $memberContext;
    // If this is a redirection board head off.
    if ($board_info['redirect']) {
        smf_db_query('
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1
			WHERE id_board = {int:current_board}', array('current_board' => $board));
        redirectexit($board_info['redirect']);
    }
    EoS_Smarty::loadTemplate('messageindex');
    fetchNewsItems($board, 0);
    $context['act_as_cat'] = $board_info['allow_topics'] ? false : true;
    $context['name'] = $board_info['name'];
    $context['description'] = $board_info['description'];
    // How many topics do we have in total?
    $board_info['total_topics'] = allowedTo('approve_posts') ? $board_info['num_topics'] + $board_info['unapproved_topics'] : $board_info['num_topics'] + $board_info['unapproved_user_topics'];
    // View all the topics, or just a few?
    $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    $context['messages_per_page'] = commonAPI::getMessagesPerPage();
    $maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['total_topics'] : $context['topics_per_page'];
    // Right, let's only index normal stuff!
    if (count($_GET) > 1) {
        $session_name = session_name();
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('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;
    }
    // If we can view unapproved messages and there are some build up a list.
    if (allowedTo('approve_posts') && ($board_info['unapproved_topics'] || $board_info['unapproved_posts'])) {
        $untopics = $board_info['unapproved_topics'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=topics;brd=' . $board . '">' . $board_info['unapproved_topics'] . '</a>' : 0;
        $unposts = $board_info['unapproved_posts'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=posts;brd=' . $board . '">' . ($board_info['unapproved_posts'] - $board_info['unapproved_topics']) . '</a>' : 0;
        $context['unapproved_posts_message'] = sprintf($txt['there_are_unapproved_topics'], $untopics, $unposts, $scripturl . '?action=moderate;area=postmod;sa=' . ($board_info['unapproved_topics'] ? 'topics' : 'posts') . ';brd=' . $board);
    }
    // Make sure the starting place makes sense and construct the page index.
    if (isset($_REQUEST['sort'])) {
        $context['page_index'] = constructPageIndex(URL::board($board_info['id'], $board_info['name'], '%1$d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), true), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    } else {
        //$context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
        $context['page_index'] = constructPageIndex(URL::board($board_info['id'], $board_info['name'], '%1$d', true), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    }
    $context['start'] =& $_REQUEST['start'];
    setcookie('smf_topicstart', intval($board) . '_' . $context['start'], time() + 86400, '/');
    // Set a canonical URL for this page.
    $context['canonical_url'] = URL::board($board, $board_info['name'], $context['start'], true);
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $context['topics_per_page']) : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $context['topics_per_page']) : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) * $context['topics_per_page'] : '', 'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0');
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) + 1);
    if (isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages']) {
        $maxindex = $modSettings['enableAllMessages'];
        $_REQUEST['start'] = 0;
    }
    // Build a list of the board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        //$context['linktree'][count($context['linktree']) - 1]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Mark current and parent boards as seen.
    if (!$user_info['is_guest']) {
        // We can't know they read it if we allow prefetches.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        smf_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'));
        if (!empty($board_info['parent_boards'])) {
            smf_db_query('
				UPDATE {db_prefix}log_boards
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
            // We've seen all these boards now!
            foreach ($board_info['parent_boards'] as $k => $dummy) {
                if (isset($_SESSION['topicseen_cache'][$k])) {
                    unset($_SESSION['topicseen_cache'][$k]);
                }
            }
        }
        if (isset($_SESSION['topicseen_cache'][$board])) {
            unset($_SESSION['topicseen_cache'][$board]);
        }
        $request = smf_db_query('
			SELECT sent
			FROM {db_prefix}log_notify
			WHERE id_board = {int:current_board}
				AND id_member = {int:current_member}
			LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id']));
        $context['is_marked_notify'] = mysql_num_rows($request) != 0;
        if ($context['is_marked_notify']) {
            list($sent) = mysql_fetch_row($request);
            if (!empty($sent)) {
                smf_db_query('
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_sent}
					WHERE id_board = {int:current_board}
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_sent' => 0));
            }
        }
        mysql_free_result($request);
    } else {
        $context['is_marked_notify'] = false;
    }
    // 'Print' the header and board info.
    $context['page_number'] = isset($_REQUEST['start']) ? $_REQUEST['start'] / $context['topics_per_page'] : 0;
    $context['page_title'] = strip_tags($board_info['name'] . ((int) $context['page_number'] > 0 ? ' - ' . $txt['page'] . ' ' . ($context['page_number'] + 1) : ''));
    $context['meta_page_description'] = !empty($board_info['description']) ? $board_info['description'] : $context['page_title'];
    // Set the variables up for the template.
    $context['can_mark_notify'] = allowedTo('mark_notify') && !$user_info['is_guest'];
    $context['can_post_new'] = allowedTo('post_new') || $modSettings['postmod_active'] && allowedTo('post_unapproved_topics');
    $context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post') && $context['can_post_new'];
    $context['can_moderate_forum'] = allowedTo('moderate_forum');
    $context['can_approve_posts'] = allowedTo('approve_posts');
    require_once $sourcedir . '/lib/Subs-BoardIndex.php';
    $boardIndexOptions = array('include_categories' => false, 'base_level' => $board_info['child_level'] + 1, 'parent_id' => $board_info['id'], 'set_latest_post' => false, 'countChildPosts' => !empty($modSettings['countChildPosts']));
    $context['boards'] = getBoardIndex($boardIndexOptions);
    // Nosey, nosey - who's viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        $request = smf_db_query('
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online, mem.id_group, mem.id_post_group
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_member_group' => 0, 'in_url_string' => 's:5:"board";i:' . $board . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = mysql_fetch_assoc($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            $class = 'member group_' . (empty($row['id_group']) ? $row['id_post_group'] : $row['id_group']) . (in_array($row['id_member'], $user_info['buddies']) ? ' buddy' : '');
            $href = URL::user($row['id_member'], $row['real_name']);
            if ($row['id_member'] == $user_info['id']) {
                $link = '<strong>' . $txt['you'] . '</strong>';
            } else {
                $link = '<a onclick="getMcard(' . $row['id_member'] . ');return(false);" class="' . $class . '" href="' . $href . '">' . $row['real_name'] . '</a>';
            }
            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' => $href, 'link' => $link, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        $context['view_num_guests'] = mysql_num_rows($request) - count($context['view_members']);
        mysql_free_result($request);
        // Put them in "last clicked" order.
        krsort($context['view_members_list']);
        krsort($context['view_members']);
        $context['full_members_viewing_list'] = empty($context['view_members_list']) ? '0 ' . $txt['members'] : implode(', ', $context['view_members_list']) . ((empty($context['view_num_hidden']) or $context['can_moderate_forum']) ? '' : ' (+ ' . $context['view_num_hidden'] . ' ' . $txt['hidden'] . ')');
    }
    // Default sort methods.
    $sort_methods = array('subject' => 'mf.subject', 'starter' => 'IFNULL(memf.real_name, mf.poster_name)', 'last_poster' => 'IFNULL(meml.real_name, ml.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg');
    // They didn't pick one, default to by last post descending.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 'id_last_msg';
        $ascending = isset($_REQUEST['asc']);
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    // Calculate the fastest way to get the topics.
    $start = (int) $_REQUEST['start'];
    if ($start > ($board_info['total_topics'] - 1) / 2) {
        $ascending = !$ascending;
        $fake_ascending = true;
        $maxindex = $board_info['total_topics'] < $start + $maxindex + 1 ? $board_info['total_topics'] - $start : $maxindex;
        $start = $board_info['total_topics'] < $start + $maxindex + 1 ? 0 : $board_info['total_topics'] - $start - $maxindex;
    } else {
        $fake_ascending = false;
    }
    $topic_ids = array();
    $context['topics'] = array();
    $prefixid = isset($_REQUEST['prefix']) ? (int) $_REQUEST['prefix'] : 0;
    $prefixfilter = !empty($prefixid) ? 't.id_prefix = {int:id_prefix} AND ' : '';
    // Sequential pages are often not optimized, so we add an additional query.
    $pre_query = $start > 0;
    if ($pre_query && $maxindex > 0) {
        $request = smf_db_query('
			SELECT t.id_topic
			FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? '
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? '
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? '
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? '
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . '
			WHERE ' . $prefixfilter . ' t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . '
			LIMIT {int:start}, {int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_guest' => 0, 'start' => $start, 'maxindex' => $maxindex, 'id_prefix' => $prefixid));
        $topic_ids = array();
        while ($row = mysql_fetch_assoc($request)) {
            $topic_ids[] = $row['id_topic'];
        }
    }
    // Grab the appropriate topic information...
    if (!$pre_query || !empty($topic_ids)) {
        // For search engine effectiveness we'll link guests differently.
        $context['pageindex_multiplier'] = commonAPI::getMessagesPerPage();
        $result = smf_db_query('
			SELECT 
				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
				' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
				t.id_last_msg, t.approved, t.unapproved_posts, t.id_prefix, ml.poster_time AS last_poster_time,
				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
				ml.poster_name AS last_member_name, ml.id_member AS last_id_member,
				IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
				mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon,
				mf.poster_name AS first_member_name, mf.id_member AS first_id_member,
				IFNULL(memf.real_name, mf.poster_name) AS first_display_name,
				ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys,
				p.name AS prefix_name
			FROM {db_prefix}topics AS t	
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : '
				LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_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})') . '
				LEFT JOIN {db_prefix}prefixes AS p ON p.id_prefix = t.id_prefix 
			WHERE ' . $prefixfilter . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : 't.id_board = {int:current_board}') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . '
			LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'is_approved' => 1, 'find_set_topics' => implode(',', $topic_ids), 'start' => $start, 'maxindex' => $maxindex, 'id_prefix' => $prefixid));
        // Begin 'printing' the message index for current board.
        $first_posters = array();
        while ($row = mysql_fetch_assoc($result)) {
            if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') {
                continue;
            }
            if (!$pre_query) {
                $topic_ids[] = $row['id_topic'];
            }
            $row['first_body'] = '';
            $row['last_body'] = '';
            censorText($row['first_subject']);
            if ($row['id_first_msg'] == $row['id_last_msg']) {
                $row['last_subject'] = $row['first_subject'];
            } else {
                censorText($row['last_subject']);
            }
            // Decide how many pages the topic should have.
            if ($row['num_replies'] + 1 > $context['messages_per_page']) {
                $pages = '&nbsp;&nbsp;';
                // We can't pass start by reference.
                $start = -1;
                $pages .= constructPageIndex(URL::topic($row['id_topic'], $row['first_subject'], '%1$d'), $start, $row['num_replies'] + 1, $context['messages_per_page'], true, false, true);
                // If we can use all, show all.
                if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages']) {
                    $pages .= '<a class="navPages compact" href="' . URL::topic($row['id_topic'], $row['first_subject'], 0) . ';all">' . $txt['show_all'] . '</a>';
                }
                $pages .= ' ';
            } else {
                $pages = '';
            }
            $first_posters[$row['id_topic']] = $row['first_id_member'];
            // 'Print' the topic info.
            $f_post_mem_href = !empty($row['first_id_member']) ? URL::user($row['first_id_member'], $row['first_display_name']) : '';
            $t_href = URL::topic($row['id_topic'], $row['first_subject'], 0);
            $l_post_mem_href = !empty($row['last_id_member']) ? URL::user($row['last_id_member'], $row['last_display_name']) : '';
            $l_post_msg_href = URL::topic($row['id_topic'], $row['last_subject'], $user_info['is_guest'] ? !empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier'] : 0, $user_info['is_guest'] ? true : false, $user_info['is_guest'] ? '' : '.msg' . $row['id_last_msg'], $user_info['is_guest'] ? '#msg' . $row['id_last_msg'] : '#new');
            $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_display_name'], 'id' => $row['first_id_member'], 'href' => $f_post_mem_href, 'link' => !empty($row['first_id_member']) ? '<a onclick="getMcard(' . $row['first_id_member'] . ', $(this));return(false);" href="' . $f_post_mem_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '">' . $row['first_display_name'] . '</a>' : $row['first_display_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'href' => $t_href, 'link' => '<a href="' . $t_href . '">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => $l_post_mem_href, 'link' => !empty($row['last_id_member']) ? '<a onclick="getMcard(' . $row['last_id_member'] . ', $(this));return(false);" href="' . $l_post_mem_href . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'icon' => $row['last_icon'], 'icon_url' => getPostIcon($row['last_icon']), 'href' => $l_post_msg_href, 'link' => '<a href="' . $l_post_msg_href . ($row['num_replies'] == 0 ? '' : ' rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'prefix' => $row['prefix_name'] ? '<a href="' . $scripturl . '?board=' . $board . ';prefix=' . $row['id_prefix'] . '" class="prefix">' . (html_entity_decode($row['prefix_name']) . '</a>') : '', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_poster_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'subject' => $row['first_subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['new_from'], '#new'), 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts']);
            determineTopicClass($context['topics'][$row['id_topic']]);
            if (!empty($context['topics'][$row['id_topic']]['prefix'])) {
                $context['topics'][$row['id_topic']]['prefix'] .= '&nbsp;';
            }
        }
        if (!empty($settings['show_user_images']) && empty($options['show_no_avatars'])) {
            $all_posters = array_unique($first_posters);
            loadMemberData($all_posters);
            foreach ($context['topics'] as &$_topic) {
                if (!isset($memberContext[$first_posters[$_topic['id']]])) {
                    loadMemberContext($first_posters[$_topic['id']], true);
                }
                if (isset($memberContext[$first_posters[$_topic['id']]]['avatar']['image'])) {
                    $_topic['first_post']['member']['avatar'] =& $memberContext[$first_posters[$_topic['id']]]['avatar']['image'];
                }
            }
        }
        mysql_free_result($result);
        // Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...)
        if ($fake_ascending) {
            $context['topics'] = array_reverse($context['topics'], true);
        }
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids)) {
            $result = smf_db_query('
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_topic IN ({array_int:topic_list})
					AND id_member = {int:current_member}
				GROUP BY id_topic
				LIMIT ' . count($topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $topic_ids));
            while ($row = mysql_fetch_assoc($result)) {
                if ($context['topics'][$row['id_topic']]['first_post']['member']['id'] != $user_info['id']) {
                    $context['topics'][$row['id_topic']]['is_posted_in'] = true;
                }
            }
            mysql_free_result($result);
        }
    }
    $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']);
    // Is Quick Moderation active/needed?
    if (!empty($options['display_quick_mod']) && !empty($context['topics'])) {
        $context['can_lock'] = allowedTo('lock_any');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['can_move'] = allowedTo('move_any');
        $context['can_remove'] = allowedTo('remove_any');
        $context['can_merge'] = allowedTo('merge_any');
        // Ignore approving own topics as it's unlikely to come up...
        $context['can_approve'] = $modSettings['postmod_active'] && allowedTo('approve_posts') && !empty($board_info['unapproved_topics']);
        // Can we restore topics?
        $context['can_restore'] = allowedTo('move_any') && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board;
        // Set permissions for all the topics.
        foreach ($context['topics'] as $t => $topic) {
            $started = $topic['first_post']['member']['id'] == $user_info['id'];
            $context['topics'][$t]['quick_mod'] = array('lock' => allowedTo('lock_any') || $started && allowedTo('lock_own'), 'sticky' => allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']), 'move' => allowedTo('move_any') || $started && allowedTo('move_own'), 'modify' => allowedTo('modify_any') || $started && allowedTo('modify_own'), 'remove' => allowedTo('remove_any') || $started && allowedTo('remove_own'), 'approve' => $context['can_approve'] && $topic['unapproved_posts']);
            $context['can_lock'] |= $started && allowedTo('lock_own');
            $context['can_move'] |= $started && allowedTo('move_own');
            $context['can_remove'] |= $started && allowedTo('remove_own');
        }
        // Find the boards/cateogories they can move their topic to.
        if ($options['display_quick_mod'] && $context['can_move'] && !empty($context['topics'])) {
            require_once $sourcedir . '/lib/Subs-MessageIndex.php';
            $boardListOptions = array('excluded_boards' => array($board), 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']);
            $context['move_to_boards'] = getBoardList($boardListOptions);
            // Make the boards safe for display.
            foreach ($context['move_to_boards'] as $id_cat => $cat) {
                $context['move_to_boards'][$id_cat]['name'] = strip_tags($cat['name']);
                foreach ($cat['boards'] as $id_board => $board) {
                    $context['move_to_boards'][$id_cat]['boards'][$id_board]['name'] = strip_tags($board['name']);
                }
            }
            // With no other boards to see, it's useless to move.
            if (empty($context['move_to_boards'])) {
                $context['can_move'] = false;
            }
        }
        // Can we use quick moderation checkboxes?
        if ($options['display_quick_mod']) {
            $context['can_quick_mod'] = $context['user']['is_logged'] || $context['can_approve'] || $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'] || $context['can_merge'] || $context['can_restore'];
        }
    }
    // If there are children, but no topics and no ability to post topics...
    $context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new'];
    $context['normal_buttons'] = array('new_topic' => array('test' => 'can_post_new', 'text' => 'new_topic', 'image' => 'new_topic.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0', 'active' => true), 'post_poll' => array('test' => 'can_post_poll', 'text' => 'new_poll', 'image' => 'new_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0;poll'), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.gif', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_board'] : $txt['notification_enable_board']) . '\');"', 'url' => $scripturl . '?action=notifyboard;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';board=' . $context['current_board'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'markread' => array('text' => 'mark_read_short', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=board;board=' . $context['current_board'] . '.0;' . $context['session_var'] . '=' . $context['session_id']));
    if (!empty($context['topics'])) {
        $context['subject_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=subject' . ($context['sort_by'] == 'subject' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['subject'] . ($context['sort_by'] == 'subject' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a> / <a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=starter' . ($context['sort_by'] == 'starter' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['started_by'] . ($context['sort_by'] == 'starter' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>';
        $context['views_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=replies' . ($context['sort_by'] == 'replies' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['replies'] . ($context['sort_by'] == 'replies' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a> / <a href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=views' . ($context['sort_by'] == 'views' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['views'] . ($context['sort_by'] == 'views' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>';
        $context['lastpost_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=last_post' . ($context['sort_by'] == 'last_post' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['last_post'] . ($context['sort_by'] == 'last_post' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>';
    }
    // They can only mark read if they are logged in and it's enabled!
    if (!$context['user']['is_logged'] || !$settings['show_mark_read']) {
        unset($context['normal_buttons']['markread']);
    }
    HookAPI::callHook('messageindex_buttons', array(&$normal_buttons));
    enqueueThemeScript('topic', 'scripts/topic.js', true);
    HookAPI::callHook('messageindex', array(&$board_info));
}
コード例 #7
0
ファイル: mod_topic.php プロジェクト: Crackpot/gftop
include_once "include/db_mysql.php";
include_once "include/common.php";
$conn = db_connect($h, $p, $u, $db);
$bid = $_GET['bid'];
$tid = $_GET['tid'];
if (!is_numeric($bid) || !is_numeric($tid)) {
    $error = $ERR['NO_PARAM'];
    showerrpage($error);
    exit;
}
$show_info = "";
$sql = "select board_name,content,DATE_FORMAT(post_time,'%Y-%m-%d %H:%i') ";
$sql .= "as post_time from topics,boards where bid=boards.id and bid={$bid} and topics.id={$tid}";
$result = mysql_query($sql) or die("ERROR: " . mysql_error() . " <br/>SQL=" . $sql);
if ($num = mysql_num_rows($result)) {
    $row = mysql_fetch_array($result);
    $board_name = $row['board_name'];
    $content = $row['content'];
    $content = str_replace("<br>&nbsp;&nbsp;&nbsp;&nbsp;", "\r\n", $content);
    $post_time = $row['post_time'];
} else {
    $error = $ERR['NO_PARAM'];
    showerrpage($error);
    exit;
}
$html_title = $HTML_TITLE['mod'];
$board_name_list = getBoardList();
$user_rank_list = userRank($bid);
close_db($conn);
include_once "template/mod_topic.htm";
コード例 #8
0
function MessageIndex()
{
    global $txt, $scripturl, $board, $modSettings, $context;
    global $options, $settings, $board_info, $user_info, $smcFunc, $sourcedir;
    // If this is a redirection board head off.
    if ($board_info['redirect']) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1
			WHERE id_board = {int:current_board}', array('current_board' => $board));
        redirectexit($board_info['redirect']);
    }
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_messageindex';
    } else {
        loadTemplate('MessageIndex');
    }
    $context['name'] = $board_info['name'];
    $context['description'] = $board_info['description'];
    // How many topics do we have in total?
    $board_info['total_topics'] = allowedTo('approve_posts') ? $board_info['num_topics'] + $board_info['unapproved_topics'] : $board_info['num_topics'] + $board_info['unapproved_user_topics'];
    // View all the topics, or just a few?
    $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) && !WIRELESS ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    $maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['total_topics'] : $context['topics_per_page'];
    // Right, let's only index normal stuff!
    if (count($_GET) > 1) {
        $session_name = session_name();
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('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;
    }
    // If we can view unapproved messages and there are some build up a list.
    if (allowedTo('approve_posts') && ($board_info['unapproved_topics'] || $board_info['unapproved_posts'])) {
        $untopics = $board_info['unapproved_topics'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=topics;brd=' . $board . '">' . $board_info['unapproved_topics'] . '</a>' : 0;
        $unposts = $board_info['unapproved_posts'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=posts;brd=' . $board . '">' . ($board_info['unapproved_posts'] - $board_info['unapproved_topics']) . '</a>' : 0;
        $context['unapproved_posts_message'] = sprintf($txt['there_are_unapproved_topics'], $untopics, $unposts, $scripturl . '?action=moderate;area=postmod;sa=' . ($board_info['unapproved_topics'] ? 'topics' : 'posts') . ';brd=' . $board);
    }
    // We only know these.
    if (isset($_REQUEST['sort']) && !in_array($_REQUEST['sort'], array('subject', 'starter', 'last_poster', 'replies', 'views', 'first_post', 'last_post'))) {
        $_REQUEST['sort'] = 'last_post';
    }
    // Make sure the starting place makes sense and construct the page index.
    if (isset($_REQUEST['sort'])) {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    } else {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    }
    $context['start'] =& $_REQUEST['start'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?board=' . $board . '.' . $context['start'];
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $context['topics_per_page']) : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $context['topics_per_page']) : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) * $context['topics_per_page'] : '', 'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0');
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) + 1);
    if (isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages']) {
        $maxindex = $modSettings['enableAllMessages'];
        $_REQUEST['start'] = 0;
    }
    // Build a list of the board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        $context['linktree'][count($context['linktree']) - 1]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Mark current and parent boards as seen.
    if (!$user_info['is_guest']) {
        // We can't know they read it if we allow prefetches.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        $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'));
        if (!empty($board_info['parent_boards'])) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}log_boards
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
            // We've seen all these boards now!
            foreach ($board_info['parent_boards'] as $k => $dummy) {
                if (isset($_SESSION['topicseen_cache'][$k])) {
                    unset($_SESSION['topicseen_cache'][$k]);
                }
            }
        }
        if (isset($_SESSION['topicseen_cache'][$board])) {
            unset($_SESSION['topicseen_cache'][$board]);
        }
        $request = $smcFunc['db_query']('', '
			SELECT sent
			FROM {db_prefix}log_notify
			WHERE id_board = {int:current_board}
				AND id_member = {int:current_member}
			LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id']));
        $context['is_marked_notify'] = $smcFunc['db_num_rows']($request) != 0;
        if ($context['is_marked_notify']) {
            list($sent) = $smcFunc['db_fetch_row']($request);
            if (!empty($sent)) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_sent}
					WHERE id_board = {int:current_board}
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_sent' => 0));
            }
        }
        $smcFunc['db_free_result']($request);
    } else {
        $context['is_marked_notify'] = false;
    }
    // 'Print' the header and board info.
    $context['page_title'] = strip_tags($board_info['name']);
    // Set the variables up for the template.
    $context['can_mark_notify'] = allowedTo('mark_notify') && !$user_info['is_guest'];
    $context['can_post_new'] = allowedTo('post_new') || $modSettings['postmod_active'] && allowedTo('post_unapproved_topics');
    $context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post') && $context['can_post_new'];
    $context['can_moderate_forum'] = allowedTo('moderate_forum');
    $context['can_approve_posts'] = allowedTo('approve_posts');
    require_once $sourcedir . '/Subs-BoardIndex.php';
    $boardIndexOptions = array('include_categories' => false, 'base_level' => $board_info['child_level'] + 1, 'parent_id' => $board_info['id'], 'set_latest_post' => false, 'countChildPosts' => !empty($modSettings['countChildPosts']));
    $context['boards'] = getBoardIndex($boardIndexOptions);
    // Nosey, nosey - who's viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        $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_member_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_member_group' => 0, 'in_url_string' => 's:5:"board";i:' . $board . ';', '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>';
            }
            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']++;
            }
        }
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Put them in "last clicked" order.
        krsort($context['view_members_list']);
        krsort($context['view_members']);
    }
    // Default sort methods.
    $sort_methods = array('subject' => 'mf.subject', 'starter' => 'IFNULL(memf.real_name, mf.poster_name)', 'last_poster' => 'IFNULL(meml.real_name, ml.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg');
    // They didn't pick one, default to by last post descending.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 'id_last_msg';
        $ascending = isset($_REQUEST['asc']);
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    // Calculate the fastest way to get the topics.
    $start = (int) $_REQUEST['start'];
    if ($start > ($board_info['total_topics'] - 1) / 2) {
        $ascending = !$ascending;
        $fake_ascending = true;
        $maxindex = $board_info['total_topics'] < $start + $maxindex + 1 ? $board_info['total_topics'] - $start : $maxindex;
        $start = $board_info['total_topics'] < $start + $maxindex + 1 ? 0 : $board_info['total_topics'] - $start - $maxindex;
    } else {
        $fake_ascending = false;
    }
    // Setup the default topic icons...
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless', 'clip');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $topic_ids = array();
    $context['topics'] = array();
    // Sequential pages are often not optimized, so we add an additional query.
    $pre_query = $start > 0;
    if ($pre_query && $maxindex > 0) {
        $request = $smcFunc['db_query']('', '
			SELECT t.id_topic
			FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? '
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? '
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? '
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? '
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . '
			WHERE t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . '
			LIMIT {int:start}, {int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_guest' => 0, 'start' => $start, 'maxindex' => $maxindex));
        $topic_ids = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $topic_ids[] = $row['id_topic'];
        }
    }
    // Grab the appropriate topic information...
    if (!$pre_query || !empty($topic_ids)) {
        // For search engine effectiveness we'll link guests differently.
        $context['pageindex_multiplier'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        $result = $smcFunc['db_query']('substring', '
			SELECT
				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
				' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
				t.id_last_msg, t.approved, t.unapproved_posts, ml.poster_time AS last_poster_time,
				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
				ml.poster_name AS last_member_name, ml.id_member AS last_id_member,
				IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
				mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon,
				mf.poster_name AS first_member_name, mf.id_member AS first_id_member,
				IFNULL(memf.real_name, mf.poster_name) AS first_display_name, SUBSTRING(ml.body, 1, 385) AS last_body,
				SUBSTRING(mf.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : '
				LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_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 ' . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : 't.id_board = {int:current_board}') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . '
			LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'is_approved' => 1, 'find_set_topics' => implode(',', $topic_ids), 'start' => $start, 'maxindex' => $maxindex));
        // Begin 'printing' the message index for current board.
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') {
                continue;
            }
            if (!$pre_query) {
                $topic_ids[] = $row['id_topic'];
            }
            if (!empty($settings['message_index_preview'])) {
                // Limit them to 128 characters - do this FIRST because it's a lot of wasted censoring otherwise.
                $row['first_body'] = strip_tags(strtr(parse_bbc($row['first_body'], $row['first_smileys'], $row['id_first_msg']), array('<br />' => '&#10;')));
                if ($smcFunc['strlen']($row['first_body']) > 128) {
                    $row['first_body'] = $smcFunc['substr']($row['first_body'], 0, 128) . '...';
                }
                $row['last_body'] = strip_tags(strtr(parse_bbc($row['last_body'], $row['last_smileys'], $row['id_last_msg']), array('<br />' => '&#10;')));
                if ($smcFunc['strlen']($row['last_body']) > 128) {
                    $row['last_body'] = $smcFunc['substr']($row['last_body'], 0, 128) . '...';
                }
                // Censor the subject and message preview.
                censorText($row['first_subject']);
                censorText($row['first_body']);
                // Don't censor them twice!
                if ($row['id_first_msg'] == $row['id_last_msg']) {
                    $row['last_subject'] = $row['first_subject'];
                    $row['last_body'] = $row['first_body'];
                } else {
                    censorText($row['last_subject']);
                    censorText($row['last_body']);
                }
            } else {
                $row['first_body'] = '';
                $row['last_body'] = '';
                censorText($row['first_subject']);
                if ($row['id_first_msg'] == $row['id_last_msg']) {
                    $row['last_subject'] = $row['first_subject'];
                } else {
                    censorText($row['last_subject']);
                }
            }
            // Decide how many pages the topic should have.
            if ($row['num_replies'] + 1 > $context['messages_per_page']) {
                $pages = '&#171; ';
                // We can't pass start by reference.
                $start = -1;
                $pages .= constructPageIndex($scripturl . '?topic=' . $row['id_topic'] . '.%1$d', $start, $row['num_replies'] + 1, $context['messages_per_page'], true);
                // If we can use all, show all.
                if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages']) {
                    $pages .= ' &nbsp;<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;all">' . $txt['all'] . '</a>';
                }
                $pages .= ' &#187;';
            } else {
                $pages = '';
            }
            // We need to check the topic icons exist...
            if (empty($modSettings['messageIconChecks_disable'])) {
                if (!isset($context['icon_sources'][$row['first_icon']])) {
                    $context['icon_sources'][$row['first_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['first_icon'] . '.gif') ? 'images_url' : 'default_images_url';
                }
                if (!isset($context['icon_sources'][$row['last_icon']])) {
                    $context['icon_sources'][$row['last_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['last_icon'] . '.gif') ? 'images_url' : 'default_images_url';
                }
            } else {
                if (!isset($context['icon_sources'][$row['first_icon']])) {
                    $context['icon_sources'][$row['first_icon']] = 'images_url';
                }
                if (!isset($context['icon_sources'][$row['last_icon']])) {
                    $context['icon_sources'][$row['last_icon']] = 'images_url';
                }
            }
            // 'Print' the topic info.
            $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_display_name'], 'id' => $row['first_id_member'], 'href' => !empty($row['first_id_member']) ? $scripturl . '?action=profile;u=' . $row['first_id_member'] : '', 'link' => !empty($row['first_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['first_id_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '">' . $row['first_display_name'] . '</a>' : $row['first_display_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'preview' => $row['first_body'], 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => !empty($row['last_id_member']) ? $scripturl . '?action=profile;u=' . $row['last_id_member'] : '', 'link' => !empty($row['last_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['last_id_member'] . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'preview' => $row['last_body'], 'icon' => $row['last_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? '.' . (!empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg'] : ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new'), 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? '.' . (!empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg'] : ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new') . '" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.gif', 'subject' => $row['first_subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new', 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts']);
            determineTopicClass($context['topics'][$row['id_topic']]);
        }
        $smcFunc['db_free_result']($result);
        // Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...)
        if ($fake_ascending) {
            $context['topics'] = array_reverse($context['topics'], true);
        }
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids)) {
            $result = $smcFunc['db_query']('', '
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_topic IN ({array_int:topic_list})
					AND id_member = {int:current_member}
				GROUP BY id_topic
				LIMIT ' . count($topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $topic_ids));
            while ($row = $smcFunc['db_fetch_assoc']($result)) {
                $context['topics'][$row['id_topic']]['is_posted_in'] = true;
                $context['topics'][$row['id_topic']]['class'] = 'my_' . $context['topics'][$row['id_topic']]['class'];
            }
            $smcFunc['db_free_result']($result);
        }
    }
    $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']);
    // Is Quick Moderation active/needed?
    if (!empty($options['display_quick_mod']) && !empty($context['topics'])) {
        $context['can_lock'] = allowedTo('lock_any');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['can_move'] = allowedTo('move_any');
        $context['can_remove'] = allowedTo('remove_any');
        $context['can_merge'] = allowedTo('merge_any');
        // Ignore approving own topics as it's unlikely to come up...
        $context['can_approve'] = $modSettings['postmod_active'] && allowedTo('approve_posts') && !empty($board_info['unapproved_topics']);
        // Can we restore topics?
        $context['can_restore'] = allowedTo('move_any') && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board;
        // Set permissions for all the topics.
        foreach ($context['topics'] as $t => $topic) {
            $started = $topic['first_post']['member']['id'] == $user_info['id'];
            $context['topics'][$t]['quick_mod'] = array('lock' => allowedTo('lock_any') || $started && allowedTo('lock_own'), 'sticky' => allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']), 'move' => allowedTo('move_any') || $started && allowedTo('move_own'), 'modify' => allowedTo('modify_any') || $started && allowedTo('modify_own'), 'remove' => allowedTo('remove_any') || $started && allowedTo('remove_own'), 'approve' => $context['can_approve'] && $topic['unapproved_posts']);
            $context['can_lock'] |= $started && allowedTo('lock_own');
            $context['can_move'] |= $started && allowedTo('move_own');
            $context['can_remove'] |= $started && allowedTo('remove_own');
        }
        // Find the boards/cateogories they can move their topic to.
        if ($options['display_quick_mod'] == 1 && $context['can_move'] && !empty($context['topics'])) {
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('excluded_boards' => array($board), 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']);
            $context['move_to_boards'] = getBoardList($boardListOptions);
            // Make the boards safe for display.
            foreach ($context['move_to_boards'] as $id_cat => $cat) {
                $context['move_to_boards'][$id_cat]['name'] = strip_tags($cat['name']);
                foreach ($cat['boards'] as $id_board => $board) {
                    $context['move_to_boards'][$id_cat]['boards'][$id_board]['name'] = strip_tags($board['name']);
                }
            }
            // With no other boards to see, it's useless to move.
            if (empty($context['move_to_boards'])) {
                $context['can_move'] = false;
            }
        }
        // Can we use quick moderation checkboxes?
        if ($options['display_quick_mod'] == 1) {
            $context['can_quick_mod'] = $context['user']['is_logged'] || $context['can_approve'] || $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'] || $context['can_merge'] || $context['can_restore'];
        } else {
            $context['can_quick_mod'] = $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'];
        }
    }
    // If there are children, but no topics and no ability to post topics...
    $context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new'];
}
コード例 #9
0
ファイル: Calendar.php プロジェクト: valek0972/hackits
function CalendarPost()
{
    global $context, $txt, $user_info, $sourcedir, $scripturl;
    global $modSettings, $topic, $smcFunc;
    // Well - can they?
    isAllowedTo('calendar_post');
    // We need this for all kinds of useful functions.
    require_once $sourcedir . '/Subs-Calendar.php';
    // Cast this for safety...
    if (isset($_REQUEST['eventid'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
    }
    // Submitting?
    if (isset($_POST[$context['session_var']], $_REQUEST['eventid'])) {
        checkSession();
        // Validate the post...
        if (!isset($_POST['link_to_board'])) {
            validateEventPost();
        }
        // If you're not allowed to edit any events, you have to be the poster.
        if ($_REQUEST['eventid'] > 0 && !allowedTo('calendar_edit_any')) {
            isAllowedTo('calendar_edit_' . (!empty($user_info['id']) && getEventPoster($_REQUEST['eventid']) == $user_info['id'] ? 'own' : 'any'));
        }
        // New - and directing?
        if ($_REQUEST['eventid'] == -1 && isset($_POST['link_to_board'])) {
            $_REQUEST['calendar'] = 1;
            require_once $sourcedir . '/Post.php';
            return Post();
        } elseif ($_REQUEST['eventid'] == -1) {
            $eventOptions = array('board' => 0, 'topic' => 0, 'title' => substr($_REQUEST['evtitle'], 0, 60), 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
            insertEvent($eventOptions);
        } elseif (isset($_REQUEST['deleteevent'])) {
            removeEvent($_REQUEST['eventid']);
        } else {
            $eventOptions = array('title' => substr($_REQUEST['evtitle'], 0, 60), 'span' => empty($modSettings['cal_allowspan']) || empty($_POST['span']) || $_POST['span'] == 1 || empty($modSettings['cal_maxspan']) || $_POST['span'] > $modSettings['cal_maxspan'] ? 0 : min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1), 'start_date' => strftime('%Y-%m-%d', mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year'])));
            modifyEvent($_REQUEST['eventid'], $eventOptions);
        }
        updateSettings(array('calendar_updated' => time()));
        // No point hanging around here now...
        redirectexit($scripturl . '?action=calendar;month=' . $_POST['month'] . ';year=' . $_POST['year']);
    }
    // If we are not enabled... we are not enabled.
    if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid'])) {
        $_REQUEST['calendar'] = 1;
        require_once $sourcedir . '/Post.php';
        return Post();
    }
    // New?
    if (!isset($_REQUEST['eventid'])) {
        $today = getdate();
        $context['event'] = array('boards' => array(), 'board' => 0, 'new' => 1, 'eventid' => -1, 'year' => isset($_REQUEST['year']) ? $_REQUEST['year'] : $today['year'], 'month' => isset($_REQUEST['month']) ? $_REQUEST['month'] : $today['mon'], 'day' => isset($_REQUEST['day']) ? $_REQUEST['day'] : $today['mday'], 'title' => '', 'span' => 1);
        $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']));
        // Get list of boards that can be posted in.
        $boards = boardsAllowedTo('post_new');
        if (empty($boards)) {
            fatal_lang_error('cannot_post_new', 'permission');
        }
        // Load the list of boards and categories 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' => $modSettings['cal_defaultboard']);
        $context['event']['categories'] = getBoardList($boardListOptions);
    } else {
        $context['event'] = getEventProperties($_REQUEST['eventid']);
        if ($context['event'] === false) {
            fatal_lang_error('no_access', false);
        }
        // If it has a board, then they should be editing it within the topic.
        if (!empty($context['event']['topic']['id']) && !empty($context['event']['topic']['first_msg'])) {
            // We load the board up, for a check on the board access rights...
            $topic = $context['event']['topic']['id'];
            loadBoard();
        }
        // Make sure the user is allowed to edit this event.
        if ($context['event']['member'] != $user_info['id']) {
            isAllowedTo('calendar_edit_any');
        } elseif (!allowedTo('calendar_edit_any')) {
            isAllowedTo('calendar_edit_own');
        }
    }
    // Template, sub template, etc.
    loadTemplate('Calendar');
    $context['sub_template'] = 'event_post';
    $context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar_edit'] : $txt['calendar_post_event'];
    $context['linktree'][] = array('name' => $context['page_title']);
}
コード例 #10
0
ファイル: Post.php プロジェクト: valek0972/hackits
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');
    }
}
コード例 #11
0
ファイル: Post.controller.php プロジェクト: Ralkage/Elkarte
    /**
     * 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';
        }
    }
コード例 #12
0
 /**
  * Editing a membergroup.
  *
  * What it does:
  * - Screen to edit a specific membergroup.
  * - Called by ?action=admin;area=membergroups;sa=edit;group=x.
  * - It requires the manage_membergroups permission.
  * - Also handles the delete button of the edit form.
  * - Redirects to ?action=admin;area=membergroups.
  *
  * @uses the edit_group sub template of ManageMembergroups.
  */
 public function action_edit()
 {
     global $context, $txt, $modSettings;
     $current_group_id = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0;
     if (!empty($modSettings['deny_boards_access'])) {
         loadLanguage('ManagePermissions');
     }
     require_once SUBSDIR . '/Membergroups.subs.php';
     // Make sure this group is editable.
     if (!empty($current_group_id)) {
         $current_group = membergroupById($current_group_id);
     }
     // Now, do we have a valid id?
     if (!allowedTo('admin_forum') && !empty($current_group_id) && $current_group['group_type'] == 1) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     // The delete this membergroup button was pressed.
     if (isset($_POST['delete'])) {
         checkSession();
         validateToken('admin-mmg');
         if (empty($current_group_id)) {
             fatal_lang_error('membergroup_does_not_exist', false);
         }
         // Let's delete the group
         deleteMembergroups($current_group['id_group']);
         redirectexit('action=admin;area=membergroups;');
     } elseif (isset($_POST['save'])) {
         // Validate the session.
         checkSession();
         validateToken('admin-mmg');
         if (empty($current_group_id)) {
             fatal_lang_error('membergroup_does_not_exist', false);
         }
         require_once SUBSDIR . '/DataValidator.class.php';
         $validator = new Data_Validator();
         // Cleanup the inputs! :D
         $validator->sanitation_rules(array('max_messages' => 'intval', 'min_posts' => 'intval|abs', 'group_type' => 'intval', 'group_desc' => 'trim|Util::htmlspecialchars', 'group_name' => 'trim|Util::htmlspecialchars', 'group_hidden' => 'intval', 'group_inherit' => 'intval', 'icon_count' => 'intval', 'icon_image' => 'trim|Util::htmlspecialchars', 'online_color' => 'trim|valid_color'));
         $validator->input_processing(array('boardaccess' => 'array'));
         $validator->validation_rules(array('boardaccess' => 'contains[allow,ignore,deny]'));
         $validator->validate($_POST);
         // Can they really inherit from this group?
         if ($validator->group_inherit != -2 && !allowedTo('admin_forum')) {
             $inherit_type = membergroupById($validator->group_inherit);
         }
         $min_posts = $validator->group_type == -1 && $validator->min_posts >= 0 && $current_group['id_group'] > 3 ? $validator->min_posts : ($current_group['id_group'] == 4 ? 0 : -1);
         $group_inherit = $current_group['id_group'] > 1 && $current_group['id_group'] != 3 && (empty($inherit_type['group_type']) || $inherit_type['group_type'] != 1) ? $validator->group_inherit : -2;
         //@todo Don't set online_color for the Moderators group?
         // Do the update of the membergroup settings.
         $properties = array('max_messages' => $validator->max_messages, 'min_posts' => $min_posts, 'group_type' => $validator->group_type < 0 || $validator->group_type > 3 || $validator->group_type == 1 && !allowedTo('admin_forum') ? 0 : $validator->group_type, 'hidden' => !$validator->group_hidden || $min_posts != -1 || $current_group['id_group'] == 3 ? 0 : $validator->group_hidden, 'id_parent' => $group_inherit, 'current_group' => $current_group['id_group'], 'group_name' => $validator->group_name, 'online_color' => $validator->online_color, 'icons' => $validator->icon_count <= 0 ? '' : min($validator->icon_count, 10) . '#' . $validator->icon_image, 'description' => $current_group['id_group'] == 1 || $validator->group_type != -1 ? $validator->group_desc : '');
         updateMembergroupProperties($properties);
         call_integration_hook('integrate_save_membergroup', array($current_group['id_group']));
         // Time to update the boards this membergroup has access to.
         if ($current_group['id_group'] == 2 || $current_group['id_group'] > 3) {
             $changed_boards = array();
             $changed_boards['allow'] = array();
             $changed_boards['deny'] = array();
             $changed_boards['ignore'] = array();
             if ($validator->boardaccess) {
                 foreach ($validator->boardaccess as $group_id => $action) {
                     $changed_boards[$action][] = (int) $group_id;
                 }
             }
             foreach (array('allow', 'deny') as $board_action) {
                 // Find all board this group is in, but shouldn't be in.
                 detachGroupFromBoards($current_group['id_group'], $changed_boards, $board_action);
                 // Add the membergroup to all boards that hadn't been set yet.
                 if (!empty($changed_boards[$board_action])) {
                     assignGroupToBoards($current_group['id_group'], $changed_boards, $board_action);
                 }
             }
         }
         // Remove everyone from this group!
         if ($min_posts != -1) {
             detachDeletedGroupFromMembers($current_group['id_group']);
         } elseif ($current_group['id_group'] != 3) {
             // Making it a hidden group? If so remove everyone with it as primary group (Actually, just make them additional).
             if ($validator->group_hidden == 2) {
                 setGroupToHidden($current_group['id_group']);
             }
             // Either way, let's check our "show group membership" setting is correct.
             validateShowGroupMembership();
         }
         // Do we need to set inherited permissions?
         if ($group_inherit != -2 && $group_inherit != $_POST['old_inherit']) {
             require_once SUBSDIR . '/Permission.subs.php';
             updateChildPermissions($group_inherit);
         }
         // Finally, moderators!
         $moderator_string = isset($_POST['group_moderators']) ? trim($_POST['group_moderators']) : '';
         detachGroupModerators($current_group['id_group']);
         if ((!empty($moderator_string) || !empty($_POST['moderator_list'])) && $min_posts == -1 && $current_group['id_group'] != 3) {
             // Get all the usernames from the string
             if (!empty($moderator_string)) {
                 $moderator_string = strtr(preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', htmlspecialchars($moderator_string, ENT_QUOTES, 'UTF-8')), array('&quot;' => '"'));
                 preg_match_all('~"([^"]+)"~', $moderator_string, $matches);
                 $moderators = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_string)));
                 for ($k = 0, $n = count($moderators); $k < $n; $k++) {
                     $moderators[$k] = trim($moderators[$k]);
                     if (strlen($moderators[$k]) == 0) {
                         unset($moderators[$k]);
                     }
                 }
                 // Find all the id_member's for the member_name's in the list.
                 if (!empty($moderators)) {
                     $group_moderators = getIDMemberFromGroupModerators($moderators);
                 }
             } else {
                 $moderators = array();
                 foreach ($_POST['moderator_list'] as $moderator) {
                     $moderators[] = (int) $moderator;
                 }
                 $group_moderators = array();
                 if (!empty($moderators)) {
                     require_once SUBSDIR . '/Members.subs.php';
                     $members = getBasicMemberData($moderators);
                     foreach ($members as $member) {
                         $group_moderators[] = $member['id_member'];
                     }
                 }
             }
             // Found some?
             if (!empty($group_moderators)) {
                 assignGroupModerators($current_group['id_group'], $group_moderators);
             }
         }
         // There might have been some post group changes.
         updateStats('postgroups');
         // We've definitely changed some group stuff.
         updateSettings(array('settings_updated' => time()));
         // Log the edit.
         logAction('edited_group', array('group' => $validator->group_name), 'admin');
         redirectexit('action=admin;area=membergroups');
     }
     // Fetch the current group information.
     $row = membergroupById($current_group['id_group'], true);
     if (empty($row) || !allowedTo('admin_forum') && $row['group_type'] == 1) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     $row['icons'] = explode('#', $row['icons']);
     $context['group'] = array('id' => $row['id_group'], 'name' => $row['group_name'], 'description' => htmlspecialchars($row['description'], ENT_COMPAT, 'UTF-8'), 'editable_name' => $row['group_name'], 'color' => $row['online_color'], 'min_posts' => $row['min_posts'], 'max_messages' => $row['max_messages'], 'icon_count' => (int) $row['icons'][0], 'icon_image' => isset($row['icons'][1]) ? $row['icons'][1] : '', 'is_post_group' => $row['min_posts'] != -1, 'type' => $row['min_posts'] != -1 ? 0 : $row['group_type'], 'hidden' => $row['min_posts'] == -1 ? $row['hidden'] : 0, 'inherited_from' => $row['id_parent'], 'allow_post_group' => $row['id_group'] == 2 || $row['id_group'] > 4, 'allow_delete' => $row['id_group'] == 2 || $row['id_group'] > 4, 'allow_protected' => allowedTo('admin_forum'));
     // Get any moderators for this group
     $context['group']['moderators'] = getGroupModerators($row['id_group']);
     $context['group']['moderator_list'] = empty($context['group']['moderators']) ? '' : '&quot;' . implode('&quot;, &quot;', $context['group']['moderators']) . '&quot;';
     if (!empty($context['group']['moderators'])) {
         list($context['group']['last_moderator_id']) = array_slice(array_keys($context['group']['moderators']), -1);
     }
     // Get a list of boards this membergroup is allowed to see.
     $context['boards'] = array();
     if ($row['id_group'] == 2 || $row['id_group'] > 3) {
         require_once SUBSDIR . '/Boards.subs.php';
         $context += getBoardList(array('override_permissions' => true, 'access' => $row['id_group'], 'not_redirection' => true));
         // Include a list of boards per category for easy toggling.
         foreach ($context['categories'] as $category) {
             $context['categories'][$category['id']]['child_ids'] = array_keys($category['boards']);
         }
     }
     // Finally, get all the groups this could be inherited off.
     $context['inheritable_groups'] = getInheritableGroups($row['id_group']);
     call_integration_hook('integrate_view_membergroup');
     $context['sub_template'] = 'edit_group';
     $context['page_title'] = $txt['membergroups_edit_group'];
     // Use the autosuggest script when needed
     if ($context['group']['id'] != 3 && $context['group']['id'] != 4) {
         loadJavascriptFile('suggest.js', array('defer' => true));
     }
     createToken('admin-mmg');
 }
コード例 #13
0
 /**
  * Retrieve and return all admin settings for boards management.
  */
 private function _settings()
 {
     global $txt;
     // We need to borrow a string from here
     loadLanguage('ManagePermissions');
     // Load the boards list - for the recycle bin!
     require_once SUBSDIR . '/Boards.subs.php';
     $boards = getBoardList(array('override_permissions' => true, 'not_redirection' => true), true);
     $recycle_boards = array('');
     foreach ($boards as $board) {
         $recycle_boards[$board['id_board']] = $board['cat_name'] . ' - ' . $board['board_name'];
     }
     // Here and the board settings...
     $config_vars = array(array('title', 'settings'), array('permissions', 'manage_boards', 'helptext' => $txt['permissionhelp_manage_boards']), '', array('check', 'countChildPosts'), array('check', 'recycle_enable', 'onclick' => 'document.getElementById(\'recycle_board\').disabled = !this.checked;'), array('select', 'recycle_board', $recycle_boards), array('check', 'allow_ignore_boards'), array('check', 'deny_boards_access'));
     // Add new settings with a nice hook, makes them available for admin settings search as well
     call_integration_hook('integrate_modify_board_settings', array(&$config_vars));
     return $config_vars;
 }
コード例 #14
0
 /**
  * Supporting function for the topics maintenance area.
  */
 public function action_topics()
 {
     global $context, $txt;
     require_once SUBSDIR . '/Boards.subs.php';
     // Let's load up the boards in case they are useful.
     $context += getBoardList(array('not_redirection' => true));
     if (isset($_GET['done']) && $_GET['done'] == 'purgeold') {
         $context['maintenance_finished'] = array('errors' => array(sprintf($txt['maintain_done'], $txt['maintain_old'])));
     } elseif (isset($_GET['done']) && $_GET['done'] == 'massmove') {
         $context['maintenance_finished'] = array('errors' => array(sprintf($txt['maintain_done'], $txt['move_topics_maintenance'])));
     }
     // Set up the sub-template
     $context['sub_template'] = 'maintain_topics';
 }
コード例 #15
0
 /**
  * Allows the user to see the list of their ignored boards.
  * (and un-ignore them)
  *
  */
 public function action_ignoreboards()
 {
     global $context, $modSettings, $cur_profile;
     $memID = currentMemberID();
     // Have the admins enabled this option?
     if (empty($modSettings['allow_ignore_boards'])) {
         fatal_lang_error('ignoreboards_disallowed', 'user');
     }
     loadTemplate('ProfileOptions');
     $context['sub_template'] = 'ignoreboards';
     require_once SUBSDIR . '/Boards.subs.php';
     $context += getBoardList(array('not_redirection' => true, 'ignore' => !empty($cur_profile['ignore_boards']) ? explode(',', $cur_profile['ignore_boards']) : array()));
     // Include a list of boards per category for easy toggling.
     foreach ($context['categories'] as $cat => &$category) {
         $context['boards_in_category'][$cat] = count($category['boards']);
         $category['child_ids'] = array_keys($category['boards']);
     }
     loadThemeOptions($memID);
 }
コード例 #16
0
 /**
  * Allows to pick a topic to merge the current topic with.
  * is accessed with ?action=mergetopics;sa=index
  * default sub action for ?action=mergetopics.
  * uses 'merge' sub template of the MergeTopics template.
  * allows to set a different target board.
  */
 public function action_mergeIndex()
 {
     global $txt, $board, $context, $scripturl, $user_info, $modSettings;
     if (!isset($_GET['from'])) {
         fatal_lang_error('no_access', false);
     }
     $_GET['from'] = (int) $_GET['from'];
     $_REQUEST['targetboard'] = isset($_REQUEST['targetboard']) ? (int) $_REQUEST['targetboard'] : $board;
     $context['target_board'] = $_REQUEST['targetboard'];
     // Prepare a handy query bit for approval...
     if ($modSettings['postmod_active']) {
         $can_approve_boards = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts');
         $onlyApproved = $can_approve_boards !== array(0) && !in_array($_REQUEST['targetboard'], $can_approve_boards);
     } else {
         $onlyApproved = false;
     }
     // How many topics are on this board?  (used for paging.)
     require_once SUBSDIR . '/Topic.subs.php';
     $topiccount = countTopicsByBoard($_REQUEST['targetboard'], $onlyApproved);
     // Make the page list.
     $context['page_index'] = constructPageIndex($scripturl . '?action=mergetopics;from=' . $_GET['from'] . ';targetboard=' . $_REQUEST['targetboard'] . ';board=' . $board . '.%1$d', $_REQUEST['start'], $topiccount, $modSettings['defaultMaxTopics'], true);
     // Get the topic's subject.
     $topic_info = getTopicInfo($_GET['from'], 'message');
     // @todo review: double check the logic
     if (empty($topic_info) || $topic_info['id_board'] != $board || $onlyApproved && empty($topic_info['approved'])) {
         fatal_lang_error('no_board');
     }
     // Tell the template a few things..
     $context['origin_topic'] = $_GET['from'];
     $context['origin_subject'] = $topic_info['subject'];
     $context['origin_js_subject'] = addcslashes(addslashes($topic_info['subject']), '/');
     $context['page_title'] = $txt['merge'];
     // Check which boards you have merge permissions on.
     $merge_boards = boardsAllowedTo('merge_any');
     if (empty($merge_boards)) {
         fatal_lang_error('cannot_merge_any', 'user');
     }
     // Get a list of boards they can navigate to to merge.
     require_once SUBSDIR . '/Boards.subs.php';
     $boardListOptions = array('not_redirection' => true);
     if (!in_array(0, $merge_boards)) {
         $boardListOptions['included_boards'] = $merge_boards;
     }
     $boards_list = getBoardList($boardListOptions, true);
     $context['boards'] = array();
     foreach ($boards_list as $board) {
         $context['boards'][] = array('id' => $board['id_board'], 'name' => $board['board_name'], 'category' => $board['cat_name']);
     }
     // Get some topics to merge it with.
     $context['topics'] = mergeableTopics($_REQUEST['targetboard'], $_GET['from'], $onlyApproved, $_REQUEST['start']);
     if (empty($context['topics']) && count($context['boards']) <= 1) {
         fatal_lang_error('merge_need_more_topics');
     }
     $context['sub_template'] = 'merge';
 }
コード例 #17
0
 /**
  * Retrieve and return all admin settings for the calendar.
  */
 private function _settings()
 {
     global $txt;
     // Load the boards list.
     require_once SUBSDIR . '/Boards.subs.php';
     $boards_list = getBoardList(array('override_permissions' => true, 'not_redirection' => true), true);
     $boards = array('');
     foreach ($boards_list as $board) {
         $boards[$board['id_board']] = $board['cat_name'] . ' - ' . $board['board_name'];
     }
     // Look, all the calendar settings - of which there are many!
     $config_vars = array(array('title', 'calendar_settings'), array('permissions', 'calendar_view'), array('permissions', 'calendar_post'), array('permissions', 'calendar_edit_own'), array('permissions', 'calendar_edit_any'), '', array('int', 'cal_days_for_index', 6, 'postinput' => $txt['days_word']), array('select', 'cal_showholidays', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])), array('select', 'cal_showbdays', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])), array('select', 'cal_showevents', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])), array('check', 'cal_export'), '', array('select', 'cal_defaultboard', $boards), array('check', 'cal_daysaslink'), array('check', 'cal_allow_unlinked'), array('check', 'cal_showInTopic'), '', array('int', 'cal_minyear'), array('int', 'cal_maxyear'), '', array('check', 'cal_allowspan'), array('int', 'cal_maxspan', 6, 'postinput' => $txt['days_word']));
     // Add new settings with a nice hook, makes them available for admin settings search as well
     call_integration_hook('integrate_modify_calendar_settings', array(&$config_vars));
     return $config_vars;
 }
コード例 #18
0
    /**
     * Allows to edit the message icons.
     */
    public function action_editicon()
    {
        global $context, $settings, $txt, $scripturl;
        require_once SUBSDIR . '/MessageIcons.subs.php';
        // Get a list of icons.
        $context['icons'] = fetchMessageIconsDetails();
        // Submitting a form?
        if (isset($_POST['icons_save'])) {
            checkSession();
            // Deleting icons?
            if (isset($_POST['delete']) && !empty($_POST['checked_icons'])) {
                $deleteIcons = array();
                foreach ($_POST['checked_icons'] as $icon) {
                    $deleteIcons[] = (int) $icon;
                }
                // Do the actual delete!
                deleteMessageIcons($deleteIcons);
            } elseif ($context['sub_action'] == 'editicon' && isset($_GET['icon'])) {
                $_GET['icon'] = (int) $_GET['icon'];
                // Do some preperation with the data... like check the icon exists *somewhere*
                if (strpos($_POST['icon_filename'], '.png') !== false) {
                    $_POST['icon_filename'] = substr($_POST['icon_filename'], 0, -4);
                }
                if (!file_exists($settings['default_theme_dir'] . '/images/post/' . $_POST['icon_filename'] . '.png')) {
                    fatal_lang_error('icon_not_found');
                } elseif (strlen($_POST['icon_filename']) > 16) {
                    fatal_lang_error('icon_name_too_long');
                } elseif ($_POST['icon_location'] == $_GET['icon'] && !empty($_GET['icon'])) {
                    fatal_lang_error('icon_after_itself');
                }
                // First do the sorting... if this is an edit reduce the order of everything after it by one ;)
                if ($_GET['icon'] != 0) {
                    $oldOrder = $context['icons'][$_GET['icon']]['true_order'];
                    foreach ($context['icons'] as $id => $data) {
                        if ($data['true_order'] > $oldOrder) {
                            $context['icons'][$id]['true_order']--;
                        }
                    }
                }
                // If there are no existing icons and this is a new one, set the id to 1 (mainly for non-mysql)
                if (empty($_GET['icon']) && empty($context['icons'])) {
                    $_GET['icon'] = 1;
                }
                // Get the new order.
                $newOrder = $_POST['icon_location'] == 0 ? 0 : $context['icons'][$_POST['icon_location']]['true_order'] + 1;
                // Do the same, but with the one that used to be after this icon, done to avoid conflict.
                foreach ($context['icons'] as $id => $data) {
                    if ($data['true_order'] >= $newOrder) {
                        $context['icons'][$id]['true_order']++;
                    }
                }
                // Finally set the current icon's position!
                $context['icons'][$_GET['icon']]['true_order'] = $newOrder;
                // Simply replace the existing data for the other bits.
                $context['icons'][$_GET['icon']]['title'] = $_POST['icon_description'];
                $context['icons'][$_GET['icon']]['filename'] = $_POST['icon_filename'];
                $context['icons'][$_GET['icon']]['board_id'] = (int) $_POST['icon_board'];
                // Do a huge replace ;)
                $iconInsert = array();
                $iconInsert_new = array();
                foreach ($context['icons'] as $id => $icon) {
                    if ($id != 0) {
                        $iconInsert[] = array($id, $icon['board_id'], $icon['title'], $icon['filename'], $icon['true_order']);
                    } else {
                        $iconInsert_new[] = array($icon['board_id'], $icon['title'], $icon['filename'], $icon['true_order']);
                    }
                }
                updateMessageIcon($iconInsert);
                if (!empty($iconInsert_new)) {
                    addMessageIcon($iconInsert_new);
                }
            }
            // Sort by order, so it is quicker :)
            sortMessageIconTable();
            // Unless we're adding a new thing, we'll escape
            if (!isset($_POST['add'])) {
                redirectexit('action=admin;area=smileys;sa=editicons');
            }
        }
        $context[$context['admin_menu_name']]['current_subsection'] = 'editicons';
        $token = createToken('admin-sort');
        $listOptions = array('id' => 'message_icon_list', 'title' => $txt['icons_edit_message_icons'], 'sortable' => true, 'base_href' => $scripturl . '?action=admin;area=smileys;sa=editicons', 'get_items' => array('function' => array($this, 'list_fetchMessageIconsDetails')), 'no_items_label' => $txt['icons_no_entries'], 'columns' => array('icon' => array('data' => array('sprintf' => array('format' => '<img src="%1$s" alt="%2$s" />', 'params' => array('image_url' => false, 'filename' => true)), 'class' => 'centertext')), 'filename' => array('header' => array('value' => $txt['smileys_filename']), 'data' => array('sprintf' => array('format' => '%1$s.png', 'params' => array('filename' => true)))), 'tooltip' => array('header' => array('value' => $txt['smileys_description']), 'data' => array('db_htmlsafe' => 'title')), 'board' => array('header' => array('value' => $txt['icons_board']), 'data' => array('db' => 'board')), 'modify' => array('header' => array('value' => $txt['smileys_modify']), 'data' => array('sprintf' => array('format' => '<a href="' . $scripturl . '?action=admin;area=smileys;sa=editicon;icon=%1$s">' . $txt['smileys_modify'] . '</a>', 'params' => array('id' => false)))), 'check' => array('header' => array('value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />', 'class' => 'centertext'), 'data' => array('sprintf' => array('format' => '<input type="checkbox" name="checked_icons[]" value="%1$d" class="input_check" />', 'params' => array('id' => false)), 'class' => 'centertext'))), 'form' => array('href' => $scripturl . '?action=admin;area=smileys;sa=editicons', 'hidden_fields' => array('icons_save' => 1)), 'additional_rows' => array(array('position' => 'below_table_data', 'class' => 'submitbutton', 'value' => '
						<input type="submit" name="delete" value="' . $txt['quickmod_delete_selected'] . '" onclick="return confirm(\'' . $txt['icons_confirm'] . '\');" class="right_submit" />
						<a class="linkbutton" href="' . $scripturl . '?action=admin;area=smileys;sa=editicon">' . $txt['icons_add_new'] . '</a>'), array('position' => 'after_title', 'value' => $txt['icons_reorder_note'])), 'javascript' => '
				$().elkSortable({
					sa: "messageiconorder",
					error: "' . $txt['admin_order_error'] . '",
					title: "' . $txt['admin_order_title'] . '",
					placeholder: "ui-state-highlight",
					href: "?action=admin;area=smileys;sa=editicons",
					token: {token_var: "' . $token['admin-sort_token_var'] . '", token_id: "' . $token['admin-sort_token'] . '"}
				});
			');
        require_once SUBSDIR . '/GenericList.class.php';
        createList($listOptions);
        // If we're adding/editing an icon we'll need a list of boards
        if ($context['sub_action'] == 'editicon' || isset($_POST['add'])) {
            // Force the sub_template just in case.
            $context['sub_template'] = 'editicon';
            $context['new_icon'] = !isset($_GET['icon']);
            // Get the properties of the current icon from the icon list.
            if (!$context['new_icon']) {
                $context['icon'] = $context['icons'][$_GET['icon']];
            }
            // Get a list of boards needed for assigning this icon to a specific board.
            $boardListOptions = array('selected_board' => isset($context['icon']['board_id']) ? $context['icon']['board_id'] : 0);
            require_once SUBSDIR . '/Boards.subs.php';
            $context += getBoardList($boardListOptions);
        }
    }
コード例 #19
0
 /**
  * Screen shown before the actual split.
  * is accessed with ?action=splittopics;sa=index.
  * default sub action for ?action=splittopics.
  * uses 'ask' sub template of the SplitTopics template.
  * redirects to action_splitSelectTopics if the message given turns out to be
  * the first message of a topic.
  * shows the user three ways to split the current topic.
  */
 public function action_splitIndex()
 {
     global $txt, $context, $modSettings;
     // Validate "at".
     if (empty($_GET['at'])) {
         fatal_lang_error('numbers_one_to_nine', false);
     }
     // Split at a specific topic
     $splitAt = (int) $_GET['at'];
     // We deal with topics here.
     require_once SUBSDIR . '/Boards.subs.php';
     require_once SUBSDIR . '/Messages.subs.php';
     // Let's load up the boards in case they are useful.
     $context += getBoardList(array('not_redirection' => true));
     // Retrieve message info for the message at the split point.
     $messageInfo = basicMessageInfo($splitAt, false, true);
     if ($messageInfo === false) {
         fatal_lang_error('cant_find_messages');
     }
     // If not approved validate they can approve it.
     if ($modSettings['postmod_active'] && !$messageInfo['topic_approved']) {
         isAllowedTo('approve_posts');
     }
     // If this topic has unapproved posts, we need to count them too...
     if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
         $messageInfo['num_replies'] += $messageInfo['unapproved_posts'] - ($messageInfo['topic_approved'] ? 0 : 1);
     }
     $context['can_move'] = allowedTo('move_any') || allowedTo('move_own');
     // Check if there is more than one message in the topic.  (there should be.)
     if ($messageInfo['num_replies'] < 1) {
         fatal_lang_error('topic_one_post', false);
     }
     // Check if this is the first message in the topic (if so, the first and second option won't be available)
     if ($messageInfo['id_first_msg'] == $splitAt) {
         $this->_new_topic_subject = $messageInfo['subject'];
         $this->_set_session_values();
         return $this->action_splitSelectTopics();
     }
     // Basic template information....
     $context['message'] = array('id' => $splitAt, 'subject' => $messageInfo['subject']);
     $context['sub_template'] = 'ask';
     $context['page_title'] = $txt['split_topic'];
 }
コード例 #20
0
 /**
  * Show permissions for a user.
  */
 public function action_showPermissions()
 {
     global $txt, $board, $user_profile, $context, $scripturl;
     // Verify if the user has sufficient permissions.
     isAllowedTo('manage_permissions');
     loadLanguage('ManagePermissions');
     loadLanguage('Admin');
     loadTemplate('ManageMembers');
     loadTemplate('ProfileInfo');
     // Load all the permission profiles.
     require_once SUBSDIR . '/ManagePermissions.subs.php';
     loadPermissionProfiles();
     $memID = currentMemberID();
     $context['member']['id'] = $memID;
     $context['member']['name'] = $user_profile[$memID]['real_name'];
     $context['page_title'] = $txt['showPermissions'];
     $board = empty($board) ? 0 : (int) $board;
     $context['board'] = $board;
     // Determine which groups this user is in.
     if (empty($user_profile[$memID]['additional_groups'])) {
         $curGroups = array();
     } else {
         $curGroups = explode(',', $user_profile[$memID]['additional_groups']);
     }
     $curGroups[] = $user_profile[$memID]['id_group'];
     $curGroups[] = $user_profile[$memID]['id_post_group'];
     // Load a list of boards for the jump box - except the defaults.
     require_once SUBSDIR . '/Boards.subs.php';
     $board_list = getBoardList(array('moderator' => $memID), true);
     $context['boards'] = array();
     $context['no_access_boards'] = array();
     foreach ($board_list as $row) {
         if (count(array_intersect($curGroups, explode(',', $row['member_groups']))) === 0 && !$row['is_mod']) {
             $context['no_access_boards'][] = array('id' => $row['id_board'], 'name' => $row['board_name'], 'is_last' => false);
         } elseif ($row['id_profile'] != 1 || $row['is_mod']) {
             $context['boards'][$row['id_board']] = array('id' => $row['id_board'], 'name' => $row['board_name'], 'url' => $scripturl, '?board=', $row['id_board'], '.0', 'selected' => $board == $row['id_board'], 'profile' => $row['id_profile'], 'profile_name' => $context['profiles'][$row['id_profile']]['name']);
         }
     }
     if (!empty($context['no_access_boards'])) {
         $context['no_access_boards'][count($context['no_access_boards']) - 1]['is_last'] = true;
     }
     $context['member']['permissions'] = array('general' => array(), 'board' => array());
     // If you're an admin we know you can do everything, we might as well leave.
     $context['member']['has_all_permissions'] = in_array(1, $curGroups);
     if ($context['member']['has_all_permissions']) {
         return;
     }
     // Get all general permissions for the groups this member is in
     $context['member']['permissions']['general'] = getMemberGeneralPermissions($curGroups);
     // Get all board permissions for this member
     $context['member']['permissions']['board'] = getMemberBoardPermissions($memID, $curGroups, $board);
 }
コード例 #21
0
ファイル: ManageSmileys.php プロジェクト: valek0972/hackits
function EditMessageIcons()
{
    global $user_info, $modSettings, $context, $settings, $txt;
    global $boarddir, $smcFunc, $scripturl, $sourcedir;
    // Get a list of icons.
    $context['icons'] = array();
    $request = $smcFunc['db_query']('', '
		SELECT m.id_icon, m.title, m.filename, m.icon_order, m.id_board, b.name AS board_name
		FROM {db_prefix}message_icons AS m
			LEFT JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
		WHERE ({query_see_board} OR b.id_board IS NULL)', array());
    $last_icon = 0;
    $trueOrder = 0;
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['icons'][$row['id_icon']] = array('id' => $row['id_icon'], 'title' => $row['title'], 'filename' => $row['filename'], 'image_url' => $settings[file_exists($settings['theme_dir'] . '/images/post/' . $row['filename'] . '.gif') ? 'actual_images_url' : 'default_images_url'] . '/post/' . $row['filename'] . '.gif', 'board_id' => $row['id_board'], 'board' => empty($row['board_name']) ? $txt['icons_edit_icons_all_boards'] : $row['board_name'], 'order' => $row['icon_order'], 'true_order' => $trueOrder++, 'after' => $last_icon);
        $last_icon = $row['id_icon'];
    }
    $smcFunc['db_free_result']($request);
    // Submitting a form?
    if (isset($_POST[$context['session_var']])) {
        checkSession();
        // Deleting icons?
        if (isset($_POST['delete']) && !empty($_POST['checked_icons'])) {
            $deleteIcons = array();
            foreach ($_POST['checked_icons'] as $icon) {
                $deleteIcons[] = (int) $icon;
            }
            // Do the actual delete!
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}message_icons
				WHERE id_icon IN ({array_int:icon_list})', array('icon_list' => $deleteIcons));
        } elseif ($context['sub_action'] == 'editicon' && isset($_GET['icon'])) {
            $_GET['icon'] = (int) $_GET['icon'];
            // Do some preperation with the data... like check the icon exists *somewhere*
            if (strpos($_POST['icon_filename'], '.gif') !== false) {
                $_POST['icon_filename'] = substr($_POST['icon_filename'], 0, -4);
            }
            if (!file_exists($settings['default_theme_dir'] . '/images/post/' . $_POST['icon_filename'] . '.gif')) {
                fatal_lang_error('icon_not_found');
            } elseif (strlen($_POST['icon_filename']) > 16) {
                fatal_lang_error('icon_name_too_long');
            } elseif ($_POST['icon_location'] == $_GET['icon'] && !empty($_GET['icon'])) {
                fatal_lang_error('icon_after_itself');
            }
            // First do the sorting... if this is an edit reduce the order of everything after it by one ;)
            if ($_GET['icon'] != 0) {
                $oldOrder = $context['icons'][$_GET['icon']]['true_order'];
                foreach ($context['icons'] as $id => $data) {
                    if ($data['true_order'] > $oldOrder) {
                        $context['icons'][$id]['true_order']--;
                    }
                }
            }
            // If there are no existing icons and this is a new one, set the id to 1 (mainly for non-mysql)
            if (empty($_GET['icon']) && empty($context['icons'])) {
                $_GET['icon'] = 1;
            }
            // Get the new order.
            $newOrder = $_POST['icon_location'] == 0 ? 0 : $context['icons'][$_POST['icon_location']]['true_order'] + 1;
            // Do the same, but with the one that used to be after this icon, done to avoid conflict.
            foreach ($context['icons'] as $id => $data) {
                if ($data['true_order'] >= $newOrder) {
                    $context['icons'][$id]['true_order']++;
                }
            }
            // Finally set the current icon's position!
            $context['icons'][$_GET['icon']]['true_order'] = $newOrder;
            // Simply replace the existing data for the other bits.
            $context['icons'][$_GET['icon']]['title'] = $_POST['icon_description'];
            $context['icons'][$_GET['icon']]['filename'] = $_POST['icon_filename'];
            $context['icons'][$_GET['icon']]['board_id'] = (int) $_POST['icon_board'];
            // Do a huge replace ;)
            $iconInsert = array();
            $iconInsert_new = array();
            foreach ($context['icons'] as $id => $icon) {
                if ($id != 0) {
                    $iconInsert[] = array($id, $icon['board_id'], $icon['title'], $icon['filename'], $icon['true_order']);
                } else {
                    $iconInsert_new[] = array($icon['board_id'], $icon['title'], $icon['filename'], $icon['true_order']);
                }
            }
            $smcFunc['db_insert']('replace', '{db_prefix}message_icons', array('id_icon' => 'int', 'id_board' => 'int', 'title' => 'string-80', 'filename' => 'string-80', 'icon_order' => 'int'), $iconInsert, array('id_icon'));
            if (!empty($iconInsert_new)) {
                $smcFunc['db_insert']('replace', '{db_prefix}message_icons', array('id_board' => 'int', 'title' => 'string-80', 'filename' => 'string-80', 'icon_order' => 'int'), $iconInsert_new, array('id_icon'));
            }
        }
        // Sort by order, so it is quicker :)
        $smcFunc['db_query']('alter_table_icons', '
			ALTER TABLE {db_prefix}message_icons
			ORDER BY icon_order', array('db_error_skip' => true));
        // Unless we're adding a new thing, we'll escape
        if (!isset($_POST['add'])) {
            redirectexit('action=admin;area=smileys;sa=editicons');
        }
    }
    $context[$context['admin_menu_name']]['current_subsection'] = 'editicons';
    $listOptions = array('id' => 'message_icon_list', 'base_href' => $scripturl . '?action=admin;area=smileys;sa=editicons', 'get_items' => array('function' => 'list_getMessageIcons'), 'no_items_label' => $txt['icons_no_entries'], 'columns' => array('icon' => array('data' => array('function' => create_function('$rowData', '
						global $settings;

						$images_url = $settings[file_exists(sprintf(\'%1$s/images/post/%2$s.gif\', $settings[\'theme_dir\'], $rowData[\'filename\'])) ? \'actual_images_url\' : \'default_images_url\'];
						return sprintf(\'<img src="%1$s/post/%2$s.gif" alt="%3$s" />\', $images_url, $rowData[\'filename\'], htmlspecialchars($rowData[\'title\']));
					')), 'style' => 'text-align: center;'), 'filename' => array('header' => array('value' => $txt['smileys_filename']), 'data' => array('sprintf' => array('format' => '%1$s.gif', 'params' => array('filename' => true)))), 'tooltip' => array('header' => array('value' => $txt['smileys_description']), 'data' => array('db_htmlsafe' => 'title', 'class' => 'windowbg')), 'board' => array('header' => array('value' => $txt['icons_board']), 'data' => array('function' => create_function('$rowData', '
						global $txt;

						return empty($rowData[\'board_name\']) ? $txt[\'icons_edit_icons_all_boards\'] : $rowData[\'board_name\'];
					'))), 'modify' => array('header' => array('value' => $txt['smileys_modify']), 'data' => array('sprintf' => array('format' => '<a href="' . $scripturl . '?action=admin;area=smileys;sa=editicon;icon=%1$s">' . $txt['smileys_modify'] . '</a>', 'params' => array('id_icon' => false)), 'style' => 'text-align: center')), 'check' => array('header' => array('value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check" />'), 'data' => array('sprintf' => array('format' => '<input type="checkbox" name="checked_icons[]" value="%1$d" class="input_check" />', 'params' => array('id_icon' => false)), 'style' => 'text-align: center'))), 'form' => array('href' => $scripturl . '?action=admin;area=smileys;sa=editicons'), 'additional_rows' => array(array('position' => 'below_table_data', 'value' => '<input type="submit" name="delete" value="' . $txt['quickmod_delete_selected'] . '" style="float: right" class="button_submit" />[<a href="' . $scripturl . '?action=admin;area=smileys;sa=editicon">' . $txt['icons_add_new'] . '</a>]')));
    require_once $sourcedir . '/Subs-List.php';
    createList($listOptions);
    // If we're adding/editing an icon we'll need a list of boards
    if ($context['sub_action'] == 'editicon' || isset($_POST['add'])) {
        // Force the sub_template just in case.
        $context['sub_template'] = 'editicon';
        $context['new_icon'] = !isset($_GET['icon']);
        // Get the properties of the current icon from the icon list.
        if (!$context['new_icon']) {
            $context['icon'] = $context['icons'][$_GET['icon']];
        }
        // Get a list of boards needed for assigning this icon to a specific board.
        $boardListOptions = array('use_permissions' => true, 'selected_board' => isset($context['icon']['board_id']) ? $context['icon']['board_id'] : 0);
        require_once $sourcedir . '/Subs-MessageIndex.php';
        $context['categories'] = getBoardList($boardListOptions);
    }
}
コード例 #22
0
ファイル: Post.php プロジェクト: albertlast/SMF2.1
/**
 * 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');
    }
}
コード例 #23
0
 /**
  * This function allows to move a topic, making sure to ask the moderator
  * to give reason for topic move.
  * It must be called with a topic specified. (that is, global $topic must
  * be set... @todo fix this thing.)
  * If the member is the topic starter requires the move_own permission,
  * otherwise the move_any permission.
  * Accessed via ?action=movetopic.
  *
  * @uses the MoveTopic template, main sub-template.
  */
 public function action_movetopic()
 {
     global $txt, $topic, $user_info, $context, $language, $scripturl, $modSettings;
     if (empty($topic)) {
         fatal_lang_error('no_access', false);
     }
     // Retrieve the basic topic information for whats being moved
     require_once SUBSDIR . '/Topic.subs.php';
     $topic_info = getTopicInfo($topic, 'message');
     if (empty($topic_info)) {
         fatal_lang_error('topic_gone', false);
     }
     $context['is_approved'] = $topic_info['approved'];
     $context['subject'] = $topic_info['subject'];
     // Can they see it - if not approved?
     if ($modSettings['postmod_active'] && !$context['is_approved']) {
         isAllowedTo('approve_posts');
     }
     // Are they allowed to actually move any topics or even their own?
     if (!allowedTo('move_any') && ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('move_own'))) {
         fatal_lang_error('cannot_move_any', false);
     }
     loadTemplate('MoveTopic');
     // Get a list of boards this moderator can move to.
     require_once SUBSDIR . '/Boards.subs.php';
     $context += getBoardList(array('not_redirection' => true));
     // No boards?
     if (empty($context['categories']) || $context['num_boards'] == 1) {
         fatal_lang_error('moveto_noboards', false);
     }
     // Already used the function, let's set the selected board back to the last
     $last_moved_to = isset($_SESSION['move_to_topic']['move_to']) && $_SESSION['move_to_topic']['move_to'] != $context['current_board'] ? (int) $_SESSION['move_to_topic']['move_to'] : 0;
     if (!empty($last_moved_to)) {
         foreach ($context['categories'] as $id => $values) {
             if (isset($values['boards'][$last_moved_to])) {
                 $context['categories'][$id]['boards'][$last_moved_to]['selected'] = true;
                 break;
             }
         }
     }
     // Set up for the template
     $context['redirect_topic'] = isset($_SESSION['move_to_topic']['redirect_topic']) ? (int) $_SESSION['move_to_topic']['redirect_topic'] : 0;
     $context['redirect_expires'] = isset($_SESSION['move_to_topic']['redirect_expires']) ? (int) $_SESSION['move_to_topic']['redirect_expires'] : 0;
     $context['page_title'] = $txt['move_topic'];
     $context['sub_template'] = 'move_topic';
     // Breadcrumbs
     $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $context['subject']);
     $context['linktree'][] = array('url' => '#', 'name' => $txt['move_topic']);
     $context['back_to_topic'] = isset($_REQUEST['goback']);
     // Ugly !
     if ($user_info['language'] != $language) {
         loadLanguage('index', $language);
         $temp = $txt['movetopic_default'];
         loadLanguage('index');
         $txt['movetopic_default'] = $temp;
     }
     // We will need this
     moveTopicConcurrence();
     // Register this form and get a sequence number in $context.
     checkSubmitOnce('register');
 }
コード例 #24
0
 /**
  * Ask the user what they want to search for.
  *
  * What it does:
  * - shows the screen to search forum posts (action=search),
  * - uses the main sub template of the Search template.
  * - uses the Search language file.
  * - requires the search_posts permission.
  * - decodes and loads search parameters given in the URL (if any).
  * - the form redirects to index.php?action=search;sa=results.
  *
  * @uses Search language file and Errors language when needed
  * @uses Search template, searchform sub template
  */
 public function action_search()
 {
     global $txt, $scripturl, $modSettings, $user_info, $context;
     // Is the load average too high to allow searching just now?
     if (!empty($modSettings['loadavg_search']) && $modSettings['current_load'] >= $modSettings['loadavg_search']) {
         fatal_lang_error('loadavg_search_disabled', false);
     }
     loadLanguage('Search');
     // Don't load this in XML mode.
     if (!isset($_REQUEST['xml'])) {
         loadTemplate('Search');
         $context['sub_template'] = 'searchform';
         loadJavascriptFile('suggest.js', array('defer' => true));
     }
     // Check the user's permissions.
     isAllowedTo('search_posts');
     // Link tree....
     $context['linktree'][] = array('url' => $scripturl . '?action=search', 'name' => $txt['search']);
     // This is hard coded maximum string length.
     $context['search_string_limit'] = 100;
     $context['require_verification'] = $user_info['is_guest'] && !empty($modSettings['search_enable_captcha']) && empty($_SESSION['ss_vv_passed']);
     if ($context['require_verification']) {
         require_once SUBSDIR . '/VerificationControls.class.php';
         $verificationOptions = array('id' => 'search');
         $context['require_verification'] = create_control_verification($verificationOptions);
         $context['visual_verification_id'] = $verificationOptions['id'];
     }
     // If you got back from search;sa=results by using the linktree, you get your original search parameters back.
     if (isset($_REQUEST['params'])) {
         // Due to IE's 2083 character limit, we have to compress long search strings
         $temp_params = base64_decode(str_replace(array('-', '_', '.'), array('+', '/', '='), $_REQUEST['params']));
         // Test for gzuncompress failing
         $temp_params2 = @gzuncompress($temp_params);
         $temp_params = explode('|"|', !empty($temp_params2) ? $temp_params2 : $temp_params);
         $context['search_params'] = array();
         foreach ($temp_params as $i => $data) {
             @(list($k, $v) = explode('|\'|', $data));
             $context['search_params'][$k] = $v;
         }
         if (isset($context['search_params']['brd'])) {
             $context['search_params']['brd'] = $context['search_params']['brd'] == '' ? array() : explode(',', $context['search_params']['brd']);
         }
     }
     if (isset($_REQUEST['search'])) {
         $context['search_params']['search'] = un_htmlspecialchars($_REQUEST['search']);
     }
     if (isset($context['search_params']['search'])) {
         $context['search_params']['search'] = Util::htmlspecialchars($context['search_params']['search']);
     }
     if (isset($context['search_params']['userspec'])) {
         $context['search_params']['userspec'] = htmlspecialchars($context['search_params']['userspec'], ENT_COMPAT, 'UTF-8');
     }
     if (!empty($context['search_params']['searchtype'])) {
         $context['search_params']['searchtype'] = 2;
     }
     if (!empty($context['search_params']['minage'])) {
         $context['search_params']['minage'] = (int) $context['search_params']['minage'];
     }
     if (!empty($context['search_params']['maxage'])) {
         $context['search_params']['maxage'] = (int) $context['search_params']['maxage'];
     }
     $context['search_params']['show_complete'] = !empty($context['search_params']['show_complete']);
     $context['search_params']['subject_only'] = !empty($context['search_params']['subject_only']);
     // Load the error text strings if there were errors in the search.
     if (!empty($context['search_errors'])) {
         loadLanguage('Errors');
         $context['search_errors']['messages'] = array();
         foreach ($context['search_errors'] as $search_error => $dummy) {
             if ($search_error === 'messages') {
                 continue;
             }
             if ($search_error == 'string_too_long') {
                 $txt['error_string_too_long'] = sprintf($txt['error_string_too_long'], $context['search_string_limit']);
             }
             $context['search_errors']['messages'][] = $txt['error_' . $search_error];
         }
     }
     require_once SUBSDIR . '/Boards.subs.php';
     $context += getBoardList(array('not_redirection' => true));
     $context['boards_in_category'] = array();
     foreach ($context['categories'] as $cat => &$category) {
         $context['boards_in_category'][$cat] = count($category['boards']);
         $category['child_ids'] = array_keys($category['boards']);
         foreach ($category['boards'] as &$board) {
             $board['selected'] = empty($context['search_params']['brd']) && (empty($modSettings['recycle_enable']) || $board['id'] != $modSettings['recycle_board']) && !in_array($board['id'], $user_info['ignoreboards']) || !empty($context['search_params']['brd']) && in_array($board['id'], $context['search_params']['brd']);
         }
     }
     if (!empty($_REQUEST['topic'])) {
         $context['search_params']['topic'] = (int) $_REQUEST['topic'];
         $context['search_params']['show_complete'] = true;
     }
     if (!empty($context['search_params']['topic'])) {
         $context['search_params']['topic'] = (int) $context['search_params']['topic'];
         $context['search_topic'] = array('id' => $context['search_params']['topic'], 'href' => $scripturl . '?topic=' . $context['search_params']['topic'] . '.0');
         require_once SUBSDIR . '/Topic.subs.php';
         $context['search_topic']['subject'] = getSubject($context['search_params']['topic']);
         $context['search_topic']['link'] = '<a href="' . $context['search_topic']['href'] . '">' . $context['search_topic']['subject'] . '</a>';
     }
     $context['page_title'] = $txt['set_parameters'];
     $context['search_params'] = $this->_fill_default_search_params($context['search_params']);
     // Start guest off collapsed
     if ($context['user']['is_guest'] && !isset($context['minmax_preferences']['asearch'])) {
         $context['minmax_preferences']['asearch'] = 1;
     }
     call_integration_hook('integrate_search');
 }
コード例 #25
0
ファイル: Who.subs.php プロジェクト: KeiroD/Elkarte
/**
 * This function determines the actions of the members passed in urls.
 *
 * Adding actions to the Who's Online list:
 * Adding actions to this list is actually relatively easy...
 * - for actions anyone should be able to see, just add a string named whoall_ACTION.
 *   (where ACTION is the action used in index.php.)
 * - for actions that have a subaction which should be represented differently, use whoall_ACTION_SUBACTION.
 * - for actions that include a topic, and should be restricted, use whotopic_ACTION.
 * - for actions that use a message, by msg or quote, use whopost_ACTION.
 * - for administrator-only actions, use whoadmin_ACTION.
 * - for actions that should be viewable only with certain permissions, use whoallow_ACTION and
 * add a list of possible permissions to the $allowedActions array, using ACTION as the key.
 *
 * @param mixed[]|string $urls a single url (string) or an array of arrays, each inner array being (serialized request data, id_member)
 * @param string|false $preferred_prefix = false
 * @return mixed[]|string an array of descriptions if you passed an array, otherwise the string describing their current location.
 */
function determineActions($urls, $preferred_prefix = false)
{
    global $txt, $user_info, $modSettings, $scripturl;
    $db = database();
    if (!allowedTo('who_view')) {
        return array();
    }
    loadLanguage('Who');
    // Actions that require a specific permission level.
    $allowedActions = array('admin' => array('moderate_forum', 'manage_membergroups', 'manage_bans', 'admin_forum', 'manage_permissions', 'send_mail', 'manage_attachments', 'manage_smileys', 'manage_boards', 'edit_news'), 'ban' => array('manage_bans'), 'boardrecount' => array('admin_forum'), 'calendar' => array('calendar_view'), 'editnews' => array('edit_news'), 'mailing' => array('send_mail'), 'maintain' => array('admin_forum'), 'manageattachments' => array('manage_attachments'), 'manageboards' => array('manage_boards'), 'memberlist' => array('view_mlist'), 'moderate' => array('access_mod_center', 'moderate_forum', 'manage_membergroups'), 'optimizetables' => array('admin_forum'), 'repairboards' => array('admin_forum'), 'search' => array('search_posts'), 'setcensor' => array('moderate_forum'), 'setreserve' => array('moderate_forum'), 'stats' => array('view_stats'), 'viewErrorLog' => array('admin_forum'), 'viewmembers' => array('moderate_forum'));
    // Provide integration a way to add to the allowed action array
    call_integration_hook('integrate_whos_online_allowed', array(&$allowedActions));
    if (!is_array($urls)) {
        $url_list = array(array($urls, $user_info['id']));
    } else {
        $url_list = $urls;
    }
    // These are done to query these in large chunks. (instead of one by one.)
    $topic_ids = array();
    $profile_ids = array();
    $board_ids = array();
    $data = array();
    foreach ($url_list as $k => $url) {
        // Get the request parameters..
        $actions = @unserialize($url[0]);
        if ($actions === false) {
            continue;
        }
        // If it's the admin or moderation center, and there is an area set, use that instead.
        if (isset($actions['action']) && ($actions['action'] == 'admin' || $actions['action'] == 'moderate') && isset($actions['area'])) {
            $actions['action'] = $actions['area'];
        }
        // Check if there was no action or the action is display.
        if (!isset($actions['action']) || $actions['action'] == 'display') {
            // It's a topic!  Must be!
            if (isset($actions['topic'])) {
                // Assume they can't view it, and queue it up for later.
                $data[$k] = $txt['who_hidden'];
                $topic_ids[(int) $actions['topic']][$k] = $txt['who_topic'];
            } elseif (isset($actions['board'])) {
                // Hide first, show later.
                $data[$k] = $txt['who_hidden'];
                $board_ids[$actions['board']][$k] = $txt['who_board'];
            } else {
                $data[$k] = replaceBasicActionUrl($txt['who_index']);
            }
        } elseif ($actions['action'] == '') {
            $data[$k] = replaceBasicActionUrl($txt['who_index']);
        } else {
            // Viewing/editing a profile.
            if ($actions['action'] == 'profile') {
                // Whose?  Their own?
                if (empty($actions['u'])) {
                    require_once SUBSDIR . '/Profile.subs.php';
                    $memID = currentMemberID();
                    if ($memID == $user_info['id']) {
                        $actions['u'] = $url[1];
                    } else {
                        $actions['u'] = $memID;
                    }
                }
                $data[$k] = $txt['who_hidden'];
                $profile_ids[(int) $actions['u']][$k] = $actions['action'] == 'profile' ? $txt['who_viewprofile'] : $txt['who_profile'];
            } elseif (($actions['action'] == 'post' || $actions['action'] == 'post2' || $actions['action'] == 'topicbyemail') && empty($actions['topic']) && isset($actions['board'])) {
                $data[$k] = $txt['who_hidden'];
                if ($actions['action'] == 'topicbyemail') {
                    $board_ids[(int) $actions['board']][$k] = $txt['who_topicbyemail'];
                } else {
                    $board_ids[(int) $actions['board']][$k] = isset($actions['poll']) ? $txt['who_poll'] : $txt['who_post'];
                }
            } elseif (isset($actions['sa']) && isset($txt['whoall_' . $actions['action'] . '_' . $actions['sa']])) {
                $data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']]) ? $txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']] : $txt['whoall_' . $actions['action'] . '_' . $actions['sa']];
            } elseif (isset($txt['whoall_' . $actions['action']])) {
                $data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action']]) ? $txt[$preferred_prefix . $actions['action']] : replaceBasicActionUrl($txt['whoall_' . $actions['action']]);
            } elseif (isset($txt['whotopic_' . $actions['action']])) {
                // Find out what topic they are accessing.
                $topic = (int) (isset($actions['topic']) ? $actions['topic'] : (isset($actions['from']) ? $actions['from'] : 0));
                $data[$k] = $txt['who_hidden'];
                $topic_ids[$topic][$k] = $txt['whotopic_' . $actions['action']];
            } elseif (isset($actions['sa']) && isset($txt['whotopic_' . $actions['action'] . '_' . $actions['sa']])) {
                // Find out what topic they are accessing.
                $topic = (int) (isset($actions['topic']) ? $actions['topic'] : (isset($actions['from']) ? $actions['from'] : 0));
                $data[$k] = $txt['who_hidden'];
                $topic_ids[$topic][$k] = $txt['whotopic_' . $actions['action'] . '_' . $actions['sa']];
            } elseif (isset($txt['whopost_' . $actions['action']])) {
                // Find out what message they are accessing.
                $msgid = (int) (isset($actions['msg']) ? $actions['msg'] : (isset($actions['quote']) ? $actions['quote'] : 0));
                $result = $db->query('', '
					SELECT m.id_topic, m.subject
					FROM {db_prefix}messages AS m
						INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
						INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ')
					WHERE m.id_msg = {int:id_msg}
						AND {query_see_board}' . ($modSettings['postmod_active'] ? '
						AND m.approved = {int:is_approved}' : '') . '
					LIMIT 1', array('is_approved' => 1, 'id_msg' => $msgid));
                list($id_topic, $subject) = $db->fetch_row($result);
                $data[$k] = sprintf($txt['whopost_' . $actions['action']], $scripturl . '?topic=' . $id_topic . '.0', $subject);
                $db->free_result($result);
                if (empty($id_topic)) {
                    $data[$k] = $txt['who_hidden'];
                }
            } elseif (allowedTo('moderate_forum') && isset($txt['whoadmin_' . $actions['action']])) {
                $data[$k] = $txt['whoadmin_' . $actions['action']];
            } elseif (isset($allowedActions[$actions['action']])) {
                if (allowedTo($allowedActions[$actions['action']])) {
                    if (isset($actions['sa']) && isset($txt['whoallow_' . $actions['action'] . '_' . $actions['sa']])) {
                        $data[$k] = replaceBasicActionUrl($txt['whoallow_' . $actions['action'] . '_' . $actions['sa']]);
                    } else {
                        $data[$k] = replaceBasicActionUrl($txt['whoallow_' . $actions['action']]);
                    }
                } elseif (in_array('moderate_forum', $allowedActions[$actions['action']])) {
                    $data[$k] = $txt['who_moderate'];
                } elseif (in_array('admin_forum', $allowedActions[$actions['action']])) {
                    $data[$k] = $txt['who_admin'];
                } else {
                    $data[$k] = $txt['who_hidden'];
                }
            } elseif (!empty($actions['action'])) {
                $data[$k] = sprintf($txt['who_generic'], $actions['action']);
            } else {
                $data[$k] = $txt['who_unknown'];
            }
        }
        // Maybe the action is integrated into another system?
        if (count($integrate_actions = call_integration_hook('integrate_whos_online', array($actions))) > 0) {
            // Try each integraion hook with this url and see if they can fill in the details
            foreach ($integrate_actions as $integrate_action) {
                if (!empty($integrate_action)) {
                    // Found it, all done then
                    $data[$k] = $integrate_action;
                    break;
                }
            }
        }
    }
    // Load topic names.
    if (!empty($topic_ids)) {
        require_once SUBSDIR . '/Topic.subs.php';
        $topics_data = topicsList(array_keys($topic_ids));
        foreach ($topics_data as $topic) {
            // Show the topic's subject for each of the members looking at this...
            foreach ($topic_ids[$topic['id_topic']] as $k => $session_text) {
                $data[$k] = sprintf($session_text, $scripturl . '?topic=' . $topic['id_topic'] . '.0', $topic['subject']);
            }
        }
    }
    // Load board names.
    if (!empty($board_ids)) {
        require_once SUBSDIR . '/Boards.subs.php';
        $boards_list = getBoardList(array('included_boards' => array_keys($board_ids)), true);
        foreach ($boards_list as $board) {
            // Put the board name into the string for each member...
            foreach ($board_ids[$board['id_board']] as $k => $session_text) {
                $data[$k] = sprintf($session_text, $scripturl . '?board=' . $board['id_board'] . '.0', $board['board_name']);
            }
        }
    }
    // Load member names for the profile.
    if (!empty($profile_ids) && (allowedTo('profile_view_any') || allowedTo('profile_view_own'))) {
        require_once SUBSDIR . '/Members.subs.php';
        $result = getBasicMemberData(array_keys($profile_ids));
        foreach ($result as $row) {
            // If they aren't allowed to view this person's profile, skip it.
            if (!allowedTo('profile_view_any') && $user_info['id'] != $row['id_member']) {
                continue;
            }
            // Set their action on each - session/text to sprintf.
            foreach ($profile_ids[$row['id_member']] as $k => $session_text) {
                $data[$k] = sprintf($session_text, $scripturl . '?action=profile;u=' . $row['id_member'], $row['real_name']);
            }
        }
    }
    if (!is_array($urls)) {
        return isset($data[0]) ? $data[0] : false;
    } else {
        return $data;
    }
}
コード例 #26
0
    /**
     * Set merge options and do the actual merge of two or more topics.
     *
     * the merge options screen:
     * * shows topics to be merged and allows to set some merge options.
     * * is accessed by ?action=mergetopics;sa=options.and can also internally be called by action_quickmod().
     * * uses 'merge_extra_options' sub template of the MergeTopics template.
     *
     * the actual merge:
     * * is accessed with ?action=mergetopics;sa=execute.
     * * updates the statistics to reflect the merge.
     * * logs the action in the moderation log.
     * * sends a notification is sent to all users monitoring this topic.
     * * redirects to ?action=mergetopics;sa=done.
     *
     * @param int[] $topics = array() of topic ids
     */
    public function action_mergeExecute($topics = array())
    {
        global $user_info, $txt, $context, $scripturl, $modSettings;
        $db = database();
        // Check the session.
        checkSession('request');
        require_once SUBSDIR . '/Topic.subs.php';
        require_once SUBSDIR . '/Post.subs.php';
        // Handle URLs from action_mergeIndex.
        if (!empty($_GET['from']) && !empty($_GET['to'])) {
            $topics = array((int) $_GET['from'], (int) $_GET['to']);
        }
        // If we came from a form, the topic IDs came by post.
        if (!empty($_POST['topics']) && is_array($_POST['topics'])) {
            $topics = $_POST['topics'];
        }
        // There's nothing to merge with just one topic...
        if (empty($topics) || !is_array($topics) || count($topics) == 1) {
            fatal_lang_error('merge_need_more_topics');
        }
        // Make sure every topic is numeric, or some nasty things could be done with the DB.
        foreach ($topics as $id => $topic) {
            $topics[$id] = (int) $topic;
        }
        // Joy of all joys, make sure they're not pi**ing about with unapproved topics they can't see :P
        if ($modSettings['postmod_active']) {
            $can_approve_boards = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts');
        }
        // Get info about the topics and polls that will be merged.
        $request = $db->query('', '
			SELECT
				t.id_topic, t.id_board, b.id_cat, t.id_poll, t.num_views, t.is_sticky, t.approved, t.num_replies, t.unapproved_posts,
				m1.subject, m1.poster_time AS time_started, IFNULL(mem1.id_member, 0) AS id_member_started, IFNULL(mem1.real_name, m1.poster_name) AS name_started,
				m2.poster_time AS time_updated, IFNULL(mem2.id_member, 0) AS id_member_updated, IFNULL(mem2.real_name, m2.poster_name) AS name_updated
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg)
				INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg)
				LEFT JOIN {db_prefix}members AS mem1 ON (mem1.id_member = m1.id_member)
				LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
				LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE t.id_topic IN ({array_int:topic_list})
			ORDER BY t.id_first_msg
			LIMIT ' . count($topics), array('topic_list' => $topics));
        if ($db->num_rows($request) < 2) {
            fatal_lang_error('no_topic_id');
        }
        $num_views = 0;
        $is_sticky = 0;
        $boardTotals = array();
        $topic_data = array();
        $boards = array();
        $polls = array();
        $firstTopic = 0;
        $firstBoard = 0;
        while ($row = $db->fetch_assoc($request)) {
            // Make a note for the board counts...
            if (!isset($boardTotals[$row['id_board']])) {
                $boardTotals[$row['id_board']] = array('num_posts' => 0, 'num_topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
            }
            // We can't see unapproved topics here?
            if ($modSettings['postmod_active'] && !$row['approved'] && $can_approve_boards != array(0) && in_array($row['id_board'], $can_approve_boards)) {
                continue;
            } elseif (!$row['approved']) {
                $boardTotals[$row['id_board']]['unapproved_topics']++;
            } else {
                $boardTotals[$row['id_board']]['num_topics']++;
            }
            $boardTotals[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts'];
            $boardTotals[$row['id_board']]['num_posts'] += $row['num_replies'] + ($row['approved'] ? 1 : 0);
            $topic_data[$row['id_topic']] = array('id' => $row['id_topic'], 'board' => $row['id_board'], 'poll' => $row['id_poll'], 'num_views' => $row['num_views'], 'subject' => $row['subject'], 'started' => array('time' => standardTime($row['time_started']), 'html_time' => htmlTime($row['time_started']), 'timestamp' => forum_time(true, $row['time_started']), 'href' => empty($row['id_member_started']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_started'], 'link' => empty($row['id_member_started']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_started'] . '">' . $row['name_started'] . '</a>'), 'updated' => array('time' => standardTime($row['time_updated']), 'html_time' => htmlTime($row['time_updated']), 'timestamp' => forum_time(true, $row['time_updated']), 'href' => empty($row['id_member_updated']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_updated'], 'link' => empty($row['id_member_updated']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_updated'] . '">' . $row['name_updated'] . '</a>'));
            $num_views += $row['num_views'];
            $boards[] = $row['id_board'];
            // If there's no poll, id_poll == 0...
            if ($row['id_poll'] > 0) {
                $polls[] = $row['id_poll'];
            }
            // Store the id_topic with the lowest id_first_msg.
            if (empty($firstTopic)) {
                $firstTopic = $row['id_topic'];
                $firstBoard = $row['id_board'];
            }
            $is_sticky = max($is_sticky, $row['is_sticky']);
        }
        $db->free_result($request);
        // If we didn't get any topics then they've been messing with unapproved stuff.
        if (empty($topic_data)) {
            fatal_lang_error('no_topic_id');
        }
        $boards = array_values(array_unique($boards));
        // The parameters of action_mergeExecute were set, so this must've been an internal call.
        if (!empty($topics)) {
            isAllowedTo('merge_any', $boards);
            loadTemplate('MergeTopics');
        }
        // Get the boards a user is allowed to merge in.
        $merge_boards = boardsAllowedTo('merge_any');
        if (empty($merge_boards)) {
            fatal_lang_error('cannot_merge_any', 'user');
        }
        require_once SUBSDIR . '/Boards.subs.php';
        // Make sure they can see all boards....
        $query_boards = array('boards' => $boards);
        if (!in_array(0, $merge_boards)) {
            $query_boards['boards'] = array_merge($query_boards['boards'], $merge_boards);
        }
        // Saved in a variable to (potentially) save a query later
        $boards_info = fetchBoardsInfo($query_boards);
        $boardListOptions = array('not_redirection' => true, 'selected_board' => $firstBoard);
        if (!in_array(0, $merge_boards)) {
            $boardListOptions['included_boards'] = $merge_boards;
        }
        $context += getBoardList($boardListOptions);
        // This is removed to avoid the board not being selectable.
        $context['current_board'] = null;
        // This happens when a member is moderator of a board he cannot see
        foreach ($boards as $board) {
            if (!isset($boards_info[$board])) {
                fatal_lang_error('no_board');
            }
        }
        if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options') {
            if (count($polls) > 1) {
                $request = $db->query('', '
					SELECT t.id_topic, t.id_poll, m.subject, p.question
					FROM {db_prefix}polls AS p
						INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
						INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
					WHERE p.id_poll IN ({array_int:polls})
					LIMIT ' . count($polls), array('polls' => $polls));
                while ($row = $db->fetch_assoc($request)) {
                    $context['polls'][] = array('id' => $row['id_poll'], 'topic' => array('id' => $row['id_topic'], 'subject' => $row['subject']), 'question' => $row['question'], 'selected' => $row['id_topic'] == $firstTopic);
                }
                $db->free_result($request);
            }
            if (count($boards) > 1) {
                // @deprecated since 1.0.3 - Kept in the remote case someone created a theme changing MergeTopics.template.php
                foreach ($boards_info as $row) {
                    $context['boards'][] = array('id' => $row['id_board'], 'name' => $row['name'], 'selected' => $row['id_board'] == $topic_data[$firstTopic]['board']);
                }
            }
            $context['topics'] = $topic_data;
            foreach ($topic_data as $id => $topic) {
                $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic;
            }
            $context['page_title'] = $txt['merge'];
            $context['sub_template'] = 'merge_extra_options';
            return;
        }
        // Determine target board.
        $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];
        if (!in_array($target_board, array_keys($boards_info))) {
            fatal_lang_error('no_board');
        }
        // Determine which poll will survive and which polls won't.
        $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0);
        if ($target_poll > 0 && !in_array($target_poll, $polls)) {
            fatal_lang_error('no_access', false);
        }
        $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll));
        // Determine the subject of the newly merged topic - was a custom subject specified?
        if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '') {
            $target_subject = strtr(Util::htmltrim(Util::htmlspecialchars($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
            // Keep checking the length.
            if (Util::strlen($target_subject) > 100) {
                $target_subject = Util::substr($target_subject, 0, 100);
            }
            // Nothing left - odd but pick the first topics subject.
            if ($target_subject == '') {
                $target_subject = $topic_data[$firstTopic]['subject'];
            }
        } elseif (!empty($topic_data[(int) $_POST['subject']]['subject'])) {
            $target_subject = $topic_data[(int) $_POST['subject']]['subject'];
        } else {
            $target_subject = $topic_data[$firstTopic]['subject'];
        }
        // Get the first and last message and the number of messages....
        $request = $db->query('', '
			SELECT approved, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg, COUNT(*) AS message_count
			FROM {db_prefix}messages
			WHERE id_topic IN ({array_int:topics})
			GROUP BY approved
			ORDER BY approved DESC', array('topics' => $topics));
        $topic_approved = 1;
        $first_msg = 0;
        while ($row = $db->fetch_assoc($request)) {
            // If this is approved, or is fully unapproved.
            if ($row['approved'] || !isset($first_msg)) {
                $first_msg = $row['first_msg'];
                $last_msg = $row['last_msg'];
                if ($row['approved']) {
                    $num_replies = $row['message_count'] - 1;
                    $num_unapproved = 0;
                } else {
                    $topic_approved = 0;
                    $num_replies = 0;
                    $num_unapproved = $row['message_count'];
                }
            } else {
                // If this has a lower first_msg then the first post is not approved and hence the number of replies was wrong!
                if ($first_msg > $row['first_msg']) {
                    $first_msg = $row['first_msg'];
                    $num_replies++;
                    $topic_approved = 0;
                }
                $num_unapproved = $row['message_count'];
            }
        }
        $db->free_result($request);
        // Ensure we have a board stat for the target board.
        if (!isset($boardTotals[$target_board])) {
            $boardTotals[$target_board] = array('num_posts' => 0, 'num_topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
        }
        // Fix the topic count stuff depending on what the new one counts as.
        if ($topic_approved) {
            $boardTotals[$target_board]['num_topics']--;
        } else {
            $boardTotals[$target_board]['unapproved_topics']--;
        }
        $boardTotals[$target_board]['unapproved_posts'] -= $num_unapproved;
        $boardTotals[$target_board]['num_posts'] -= $topic_approved ? $num_replies + 1 : $num_replies;
        // Get the member ID of the first and last message.
        $request = $db->query('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_msg IN ({int:first_msg}, {int:last_msg})
			ORDER BY id_msg
			LIMIT 2', array('first_msg' => $first_msg, 'last_msg' => $last_msg));
        list($member_started) = $db->fetch_row($request);
        list($member_updated) = $db->fetch_row($request);
        // First and last message are the same, so only row was returned.
        if ($member_updated === null) {
            $member_updated = $member_started;
        }
        $db->free_result($request);
        // Obtain all the message ids we are going to affect.
        $affected_msgs = messagesInTopics($topics);
        // Assign the first topic ID to be the merged topic.
        $id_topic = min($topics);
        // Grab the response prefix (like 'Re: ') in the default forum language.
        $context['response_prefix'] = response_prefix();
        $enforce_subject = isset($_POST['enforce_subject']) ? Util::htmlspecialchars(trim($_POST['enforce_subject'])) : '';
        // Merge topic notifications.
        $notifications = isset($_POST['notifications']) && is_array($_POST['notifications']) ? array_intersect($topics, $_POST['notifications']) : array();
        fixMergedTopics($first_msg, $topics, $id_topic, $target_board, $target_subject, $enforce_subject, $notifications);
        // Asssign the properties of the newly merged topic.
        $db->query('', '
			UPDATE {db_prefix}topics
			SET
				id_board = {int:id_board},
				id_member_started = {int:id_member_started},
				id_member_updated = {int:id_member_updated},
				id_first_msg = {int:id_first_msg},
				id_last_msg = {int:id_last_msg},
				id_poll = {int:id_poll},
				num_replies = {int:num_replies},
				unapproved_posts = {int:unapproved_posts},
				num_views = {int:num_views},
				is_sticky = {int:is_sticky},
				approved = {int:approved}
			WHERE id_topic = {int:id_topic}', array('id_board' => $target_board, 'is_sticky' => $is_sticky, 'approved' => $topic_approved, 'id_topic' => $id_topic, 'id_member_started' => $member_started, 'id_member_updated' => $member_updated, 'id_first_msg' => $first_msg, 'id_last_msg' => $last_msg, 'id_poll' => $target_poll, 'num_replies' => $num_replies, 'unapproved_posts' => $num_unapproved, 'num_views' => $num_views));
        // Get rid of the redundant polls.
        if (!empty($deleted_polls)) {
            require_once SUBSDIR . '/Poll.subs.php';
            removePoll($deleted_polls);
        }
        // Cycle through each board...
        foreach ($boardTotals as $id_board => $stats) {
            decrementBoard($id_board, $stats);
        }
        // Determine the board the final topic resides in
        $topic_info = getTopicInfo($id_topic);
        $id_board = $topic_info['id_board'];
        // Update all the statistics.
        updateStats('topic');
        updateStats('subject', $id_topic, $target_subject);
        updateLastMessages($boards);
        logAction('merge', array('topic' => $id_topic, 'board' => $id_board));
        // Notify people that these topics have been merged?
        require_once SUBSDIR . '/Notification.subs.php';
        sendNotifications($id_topic, 'merge');
        // If there's a search index that needs updating, update it...
        require_once SUBSDIR . '/Search.subs.php';
        $searchAPI = findSearchAPI();
        if (is_callable(array($searchAPI, 'topicMerge'))) {
            $searchAPI->topicMerge($id_topic, $topics, $affected_msgs, empty($enforce_subject) ? null : array($context['response_prefix'], $target_subject));
        }
        // Send them to the all done page.
        redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board);
    }