Beispiel #1
0
/**
 * Find the ID of the "current" member
 *
 * @param boolean $fatal if the function ends in a fatal error in case of problems (default true)
 * @param boolean $reload_id if true the already set value is ignored (default false)
 *
 * @return mixed and integer if no error, false in case of problems if $fatal is false
 */
function currentMemberID($fatal = true, $reload_id = false)
{
    global $user_info;
    static $memID;
    // If we already know who we're dealing with
    if (isset($memID) && !$reload_id) {
        return $memID;
    }
    // Did we get the user by name...
    if (isset($_REQUEST['user'])) {
        $memberResult = loadMemberData($_REQUEST['user'], true, 'profile');
    } elseif (!empty($_REQUEST['u'])) {
        $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile');
    } else {
        $memberResult = loadMemberData($user_info['id'], false, 'profile');
    }
    // Check if loadMemberData() has returned a valid result.
    if (!is_array($memberResult)) {
        // Members only...
        is_not_guest('', $fatal);
        if ($fatal) {
            fatal_lang_error('not_a_user', false);
        } else {
            return false;
        }
    }
    // If all went well, we have a valid member ID!
    list($memID) = $memberResult;
    return $memID;
}
Beispiel #2
0
function ENotifyMain()
{
    global $modSettings;
    // Guests can't have unread things, we don't know anything about them.
    is_not_guest();
    // Update our unread replies log
    if (!empty($modSettings['enotify_replies'])) {
        ENotifyUpdateUnreadReplies();
    }
    // Update our personal messages log
    if (!empty($modSettings['enotify_pms'])) {
        ENotifyUpdatePms();
    }
    // Load up the notifications at last :)
    ENotifyLoad();
    // Run our garbage collection randomly (setting 0.05% chance for it to run)
    $random = rand(1, 5000);
    if ($random == '1987') {
        ENotifyGarbageCollect();
    }
    // Load the language and the template file.
    loadLanguage('ENotify');
    loadTemplate('ENotify');
    template_enotify_main();
    // We use this to deactivate the SMF Wrapping Templates
    die;
}
 /**
  * Subaction handler - manages the action and delegates control to the proper
  * sub-action.
  *
  * What it does:
  * - It loads both the Themes and Settings language files.
  * - Checks the session by GET or POST to verify the sent data.
  * - Requires the user to not be a guest.
  * - Accessed via ?action=admin;area=theme.
  *
  * @see Action_Controller::action_index()
  */
 public function action_index()
 {
     global $txt, $context;
     if (isset($_REQUEST['api'])) {
         return $this->action_index_api();
     }
     // Load the important language files...
     loadLanguage('ManageThemes');
     loadLanguage('Settings');
     require_once SUBSDIR . '/Action.class.php';
     // No guests in here.
     is_not_guest();
     // Theme administration, removal, choice, or installation...
     $subActions = array('admin' => array($this, 'action_admin', 'permission' => 'admin_forum'), 'list' => array($this, 'action_list', 'permission' => 'admin_forum'), 'reset' => array($this, 'action_options', 'permission' => 'admin_forum'), 'options' => array($this, 'action_options', 'permission' => 'admin_forum'), 'install' => array($this, 'action_install', 'permission' => 'admin_forum'), 'remove' => array($this, 'action_remove', 'permission' => 'admin_forum'), 'pick' => array($this, 'action_pick'), 'edit' => array($this, 'action_edit', 'permission' => 'admin_forum'), 'copy' => array($this, 'action_copy', 'permission' => 'admin_forum'), 'themelist' => array($this, 'action_themelist', 'permission' => 'admin_forum'), 'browse' => array($this, 'action_browse', 'permission' => 'admin_forum'));
     // Action controller
     $action = new Action('manage_themes');
     // @todo Layout Settings?
     if (!empty($context['admin_menu_name'])) {
         $context[$context['admin_menu_name']]['tab_data'] = array('title' => $txt['themeadmin_title'], 'description' => $txt['themeadmin_description'], 'tabs' => array('admin' => array('description' => $txt['themeadmin_admin_desc']), 'list' => array('description' => $txt['themeadmin_list_desc']), 'reset' => array('description' => $txt['themeadmin_reset_desc']), 'edit' => array('description' => $txt['themeadmin_edit_desc']), 'themelist' => array('description' => $txt['themeadmin_edit_desc']), 'browse' => array('description' => $txt['themeadmin_edit_desc'])));
     }
     // Follow the sa or just go to administration, call integrate_sa_manage_themes
     $subAction = $action->initialize($subActions, 'admin');
     // Default the page title to Theme Administration by default.
     $context['page_title'] = $txt['themeadmin_title'];
     $context['sub_action'] = $subAction;
     // Go to the action, if you have permissions
     $action->dispatch($subAction);
 }
 /**
  * This is the main function for markasread file.
  *
  * @see Action_Controller::action_index()
  */
 public function action_index()
 {
     // These checks have been moved here.
     // Do NOT call the specific handlers directly.
     // Guests can't mark things.
     is_not_guest();
     checkSession('get');
     $redir = $this->_dispatch();
     redirectexit($redir);
 }
/**
 *	Marks a ticket unread.
 *
 *	There are no permission checks made; other than that the user is who they claim to be. If a ticket is marked unread
 *	but they can't see it anyway, the consequence is that the database gets lighter.
 *
 *	Invoked through ?action=helpdesk;sa=unreadticket;ticket=x;sessvar=sessid before redirecting back to the main helpdesk page.
 *
 *	@since 1.0
*/
function shd_ticket_unread()
{
    global $smcFunc, $user_info, $context;
    is_not_guest();
    checkSession('get');
    if (!empty($context['ticket_id'])) {
        call_integration_hook('shd_hook_markunread');
        $result = shd_db_query('', '
			DELETE FROM {db_prefix}helpdesk_log_read
			WHERE id_ticket = {int:current_ticket}
				AND id_member = {int:user}', array('current_ticket' => $context['ticket_id'], 'user' => $user_info['id']));
    }
    redirectexit($context['shd_home'] . $context['shd_dept_link']);
}
Beispiel #6
0
function BoardNotify()
{
    global $scripturl, $txt, $board, $user_info, $context, $smcFunc;
    // Permissions are an important part of anything ;).
    is_not_guest();
    isAllowedTo('mark_notify');
    // You have to specify a board to turn notifications on!
    if (empty($board)) {
        fatal_lang_error('no_board', false);
    }
    // No subaction: find out what to do.
    if (empty($_GET['sa'])) {
        // We're gonna need the notify template...
        loadTemplate('Notify');
        // Find out if they have notification set for this topic already.
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}
			LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id']));
        $context['notification_set'] = $smcFunc['db_num_rows']($request) != 0;
        $smcFunc['db_free_result']($request);
        // Set the template variables...
        $context['board_href'] = $scripturl . '?board=' . $board . '.' . $_REQUEST['start'];
        $context['start'] = $_REQUEST['start'];
        $context['page_title'] = $txt['notification'];
        $context['sub_template'] = 'notify_board';
        return;
    } elseif ($_GET['sa'] == 'on') {
        checkSession('get');
        // Turn notification on.  (note this just blows smoke if it's already on.)
        $smcFunc['db_insert']('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_board' => 'int'), array($user_info['id'], $board), array('id_member', 'id_board'));
    } else {
        checkSession('get');
        // Turn notification off for this board.
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id']));
    }
    // Back to the board!
    redirectexit('board=' . $board . '.' . $_REQUEST['start']);
}
Beispiel #7
0
/**
 * Subaction handler - manages the action and delegates control to the proper
 * sub-action.
 * It loads both the Themes and Settings language files.
 * Checks the session by GET or POST to verify the sent data.
 * Requires the user not be a guest. (@todo what?)
 * Accessed via ?action=admin;area=theme.
 */
function ThemesMain()
{
    global $txt, $context, $scripturl;
    // Load the important language files...
    loadLanguage('Themes');
    loadLanguage('Settings');
    // No funny business - guests only.
    is_not_guest();
    // Default the page title to Theme Administration by default.
    $context['page_title'] = $txt['themeadmin_title'];
    // Theme administration, removal, choice, or installation...
    $subActions = array('admin' => 'ThemeAdmin', 'list' => 'ThemeList', 'reset' => 'SetThemeOptions', 'options' => 'SetThemeOptions', 'install' => 'ThemeInstall', 'remove' => 'RemoveTheme', 'pick' => 'PickTheme', 'edit' => 'EditTheme', 'copy' => 'CopyTemplate');
    // @todo Layout Settings?
    if (!empty($context['admin_menu_name'])) {
        $context[$context['admin_menu_name']]['tab_data'] = array('title' => $txt['themeadmin_title'], 'help' => 'themes', 'description' => $txt['themeadmin_description'], 'tabs' => array('admin' => array('description' => $txt['themeadmin_admin_desc']), 'list' => array('description' => $txt['themeadmin_list_desc']), 'reset' => array('description' => $txt['themeadmin_reset_desc']), 'edit' => array('description' => $txt['themeadmin_edit_desc'])));
    }
    // Follow the sa or just go to administration.
    if (isset($_GET['sa']) && !empty($subActions[$_GET['sa']])) {
        $subActions[$_GET['sa']]();
    } else {
        $subActions['admin']();
    }
}
Beispiel #8
0
function UnreadTopics()
{
    global $board, $txt, $scripturl, $db_prefix, $sourcedir;
    global $ID_MEMBER, $user_info, $context, $settings, $modSettings, $func;
    // Guests can't have unread things, we don't know anything about them.
    is_not_guest();
    // Prefetching + lots of MySQL work = bad mojo.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Forbidden');
        die;
    }
    $context['showing_all_topics'] = isset($_GET['all']);
    if ($_REQUEST['action'] == 'unread') {
        $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit'];
    } else {
        $context['page_title'] = $txt['unread_replies'];
    }
    if ($context['showing_all_topics'] && !empty($context['load_average']) && !empty($modSettings['loadavg_allunread']) && $context['load_average'] >= $modSettings['loadavg_allunread']) {
        fatal_lang_error('loadavg_allunread_disabled', false);
    } elseif ($_REQUEST['action'] != 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unreadreplies']) && $context['load_average'] >= $modSettings['loadavg_unreadreplies']) {
        fatal_lang_error('loadavg_unreadreplies_disabled', false);
    }
    // Are we specifying any specific board?
    if (!empty($board)) {
        $query_this_board = 'ID_BOARD = ' . $board;
        $context['querystring_board_limits'] = ';board=' . $board . '.%d';
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}\n\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $_REQUEST['boards']) . ")", __FILE__, __LINE__);
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
        }
        mysql_free_result($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')';
        $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%d';
    } elseif (!empty($_REQUEST['c'])) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}\n\t\t\t\tAND b.ID_CAT IN (" . implode(', ', $_REQUEST['c']) . ")", __FILE__, __LINE__);
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
        }
        mysql_free_result($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')';
        $context['querystring_board_limits'] = ';c=' . implode(',', $_REQUEST['c']) . ';start=%d';
    } else {
        // Don't bother to show deleted posts!
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}" . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "\n\t\t\t\tAND b.ID_BOARD != " . (int) $modSettings['recycle_board'] : ''), __FILE__, __LINE__);
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
        }
        mysql_free_result($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')';
        $context['querystring_board_limits'] = ';start=%d';
        $context['no_board_limits'] = true;
    }
    $sort_methods = array('subject' => 'ms.subject', 'starter' => 'IFNULL(mems.realName, ms.posterName)', 'replies' => 't.numReplies', 'views' => 't.numViews', 'first_post' => 't.ID_TOPIC', 'last_post' => 't.ID_LAST_MSG');
    // The default is the most logical: newest first.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 't.ID_LAST_MSG';
        $ascending = isset($_REQUEST['asc']);
        $context['querystring_sort_limits'] = $ascending ? ';asc' : '';
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
        $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc');
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    if (!empty($_REQUEST['c']) && is_array($_REQUEST['c']) && count($_REQUEST['c']) == 1) {
        $request = db_query("\n\t\t\tSELECT name\n\t\t\tFROM {$db_prefix}categories\n\t\t\tWHERE ID_CAT = " . (int) $_REQUEST['c'][0] . "\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($name) = mysql_fetch_row($request);
        mysql_free_result($request);
        $context['linktree'][] = array('url' => $scripturl . '#' . (int) $_REQUEST['c'][0], 'name' => $name);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $_REQUEST['action'] == 'unread' ? $txt['unread_topics_visit'] : $txt['unread_replies']);
    if ($context['showing_all_topics']) {
        $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $txt['unread_topics_all']);
    } else {
        $txt['unread_topics_visit_none'] = strtr($txt['unread_topics_visit_none'], array('?action=unread;all' => '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits']));
    }
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_recent';
    } else {
        loadTemplate('Recent');
        $context['sub_template'] = $_REQUEST['action'] == 'unread' ? 'unread' : 'replies';
    }
    // Setup the default topic icons... for checking they exist and the like ;)
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $is_topics = $_REQUEST['action'] == 'unread';
    // This part is the same for each query.
    $select_clause = '
				ms.subject AS firstSubject, ms.posterTime AS firstPosterTime, ms.ID_TOPIC, t.ID_BOARD, b.name AS bname,
				t.numReplies, t.numViews, ms.ID_MEMBER AS ID_FIRST_MEMBER, ml.ID_MEMBER AS ID_LAST_MEMBER,
				ml.posterTime AS lastPosterTime, IFNULL(mems.realName, ms.posterName) AS firstPosterName,
				IFNULL(meml.realName, ml.posterName) AS lastPosterName, ml.subject AS lastSubject,
				ml.icon AS lastIcon, ms.icon AS firstIcon, t.ID_POLL, t.isSticky, t.locked, ml.modifiedTime AS lastModifiedTime,
				IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1 AS new_from, LEFT(ml.body, 384) AS lastBody, LEFT(ms.body, 384) AS firstBody,
				ml.smileysEnabled AS lastSmileys, ms.smileysEnabled AS firstSmileys, t.ID_FIRST_MSG, t.ID_LAST_MSG';
    if ($context['showing_all_topics']) {
        if (!empty($board)) {
            $request = db_query("\n\t\t\t\tSELECT MIN(ID_MSG)\n\t\t\t\tFROM {$db_prefix}log_mark_read\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_BOARD = {$board}", __FILE__, __LINE__);
            list($earliest_msg) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $request = db_query("\n\t\t\t\tSELECT MIN(lmr.ID_MSG)\n\t\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = b.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE {$user_info['query_see_board']}", __FILE__, __LINE__);
            list($earliest_msg) = mysql_fetch_row($request);
            mysql_free_result($request);
        }
        // This is needed in case of topics marked unread.
        if (empty($earliest_msg)) {
            $earliest_msg = 0;
        } else {
            // Using caching, when possible, to ignore the below slow query.
            if (isset($_SESSION['cached_log_time']) && $_SESSION['cached_log_time'][0] + 45 > time()) {
                $earliest_msg2 = $_SESSION['cached_log_time'][1];
            } else {
                // This query is pretty slow, but it's needed to ensure nothing crucial is ignored.
                $request = db_query("\n\t\t\t\t\tSELECT MIN(ID_MSG)\n\t\t\t\t\tFROM {$db_prefix}log_topics\n\t\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
                list($earliest_msg2) = mysql_fetch_row($request);
                mysql_free_result($request);
                // In theory this could be zero, if the first ever post is unread, so fudge it ;)
                if ($earliest_msg2 == 0) {
                    $earliest_msg2 = -1;
                }
                $_SESSION['cached_log_time'] = array(time(), $earliest_msg2);
            }
            $earliest_msg = min($earliest_msg2, $earliest_msg);
        }
    }
    // !!! Add modifiedTime in for logTime check?
    if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics']) {
        db_query("\n\t\t\tDROP TABLE IF EXISTS {$db_prefix}log_topics_unread", false, false);
        // Let's copy things out of the log_topics table, to reduce searching.
        $have_temp_table = db_query("\n\t\t\tCREATE TEMPORARY TABLE {$db_prefix}log_topics_unread (\n\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t)\n\t\t\tSELECT lt.ID_TOPIC, lt.ID_MSG\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}log_topics AS lt)\n\t\t\tWHERE lt.ID_TOPIC = t.ID_TOPIC\n\t\t\t\tAND lt.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND t.{$query_this_board}" . (!empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : ''), false, false) !== false;
    } else {
        $have_temp_table = false;
    }
    if ($context['showing_all_topics'] && $have_temp_table) {
        $request = db_query("\n\t\t\tSELECT COUNT(*), MIN(t.ID_LAST_MSG)\n\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.{$query_this_board}" . ($context['showing_all_topics'] && !empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : "\n\t\t\t\tAND t.ID_LAST_MSG > {$_SESSION['ID_MSG_LAST_VISIT']}") . "\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__);
        list($num_topics, $min_message) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1);
        if ($num_topics == 0) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        } else {
            $min_message = (int) $min_message;
        }
        $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND t.{$query_this_board}\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\t\tAND t.ID_LAST_MSG >= {$min_message}\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__);
    } elseif ($is_topics) {
        $request = db_query("\n\t\t\tSELECT COUNT(*), MIN(t.ID_LAST_MSG)\n\t\t\tFROM {$db_prefix}topics AS t" . ($have_temp_table ? "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)" : "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})") . "\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.{$query_this_board}" . ($context['showing_all_topics'] && !empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : "\n\t\t\t\tAND t.ID_LAST_MSG > {$_SESSION['ID_MSG_LAST_VISIT']}") . "\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__);
        list($num_topics, $min_message) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1);
        if ($num_topics == 0) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        } else {
            $min_message = (int) $min_message;
        }
        $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)" . ($have_temp_table ? "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)" : "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})") . "\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND t.{$query_this_board}\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\t\tAND t.ID_LAST_MSG >= {$min_message}\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < ml.ID_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__);
    } else {
        if ($modSettings['totalMessages'] > 100000) {
            db_query("\n\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}topics_posted_in", false, false);
            db_query("\n\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}log_topics_posted_in", false, false);
            $sortKey_joins = array('ms.subject' => "\n\t\t\t\t\tINNER JOIN {$db_prefix}messages AS ms ON (ms.ID_MSG = t.ID_FIRST_MSG)", 'IFNULL(mems.realName, ms.posterName)' => "\n\t\t\t\t\tINNER JOIN {$db_prefix}messages AS ms ON (ms.ID_MSG = t.ID_FIRST_MSG)\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)");
            // The main benefit of this temporary table is not that it's faster; it's that it avoids locks later.
            $have_temp_table = db_query("\n\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}topics_posted_in (\n\t\t\t\t\tID_TOPIC mediumint(8) unsigned NOT NULL default '0',\n\t\t\t\t\tID_BOARD smallint(5) unsigned NOT NULL default '0',\n\t\t\t\t\tID_LAST_MSG int(10) unsigned NOT NULL default '0',\n\t\t\t\t\tID_MSG int(10) unsigned NOT NULL default '0',\n\t\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t\t)\n\t\t\t\tSELECT t.ID_TOPIC, t.ID_BOARD, t.ID_LAST_MSG, IFNULL(lmr.ID_MSG, 0) AS ID_MSG" . (!in_array($_REQUEST['sort'], array('t.ID_LAST_MSG', 't.ID_TOPIC')) ? ", {$_REQUEST['sort']} AS sortKey" : '') . "\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})" . (isset($sortKey_joins[$_REQUEST['sort']]) ? $sortKey_joins[$_REQUEST['sort']] : '') . "\n\t\t\t\tWHERE m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND t.ID_TOPIC = m.ID_TOPIC" . (!empty($board) ? "\n\t\t\t\t\tAND t.ID_BOARD = {$board}" : '') . "\n\t\t\t\tGROUP BY m.ID_TOPIC", false, false) !== false;
            // If that worked, create a sample of the log_topics table too.
            if ($have_temp_table) {
                $have_temp_table = db_query("\n\t\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}log_topics_posted_in (\n\t\t\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t\t\t)\n\t\t\t\t\tSELECT lt.ID_TOPIC, lt.ID_MSG\n\t\t\t\t\tFROM ({$db_prefix}log_topics AS lt, {$db_prefix}topics_posted_in AS pi)\n\t\t\t\t\tWHERE lt.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\t\tAND lt.ID_TOPIC = pi.ID_TOPIC", false, false) !== false;
            }
        }
        if ($have_temp_table) {
            $request = db_query("\n\t\t\t\tSELECT COUNT(*)\n\t\t\t\tFROM ({$db_prefix}topics_posted_in AS pi)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics_posted_in AS lt ON (lt.ID_TOPIC = pi.ID_TOPIC)\n\t\t\t\tWHERE pi.{$query_this_board}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, pi.ID_MSG) < pi.ID_LAST_MSG", __FILE__, __LINE__);
            list($num_topics) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $request = db_query("\n\t\t\t\tSELECT COUNT(DISTINCT t.ID_TOPIC), MIN(t.ID_LAST_MSG)\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE t.{$query_this_board}\n\t\t\t\t\tAND m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__);
            list($num_topics, $min_message) = mysql_fetch_row($request);
            mysql_free_result($request);
        }
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1);
        if ($num_topics == 0) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        }
        if ($have_temp_table) {
            $request = db_query("\n\t\t\t\tSELECT t.ID_TOPIC\n\t\t\t\tFROM {$db_prefix}topics_posted_in AS t\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics_posted_in AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tWHERE t.{$query_this_board}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, t.ID_MSG) < t.ID_LAST_MSG\n\t\t\t\tORDER BY " . (in_array($_REQUEST['sort'], array('t.ID_LAST_MSG', 't.ID_TOPIC')) ? $_REQUEST['sort'] : 't.sortKey') . ($ascending ? '' : ' DESC') . "\n\t\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__);
        } else {
            $request = db_query("\n\t\t\t\tSELECT DISTINCT t.ID_TOPIC\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m" . (strpos($_REQUEST['sort'], 'ms.') === false ? '' : ", {$db_prefix}messages AS ms") . ')' . (strpos($_REQUEST['sort'], 'mems.') === false ? '' : "\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)") . "\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND t.{$query_this_board}\n\t\t\t\t\tAND t.ID_LAST_MSG >= " . (int) $min_message . "\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG" . (strpos($_REQUEST['sort'], 'ms.') !== false ? "\n\t\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG" : '') . "\n\t\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__);
        }
        $topics = array();
        while ($row = mysql_fetch_assoc($request)) {
            $topics[] = $row['ID_TOPIC'];
        }
        mysql_free_result($request);
        // Sanity... where have you gone?
        if (empty($topics)) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        }
        $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC IN (" . implode(', ', $topics) . ")\n\t\t\t\tAND t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT " . count($topics), __FILE__, __LINE__);
    }
    $context['topics'] = array();
    $topic_ids = array();
    while ($row = mysql_fetch_assoc($request)) {
        if ($row['ID_POLL'] > 0 && $modSettings['pollMode'] == '0') {
            continue;
        }
        $topic_ids[] = $row['ID_TOPIC'];
        // Clip the strings first because censoring is slow :/. (for some reason?)
        $row['firstBody'] = strip_tags(strtr(parse_bbc($row['firstBody'], $row['firstSmileys'], $row['ID_FIRST_MSG']), array('<br />' => '&#10;')));
        if ($func['strlen']($row['firstBody']) > 128) {
            $row['firstBody'] = $func['substr']($row['firstBody'], 0, 128) . '...';
        }
        $row['lastBody'] = strip_tags(strtr(parse_bbc($row['lastBody'], $row['lastSmileys'], $row['ID_LAST_MSG']), array('<br />' => '&#10;')));
        if ($func['strlen']($row['lastBody']) > 128) {
            $row['lastBody'] = $func['substr']($row['lastBody'], 0, 128) . '...';
        }
        // Do a bit of censoring...
        censorText($row['firstSubject']);
        censorText($row['firstBody']);
        // But don't do it twice, it can be a slow ordeal!
        if ($row['ID_FIRST_MSG'] == $row['ID_LAST_MSG']) {
            $row['lastSubject'] = $row['firstSubject'];
            $row['lastBody'] = $row['firstBody'];
        } else {
            censorText($row['lastSubject']);
            censorText($row['lastBody']);
        }
        // Decide how many pages the topic should have.
        $topic_length = $row['numReplies'] + 1;
        if ($topic_length > $modSettings['defaultMaxMessages']) {
            $tmppages = array();
            $tmpa = 1;
            for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $modSettings['defaultMaxMessages']) {
                $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.' . $tmpb . ';topicseen">' . $tmpa . '</a>';
                $tmpa++;
            }
            // Show links to all the pages?
            if (count($tmppages) <= 5) {
                $pages = '&#171; ' . implode(' ', $tmppages);
            } else {
                $pages = '&#171; ' . $tmppages[0] . ' ' . $tmppages[1] . ' ... ' . $tmppages[count($tmppages) - 2] . ' ' . $tmppages[count($tmppages) - 1];
            }
            if (!empty($modSettings['enableAllMessages']) && $topic_length < $modSettings['enableAllMessages']) {
                $pages .= ' &nbsp;<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;all">' . $txt[190] . '</a>';
            }
            $pages .= ' &#187;';
        } else {
            $pages = '';
        }
        // We need to check the topic icons exist... you can never be too sure!
        if (empty($modSettings['messageIconChecks_disable'])) {
            // First icon first... as you'd expect.
            if (!isset($context['icon_sources'][$row['firstIcon']])) {
                $context['icon_sources'][$row['firstIcon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['firstIcon'] . '.gif') ? 'images_url' : 'default_images_url';
            }
            // Last icon... last... duh.
            if (!isset($context['icon_sources'][$row['lastIcon']])) {
                $context['icon_sources'][$row['lastIcon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['lastIcon'] . '.gif') ? 'images_url' : 'default_images_url';
            }
        }
        // And build the array.
        $context['topics'][$row['ID_TOPIC']] = array('id' => $row['ID_TOPIC'], 'first_post' => array('id' => $row['ID_FIRST_MSG'], 'member' => array('name' => $row['firstPosterName'], 'id' => $row['ID_FIRST_MEMBER'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'], 'link' => !empty($row['ID_FIRST_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'] . '" title="' . $txt[92] . ' ' . $row['firstPosterName'] . '">' . $row['firstPosterName'] . '</a>' : $row['firstPosterName']), 'time' => timeformat($row['firstPosterTime']), 'timestamp' => forum_time(true, $row['firstPosterTime']), 'subject' => $row['firstSubject'], 'preview' => $row['firstBody'], 'icon' => $row['firstIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['firstIcon']]] . '/post/' . $row['firstIcon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;topicseen', 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;topicseen">' . $row['firstSubject'] . '</a>'), 'last_post' => array('id' => $row['ID_LAST_MSG'], 'member' => array('name' => $row['lastPosterName'], 'id' => $row['ID_LAST_MEMBER'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_LAST_MEMBER'], 'link' => !empty($row['ID_LAST_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_LAST_MEMBER'] . '">' . $row['lastPosterName'] . '</a>' : $row['lastPosterName']), 'time' => timeformat($row['lastPosterTime']), 'timestamp' => forum_time(true, $row['lastPosterTime']), 'subject' => $row['lastSubject'], 'preview' => $row['lastBody'], 'icon' => $row['lastIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['lastIcon']]] . '/post/' . $row['lastIcon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['ID_LAST_MSG']) . ';topicseen#msg' . $row['ID_LAST_MSG'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['ID_LAST_MSG']) . ';topicseen#msg' . $row['ID_LAST_MSG'] . '">' . $row['lastSubject'] . '</a>'), 'new_from' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['new_from'] . ';topicseen#new', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen' . ($row['numReplies'] == 0 ? '' : 'new'), 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen#msg' . $row['new_from'] . '">' . $row['firstSubject'] . '</a>', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['isSticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['ID_POLL'] > 0, 'is_hot' => $row['numReplies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['numReplies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'icon' => $row['firstIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['firstIcon']]] . '/post/' . $row['firstIcon'] . '.gif', 'subject' => $row['firstSubject'], 'pages' => $pages, 'replies' => $row['numReplies'], 'views' => $row['numViews'], 'board' => array('id' => $row['ID_BOARD'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bname'] . '</a>'));
        determineTopicClass($context['topics'][$row['ID_TOPIC']]);
    }
    mysql_free_result($request);
    if ($is_topics && !empty($modSettings['enableParticipation']) && !empty($topic_ids)) {
        $result = db_query("\n\t\t\tSELECT ID_TOPIC\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $topic_ids) . ")\n\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($result)) {
            if (empty($context['topics'][$row['ID_TOPIC']]['is_posted_in'])) {
                $context['topics'][$row['ID_TOPIC']]['is_posted_in'] = true;
                $context['topics'][$row['ID_TOPIC']]['class'] = 'my_' . $context['topics'][$row['ID_TOPIC']]['class'];
            }
        }
        mysql_free_result($result);
    }
    $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
    $context['topics_to_mark'] = implode('-', $topic_ids);
}
Beispiel #9
0
function BuddyListToggle()
{
    global $user_info;
    checkSession('get');
    isAllowedTo('profile_identity_own');
    is_not_guest();
    if (empty($_REQUEST['u'])) {
        fatal_lang_error('no_access', false);
    }
    $_REQUEST['u'] = (int) $_REQUEST['u'];
    // Remove if it's already there...
    if (in_array($_REQUEST['u'], $user_info['buddies'])) {
        $user_info['buddies'] = array_diff($user_info['buddies'], array($_REQUEST['u']));
    } elseif ($user_info['id'] != $_REQUEST['u']) {
        $user_info['buddies'][] = (int) $_REQUEST['u'];
    }
    // Update the settings.
    updateMemberData($user_info['id'], array('buddy_list' => implode(',', $user_info['buddies'])));
    // Redirect back to the profile
    redirectexit('action=profile;u=' . $_REQUEST['u']);
}
Beispiel #10
0
function Post()
{
    global $txt, $scripturl, $topic, $modSettings, $board;
    global $user_info, $sc, $board_info, $context, $settings;
    global $sourcedir, $options, $smcFunc, $language;
    loadLanguage('Post');
    // You can't reply with a poll... hacker.
    if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) {
        unset($_REQUEST['poll']);
    }
    // Posting an event?
    $context['make_event'] = isset($_REQUEST['calendar']);
    $context['robot_no_index'] = true;
    // You must be posting to *some* board.
    if (empty($board) && !$context['make_event']) {
        fatal_lang_error('no_board', false);
    }
    require_once $sourcedir . '/Subs-Post.php';
    if (isset($_REQUEST['xml'])) {
        $context['sub_template'] = 'post';
        // Just in case of an earlier error...
        $context['preview_message'] = '';
        $context['preview_subject'] = '';
    }
    // No message is complete without a topic.
    if (empty($topic) && !empty($_REQUEST['msg'])) {
        $request = $smcFunc['db_query']('', '
			SELECT id_topic
			FROM {db_prefix}messages
			WHERE id_msg = {int:msg}', array('msg' => (int) $_REQUEST['msg']));
        if ($smcFunc['db_num_rows']($request) != 1) {
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        } else {
            list($topic) = $smcFunc['db_fetch_row']($request);
        }
        $smcFunc['db_free_result']($request);
    }
    // Check if it's locked.  It isn't locked if no topic is specified.
    if (!empty($topic)) {
        $request = $smcFunc['db_query']('', '
			SELECT
				t.locked, IFNULL(ln.id_topic, 0) AS notify, t.is_sticky, t.id_poll, t.id_last_msg, mf.id_member,
				t.id_first_msg, mf.subject,
				CASE WHEN ml.poster_time > ml.modified_time THEN ml.poster_time ELSE ml.modified_time END AS last_post_time
			FROM {db_prefix}topics AS t
				LEFT JOIN {db_prefix}log_notify AS ln ON (ln.id_topic = t.id_topic AND ln.id_member = {int:current_member})
				LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
			WHERE t.id_topic = {int:current_topic}
			LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic));
        list($locked, $context['notify'], $sticky, $pollID, $context['topic_last_message'], $id_member_poster, $id_first_msg, $first_subject, $lastPostTime) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // If this topic already has a poll, they sure can't add another.
        if (isset($_REQUEST['poll']) && $pollID > 0) {
            unset($_REQUEST['poll']);
        }
        if (empty($_REQUEST['msg'])) {
            if ($user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) {
                is_not_guest();
            }
            // By default the reply will be approved...
            $context['becomes_approved'] = true;
            if ($id_member_poster != $user_info['id']) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_any');
                }
            } elseif (!allowedTo('post_reply_any')) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                    $context['becomes_approved'] = false;
                } else {
                    isAllowedTo('post_reply_own');
                }
            }
        } else {
            $context['becomes_approved'] = true;
        }
        $context['can_lock'] = allowedTo('lock_any') || $user_info['id'] == $id_member_poster && allowedTo('lock_own');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky;
    } else {
        $context['becomes_approved'] = true;
        if (!$context['make_event'] || !empty($board)) {
            if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                $context['becomes_approved'] = false;
            } else {
                isAllowedTo('post_new');
            }
        }
        $locked = 0;
        // !!! These won't work if you're making an event.
        $context['can_lock'] = allowedTo(array('lock_any', 'lock_own'));
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['notify'] = !empty($context['notify']);
        $context['sticky'] = !empty($_REQUEST['sticky']);
    }
    // !!! These won't work if you're posting an event!
    $context['can_notify'] = allowedTo('mark_any_notify');
    $context['can_move'] = allowedTo('move_any');
    $context['move'] = !empty($_REQUEST['move']);
    $context['announce'] = !empty($_REQUEST['announce']);
    // You can only announce topics that will get approved...
    $context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved'];
    $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']);
    $context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    // Generally don't show the approval box... (Assume we want things approved)
    $context['show_approval'] = false;
    // An array to hold all the attachments for this topic.
    $context['current_attachments'] = array();
    // Don't allow a post if it's locked and you aren't all powerful.
    if ($locked && !allowedTo('moderate_board')) {
        fatal_lang_error('topic_locked', false);
    }
    // Check the users permissions - is the user allowed to add or post a poll?
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        // New topic, new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $id_member_poster && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        require_once $sourcedir . '/Subs-Members.php';
        $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
        // Set up the poll options.
        $context['poll_options'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expire' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_enabled' => in_array(-1, $allowedVoteGroups['allowed']));
        // Make all five poll choices empty.
        $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true));
    }
    if ($context['make_event']) {
        // They might want to pick a board.
        if (!isset($context['current_board'])) {
            $context['current_board'] = 0;
        }
        // Start loading up the event info.
        $context['event'] = array();
        $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : '';
        $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1;
        $context['event']['new'] = $context['event']['id'] == -1;
        // Permissions check!
        isAllowedTo('calendar_post');
        // Editing an event?  (but NOT previewing!?)
        if (!$context['event']['new'] && !isset($_REQUEST['subject'])) {
            // If the user doesn't have permission to edit the post in this topic, redirect them.
            if ((empty($id_member_poster) || $id_member_poster != $user_info['id'] || !allowedTo('modify_own')) && !allowedTo('modify_any')) {
                require_once $sourcedir . '/Calendar.php';
                return CalendarPost();
            }
            // Get the current event information.
            $request = $smcFunc['db_query']('', '
				SELECT
					id_member, title, MONTH(start_date) AS month, DAYOFMONTH(start_date) AS day,
					YEAR(start_date) AS year, (TO_DAYS(end_date) - TO_DAYS(start_date)) AS span
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}
				LIMIT 1', array('id_event' => $context['event']['id']));
            $row = $smcFunc['db_fetch_assoc']($request);
            $smcFunc['db_free_result']($request);
            // Make sure the user is allowed to edit this event.
            if ($row['id_member'] != $user_info['id']) {
                isAllowedTo('calendar_edit_any');
            } elseif (!allowedTo('calendar_edit_any')) {
                isAllowedTo('calendar_edit_own');
            }
            $context['event']['month'] = $row['month'];
            $context['event']['day'] = $row['day'];
            $context['event']['year'] = $row['year'];
            $context['event']['title'] = $row['title'];
            $context['event']['span'] = $row['span'] + 1;
        } else {
            $today = getdate();
            // You must have a month and year specified!
            if (!isset($_REQUEST['month'])) {
                $_REQUEST['month'] = $today['mon'];
            }
            if (!isset($_REQUEST['year'])) {
                $_REQUEST['year'] = $today['year'];
            }
            $context['event']['month'] = (int) $_REQUEST['month'];
            $context['event']['year'] = (int) $_REQUEST['year'];
            $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0);
            $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1;
            // Make sure the year and month are in the valid range.
            if ($context['event']['month'] < 1 || $context['event']['month'] > 12) {
                fatal_lang_error('invalid_month', false);
            }
            if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) {
                fatal_lang_error('invalid_year', false);
            }
            // Get a list of boards they can post in.
            $boards = boardsAllowedTo('post_new');
            if (empty($boards)) {
                fatal_lang_error('cannot_post_new', 'user');
            }
            // Load a list of boards for this event in the context.
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($context['current_board']) ? $modSettings['cal_defaultboard'] : $context['current_board']);
            $context['event']['categories'] = getBoardList($boardListOptions);
        }
        // Find the last day of the month.
        $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
        $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard'];
    }
    if (empty($context['post_errors'])) {
        $context['post_errors'] = array();
    }
    // See if any new replies have come along.
    if (empty($_REQUEST['msg']) && !empty($topic)) {
        if (empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $context['topic_last_message'] > $_REQUEST['last_msg']) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}messages
				WHERE id_topic = {int:current_topic}
					AND id_msg > {int:last_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND approved = {int:approved}') . '
				LIMIT 1', array('current_topic' => $topic, 'last_msg' => (int) $_REQUEST['last_msg'], 'approved' => 1));
            list($context['new_replies']) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            if (!empty($context['new_replies'])) {
                if ($context['new_replies'] == 1) {
                    $txt['error_new_reply'] = isset($_GET['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply'];
                } else {
                    $txt['error_new_replies'] = sprintf(isset($_GET['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']);
                }
                // If they've come from the display page then we treat the error differently....
                if (isset($_GET['last_msg'])) {
                    $newRepliesError = $context['new_replies'];
                } else {
                    $context['post_error'][$context['new_replies'] == 1 ? 'new_reply' : 'new_replies'] = true;
                }
                $modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts'];
            }
        }
        // Check whether this is a really old post being bumped...
        if (!empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) {
            $oldTopicError = true;
        }
    }
    // Get a response prefix (like 'Re:') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // Previewing, modifying, or posting?
    if (isset($_REQUEST['message']) || !empty($context['post_error'])) {
        // Validate inputs.
        if (empty($context['post_error'])) {
            if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['subject'])) == '') {
                $context['post_error']['no_subject'] = true;
            }
            if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['message'])) == '') {
                $context['post_error']['no_message'] = true;
            }
            if (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_REQUEST['message']) > $modSettings['max_messageLength']) {
                $context['post_error']['long_message'] = true;
            }
            // Are you... a guest?
            if ($user_info['is_guest']) {
                $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']);
                $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']);
                // Validate the name and email.
                if (!isset($_REQUEST['guestname']) || trim(strtr($_REQUEST['guestname'], '_', ' ')) == '') {
                    $context['post_error']['no_name'] = true;
                } elseif ($smcFunc['strlen']($_REQUEST['guestname']) > 25) {
                    $context['post_error']['long_name'] = true;
                } else {
                    require_once $sourcedir . '/Subs-Members.php';
                    if (isReservedName(htmlspecialchars($_REQUEST['guestname']), 0, true, false)) {
                        $context['post_error']['bad_name'] = true;
                    }
                }
                if (empty($modSettings['guest_post_no_email'])) {
                    if (!isset($_REQUEST['email']) || $_REQUEST['email'] == '') {
                        $context['post_error']['no_email'] = true;
                    } elseif (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_REQUEST['email']) == 0) {
                        $context['post_error']['bad_email'] = true;
                    }
                }
            }
            // This is self explanatory - got any questions?
            if (isset($_REQUEST['question']) && trim($_REQUEST['question']) == '') {
                $context['post_error']['no_question'] = true;
            }
            // This means they didn't click Post and get an error.
            $really_previewing = true;
        } else {
            if (!isset($_REQUEST['subject'])) {
                $_REQUEST['subject'] = '';
            }
            if (!isset($_REQUEST['message'])) {
                $_REQUEST['message'] = '';
            }
            if (!isset($_REQUEST['icon'])) {
                $_REQUEST['icon'] = 'xx';
            }
            // They are previewing if they asked to preview (i.e. came from quick reply).
            $really_previewing = !empty($_POST['preview']);
        }
        // In order to keep the approval status flowing through, we have to pass it through the form...
        $context['becomes_approved'] = empty($_REQUEST['not_approved']);
        $context['show_approval'] = isset($_REQUEST['approve']) ? $_REQUEST['approve'] ? 2 : 1 : 0;
        $context['can_announce'] &= $context['becomes_approved'];
        // Set up the inputs for the form.
        $form_subject = strtr($smcFunc['htmlspecialchars']($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $form_message = $smcFunc['htmlspecialchars']($_REQUEST['message'], ENT_QUOTES);
        // Make sure the subject isn't too long - taking into account special characters.
        if ($smcFunc['strlen']($form_subject) > 100) {
            $form_subject = $smcFunc['substr']($form_subject, 0, 100);
        }
        // Have we inadvertently trimmed off the subject of useful information?
        if ($smcFunc['htmltrim']($form_subject) === '') {
            $context['post_error']['no_subject'] = true;
        }
        // Any errors occurred?
        if (!empty($context['post_error'])) {
            loadLanguage('Errors');
            $context['error_type'] = 'minor';
            $context['post_error']['messages'] = array();
            foreach ($context['post_error'] as $post_error => $dummy) {
                if ($post_error == 'messages') {
                    continue;
                }
                if ($post_error == 'long_message') {
                    $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']);
                }
                $context['post_error']['messages'][] = $txt['error_' . $post_error];
                // If it's not a minor error flag it as such.
                if (!in_array($post_error, array('new_reply', 'not_approved', 'new_replies', 'old_topic', 'need_qr_verification'))) {
                    $context['error_type'] = 'serious';
                }
            }
        }
        if (isset($_REQUEST['poll'])) {
            $context['question'] = isset($_REQUEST['question']) ? $smcFunc['htmlspecialchars'](trim($_REQUEST['question'])) : '';
            $context['choices'] = array();
            $choice_id = 0;
            $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive($_POST['options']);
            foreach ($_POST['options'] as $option) {
                if (trim($option) == '') {
                    continue;
                }
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false);
            }
            if (count($context['choices']) < 2) {
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
                $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false);
            }
            $context['choices'][count($context['choices']) - 1]['is_last'] = true;
        }
        // Are you... a guest?
        if ($user_info['is_guest']) {
            $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']);
            $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']);
            $_REQUEST['guestname'] = htmlspecialchars($_REQUEST['guestname']);
            $context['name'] = $_REQUEST['guestname'];
            $_REQUEST['email'] = htmlspecialchars($_REQUEST['email']);
            $context['email'] = $_REQUEST['email'];
            $user_info['name'] = $_REQUEST['guestname'];
        }
        // Only show the preview stuff if they hit Preview.
        if ($really_previewing == true || isset($_REQUEST['xml'])) {
            // Set up the preview message and subject and censor them...
            $context['preview_message'] = $form_message;
            preparsecode($form_message, true);
            preparsecode($context['preview_message']);
            // Do all bulletin board code tags, with or without smileys.
            $context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1);
            if ($form_subject != '') {
                $context['preview_subject'] = $form_subject;
                censorText($context['preview_subject']);
                censorText($context['preview_message']);
            } else {
                $context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>';
            }
            // Protect any CDATA blocks.
            if (isset($_REQUEST['xml'])) {
                $context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>'));
            }
        }
        // Set up the checkboxes.
        $context['notify'] = !empty($_REQUEST['notify']);
        $context['use_smileys'] = !isset($_REQUEST['ns']);
        $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx';
        // Set the destination action for submission.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '') . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = isset($_REQUEST['msg']) ? $txt['save'] : $txt['post'];
        // Previewing an edit?
        if (isset($_REQUEST['msg']) && !empty($topic)) {
            // Get the existing message.
            $request = $smcFunc['db_query']('', '
				SELECT
					m.id_member, m.modified_time, m.smileys_enabled, m.body,
					m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
					IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
					a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
					m.poster_time
			FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
					LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
				WHERE m.id_msg = {int:id_msg}
					AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg']));
            // The message they were trying to edit was most likely deleted.
            // !!! Change this error message?
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('no_board', false);
            }
            $row = $smcFunc['db_fetch_assoc']($request);
            $attachment_stuff = array($row);
            while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
                $attachment_stuff[] = $row2;
            }
            $smcFunc['db_free_result']($request);
            if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
                // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
                if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                    isAllowedTo('modify_replies');
                } else {
                    isAllowedTo('modify_own');
                }
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_any');
            }
            if (!empty($modSettings['attachmentEnable'])) {
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(size, -1) AS filesize, filename, id_attach, approved
					FROM {db_prefix}attachments
					WHERE id_msg = {int:id_msg}
						AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    if ($row['filesize'] <= 0) {
                        continue;
                    }
                    $context['current_attachments'][] = array('name' => htmlspecialchars($row['filename']), 'id' => $row['id_attach'], 'approved' => $row['approved']);
                }
                $smcFunc['db_free_result']($request);
            }
            // Allow moderators to change names....
            if (allowedTo('moderate_forum') && !empty($topic)) {
                $request = $smcFunc['db_query']('', '
					SELECT id_member, poster_name, poster_email
					FROM {db_prefix}messages
					WHERE id_msg = {int:id_msg}
						AND id_topic = {int:current_topic}
					LIMIT 1', array('current_topic' => $topic, 'id_msg' => (int) $_REQUEST['msg']));
                $row = $smcFunc['db_fetch_assoc']($request);
                $smcFunc['db_free_result']($request);
                if (empty($row['id_member'])) {
                    $context['name'] = htmlspecialchars($row['poster_name']);
                    $context['email'] = htmlspecialchars($row['poster_email']);
                }
            }
        }
        // No check is needed, since nothing is really posted.
        checkSubmitOnce('free');
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Get the existing message.
        $request = $smcFunc['db_query']('', '
			SELECT
				m.id_member, m.modified_time, m.smileys_enabled, m.body,
				m.poster_name, m.poster_email, m.subject, m.icon, m.approved,
				IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach,
				a.approved AS attachment_approved, t.id_member_started AS id_member_poster,
				m.poster_time
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
				LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type})
			WHERE m.id_msg = {int:id_msg}
				AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg']));
        // The message they were trying to edit was most likely deleted.
        // !!! Change this error message?
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('no_board', false);
        }
        $row = $smcFunc['db_fetch_assoc']($request);
        $attachment_stuff = array($row);
        while ($row2 = $smcFunc['db_fetch_assoc']($request)) {
            $attachment_stuff[] = $row2;
        }
        $smcFunc['db_free_result']($request);
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public.
            if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
        } else {
            isAllowedTo('modify_any');
        }
        // When was it last modified?
        if (!empty($row['modified_time'])) {
            $context['last_modified'] = timeformat($row['modified_time']);
        }
        // Get the stuff ready for the form.
        $form_subject = $row['subject'];
        $form_message = un_preparsecode($row['body']);
        censorText($form_message);
        censorText($form_subject);
        // Check the boxes that should be checked.
        $context['use_smileys'] = !empty($row['smileys_enabled']);
        $context['icon'] = $row['icon'];
        // Show an "approve" box if the user can approve it, and the message isn't approved.
        if (!$row['approved'] && !$context['show_approval']) {
            $context['show_approval'] = allowedTo('approve_posts');
        }
        // Load up 'em attachments!
        foreach ($attachment_stuff as $attachment) {
            if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) {
                $context['current_attachments'][] = array('name' => htmlspecialchars($attachment['filename']), 'id' => $attachment['id_attach'], 'approved' => $attachment['attachment_approved']);
            }
        }
        // Allow moderators to change names....
        if (allowedTo('moderate_forum') && empty($row['id_member'])) {
            $context['name'] = htmlspecialchars($row['poster_name']);
            $context['email'] = htmlspecialchars($row['poster_email']);
        }
        // Set the destinaton.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['save'];
    } else {
        // By default....
        $context['use_smileys'] = true;
        $context['icon'] = 'xx';
        if ($user_info['is_guest']) {
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
        }
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt['post'];
        // Posting a quoted reply?
        if (!empty($topic) && !empty($_REQUEST['quote'])) {
            // Make sure they _can_ quote this post, and if so get it.
            $request = $smcFunc['db_query']('', '
				SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
					LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
				WHERE m.id_msg = {int:id_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND m.approved = {int:is_approved}') . '
				LIMIT 1', array('id_msg' => (int) $_REQUEST['quote'], 'is_approved' => 1));
            if ($smcFunc['db_num_rows']($request) == 0) {
                fatal_lang_error('quoted_post_deleted', false);
            }
            list($form_subject, $mname, $mdate, $form_message) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // Add 'Re: ' to the front of the quoted subject.
            if (trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the message and subject.
            censorText($form_message);
            censorText($form_subject);
            // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited!
            if (strpos($form_message, '[html]') !== false) {
                $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE);
                for ($i = 0, $n = count($parts); $i < $n; $i++) {
                    // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat.
                    if ($i % 4 == 0) {
                        $parts[$i] = preg_replace('~\\[html\\](.+?)\\[/html\\]~ise', '\'[html]\' . preg_replace(\'~<br\\s?/?' . '>~i\', \'&lt;br /&gt;<br />\', \'$1\') . \'[/html]\'', $parts[$i]);
                    }
                }
                $form_message = implode('', $parts);
            }
            $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $form_message);
            // Remove any nested quotes, if necessary.
            if (!empty($modSettings['removeNestedQuotes'])) {
                $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message);
            }
            // Add a quote string on the front and end.
            $form_message = '[quote author=' . $mname . ' link=topic=' . $topic . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $mdate . ']' . "\n" . rtrim($form_message) . "\n" . '[/quote]';
        } elseif (!empty($topic) && empty($_REQUEST['quote'])) {
            // Get the first message's subject.
            $form_subject = $first_subject;
            // Add 'Re: ' to the front of the subject.
            if (trim($context['response_prefix']) != '' && $form_subject != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) {
                $form_subject = $context['response_prefix'] . $form_subject;
            }
            // Censor the subject.
            censorText($form_subject);
            $form_message = '';
        } else {
            $form_subject = isset($_GET['subject']) ? $_GET['subject'] : '';
            $form_message = '';
        }
    }
    // !!! This won't work if you're posting an event.
    if (allowedTo('post_attachment') || allowedTo('post_unapproved_attachments')) {
        if (empty($_SESSION['temp_attachments'])) {
            $_SESSION['temp_attachments'] = array();
        }
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            // Just use the current path for temp files.
            $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $current_attach_dir = $modSettings['attachmentUploadDir'];
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*), SUM(size)
				FROM {db_prefix}attachments
				WHERE id_msg = {int:id_msg}
					AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
            list($quantity, $total_size) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        $temp_start = 0;
        if (!empty($_SESSION['temp_attachments'])) {
            if ($context['current_action'] != 'post2' || !empty($_POST['from_qr'])) {
                $context['post_error']['messages'][] = $txt['error_temp_attachments'];
                $context['error_type'] = 'minor';
            }
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                $temp_start++;
                if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    $deleted_attachments = true;
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($current_attach_dir . '/' . $attachID);
                    continue;
                }
                $quantity++;
                $total_size += filesize($current_attach_dir . '/' . $attachID);
                $context['current_attachments'][] = array('name' => htmlspecialchars($name), 'id' => $attachID, 'approved' => 1);
            }
        }
        if (!empty($_POST['attach_del'])) {
            $del_temp = array();
            foreach ($_POST['attach_del'] as $i => $dummy) {
                $del_temp[$i] = (int) $dummy;
            }
            foreach ($context['current_attachments'] as $k => $dummy) {
                if (!in_array($dummy['id'], $del_temp)) {
                    $context['current_attachments'][$k]['unchecked'] = true;
                    $deleted_attachments = !isset($deleted_attachments) || is_bool($deleted_attachments) ? 1 : $deleted_attachments + 1;
                    $quantity--;
                }
            }
        }
        if (!empty($_FILES['attachment'])) {
            foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
                if ($_FILES['attachment']['name'][$n] == '') {
                    continue;
                }
                if (!is_uploaded_file($_FILES['attachment']['tmp_name'][$n]) || @ini_get('open_basedir') == '' && !file_exists($_FILES['attachment']['tmp_name'][$n])) {
                    fatal_lang_error('attach_timeout', 'critical');
                }
                if (!empty($modSettings['attachmentSizeLimit']) && $_FILES['attachment']['size'][$n] > $modSettings['attachmentSizeLimit'] * 1024) {
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit']));
                }
                $quantity++;
                if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                    fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
                }
                $total_size += $_FILES['attachment']['size'][$n];
                if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit']));
                }
                if (!empty($modSettings['attachmentCheckExtensions'])) {
                    if (!in_array(strtolower(substr(strrchr($_FILES['attachment']['name'][$n], '.'), 1)), explode(',', strtolower($modSettings['attachmentExtensions'])))) {
                        fatal_error($_FILES['attachment']['name'][$n] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                    }
                }
                if (!empty($modSettings['attachmentDirSizeLimit'])) {
                    // Make sure the directory isn't full.
                    $dirSize = 0;
                    $dir = @opendir($current_attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical');
                    while ($file = readdir($dir)) {
                        if ($file == '.' || $file == '..') {
                            continue;
                        }
                        if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) {
                            // Temp file is more than 5 hours old!
                            if (filemtime($current_attach_dir . '/' . $file) < time() - 18000) {
                                @unlink($current_attach_dir . '/' . $file);
                            }
                            continue;
                        }
                        $dirSize += filesize($current_attach_dir . '/' . $file);
                    }
                    closedir($dir);
                    // Too big!  Maybe you could zip it or something...
                    if ($_FILES['attachment']['size'][$n] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) {
                        fatal_lang_error('ran_out_of_space');
                    }
                }
                if (!is_writable($current_attach_dir)) {
                    fatal_lang_error('attachments_no_write', 'critical');
                }
                $attachID = 'post_tmp_' . $user_info['id'] . '_' . $temp_start++;
                $_SESSION['temp_attachments'][$attachID] = basename($_FILES['attachment']['name'][$n]);
                $context['current_attachments'][] = array('name' => htmlspecialchars(basename($_FILES['attachment']['name'][$n])), 'id' => $attachID, 'approved' => 1);
                $destName = $current_attach_dir . '/' . $attachID;
                if (!move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) {
                    fatal_lang_error('attach_timeout', 'critical');
                }
                @chmod($destName, 0644);
            }
        }
    }
    // If we are coming here to make a reply, and someone has already replied... make a special warning message.
    if (isset($newRepliesError)) {
        $context['post_error']['messages'][] = $newRepliesError == 1 ? $txt['error_new_reply'] : $txt['error_new_replies'];
        $context['error_type'] = 'minor';
    }
    if (isset($oldTopicError)) {
        $context['post_error']['messages'][] = sprintf($txt['error_old_topic'], $modSettings['oldTopicDays']);
        $context['error_type'] = 'minor';
    }
    // What are you doing?  Posting a poll, modifying, previewing, new post, or reply...
    if (isset($_REQUEST['poll'])) {
        $context['page_title'] = $txt['new_poll'];
    } elseif ($context['make_event']) {
        $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar_post_event'] : $txt['calendar_edit'];
    } elseif (isset($_REQUEST['msg'])) {
        $context['page_title'] = $txt['modify_msg'];
    } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) {
        $context['page_title'] = $txt['preview'] . ' - ' . strip_tags($context['preview_subject']);
    } elseif (empty($topic)) {
        $context['page_title'] = $txt['start_new_topic'];
    } else {
        $context['page_title'] = $txt['post_reply'];
    }
    // Build the link tree.
    if (empty($topic)) {
        $context['linktree'][] = array('name' => '<em>' . $txt['start_new_topic'] . '</em>');
    } else {
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', 'extra_after' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav"> )</strong></span>');
    }
    // Give wireless a linktree url to the post screen, so that they can switch to full version.
    if (WIRELESS) {
        $context['linktree'][count($context['linktree']) - 1]['url'] = $scripturl . '?action=post;' . (!empty($topic) ? 'topic=' . $topic : 'board=' . $board) . '.' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . (int) $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '');
    }
    // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments.
    // !!! This won't work if you're posting an event.
    $context['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['current_attachments']) + (isset($deleted_attachments) ? $deleted_attachments : 0), $modSettings['attachmentNumPerPostLimit']);
    $context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments')) && $context['num_allowed_attachments'] > 0;
    $context['can_post_attachment_unapproved'] = allowedTo('post_attachment');
    $context['subject'] = addcslashes($form_subject, '"');
    $context['message'] = str_replace(array('"', '<', '>', '&nbsp;'), array('&quot;', '&lt;', '&gt;', ' '), $form_message);
    // Needed for the editor and message icons.
    require_once $sourcedir . '/Subs-Editor.php';
    // Now create the editor.
    $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'height' => '175px', 'width' => '100%', 'preview_type' => 2);
    create_control_richedit($editorOptions);
    // Store the ID.
    $context['post_box_name'] = $editorOptions['id'];
    $context['attached'] = '';
    $context['make_poll'] = isset($_REQUEST['poll']);
    // Message icons - customized icons are off?
    $context['icons'] = getMessageIcons($board);
    if (!empty($context['icons'])) {
        $context['icons'][count($context['icons']) - 1]['is_last'] = true;
    }
    $context['icon_url'] = '';
    for ($i = 0, $n = count($context['icons']); $i < $n; $i++) {
        $context['icons'][$i]['selected'] = $context['icon'] == $context['icons'][$i]['value'];
        if ($context['icons'][$i]['selected']) {
            $context['icon_url'] = $context['icons'][$i]['url'];
        }
    }
    if (empty($context['icon_url'])) {
        $context['icon_url'] = $settings[file_exists($settings['theme_dir'] . '/images/post/' . $context['icon'] . '.gif') ? 'images_url' : 'default_images_url'] . '/post/' . $context['icon'] . '.gif';
        array_unshift($context['icons'], array('value' => $context['icon'], 'name' => $txt['current_icon'], 'url' => $context['icon_url'], 'is_last' => empty($context['icons']), 'selected' => true));
    }
    if (!empty($topic) && !empty($modSettings['topicSummaryPosts'])) {
        getTopic();
    }
    // If the user can post attachments prepare the warning labels.
    if ($context['can_post_attachment']) {
        $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', '));
        $context['attachment_restrictions'] = array();
        $attachmentRestrictionTypes = array('attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit');
        foreach ($attachmentRestrictionTypes as $type) {
            if (!empty($modSettings[$type])) {
                $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_' . $type], $modSettings[$type]);
            }
        }
    }
    $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']);
    $context['show_additional_options'] = !empty($_POST['additional_options']) || !empty($_SESSION['temp_attachments']) || !empty($deleted_attachments);
    $context['is_new_topic'] = empty($topic);
    $context['is_new_post'] = !isset($_REQUEST['msg']);
    $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $id_first_msg;
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // If they came from quick reply, and have to enter verification details, give them some notice.
    if (!empty($_REQUEST['from_qr']) && !empty($context['require_verification'])) {
        $context['post_error']['messages'][] = $txt['enter_verification_details'];
        $context['error_type'] = 'minor';
    }
    // WYSIWYG only works if BBC is enabled
    $modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']);
    // Register this form in the session variables.
    checkSubmitOnce('register');
    // Finally, load the template.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_post';
    } elseif (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
}
*                                                                                 *
* This program is distributed in the hope that it is and will be useful, but      *
* WITHOUT ANY WARRANTIES; without even any implied warranty of MERCHANTABILITY    *
* or FITNESS FOR A PARTICULAR PURPOSE.                                            *
*                                                                                 *
* See the "license.txt" file for details of the Simple Machines license.          *
* The latest version can always be found at http://www.simplemachines.org.        *
**********************************************************************************/
$smfsite = 'http://www.simplemachines.org/smf';
if (!file_exists(dirname(__FILE__) . '/SSI.php')) {
    die('Please move this file to the main SMF directory and make sure SSI.php is part of that directory.');
}
$sphinx_ver = '0.9.9';
require dirname(__FILE__) . '/SSI.php';
// Kick the guests.
is_not_guest();
// Kick the non-admin
if (!$user_info['is_admin']) {
    die('You need admin permission to use this tool.');
}
if (!isset($_REQUEST['step'])) {
    step_0();
} else {
    $cur_step = 'step_' . (int) $_REQUEST['step'];
    $cur_step();
}
function step_0()
{
    global $txt;
    template_sphinx_config_above('Introduction');
    echo '
Beispiel #12
0
function loadBoard()
{
    global $txt, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $user_info, $db_show_debug;
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Have they by chance specified a message id but nothing else?
    if (empty($_REQUEST['action']) && empty($topic) && empty($board) && !empty($_REQUEST['msg'])) {
        // Make sure the message id is really an int.
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Looking through the message table can be slow, so try using the cache first.
        if (($topic = CacheAPI::getCache('msg_topic-' . $_REQUEST['msg'], 120)) === NULL) {
            $request = smf_db_query('
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_msg = {int:id_msg}
				LIMIT 1', array('id_msg' => $_REQUEST['msg']));
            // So did it find anything?
            if (mysql_num_rows($request)) {
                list($topic) = mysql_fetch_row($request);
                mysql_free_result($request);
                // Save save save.
                CacheAPI::putCache('msg_topic-' . $_REQUEST['msg'], $topic, 120);
            }
        }
        // Remember redirection is the key to avoiding fallout from your bosses.
        if (!empty($topic)) {
            if (isset($_REQUEST['perma'])) {
                redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . ';perma' . (isset($_REQUEST['xml']) ? ';xml' : ''));
            } else {
                redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']);
            }
        } else {
            loadPermissions();
            loadTheme();
            EoS_Smarty::init($db_show_debug);
            fatal_lang_error('topic_gone', false);
        }
    }
    // Load this board only if it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
        // !!! SLOW?
        if (!empty($topic)) {
            $temp = CacheAPI::getCache('topic_board-' . $topic, 120);
        } else {
            $temp = CacheAPI::getCache('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $request = smf_db_query('
			SELECT
				c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups,
				b.id_parent, c.name AS cname, IFNULL(mem.id_member, 0) AS id_moderator,
				mem.real_name' . (!empty($topic) ? ', b.id_board' : '') . ', b.child_level,
				b.id_theme, b.override_theme, b.count_posts, b.id_profile, b.redirect, b.allow_topics,
				b.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . '
			FROM {db_prefix}boards AS b' . (!empty($topic) ? '
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . '
				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = {raw:board_link})
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
			WHERE b.id_board = {raw:board_link}', array('current_topic' => $topic, 'board_link' => empty($topic) ? smf_db_quote('{int:current_board}', array('current_board' => $board)) : 't.id_board'));
        // If there aren't any, skip.
        if (mysql_num_rows($request) > 0) {
            $row = mysql_fetch_assoc($request);
            // Set the current board.
            if (!empty($row['id_board'])) {
                $board = $row['id_board'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'is_root' => $row['cname'][0] === '!' ? true : false), 'name' => $row['bname'], 'allow_topics' => $row['allow_topics'], 'description' => $row['description'], 'num_topics' => $row['num_topics'], 'unapproved_topics' => $row['unapproved_topics'], 'unapproved_posts' => $row['unapproved_posts'], 'unapproved_user_topics' => 0, 'parent_boards' => getBoardParents($row['id_parent']), 'parent' => $row['id_parent'], 'child_level' => $row['child_level'], 'theme' => $row['id_theme'], 'override_theme' => !empty($row['override_theme']), 'profile' => $row['id_profile'], 'redirect' => $row['redirect'], 'posts_count' => empty($row['count_posts']), 'cur_topic_approved' => empty($topic) || $row['approved'], 'cur_topic_starter' => empty($topic) ? 0 : $row['id_member_started']);
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['member_groups'] == '' ? array() : explode(',', $row['member_groups']);
            do {
                if (!empty($row['id_moderator'])) {
                    $board_info['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_moderator'] . '">' . $row['real_name'] . '</a>');
                }
            } while ($row = mysql_fetch_assoc($request));
            // If the board only contains unapproved posts and the user isn't an approver then they can't see any topics.
            // If that is the case do an additional check to see if they have any topics waiting to be approved.
            if ($board_info['num_topics'] == 0 && $modSettings['postmod_active'] && !allowedTo('approve_posts')) {
                mysql_free_result($request);
                // Free the previous result
                $request = smf_db_query('
					SELECT COUNT(id_topic)
					FROM {db_prefix}topics
					WHERE id_member_started={int:id_member}
						AND approved = {int:unapproved}
						AND id_board = {int:board}', array('id_member' => $user_info['id'], 'unapproved' => 0, 'board' => $board));
                list($board_info['unapproved_user_topics']) = mysql_fetch_row($request);
            }
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
                // !!! SLOW?
                if (!empty($topic)) {
                    CacheAPI::putCache('topic_board-' . $topic, $board_info, 120);
                }
                CacheAPI::putCache('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        mysql_free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    /*
     * if we are in topic view, set up the breadcrumb so that it
     * gives a link back to the last active message index page instead of
     * always pointing back to page one, but ignore the cookie when the board has changed.
     * the cookie is set in MessageIndex.php
     */
    $stored_topicstart = 0;
    if (isset($_COOKIE['smf_topicstart']) && !empty($topic)) {
        $topicstart_cookie = $_COOKIE['smf_topicstart'];
        $_t = explode('_', $topicstart_cookie);
        if (isset($_t[0]) && isset($_t[1]) && intval($_t[1]) > 0) {
            if ($_t[0] == $board) {
                $stored_topicstart = $_t[1];
            }
            $topics_per_page = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
        }
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]);
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], $board_info['cat']['is_root'] ? array() : array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => URL::board($board, $board_info['name'], $stored_topicstart > 0 ? $stored_topicstart : 0, false), 'name' => $board_info['name'] . ($stored_topicstart > 0 ? ' [' . ($stored_topicstart / $topics_per_page + 1) . ']' : ''))));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        EoS_Smarty::init($db_show_debug);
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // The linktree should not give the game away mate!
        $context['linktree'] = array(array('url' => URL::home(), 'name' => $context['forum_name_html_safe']));
        // If it's a prefetching agent or we're requesting an attachment.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch' || !empty($_REQUEST['action']) && $_REQUEST['action'] === 'dlattach') {
            ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}
Beispiel #13
0
function action_get_message()
{
    global $context, $smcFunc, $modSettings, $scripturl, $sourcedir, $user_info, $msg_id, $box_id, $user_profile, $memberContext;
    require_once 'include/PersonalMessage.php';
    // No guests!
    is_not_guest();
    // You're not supposed to be here at all, if you can't even read PMs.
    isAllowedTo('pm_read');
    loadLanguage('PersonalMessage');
    $request = $smcFunc['db_query']('', '
        SELECT COUNT(*) AS num
        FROM {db_prefix}pm_recipients pr
            INNER JOIN {db_prefix}personal_messages AS pm ON (pr.id_pm = pm.id_pm)
        WHERE pm.id_pm = {int:id_message} and (pr.id_member = {int:id_member} or pm.id_member_from = {int:id_member})', array('id_message' => $msg_id, 'id_member' => $user_info['id']));
    $permission = $smcFunc['db_fetch_assoc']($request);
    if (empty($permission) || $permission['num'] <= 0) {
        fatal_lang_error('no_access', false);
    }
    $request = $smcFunc['db_query']('', '
        SELECT pm.id_member_from, pm.msgtime, pm.subject, pm.body, m.member_name, m.real_name
        FROM {db_prefix}personal_messages AS pm
            LEFT JOIN {db_prefix}members AS m ON (pm.id_member_from = m.id_member)
        WHERE pm.id_pm = {int:id_message} ' . ($box_id == 'sent' ? 'AND pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = 0' : ''), array('id_message' => $msg_id, 'current_member' => $user_info['id']));
    $pm = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    if (empty($pm)) {
        fatal_lang_error('no_access', false);
    }
    censorText($pm['subject']);
    censorText($pm['body']);
    $context['pm'] = array('id_member' => $pm['id_member_from'], 'username' => $pm['member_name'], 'name' => $pm['real_name'], 'time' => timeformat($pm['msgtime']), 'timestamp' => $pm['msgtime'], 'subject' => $pm['subject'], 'body' => mobiquo_parse_bbc($pm['body'], false, 'pm' . $msg_id), 'recipients' => array());
    $request = $smcFunc['db_query']('', '
        SELECT pmr.id_member, m.member_name, m.real_name
        FROM {db_prefix}pm_recipients AS pmr
            LEFT JOIN {db_prefix}members AS m ON (pmr.id_member = m.id_member)
        WHERE pmr.id_pm = {int:id_message} ' . ($box_id == 'inbox' ? 'AND ((pmr.id_member = {int:current_member} AND pmr.deleted = 0) OR (pmr.id_member != {int:current_member} AND pmr.bcc = 0))' : ''), array('id_message' => $msg_id, 'current_member' => $user_info['id']));
    $no_member = true;
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['pm']['recipients'][] = new xmlrpcval(array('user_id' => new xmlrpcval(basic_clean($row['id_member'])), 'username' => new xmlrpcval(basic_clean($row['real_name']), 'base64')), 'struct');
        if ($no_member) {
            $display_member_id = $box_id == 'inbox' ? $pm['id_member_from'] : $row['id_member'];
            $no_member = false;
        }
    }
    $smcFunc['db_free_result']($request);
    loadMemberData($display_member_id);
    loadMemberContext($display_member_id);
    $context['pm']['member'] = $memberContext[$display_member_id];
    if ($no_avatar) {
        fatal_lang_error('no_access', false);
    }
    // Mark this as read, if it is not already
    markMessages(array($msg_id));
}
function sp_shoutbox($parameters, $id, $return_parameters = false)
{
    global $smcFunc, $context, $sourcedir, $modSettings, $user_info, $settings, $txt, $scripturl;
    $block_parameters = array('shoutbox' => array());
    if ($return_parameters) {
        $shoutboxes = sportal_get_shoutbox();
        $in_use = array();
        $request = $smcFunc['db_query']('', '
			SELECT id_block, value
			FROM {db_prefix}sp_parameters
			WHERE variable = {string:name}', array('name' => 'shoutbox'));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($_REQUEST['block_id']) || $_REQUEST['block_id'] != $row['id_block']) {
                $in_use[] = $row['value'];
            }
        }
        $smcFunc['db_free_result']($request);
        foreach ($shoutboxes as $shoutbox) {
            if (!in_array($shoutbox['id'], $in_use)) {
                $block_parameters['shoutbox'][$shoutbox['id']] = $shoutbox['name'];
            }
        }
        if (empty($block_parameters['shoutbox'])) {
            fatal_error(allowedTo(array('sp_admin', 'sp_manage_shoutbox')) ? $txt['error_sp_no_shoutbox'] . '<br />' . sprintf($txt['error_sp_no_shoutbox_sp_moderator'], $scripturl . '?action=admin;area=portalshoutbox;sa=add') : $txt['error_sp_no_shoutbox_normaluser'], false);
        }
        return $block_parameters;
    }
    loadTemplate('PortalShoutbox');
    loadLanguage('Post');
    $shoutbox = sportal_get_shoutbox($parameters['shoutbox'], true, true);
    if (empty($shoutbox)) {
        echo '
								', $txt['error_sp_shoutbox_not_exist'];
        return;
    }
    if (!empty($_POST['new_shout']) && !empty($_POST['submit_shout']) && !empty($_POST['shoutbox_id']) && $_POST['shoutbox_id'] == $shoutbox['id']) {
        checkSession();
        is_not_guest();
        if (!($flood = sp_prevent_flood('spsbp', false))) {
            require_once $sourcedir . '/Subs-Post.php';
            $_POST['new_shout'] = $smcFunc['htmlspecialchars'](trim($_POST['new_shout']));
            preparsecode($_POST['new_shout']);
            if (!empty($_POST['new_shout'])) {
                sportal_create_shout($shoutbox, $_POST['new_shout']);
            }
        } else {
            $shoutbox['warning'] = $flood;
        }
    }
    $can_moderate = allowedTo('sp_admin') || allowedTo('sp_manage_shoutbox');
    if (!$can_moderate && !empty($shoutbox['moderator_groups'])) {
        $can_moderate = count(array_intersect($user_info['groups'], $shoutbox['moderator_groups'])) > 0;
    }
    $shout_parameters = array('limit' => $shoutbox['num_show'], 'bbc' => $shoutbox['allowed_bbc'], 'reverse' => $shoutbox['reverse'], 'cache' => $shoutbox['caching'], 'can_moderate' => $can_moderate);
    $shoutbox['shouts'] = sportal_get_shouts($shoutbox['id'], $shout_parameters);
    $shoutbox['warning'] = parse_bbc($shoutbox['warning']);
    $context['can_shout'] = $context['user']['is_logged'];
    if ($context['can_shout']) {
        $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set'];
        $shoutbox['smileys'] = array('normal' => array(), 'popup' => array());
        if (empty($modSettings['smiley_enable'])) {
            $shoutbox['smileys']['normal'] = array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt['icon_smiley']), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt['icon_wink']), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt['icon_cheesy']), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt['icon_grin']), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt['icon_angry']), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt['icon_sad']), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt['icon_shocked']), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt['icon_cool']), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt['icon_huh']), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt['icon_rolleyes']), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt['icon_tongue']), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt['icon_embarrassed']), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt['icon_lips']), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt['icon_undecided']), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt['icon_kiss']), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt['icon_cry']));
        } else {
            if (($temp = cache_get_data('shoutbox_smileys', 3600)) == null) {
                $request = $smcFunc['db_query']('', '
					SELECT code, filename, description, smiley_row, hidden
					FROM {db_prefix}smileys
					WHERE hidden IN ({array_int:hidden})
					ORDER BY smiley_row, smiley_order', array('hidden' => array(0, 2)));
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    $row['filename'] = htmlspecialchars($row['filename']);
                    $row['description'] = htmlspecialchars($row['description']);
                    $row['code'] = htmlspecialchars($row['code']);
                    $shoutbox['smileys'][empty($row['hidden']) ? 'normal' : 'popup'][] = $row;
                }
                $smcFunc['db_free_result']($request);
                cache_put_data('shoutbox_smileys', $shoutbox['smileys'], 3600);
            } else {
                $shoutbox['smileys'] = $temp;
            }
        }
        foreach (array_keys($shoutbox['smileys']) as $location) {
            $n = count($shoutbox['smileys'][$location]);
            for ($i = 0; $i < $n; $i++) {
                $shoutbox['smileys'][$location][$i]['code'] = addslashes($shoutbox['smileys'][$location][$i]['code']);
                $shoutbox['smileys'][$location][$i]['js_description'] = addslashes($shoutbox['smileys'][$location][$i]['description']);
            }
            if (!empty($shoutbox['smileys'][$location])) {
                $shoutbox['smileys'][$location][$n - 1]['last'] = true;
            }
        }
        $shoutbox['bbc'] = array('bold' => array('code' => 'b', 'before' => '[b]', 'after' => '[/b]', 'description' => $txt['bold']), 'italicize' => array('code' => 'i', 'before' => '[i]', 'after' => '[/i]', 'description' => $txt['italic']), 'underline' => array('code' => 'u', 'before' => '[u]', 'after' => '[/u]', 'description' => $txt['underline']), 'strike' => array('code' => 's', 'before' => '[s]', 'after' => '[/s]', 'description' => $txt['strike']), 'pre' => array('code' => 'pre', 'before' => '[pre]', 'after' => '[/pre]', 'description' => $txt['preformatted']), 'flash' => array('code' => 'flash', 'before' => '[flash=200,200]', 'after' => '[/flash]', 'description' => $txt['flash']), 'img' => array('code' => 'img', 'before' => '[img]', 'after' => '[/img]', 'description' => $txt['image']), 'url' => array('code' => 'url', 'before' => '[url]', 'after' => '[/url]', 'description' => $txt['hyperlink']), 'email' => array('code' => 'email', 'before' => '[email]', 'after' => '[/email]', 'description' => $txt['insert_email']), 'ftp' => array('code' => 'ftp', 'before' => '[ftp]', 'after' => '[/ftp]', 'description' => $txt['ftp']), 'glow' => array('code' => 'glow', 'before' => '[glow=red,2,300]', 'after' => '[/glow]', 'description' => $txt['glow']), 'shadow' => array('code' => 'shadow', 'before' => '[shadow=red,left]', 'after' => '[/shadow]', 'description' => $txt['shadow']), 'sup' => array('code' => 'sup', 'before' => '[sup]', 'after' => '[/sup]', 'description' => $txt['superscript']), 'sub' => array('code' => 'sub', 'before' => '[sub]', 'after' => '[/sub]', 'description' => $txt['subscript']), 'tele' => array('code' => 'tt', 'before' => '[tt]', 'after' => '[/tt]', 'description' => $txt['teletype']), 'code' => array('code' => 'code', 'before' => '[code]', 'after' => '[/code]', 'description' => $txt['bbc_code']), 'quote' => array('code' => 'quote', 'before' => '[quote]', 'after' => '[/quote]', 'description' => $txt['bbc_quote']));
    }
    template_shoutbox_embed($shoutbox);
}
function isAllowedTo($permission, $boards = null)
{
    global $user_info, $txt;
    static $heavy_permissions = array('admin_forum', 'manage_attachments', 'manage_smileys', 'manage_boards', 'edit_news', 'moderate_forum', 'manage_bans', 'manage_membergroups', 'manage_permissions');
    // Make it an array, even if a string was passed.
    $permission = is_array($permission) ? $permission : array($permission);
    // Check the permission and return an error...
    if (!allowedTo($permission, $boards)) {
        // Pick the last array entry as the permission shown as the error.
        $error_permission = array_shift($permission);
        // If they are a guest, show a login. (because the error might be gone if they do!)
        if ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['cannot_' . $error_permission]);
        }
        // Clear the action because they aren't really doing that!
        $_GET['action'] = '';
        $_GET['board'] = '';
        $_GET['topic'] = '';
        writeLog(true);
        fatal_lang_error('cannot_' . $error_permission, false);
        // Getting this far is a really big problem, but let's try our best to prevent any cases...
        trigger_error('Hacking attempt...', E_USER_ERROR);
    }
    // If you're doing something on behalf of some "heavy" permissions, validate your session.
    // (take out the heavy permissions, and if you can't do anything but those, you need a validated session.)
    if (!allowedTo(array_diff($permission, $heavy_permissions), $boards)) {
        validateSession();
    }
}
Beispiel #16
0
function MarkRead()
{
    global $board, $topic, $user_info, $board_info, $modSettings, $smcFunc;
    // No Guests allowed!
    is_not_guest();
    checkSession('get');
    if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'all') {
        // Find all the boards this user can see.
        $result = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE {query_see_board}', array());
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            $boards[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($result);
        if (!empty($boards)) {
            markBoardsRead($boards, isset($_REQUEST['unread']));
        }
        $_SESSION['id_msg_last_visit'] = $modSettings['maxMsgID'];
        if (!empty($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'action=unread') !== false) {
            redirectexit('action=unread');
        }
        if (isset($_SESSION['topicseen_cache'])) {
            $_SESSION['topicseen_cache'] = array();
        }
        redirectexit();
    } elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'unreadreplies') {
        // Make sure all the boards are integers!
        $topics = explode('-', $_REQUEST['topics']);
        $markRead = array();
        foreach ($topics as $id_topic) {
            $markRead[] = array($modSettings['maxMsgID'], $user_info['id'], (int) $id_topic);
        }
        $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'), $markRead, array('id_member', 'id_topic'));
        if (isset($_SESSION['topicseen_cache'])) {
            $_SESSION['topicseen_cache'] = array();
        }
        redirectexit('action=unreadreplies');
    } elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'topic') {
        // First, let's figure out what the latest message is.
        $result = $smcFunc['db_query']('', '
			SELECT id_first_msg, id_last_msg
			FROM {db_prefix}topics
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic));
        $topicinfo = $smcFunc['db_fetch_assoc']($result);
        $smcFunc['db_free_result']($result);
        if (!empty($_GET['t'])) {
            // If they read the whole topic, go back to the beginning.
            if ($_GET['t'] >= $topicinfo['id_last_msg']) {
                $earlyMsg = 0;
            } elseif ($_GET['t'] <= $topicinfo['id_first_msg']) {
                $earlyMsg = 0;
            } else {
                $result = $smcFunc['db_query']('', '
					SELECT MAX(id_msg)
					FROM {db_prefix}messages
					WHERE id_topic = {int:current_topic}
						AND id_msg >= {int:id_first_msg}
						AND id_msg < {int:topic_msg_id}', array('current_topic' => $topic, 'topic_msg_id' => (int) $_GET['t'], 'id_first_msg' => $topicinfo['id_first_msg']));
                list($earlyMsg) = $smcFunc['db_fetch_row']($result);
                $smcFunc['db_free_result']($result);
            }
        } elseif ($_REQUEST['start'] == 0) {
            $earlyMsg = 0;
        } else {
            $result = $smcFunc['db_query']('', '
				SELECT id_msg
				FROM {db_prefix}messages
				WHERE id_topic = {int:current_topic}
				ORDER BY id_msg
				LIMIT ' . (int) $_REQUEST['start'] . ', 1', array('current_topic' => $topic));
            list($earlyMsg) = $smcFunc['db_fetch_row']($result);
            $smcFunc['db_free_result']($result);
            $earlyMsg--;
        }
        // Blam, unread!
        $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'), array($earlyMsg, $user_info['id'], $topic), array('id_member', 'id_topic'));
        redirectexit('board=' . $board . '.0');
    } else {
        $categories = array();
        $boards = array();
        if (isset($_REQUEST['c'])) {
            $_REQUEST['c'] = explode(',', $_REQUEST['c']);
            foreach ($_REQUEST['c'] as $c) {
                $categories[] = (int) $c;
            }
        }
        if (isset($_REQUEST['boards'])) {
            $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
            foreach ($_REQUEST['boards'] as $b) {
                $boards[] = (int) $b;
            }
        }
        if (!empty($board)) {
            $boards[] = (int) $board;
        }
        if (isset($_REQUEST['children']) && !empty($boards)) {
            // They want to mark the entire tree starting with the boards specified
            // The easist thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them
            $request = $smcFunc['db_query']('', '
				SELECT b.id_board, b.id_parent
				FROM {db_prefix}boards AS b
				WHERE {query_see_board}
					AND b.child_level > {int:no_parents}
					AND b.id_board NOT IN ({array_int:board_list})
				ORDER BY child_level ASC
				', array('no_parents' => 0, 'board_list' => $boards));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (in_array($row['id_parent'], $boards)) {
                    $boards[] = $row['id_board'];
                }
            }
            $smcFunc['db_free_result']($request);
        }
        $clauses = array();
        $clauseParameters = array();
        if (!empty($categories)) {
            $clauses[] = 'id_cat IN ({array_int:category_list})';
            $clauseParameters['category_list'] = $categories;
        }
        if (!empty($boards)) {
            $clauses[] = 'id_board IN ({array_int:board_list})';
            $clauseParameters['board_list'] = $boards;
        }
        if (empty($clauses)) {
            redirectexit();
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE {query_see_board}
				AND b.' . implode(' OR b.', $clauses), array_merge($clauseParameters, array()));
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            redirectexit();
        }
        markBoardsRead($boards, isset($_REQUEST['unread']));
        foreach ($boards as $b) {
            if (isset($_SESSION['topicseen_cache'][$b])) {
                $_SESSION['topicseen_cache'][$b] = array();
            }
        }
        if (!isset($_REQUEST['unread'])) {
            // Find all the boards this user can see.
            $result = $smcFunc['db_query']('', '
				SELECT b.id_board
				FROM {db_prefix}boards AS b
				WHERE b.id_parent IN ({array_int:parent_list})
					AND {query_see_board}', array('parent_list' => $boards));
            if ($smcFunc['db_num_rows']($result) > 0) {
                $logBoardInserts = '';
                while ($row = $smcFunc['db_fetch_assoc']($result)) {
                    $logBoardInserts[] = array($modSettings['maxMsgID'], $user_info['id'], $row['id_board']);
                }
                $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), $logBoardInserts, array('id_member', 'id_board'));
            }
            $smcFunc['db_free_result']($result);
            if (empty($board)) {
                redirectexit();
            } else {
                redirectexit('board=' . $board . '.0');
            }
        } else {
            if (empty($board_info['parent'])) {
                redirectexit();
            } else {
                redirectexit('board=' . $board_info['parent'] . '.0');
            }
        }
    }
}
Beispiel #17
0
function MessageMain()
{
    global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $db_prefix, $ID_MEMBER;
    // No guests!
    is_not_guest();
    // You're not supposed to be here at all, if you can't even read PMs.
    isAllowedTo('pm_read');
    // This file contains the basic functions for sending a PM.
    require_once $sourcedir . '/Subs-Post.php';
    if (loadLanguage('PersonalMessage', '', false) === false) {
        loadLanguage('InstantMessage');
    }
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_pm';
    } else {
        if (loadTemplate('PersonalMessage', false) === false) {
            loadTemplate('InstantMessage');
        }
    }
    // Load up the members maximum message capacity.
    if (!$user_info['is_admin']) {
        // !!! Why do we do this?  It seems like if they have any limit we should use it.
        $request = db_query("\n\t\t\tSELECT MAX(maxMessages) AS topLimit, MIN(maxMessages) AS bottomLimit\n\t\t\tFROM {$db_prefix}membergroups\n\t\t\tWHERE ID_GROUP IN (" . implode(', ', $user_info['groups']) . ')', __FILE__, __LINE__);
        list($maxMessage, $minMessage) = mysql_fetch_row($request);
        mysql_free_result($request);
        $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage;
    } else {
        $context['message_limit'] = 0;
    }
    // Prepare the context for the capacity bar.
    if (!empty($context['message_limit'])) {
        $bar = $user_info['messages'] * 100 / $context['message_limit'];
        $context['limit_bar'] = array('messages' => $user_info['messages'], 'allowed' => $context['message_limit'], 'percent' => $bar, 'bar' => min(100, (int) $bar), 'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1)));
    }
    // We should probably cache this information for speed.
    $context['labels'] = $user_settings['messageLabels'] == '' ? array() : explode(',', $user_settings['messageLabels']);
    foreach ($context['labels'] as $k => $v) {
        $context['labels'][(int) $k] = array('id' => $k, 'name' => trim($v), 'messages' => 0, 'unread_messages' => 0);
    }
    $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0);
    // !!! The idea would be to cache this information in the members table, and invlidate it when they are sent messages.
    $result = db_query("\n\t\tSELECT labels, is_read, COUNT(*) AS num\n\t\tFROM {$db_prefix}pm_recipients\n\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\tGROUP BY labels, is_read", __FILE__, __LINE__);
    while ($row = mysql_fetch_assoc($result)) {
        $this_labels = explode(',', $row['labels']);
        foreach ($this_labels as $this_label) {
            $context['labels'][(int) $this_label]['messages'] += $row['num'];
            if (!($row['is_read'] & 1)) {
                $context['labels'][(int) $this_label]['unread_messages'] += $row['num'];
            }
        }
    }
    mysql_free_result($result);
    // This determines if we have more labels than just the standard inbox.
    $context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0;
    // Some stuff for the labels...
    $context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][(int) $_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1;
    $context['current_label'] =& $context['labels'][(int) $context['current_label_id']]['name'];
    $context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'outbox' ? 'inbox' : 'outbox';
    // This is convenient.  Do you know how annoying it is to do this every time?!
    $context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : '');
    // Build the linktree for all the actions...
    $context['linktree'][] = array('url' => $scripturl . '?action=pm', 'name' => $txt[144]);
    $subActions = array('addbuddy' => 'WirelessAddBuddy', 'manlabels' => 'ManageLabels', 'outbox' => 'MessageFolder', 'pmactions' => 'MessageActionsApply', 'prune' => 'MessagePrune', 'removeall' => 'MessageKillAllQuery', 'removeall2' => 'MessageKillAll', 'report' => 'ReportMessage', 'search' => 'MessageSearch', 'search2' => 'MessageSearch2', 'send' => 'MessagePost', 'send2' => 'MessagePost2');
    if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) {
        MessageFolder();
    } else {
        messageIndexBar($_REQUEST['sa']);
        $subActions[$_REQUEST['sa']]();
    }
}
Beispiel #18
0
/**
 * Check for moderators and see if they have access to the board.
 *
 * What it does:
 * - sets up the $board_info array for current board information.
 * - if cache is enabled, the $board_info array is stored in cache.
 * - redirects to appropriate post if only message id is requested.
 * - is only used when inside a topic or board.
 * - determines the local moderators for the board.
 * - adds group id 3 if the user is a local moderator for the board they are in.
 * - prevents access if user is not in proper group nor a local moderator of the board.
 */
function loadBoard()
{
    global $txt, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $user_info;
    $db = database();
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // @since 1.0.5 - is_mod takes into account only local (board) moderators,
    // and not global moderators, is_moderator is meant to take into account both.
    $user_info['is_moderator'] = false;
    $context['user']['is_moderator'] =& $user_info['is_moderator'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Have they by chance specified a message id but nothing else?
    if (empty($_REQUEST['action']) && empty($topic) && empty($board) && !empty($_REQUEST['msg'])) {
        // Make sure the message id is really an int.
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Looking through the message table can be slow, so try using the cache first.
        if (($topic = cache_get_data('msg_topic-' . $_REQUEST['msg'], 120)) === null) {
            require_once SUBSDIR . '/Messages.subs.php';
            $topic = associatedTopic($_REQUEST['msg']);
            // So did it find anything?
            if ($topic !== false) {
                // Save save save.
                cache_put_data('msg_topic-' . $_REQUEST['msg'], $topic, 120);
            }
        }
        // Remember redirection is the key to avoiding fallout from your bosses.
        if (!empty($topic)) {
            redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']);
        } else {
            loadPermissions();
            loadTheme();
            fatal_lang_error('topic_gone', false);
        }
    }
    // Load this board only if it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
        // @todo SLOW?
        if (!empty($topic)) {
            $temp = cache_get_data('topic_board-' . $topic, 120);
        } else {
            $temp = cache_get_data('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $select_columns = array();
        $select_tables = array();
        // Wanna grab something more from the boards table or another table at all?
        call_integration_hook('integrate_load_board_query', array(&$select_columns, &$select_tables));
        $request = $db->query('', '
			SELECT
				c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups, b.deny_member_groups,
				b.id_parent, c.name AS cname, IFNULL(mem.id_member, 0) AS id_moderator,
				mem.real_name' . (!empty($topic) ? ', b.id_board' : '') . ', b.child_level,
				b.id_theme, b.override_theme, b.count_posts, b.id_profile, b.redirect,
				b.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . (!empty($select_columns) ? ', ' . implode(', ', $select_columns) : '') . '
			FROM {db_prefix}boards AS b' . (!empty($topic) ? '
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . (!empty($select_tables) ? '
				' . implode("\n\t\t\t\t", $select_tables) : '') . '
				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = {raw:board_link})
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
			WHERE b.id_board = {raw:board_link}', array('current_topic' => $topic, 'board_link' => empty($topic) ? $db->quote('{int:current_board}', array('current_board' => $board)) : 't.id_board'));
        // If there aren't any, skip.
        if ($db->num_rows($request) > 0) {
            $row = $db->fetch_assoc($request);
            // Set the current board.
            if (!empty($row['id_board'])) {
                $board = $row['id_board'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['id_cat'], 'name' => $row['cname']), 'name' => $row['bname'], 'description' => $row['description'], 'num_topics' => $row['num_topics'], 'unapproved_topics' => $row['unapproved_topics'], 'unapproved_posts' => $row['unapproved_posts'], 'unapproved_user_topics' => 0, 'parent_boards' => getBoardParents($row['id_parent']), 'parent' => $row['id_parent'], 'child_level' => $row['child_level'], 'theme' => $row['id_theme'], 'override_theme' => !empty($row['override_theme']), 'profile' => $row['id_profile'], 'redirect' => $row['redirect'], 'posts_count' => empty($row['count_posts']), 'cur_topic_approved' => empty($topic) || $row['approved'], 'cur_topic_starter' => empty($topic) ? 0 : $row['id_member_started']);
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['member_groups'] == '' ? array() : explode(',', $row['member_groups']);
            $board_info['deny_groups'] = $row['deny_member_groups'] == '' ? array() : explode(',', $row['deny_member_groups']);
            do {
                if (!empty($row['id_moderator'])) {
                    $board_info['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_moderator'] . '">' . $row['real_name'] . '</a>');
                }
            } while ($row = $db->fetch_assoc($request));
            // If the board only contains unapproved posts and the user isn't an approver then they can't see any topics.
            // If that is the case do an additional check to see if they have any topics waiting to be approved.
            if ($board_info['num_topics'] == 0 && $modSettings['postmod_active'] && !allowedTo('approve_posts')) {
                // Free the previous result
                $db->free_result($request);
                // @todo why is this using id_topic?
                // @todo Can this get cached?
                $request = $db->query('', '
					SELECT COUNT(id_topic)
					FROM {db_prefix}topics
					WHERE id_member_started={int:id_member}
						AND approved = {int:unapproved}
						AND id_board = {int:board}', array('id_member' => $user_info['id'], 'unapproved' => 0, 'board' => $board));
                list($board_info['unapproved_user_topics']) = $db->fetch_row($request);
            }
            call_integration_hook('integrate_loaded_board', array(&$board_info, &$row));
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
                // @todo SLOW?
                if (!empty($topic)) {
                    cache_put_data('topic_board-' . $topic, $board_info, 120);
                }
                cache_put_data('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        $db->free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]);
        $user_info['is_moderator'] = $user_info['is_mod'] || allowedTo('moderate_board');
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        if (!empty($modSettings['deny_boards_access']) && count(array_intersect($user_info['groups'], $board_info['deny_groups'])) != 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name'])));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['user']['is_moderator'] =& $user_info['is_moderator'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && (!empty($modSettings['deny_boards_access']) || $board_info['error'] != 'access' || !$user_info['is_moderator'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // The linktree should not give the game away mate!
        $context['linktree'] = array(array('url' => $scripturl, 'name' => $context['forum_name_html_safe']));
        // If it's a prefetching agent or we're requesting an attachment.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch' || !empty($_REQUEST['action']) && $_REQUEST['action'] === 'dlattach') {
            @ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}
Beispiel #19
0
 /**
  * Turn off/on unread replies subscription for a topic
  * Must be called with a topic specified in the URL.
  * The sub-action can be 'on', 'off', or nothing for what to do.
  * Requires the mark_any_notify permission.
  * Upon successful completion of action will direct user back to topic.
  * Accessed via ?action=unwatchtopic.
  */
 public function action_unwatchtopic()
 {
     global $user_info, $topic, $modSettings;
     is_not_guest();
     // our topic functions are here
     require_once SUBSDIR . '/Topic.subs.php';
     // Let's do something only if the function is enabled
     if (!$user_info['is_guest'] && !empty($modSettings['enable_unwatch'])) {
         checkSession('get');
         setTopicWatch($user_info['id'], $topic, $_GET['sa'] == 'on');
     }
     // Back to the topic.
     redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
 }
function sportal_shoutbox()
{
    global $smcFunc, $context, $scripturl, $txt, $sourcedir, $user_info;
    $shoutbox_id = !empty($_REQUEST['shoutbox_id']) ? (int) $_REQUEST['shoutbox_id'] : 0;
    $request_time = !empty($_REQUEST['time']) ? (int) $_REQUEST['time'] : 0;
    $context['SPortal']['shoutbox'] = sportal_get_shoutbox($shoutbox_id, true, true);
    if (empty($context['SPortal']['shoutbox'])) {
        fatal_lang_error('error_sp_shoutbox_not_exist', false);
    }
    $context['SPortal']['shoutbox']['warning'] = parse_bbc($context['SPortal']['shoutbox']['warning']);
    $can_moderate = allowedTo('sp_admin') || allowedTo('sp_manage_shoutbox');
    if (!$can_moderate && !empty($context['SPortal']['shoutbox']['moderator_groups'])) {
        $can_moderate = count(array_intersect($user_info['groups'], $context['SPortal']['shoutbox']['moderator_groups'])) > 0;
    }
    if (!empty($_REQUEST['shout'])) {
        checkSession('request');
        is_not_guest();
        if (!($flood = sp_prevent_flood('spsbp', false))) {
            require_once $sourcedir . '/Subs-Post.php';
            $_REQUEST['shout'] = $smcFunc['htmlspecialchars'](trim($_REQUEST['shout']));
            preparsecode($_REQUEST['shout']);
            if (!empty($_REQUEST['shout'])) {
                sportal_create_shout($context['SPortal']['shoutbox'], $_REQUEST['shout']);
            }
        } else {
            $context['SPortal']['shoutbox']['warning'] = $flood;
        }
    }
    if (!empty($_REQUEST['delete'])) {
        checkSession('request');
        if (!$can_moderate) {
            fatal_lang_error('error_sp_cannot_shoutbox_moderate', false);
        }
        $_REQUEST['delete'] = (int) $_REQUEST['delete'];
        if (!empty($_REQUEST['delete'])) {
            sportal_delete_shout($shoutbox_id, $_REQUEST['delete']);
        }
    }
    loadTemplate('PortalShoutbox');
    if (isset($_REQUEST['xml'])) {
        $shout_parameters = array('limit' => $context['SPortal']['shoutbox']['num_show'], 'bbc' => $context['SPortal']['shoutbox']['allowed_bbc'], 'reverse' => $context['SPortal']['shoutbox']['reverse'], 'cache' => $context['SPortal']['shoutbox']['caching'], 'can_moderate' => $can_moderate);
        $context['SPortal']['shouts'] = sportal_get_shouts($shoutbox_id, $shout_parameters);
        $context['sub_template'] = 'shoutbox_xml';
        $context['SPortal']['updated'] = empty($context['SPortal']['shoutbox']['last_update']) || $context['SPortal']['shoutbox']['last_update'] > $request_time;
        return;
    }
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}sp_shouts
		WHERE id_shoutbox = {int:current}', array('current' => $shoutbox_id));
    list($total_shouts) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['per_page'] = $context['SPortal']['shoutbox']['num_show'];
    $context['start'] = !empty($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    $context['page_index'] = constructPageIndex($scripturl . '?action=portal;sa=shoutbox;shoutbox_id=' . $shoutbox_id, $context['start'], $total_shouts, $context['per_page']);
    $shout_parameters = array('start' => $context['start'], 'limit' => $context['per_page'], 'bbc' => $context['SPortal']['shoutbox']['allowed_bbc'], 'cache' => $context['SPortal']['shoutbox']['caching'], 'can_moderate' => $can_moderate);
    $context['SPortal']['shouts_history'] = sportal_get_shouts($shoutbox_id, $shout_parameters);
    $context['SPortal']['shoutbox_id'] = $shoutbox_id;
    $context['sub_template'] = 'shoutbox_all';
    $context['page_title'] = $context['SPortal']['shoutbox']['name'];
}
/**
 *	Enforces a user having a given permission and returning to a fatal error message if not.
 *
 *	All fatal-level SimpleDesk-specific permissions should be checked with this function. Any other permission check that is
 *	not specifically SimpleDesk-related should use isAllowedTo instead. Note that this is a void function because should this
 *	fail, SMF execution will be halted.
 *
 *	Prior to 1.0, this function was in Subs-SimpleDesk.php
 *
 *	@param mixed $permission A string or array of strings naming a permission or permissions that wish to be examined.
 *	@param int $dept A number indicating a department that the user must the permission in, or 0 for not caring which department provided the user has that permission in at least one department.
 *	@see shd_allowed_to()
 *	@since 1.0
*/
function shd_is_allowed_to($permission, $dept = 0)
{
    global $user_info, $txt;
    $permission = is_array($permission) ? $permission : (array) $permission;
    if (!shd_allowed_to($permission, $dept)) {
        // Pick the last array entry as the permission shown as the error.
        $error_permission = array_shift($permission);
        // If they are a guest, show a login. (because the error might be gone if they do!)
        if ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['cannot_' . $error_permission]);
        }
        // Clear the action because they aren't really doing that!
        $_GET['action'] = '';
        $_GET['board'] = '';
        $_GET['topic'] = '';
        writeLog(true);
        fatal_lang_error('cannot_' . $error_permission, false);
        // Getting this far is a really big problem, but let's try our best to prevent any cases...
        trigger_error('Hacking attempt...', E_USER_ERROR);
    }
}
Beispiel #22
0
 /**
  * Checks that few things are in order (in addition to permissions) for likes.
  */
 private function prepare_like()
 {
     global $modSettings, $user_info, $txt;
     $check = true;
     // Valid request
     checkSession('get');
     // If you're a guest or simply can't do this, we stop
     is_not_guest();
     isAllowedTo('like_posts');
     // Load up the helpers
     require_once SUBSDIR . '/Likes.subs.php';
     // Maintain our log
     clearLikes(empty($modSettings['likeWaitTime']) ? 0 : $modSettings['likeWaitTime']);
     // Not a moderator/administrator then we do some checking
     if (!empty($modSettings['likeRestrictAdmins']) || !allowedTo('moderate_forum')) {
         // Find out if this user has done this recently...
         $check = lastLikeOn($user_info['id']);
     }
     // Past the post threshold?
     if (!$user_info['is_admin'] && !empty($modSettings['likeMinPosts']) && $user_info['posts'] < $modSettings['likeMinPosts']) {
         $check = false;
     }
     // If they have exceeded their limits, provide a message for the ajax response
     if ($check === false && $this->_api) {
         loadLanguage('Errors');
         $wait = $modSettings['likeWaitTime'] > 60 ? round($modSettings['likeWaitTime'] / 60, 2) : $modSettings['likeWaitTime'];
         $error = sprintf($txt['like_wait_time'], $wait, $modSettings['likeWaitTime'] < 60 ? strtolower($txt['minutes']) : $txt['hours']);
         $this->_likes_response = array('result' => false, 'data' => $error);
     }
     return $check;
 }
Beispiel #23
0
function RateLink()
{
    global $db_prefix, $ID_MEMBER, $txt;
    isAllowedTo('rate_links');
    // Guests can't rate links? Cause how can we keep track???
    is_not_guest();
    // Get the link ID
    if (!empty($_REQUEST['id'])) {
        $id = (int) $_REQUEST['id'];
    }
    if (empty($id)) {
        fatal_error($txt['smflinks_nolinkselected']);
    }
    $dbresult = db_query("\n\tSELECT \n\t   ID_LINK  \n\tFROM {$db_prefix}links \n\tWHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__);
    $row = mysql_fetch_assoc($dbresult);
    if (empty($row['ID_LINK'])) {
        fatal_error($txt['smflinks_nolinkselected']);
    }
    // See if the user already rated the link.
    $dbresult = db_query("\n\tSELECT \n\t\tID_LINK, ID_MEMBER \n\tFROM {$db_prefix}links_rating \n\tWHERE ID_MEMBER = {$ID_MEMBER} AND ID_LINK = {$id}", __FILE__, __LINE__);
    if (db_affected_rows() != 0) {
        fatal_error($txt['smflinks_alreadyrated'], false);
    }
    mysql_free_result($dbresult);
    //Get the value of rating
    if (!empty($_REQUEST['value'])) {
        $value = (int) $_REQUEST['value'];
    } else {
        $value = 0;
    }
    //Check value
    if ($value == 0) {
        //Lower Ranking
        //Insert rating
        db_query("INSERT INTO {$db_prefix}links_rating\n\t\t\t\t(ID_LINK, ID_MEMBER,value)\n\t\t\tVALUES ({$id}, {$ID_MEMBER},0)", __FILE__, __LINE__);
        // Update main link rating
        db_query("UPDATE {$db_prefix}links\n\t\t\tSET rating = rating - 1 WHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__);
    } else {
        //Higher Ranking
        //Insert rating
        db_query("INSERT INTO {$db_prefix}links_rating\n\t\t\t\t(ID_LINK, ID_MEMBER,value)\n\t\t\tVALUES ({$id}, {$ID_MEMBER},1)", __FILE__, __LINE__);
        //Update main link rating
        db_query("UPDATE {$db_prefix}links\n\t\t\tSET rating = rating + 1 WHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__);
    }
    redirectexit('action=links');
}
Beispiel #24
0
function UnreadTopics()
{
    global $board, $txt, $scripturl, $sourcedir;
    global $user_info, $context, $settings, $modSettings, $smcFunc, $options;
    // Guests can't have unread things, we don't know anything about them.
    is_not_guest();
    // Prefetching + lots of MySQL work = bad mojo.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Forbidden');
        die;
    }
    $context['showing_all_topics'] = isset($_GET['all']);
    $context['start'] = (int) $_REQUEST['start'];
    $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) && !WIRELESS ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    if ($_REQUEST['action'] == 'unread') {
        $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit'];
    } else {
        $context['page_title'] = $txt['unread_replies'];
    }
    if ($context['showing_all_topics'] && !empty($context['load_average']) && !empty($modSettings['loadavg_allunread']) && $context['load_average'] >= $modSettings['loadavg_allunread']) {
        fatal_lang_error('loadavg_allunread_disabled', false);
    } elseif ($_REQUEST['action'] != 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unreadreplies']) && $context['load_average'] >= $modSettings['loadavg_unreadreplies']) {
        fatal_lang_error('loadavg_unreadreplies_disabled', false);
    } elseif (!$context['showing_all_topics'] && $_REQUEST['action'] == 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unread']) && $context['load_average'] >= $modSettings['loadavg_unread']) {
        fatal_lang_error('loadavg_unread_disabled', false);
    }
    // Parameters for the main query.
    $query_parameters = array();
    // Are we specifying any specific board?
    if (isset($_REQUEST['children']) && (!empty($board) || !empty($_REQUEST['boards']))) {
        $boards = array();
        if (!empty($_REQUEST['boards'])) {
            $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
            foreach ($_REQUEST['boards'] as $b) {
                $boards[] = (int) $b;
            }
        }
        if (!empty($board)) {
            $boards[] = (int) $board;
        }
        // The easiest thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board, b.id_parent
			FROM {db_prefix}boards AS b
			WHERE {query_wanna_see_board}
				AND b.child_level > {int:no_child}
				AND b.id_board NOT IN ({array_int:boards})
			ORDER BY child_level ASC
			', array('no_child' => 0, 'boards' => $boards));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (in_array($row['id_parent'], $boards)) {
                $boards[] = $row['id_board'];
            }
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%d';
    } elseif (!empty($board)) {
        $query_this_board = 'id_board = {int:board}';
        $query_parameters['board'] = $board;
        $context['querystring_board_limits'] = ';board=' . $board . '.%1$d';
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE {query_see_board}
				AND b.id_board IN ({array_int:board_list})', array('board_list' => $_REQUEST['boards']));
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%1$d';
    } elseif (!empty($_REQUEST['c'])) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board';
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE ' . $user_info[$see_board] . '
				AND b.id_cat IN ({array_int:id_cat})', array('id_cat' => $_REQUEST['c']));
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        $context['querystring_board_limits'] = ';c=' . implode(',', $_REQUEST['c']) . ';start=%1$d';
    } else {
        $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board';
        // Don't bother to show deleted posts!
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE ' . $user_info[$see_board] . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
				AND b.id_board != {int:recycle_board}' : ''), array('recycle_board' => (int) $modSettings['recycle_board']));
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        $context['querystring_board_limits'] = ';start=%1$d';
        $context['no_board_limits'] = true;
    }
    $sort_methods = array('subject' => 'ms.subject', 'starter' => 'IFNULL(mems.real_name, ms.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg');
    // The default is the most logical: newest first.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 't.id_last_msg';
        $ascending = isset($_REQUEST['asc']);
        $context['querystring_sort_limits'] = $ascending ? ';asc' : '';
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
        $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc');
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    if (!empty($_REQUEST['c']) && is_array($_REQUEST['c']) && count($_REQUEST['c']) == 1) {
        $request = $smcFunc['db_query']('', '
			SELECT name
			FROM {db_prefix}categories
			WHERE id_cat = {int:id_cat}
			LIMIT 1', array('id_cat' => (int) $_REQUEST['c'][0]));
        list($name) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['linktree'][] = array('url' => $scripturl . '#c' . (int) $_REQUEST['c'][0], 'name' => $name);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $_REQUEST['action'] == 'unread' ? $txt['unread_topics_visit'] : $txt['unread_replies']);
    if ($context['showing_all_topics']) {
        $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $txt['unread_topics_all']);
    } else {
        $txt['unread_topics_visit_none'] = strtr($txt['unread_topics_visit_none'], array('?action=unread;all' => '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits']));
    }
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_recent';
    } else {
        loadTemplate('Recent');
        $context['sub_template'] = $_REQUEST['action'] == 'unread' ? 'unread' : 'replies';
    }
    // Setup the default topic icons... for checking they exist and the like ;)
    $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';
    }
    $is_topics = $_REQUEST['action'] == 'unread';
    // This part is the same for each query.
    $select_clause = '
				ms.subject AS first_subject, ms.poster_time AS first_poster_time, ms.id_topic, t.id_board, b.name AS bname,
				t.num_replies, t.num_views, ms.id_member AS id_first_member, ml.id_member AS id_last_member,
				ml.poster_time AS last_poster_time, IFNULL(mems.real_name, ms.poster_name) AS first_poster_name,
				IFNULL(meml.real_name, ml.poster_name) AS last_poster_name, ml.subject AS last_subject,
				ml.icon AS last_icon, ms.icon AS first_icon, t.id_poll, t.is_sticky, t.locked, ml.modified_time AS last_modified_time,
				IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from, SUBSTRING(ml.body, 1, 385) AS last_body,
				SUBSTRING(ms.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, ms.smileys_enabled AS first_smileys, t.id_first_msg, t.id_last_msg';
    if ($context['showing_all_topics']) {
        if (!empty($board)) {
            $request = $smcFunc['db_query']('', '
				SELECT MIN(id_msg)
				FROM {db_prefix}log_mark_read
				WHERE id_member = {int:current_member}
					AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id']));
            list($earliest_msg) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $request = $smcFunc['db_query']('', '
				SELECT MIN(lmr.id_msg)
				FROM {db_prefix}boards AS b
					LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member})
				WHERE {query_see_board}', array('current_member' => $user_info['id']));
            list($earliest_msg) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        }
        // This is needed in case of topics marked unread.
        if (empty($earliest_msg)) {
            $earliest_msg = 0;
        } else {
            // Using caching, when possible, to ignore the below slow query.
            if (isset($_SESSION['cached_log_time']) && $_SESSION['cached_log_time'][0] + 45 > time()) {
                $earliest_msg2 = $_SESSION['cached_log_time'][1];
            } else {
                // This query is pretty slow, but it's needed to ensure nothing crucial is ignored.
                $request = $smcFunc['db_query']('', '
					SELECT MIN(id_msg)
					FROM {db_prefix}log_topics
					WHERE id_member = {int:current_member}', array('current_member' => $user_info['id']));
                list($earliest_msg2) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // In theory this could be zero, if the first ever post is unread, so fudge it ;)
                if ($earliest_msg2 == 0) {
                    $earliest_msg2 = -1;
                }
                $_SESSION['cached_log_time'] = array(time(), $earliest_msg2);
            }
            $earliest_msg = min($earliest_msg2, $earliest_msg);
        }
    }
    // !!! Add modified_time in for log_time check?
    if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics']) {
        $smcFunc['db_query']('', '
			DROP TABLE IF EXISTS {db_prefix}log_topics_unread', array());
        // Let's copy things out of the log_topics table, to reduce searching.
        $have_temp_table = $smcFunc['db_query']('', '
			CREATE TEMPORARY TABLE {db_prefix}log_topics_unread (
				PRIMARY KEY (id_topic)
			)
			SELECT lt.id_topic, lt.id_msg
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic)
			WHERE lt.id_member = {int:current_member}
				AND t.' . $query_this_board . (empty($earliest_msg) ? '' : '
				AND t.id_last_msg > {int:earliest_msg}') . ($modSettings['postmod_active'] ? '
				AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1, 'db_error_skip' => true))) !== false;
    } else {
        $have_temp_table = false;
    }
    if ($context['showing_all_topics'] && $have_temp_table) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(*), MIN(t.id_last_msg)
			FROM {db_prefix}topics AS t
				LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)
				LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})
			WHERE t.' . $query_this_board . (!empty($earliest_msg) ? '
				AND t.id_last_msg > {int:earliest_msg}' : '') . '
				AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? '
				AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1)));
        list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1);
        if ($num_topics == 0) {
            // Mark the boards as read if there are no unread topics!
            require_once $sourcedir . '/Subs-Boards.php';
            markBoardsRead(empty($boards) ? $board : $boards);
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%1$d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        } else {
            $min_message = (int) $min_message;
        }
        $request = $smcFunc['db_query']('substring', '
			SELECT ' . $select_clause . '
			FROM {db_prefix}messages AS ms
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg)
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				LEFT JOIN {db_prefix}boards AS b ON (b.id_board = ms.id_board)
				LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
				LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)
				LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})
			WHERE b.' . $query_this_board . '
				AND t.id_last_msg >= {int:min_message}
				AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? '
				AND ms.approved = {int:is_approved}' : '') . '
			ORDER BY {raw:sort}
			LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'sort' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'])));
    } elseif ($is_topics) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(*), MIN(t.id_last_msg)
			FROM {db_prefix}topics AS t' . (!empty($have_temp_table) ? '
				LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : '
				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 = t.id_board AND lmr.id_member = {int:current_member})
			WHERE t.' . $query_this_board . ($context['showing_all_topics'] && !empty($earliest_msg) ? '
				AND t.id_last_msg > {int:earliest_msg}' : (!$context['showing_all_topics'] && empty($_SESSION['first_login']) ? '
				AND t.id_last_msg > {int:id_msg_last_visit}' : '')) . '
				AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? '
				AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'id_msg_last_visit' => $_SESSION['id_msg_last_visit'], 'is_approved' => 1)));
        list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1);
        if ($num_topics == 0) {
            // Is this an all topics query?
            if ($context['showing_all_topics']) {
                // Since there are no unread topics, mark the boards as read!
                require_once $sourcedir . '/Subs-Boards.php';
                markBoardsRead(empty($boards) ? $board : $boards);
            }
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        } else {
            $min_message = (int) $min_message;
        }
        $request = $smcFunc['db_query']('substring', '
			SELECT ' . $select_clause . '
			FROM {db_prefix}messages AS ms
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg)
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
				LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' . (!empty($have_temp_table) ? '
				LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : '
				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 = t.id_board AND lmr.id_member = {int:current_member})
			WHERE t.' . $query_this_board . '
				AND t.id_last_msg >= {int:min_message}
				AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < ml.id_msg' . ($modSettings['postmod_active'] ? '
				AND ms.approved = {int:is_approved}' : '') . '
			ORDER BY {raw:order}
			LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'])));
    } else {
        if ($modSettings['totalMessages'] > 100000) {
            $smcFunc['db_query']('', '
				DROP TABLE IF EXISTS {db_prefix}topics_posted_in', array());
            $smcFunc['db_query']('', '
				DROP TABLE IF EXISTS {db_prefix}log_topics_posted_in', array());
            $sortKey_joins = array('ms.subject' => '
					INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)', 'IFNULL(mems.real_name, ms.poster_name)' => '
					INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
					LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)');
            // The main benefit of this temporary table is not that it's faster; it's that it avoids locks later.
            $have_temp_table = $smcFunc['db_query']('', '
				CREATE TEMPORARY TABLE {db_prefix}topics_posted_in (
					id_topic mediumint(8) unsigned NOT NULL default {string:string_zero},
					id_board smallint(5) unsigned NOT NULL default {string:string_zero},
					id_last_msg int(10) unsigned NOT NULL default {string:string_zero},
					id_msg int(10) unsigned NOT NULL default {string:string_zero},
					PRIMARY KEY (id_topic)
				)
				SELECT t.id_topic, t.id_board, t.id_last_msg, IFNULL(lmr.id_msg, 0) AS id_msg' . (!in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? ', ' . $_REQUEST['sort'] . ' AS sort_key' : '') . '
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
					LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})' . (isset($sortKey_joins[$_REQUEST['sort']]) ? $sortKey_joins[$_REQUEST['sort']] : '') . '
				WHERE m.id_member = {int:current_member}' . (!empty($board) ? '
					AND t.id_board = {int:current_board}' : '') . ($modSettings['postmod_active'] ? '
					AND t.approved = {int:is_approved}' : '') . '
				GROUP BY m.id_topic', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'string_zero' => '0', 'db_error_skip' => true)) !== false;
            // If that worked, create a sample of the log_topics table too.
            if ($have_temp_table) {
                $have_temp_table = $smcFunc['db_query']('', '
					CREATE TEMPORARY TABLE {db_prefix}log_topics_posted_in (
						PRIMARY KEY (id_topic)
					)
					SELECT lt.id_topic, lt.id_msg
					FROM {db_prefix}log_topics AS lt
						INNER JOIN {db_prefix}topics_posted_in AS pi ON (pi.id_topic = lt.id_topic)
					WHERE lt.id_member = {int:current_member}', array('current_member' => $user_info['id'], 'db_error_skip' => true)) !== false;
            }
        }
        if (!empty($have_temp_table)) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}topics_posted_in AS pi
					LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = pi.id_topic)
				WHERE pi.' . $query_this_board . '
					AND IFNULL(lt.id_msg, pi.id_msg) < pi.id_last_msg', array_merge($query_parameters, array()));
            list($num_topics) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $request = $smcFunc['db_query']('unread_fetch_topic_count', '
				SELECT COUNT(DISTINCT t.id_topic), MIN(t.id_last_msg)
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic)
					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 = t.id_board AND lmr.id_member = {int:current_member})
				WHERE t.' . $query_this_board . '
					AND m.id_member = {int:current_member}
					AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? '
					AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'is_approved' => 1)));
            list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        }
        // Make sure the starting place makes sense and construct the page index.
        $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true);
        $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page'];
        $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl);
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1);
        if ($num_topics == 0) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        }
        if (!empty($have_temp_table)) {
            $request = $smcFunc['db_query']('', '
				SELECT t.id_topic
				FROM {db_prefix}topics_posted_in AS t
					LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = t.id_topic)
				WHERE t.' . $query_this_board . '
					AND IFNULL(lt.id_msg, t.id_msg) < t.id_last_msg
				ORDER BY {raw:order}
				LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('order' => (in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? $_REQUEST['sort'] : 't.sort_key') . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'])));
        } else {
            $request = $smcFunc['db_query']('unread_replies', '
				SELECT DISTINCT t.id_topic
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic AND m.id_member = {int:current_member})' . (strpos($_REQUEST['sort'], 'ms.') === false ? '' : '
					INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)') . (strpos($_REQUEST['sort'], 'mems.') === false ? '' : '
					LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)') . '
					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 = t.id_board AND lmr.id_member = {int:current_member})
				WHERE t.' . $query_this_board . '
					AND t.id_last_msg >= {int:min_message}
					AND (IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0))) < t.id_last_msg
					AND t.approved = {int:is_approved}
				ORDER BY {raw:order}
				LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => (int) $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'], 'sort' => $_REQUEST['sort'])));
        }
        $topics = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $topics[] = $row['id_topic'];
        }
        $smcFunc['db_free_result']($request);
        // Sanity... where have you gone?
        if (empty($topics)) {
            $context['topics'] = array();
            if ($context['querystring_board_limits'] == ';start=%d') {
                $context['querystring_board_limits'] = '';
            } else {
                $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
            }
            return;
        }
        $request = $smcFunc['db_query']('substring', '
			SELECT ' . $select_clause . '
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS ms ON (ms.id_topic = t.id_topic AND ms.id_msg = t.id_first_msg)
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
				LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
				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 = t.id_board AND lmr.id_member = {int:current_member})
			WHERE t.id_topic IN ({array_int:topic_list})
			ORDER BY ' . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . '
			LIMIT ' . count($topics), array('current_member' => $user_info['id'], 'topic_list' => $topics));
    }
    $context['topics'] = array();
    $topic_ids = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') {
            continue;
        }
        $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.
        $topic_length = $row['num_replies'] + 1;
        $messages_per_page = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        if ($topic_length > $messages_per_page) {
            $tmppages = array();
            $tmpa = 1;
            for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $messages_per_page) {
                $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.' . $tmpb . ';topicseen">' . $tmpa . '</a>';
                $tmpa++;
            }
            // Show links to all the pages?
            if (count($tmppages) <= 5) {
                $pages = '&#171; ' . implode(' ', $tmppages);
            } else {
                $pages = '&#171; ' . $tmppages[0] . ' ' . $tmppages[1] . ' ... ' . $tmppages[count($tmppages) - 2] . ' ' . $tmppages[count($tmppages) - 1];
            }
            if (!empty($modSettings['enableAllMessages']) && $topic_length < $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... you can never be too sure!
        if (empty($modSettings['messageIconChecks_disable'])) {
            // First icon first... as you'd expect.
            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';
            }
            // Last icon... last... duh.
            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';
            }
        }
        // And build the array.
        $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('name' => $row['first_poster_name'], 'id' => $row['id_first_member'], 'href' => $scripturl . '?action=profile;u=' . $row['id_first_member'], 'link' => !empty($row['id_first_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_first_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_poster_name'] . '">' . $row['first_poster_name'] . '</a>' : $row['first_poster_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;topicseen', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;topicseen">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('name' => $row['last_poster_name'], 'id' => $row['id_last_member'], 'href' => $scripturl . '?action=profile;u=' . $row['id_last_member'], 'link' => !empty($row['id_last_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_last_member'] . '">' . $row['last_poster_name'] . '</a>' : $row['last_poster_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'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . ';topicseen#msg' . $row['id_last_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . ';topicseen#msg' . $row['id_last_msg'] . '" rel="nofollow">' . $row['last_subject'] . '</a>'), 'new_from' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . ';topicseen#new', 'href' => $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen' . ($row['num_replies'] == 0 ? '' : 'new'), 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen#msg' . $row['new_from'] . '" rel="nofollow">' . $row['first_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'], 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['bname'] . '</a>'));
        determineTopicClass($context['topics'][$row['id_topic']]);
    }
    $smcFunc['db_free_result']($request);
    if ($is_topics && !empty($modSettings['enableParticipation']) && !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 {int:limit}', array('current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'limit' => count($topic_ids)));
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            if (empty($context['topics'][$row['id_topic']]['is_posted_in'])) {
                $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['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']);
    $context['topics_to_mark'] = implode('-', $topic_ids);
}
Beispiel #25
0
function ModifyKarma()
{
    global $modSettings, $txt, $user_info, $topic, $smcFunc, $context;
    // If the mod is disabled, show an error.
    if (empty($modSettings['karmaMode'])) {
        fatal_lang_error('feature_disabled', true);
    }
    // If you're a guest or can't do this, blow you off...
    is_not_guest();
    isAllowedTo('karma_edit');
    checkSession('get');
    // If you don't have enough posts, tough luck.
    // !!! Should this be dropped in favor of post group permissions?  Should this apply to the member you are smiting/applauding?
    if (!$user_info['is_admin'] && $user_info['posts'] < $modSettings['karmaMinPosts']) {
        fatal_lang_error('not_enough_posts_karma', true, array($modSettings['karmaMinPosts']));
    }
    // And you can't modify your own, punk! (use the profile if you need to.)
    if (empty($_REQUEST['uid']) || (int) $_REQUEST['uid'] == $user_info['id']) {
        fatal_lang_error('cant_change_own_karma', false);
    }
    // The user ID _must_ be a number, no matter what.
    $_REQUEST['uid'] = (int) $_REQUEST['uid'];
    // Applauding or smiting?
    $dir = $_REQUEST['sa'] != 'applaud' ? -1 : 1;
    // Delete any older items from the log. (karmaWaitTime is by hour.)
    smf_db_query('
		DELETE FROM {db_prefix}log_karma
		WHERE {int:current_time} - log_time > {int:wait_time}', array('wait_time' => (int) ($modSettings['karmaWaitTime'] * 3600), 'current_time' => time()));
    // Start off with no change in karma.
    $action = 0;
    // Not an administrator... or one who is restricted as well.
    if (!empty($modSettings['karmaTimeRestrictAdmins']) || !allowedTo('moderate_forum')) {
        // Find out if this user has done this recently...
        $request = smf_db_query('
			SELECT action
			FROM {db_prefix}log_karma
			WHERE id_target = {int:id_target}
				AND id_executor = {int:current_member}
			LIMIT 1', array('current_member' => $user_info['id'], 'id_target' => $_REQUEST['uid']));
        if (mysql_num_rows($request) > 0) {
            list($action) = mysql_fetch_row($request);
        }
        mysql_free_result($request);
    }
    // They haven't, not before now, anyhow.
    if (empty($action) || empty($modSettings['karmaWaitTime'])) {
        // Put it in the log.
        smf_db_insert('replace', '{db_prefix}log_karma', array('action' => 'int', 'id_target' => 'int', 'id_executor' => 'int', 'log_time' => 'int'), array($dir, $_REQUEST['uid'], $user_info['id'], time()), array('id_target', 'id_executor'));
        // Change by one.
        updateMemberData($_REQUEST['uid'], array($dir == 1 ? 'karma_good' : 'karma_bad' => '+'));
    } else {
        // If you are gonna try to repeat.... don't allow it.
        if ($action == $dir) {
            fatal_lang_error('karma_wait_time', false, array($modSettings['karmaWaitTime'], $txt['hours']));
        }
        // You decided to go back on your previous choice?
        smf_db_query('
			UPDATE {db_prefix}log_karma
			SET action = {int:action}, log_time = {int:current_time}
			WHERE id_target = {int:id_target}
				AND id_executor = {int:current_member}', array('current_member' => $user_info['id'], 'action' => $dir, 'current_time' => time(), 'id_target' => $_REQUEST['uid']));
        // It was recently changed the OTHER way... so... reverse it!
        if ($dir == 1) {
            updateMemberData($_REQUEST['uid'], array('karma_good' => '+', 'karma_bad' => '-'));
        } else {
            updateMemberData($_REQUEST['uid'], array('karma_bad' => '+', 'karma_good' => '-'));
        }
    }
    // Figure out where to go back to.... the topic?
    if (!empty($topic)) {
        redirectexit('topic=' . $topic . '.' . $_REQUEST['start'] . '#msg' . (int) $_REQUEST['m']);
    } elseif (isset($_REQUEST['f'])) {
        redirectexit('action=pm;f=' . $_REQUEST['f'] . ';start=' . $_REQUEST['start'] . (isset($_REQUEST['l']) ? ';l=' . (int) $_REQUEST['l'] : '') . (isset($_REQUEST['pm']) ? '#' . (int) $_REQUEST['pm'] : ''));
    } else {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"', $context['right_to_left'] ? ' dir="rtl"' : '', '>
	<head>
		<title>...</title>
		<script type="text/javascript"><!-- // --><![CDATA[
			history.go(-1);
		// ]]></script>
	</head>
	<body>&laquo;</body>
</html>';
        obExit(false);
    }
}
Beispiel #26
0
function Post()
{
    global $txt, $scripturl, $topic, $db_prefix, $modSettings, $board, $ID_MEMBER;
    global $user_info, $sc, $board_info, $context, $settings, $sourcedir;
    global $options, $func, $language;
    loadLanguage('Post');
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // 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']);
    // You must be posting to *some* board.
    if (empty($board) && !$context['make_event']) {
        fatal_lang_error('smf232', 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'] = '';
    }
    // Check if it's locked.  It isn't locked if no topic is specified.
    if (!empty($topic)) {
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tt.locked, IFNULL(ln.ID_TOPIC, 0) AS notify, t.isSticky, t.ID_POLL, t.numReplies, mf.ID_MEMBER,\n\t\t\t\tt.ID_FIRST_MSG, mf.subject, GREATEST(ml.posterTime, ml.modifiedTime) AS lastPostTime\n\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\tLEFT JOIN {$db_prefix}log_notify AS ln ON (ln.ID_TOPIC = t.ID_TOPIC AND ln.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tLEFT JOIN {$db_prefix}messages AS mf ON (mf.ID_MSG = t.ID_FIRST_MSG)\n\t\t\t\tLEFT JOIN {$db_prefix}messages AS ml ON (ml.ID_MSG = t.ID_LAST_MSG)\n\t\t\tWHERE t.ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($locked, $context['notify'], $sticky, $pollID, $context['num_replies'], $ID_MEMBER_POSTER, $ID_FIRST_MSG, $first_subject, $lastPostTime) = mysql_fetch_row($request);
        mysql_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')) {
                is_not_guest();
            }
            if ($ID_MEMBER_POSTER != $ID_MEMBER) {
                isAllowedTo('post_reply_any');
            } elseif (!allowedTo('post_reply_any')) {
                isAllowedTo('post_reply_own');
            }
        }
        $context['can_lock'] = allowedTo('lock_any') || $ID_MEMBER == $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 {
        if ((!$context['make_event'] || !empty($board)) && (!isset($_REQUEST['poll']) || $modSettings['pollMode'] != '1')) {
            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['can_announce'] = allowedTo('announce_topic');
    $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']);
    // 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(90, 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 ($ID_MEMBER == $ID_MEMBER_POSTER && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        // 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']));
        // 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 ($ID_MEMBER_POSTER != $ID_MEMBER || !allowedTo('modify_own') && !allowedTo('modify_any')) {
                require_once $sourcedir . '/Calendar.php';
                return CalendarPost();
            }
            // Get the current event information.
            $request = db_query("\n\t\t\t\tSELECT\n\t\t\t\t\tID_MEMBER, title, MONTH(startDate) AS month, DAYOFMONTH(startDate) AS day,\n\t\t\t\t\tYEAR(startDate) AS year, (TO_DAYS(endDate) - TO_DAYS(startDate)) AS span\n\t\t\t\tFROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = " . $context['event']['id'] . "\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            $row = mysql_fetch_assoc($request);
            mysql_free_result($request);
            // Make sure the user is allowed to edit this event.
            if ($row['ID_MEMBER'] != $ID_MEMBER) {
                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('calendar1', false);
            }
            if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) {
                fatal_lang_error('calendar2', false);
            }
            // Get a list of boards they can post in.
            $boards = boardsAllowedTo('post_new');
            if (empty($boards)) {
                fatal_lang_error('cannot_post_new');
            }
            $request = db_query("\n\t\t\t\tSELECT c.name AS catName, c.ID_CAT, b.ID_BOARD, b.name AS boardName, b.childLevel\n\t\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\t\tWHERE {$user_info['query_see_board']}" . (in_array(0, $boards) ? '' : "\n\t\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $boards) . ")"), __FILE__, __LINE__);
            $context['event']['boards'] = array();
            while ($row = mysql_fetch_assoc($request)) {
                $context['event']['boards'][] = array('id' => $row['ID_BOARD'], 'name' => $row['boardName'], 'childLevel' => $row['childLevel'], 'prefix' => str_repeat('&nbsp;', $row['childLevel'] * 3), 'cat' => array('id' => $row['ID_CAT'], 'name' => $row['catName']));
            }
            mysql_free_result($request);
        }
        // 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['num_replies'])) {
            $newReplies = $context['num_replies'] > $_REQUEST['num_replies'] ? $context['num_replies'] - $_REQUEST['num_replies'] : 0;
            if (!empty($newReplies)) {
                if ($newReplies == 1) {
                    $txt['error_new_reply'] = isset($_GET['num_replies']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply'];
                } else {
                    $txt['error_new_replies'] = sprintf(isset($_GET['num_replies']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $newReplies);
                }
                // If they've come from the display page then we treat the error differently....
                if (isset($_GET['num_replies'])) {
                    $newRepliesError = $newReplies;
                } else {
                    $context['post_error'][$newReplies == 1 ? 'new_reply' : 'new_replies'] = true;
                }
                $modSettings['topicSummaryPosts'] = $newReplies > $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 ($func['htmltrim']($_REQUEST['subject']) == '') {
                $context['post_error']['no_subject'] = true;
            }
            if ($func['htmltrim']($_REQUEST['message']) == '') {
                $context['post_error']['no_message'] = true;
            }
            if (!empty($modSettings['max_messageLength']) && $func['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 ($func['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})$~', stripslashes($_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';
            }
            $really_previewing = false;
        }
        // Set up the inputs for the form.
        $form_subject = strtr($func['htmlspecialchars'](stripslashes($_REQUEST['subject'])), array("\r" => '', "\n" => '', "\t" => ''));
        $form_message = $func['htmlspecialchars'](stripslashes($_REQUEST['message']), ENT_QUOTES);
        // Make sure the subject isn't too long - taking into account special characters.
        if ($func['strlen']($form_subject) > 100) {
            $form_subject = $func['substr']($form_subject, 0, 100);
        }
        // Have we inadvertently trimmed off the subject of useful information?
        if ($func['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;
                }
                $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', 'new_replies', 'old_topic'))) {
                    $context['error_type'] = 'serious';
                }
            }
        }
        if (isset($_REQUEST['poll'])) {
            $context['question'] = isset($_REQUEST['question']) ? $func['htmlspecialchars'](stripslashes(trim($_REQUEST['question']))) : '';
            $context['choices'] = array();
            $choice_id = 0;
            $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive(stripslashes__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'] = '<i>' . $txt[24] . '</i>';
            }
            // 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'] . ';sesc=' . $sc : '') . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = isset($_REQUEST['msg']) ? $txt[10] : $txt[105];
        // Previewing an edit?
        if (isset($_REQUEST['msg'])) {
            if (!empty($modSettings['attachmentEnable'])) {
                $request = db_query("\n\t\t\t\t\tSELECT IFNULL(size, -1) AS filesize, filename, ID_ATTACH\n\t\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\t\t AND attachmentType = 0", __FILE__, __LINE__);
                while ($row = mysql_fetch_assoc($request)) {
                    if ($row['filesize'] <= 0) {
                        continue;
                    }
                    $context['current_attachments'][] = array('name' => $row['filename'], 'id' => $row['ID_ATTACH']);
                }
                mysql_free_result($request);
            }
            // Allow moderators to change names....
            if (allowedTo('moderate_forum') && !empty($topic)) {
                $request = db_query("\n\t\t\t\t\tSELECT ID_MEMBER, posterName, posterEmail\n\t\t\t\t\tFROM {$db_prefix}messages\n\t\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\t\tAND ID_TOPIC = {$topic}\n\t\t\t\t\tLIMIT 1", __FILE__, __LINE__);
                $row = mysql_fetch_assoc($request);
                mysql_free_result($request);
                if (empty($row['ID_MEMBER'])) {
                    $context['name'] = htmlspecialchars($row['posterName']);
                    $context['email'] = htmlspecialchars($row['posterEmail']);
                }
            }
        }
        // No check is needed, since nothing is really posted.
        checkSubmitOnce('free');
    } elseif (isset($_REQUEST['msg'])) {
        checkSession('get');
        // Get the existing message.
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tm.ID_MEMBER, m.modifiedTime, m.smileysEnabled, m.body,\n\t\t\t\tm.posterName, m.posterEmail, m.subject, m.icon,\n\t\t\t\tIFNULL(a.size, -1) AS filesize, a.filename, a.ID_ATTACH,\n\t\t\t\tt.ID_MEMBER_STARTED AS ID_MEMBER_POSTER, m.posterTime\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\t\tLEFT JOIN {$db_prefix}attachments AS a ON (a.ID_MSG = m.ID_MSG AND a.attachmentType = 0)\n\t\t\tWHERE m.ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\tAND m.ID_TOPIC = {$topic}\n\t\t\t\tAND t.ID_TOPIC = {$topic}", __FILE__, __LINE__);
        // The message they were trying to edit was most likely deleted.
        // !!! Change this error message?
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('smf232', false);
        }
        $row = mysql_fetch_assoc($request);
        $attachment_stuff = array($row);
        while ($row2 = mysql_fetch_assoc($request)) {
            $attachment_stuff[] = $row2;
        }
        mysql_free_result($request);
        if ($row['ID_MEMBER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            // Give an extra five minutes over the disable time threshold, so they can type.
            if (!empty($modSettings['edit_disable_time']) && $row['posterTime'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
        } else {
            isAllowedTo('modify_any');
        }
        // When was it last modified?
        if (!empty($row['modifiedTime'])) {
            $context['last_modified'] = timeformat($row['modifiedTime']);
        }
        // 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['smileysEnabled']);
        $context['icon'] = $row['icon'];
        // Load up 'em attachments!
        foreach ($attachment_stuff as $attachment) {
            if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) {
                $context['current_attachments'][] = array('name' => $attachment['filename'], 'id' => $attachment['ID_ATTACH']);
            }
        }
        // Allow moderators to change names....
        if (allowedTo('moderate_forum') && empty($row['ID_MEMBER'])) {
            $context['name'] = htmlspecialchars($row['posterName']);
            $context['email'] = htmlspecialchars($row['posterEmail']);
        }
        // Set the destinaton.
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';sesc=' . $sc . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt[10];
    } else {
        // By default....
        $context['use_smileys'] = true;
        $context['icon'] = 'xx';
        if ($user_info['is_guest']) {
            $context['name'] = '';
            $context['email'] = '';
        }
        $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : '');
        $context['submit_label'] = $txt[105];
        // Posting a quoted reply?
        if (!empty($topic) && !empty($_REQUEST['quote'])) {
            checkSession('get');
            // Make sure they _can_ quote this post, and if so get it.
            $request = db_query("\n\t\t\t\tSELECT m.subject, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime, m.body\n\t\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b)\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)\n\t\t\t\tWHERE m.ID_MSG = " . (int) $_REQUEST['quote'] . "\n\t\t\t\t\tAND b.ID_BOARD = m.ID_BOARD\n\t\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            if (mysql_num_rows($request) == 0) {
                fatal_lang_error('quoted_post_deleted', false);
            }
            list($form_subject, $mname, $mdate, $form_message) = mysql_fetch_row($request);
            mysql_free_result($request);
            // Add 'Re: ' to the front of the quoted subject.
            if (trim($context['response_prefix']) != '' && $func['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);
            $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" . $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 != '' && $func['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')) {
        if (empty($_SESSION['temp_attachments'])) {
            $_SESSION['temp_attachments'] = array();
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = db_query("\n\t\t\t\tSELECT COUNT(*), SUM(size)\n\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\tAND attachmentType = 0", __FILE__, __LINE__);
            list($quantity, $total_size) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        $temp_start = 0;
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                $temp_start++;
                if (preg_match('~^post_tmp_' . $ID_MEMBER . '_\\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($modSettings['attachmentUploadDir'] . '/' . $attachID);
                    continue;
                }
                $quantity++;
                $total_size += filesize($modSettings['attachmentUploadDir'] . '/' . $attachID);
                $context['current_attachments'][] = array('name' => getAttachmentFilename($name, false, true), 'id' => $attachID);
            }
        }
        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('smf124');
                }
                if (!empty($modSettings['attachmentSizeLimit']) && $_FILES['attachment']['size'][$n] > $modSettings['attachmentSizeLimit'] * 1024) {
                    fatal_lang_error('smf122', 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('smf122', 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['smf123'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                    }
                }
                if (!empty($modSettings['attachmentDirSizeLimit'])) {
                    // Make sure the directory isn't full.
                    $dirSize = 0;
                    $dir = @opendir($modSettings['attachmentUploadDir']) or fatal_lang_error('smf115b');
                    while ($file = readdir($dir)) {
                        if (substr($file, 0, -1) == '.') {
                            continue;
                        }
                        if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) {
                            // Temp file is more than 5 hours old!
                            if (filemtime($modSettings['attachmentUploadDir'] . '/' . $file) < time() - 18000) {
                                @unlink($modSettings['attachmentUploadDir'] . '/' . $file);
                            }
                            continue;
                        }
                        $dirSize += filesize($modSettings['attachmentUploadDir'] . '/' . $file);
                    }
                    closedir($dir);
                    // Too big!  Maybe you could zip it or something...
                    if ($_FILES['attachment']['size'][$n] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) {
                        fatal_lang_error('smf126');
                    }
                }
                if (!is_writable($modSettings['attachmentUploadDir'])) {
                    fatal_lang_error('attachments_no_write');
                }
                $attachID = 'post_tmp_' . $ID_MEMBER . '_' . $temp_start++;
                $_SESSION['temp_attachments'][$attachID] = stripslashes(basename($_FILES['attachment']['name'][$n]));
                $context['current_attachments'][] = array('name' => basename(stripslashes($_FILES['attachment']['name'][$n])), 'id' => $attachID);
                $destName = $modSettings['attachmentUploadDir'] . '/' . $attachID;
                if (!move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) {
                    fatal_lang_error('smf124');
                }
                @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'][] = $txt['error_old_topic'];
        $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['smf20'];
    } elseif ($context['make_event']) {
        $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar23'] : $txt['calendar20'];
    } elseif (isset($_REQUEST['msg'])) {
        $context['page_title'] = $txt[66];
    } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) {
        $context['page_title'] = $txt[507] . ' - ' . strip_tags($context['preview_subject']);
    } elseif (empty($topic)) {
        $context['page_title'] = $txt[33];
    } else {
        $context['page_title'] = $txt[25];
    }
    // Build the link tree.
    if (empty($topic)) {
        $context['linktree'][] = array('name' => '<i>' . $txt[33] . '</i>');
    } else {
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><b class="nav">' . $context['page_title'] . ' ( </b></span>', 'extra_after' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><b class="nav"> )</b></span>');
    }
    // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments.
    // !!! This won't work if you're posting an event.
    $context['num_allowed_attachments'] = 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') && $context['num_allowed_attachments'] > 0;
    $context['subject'] = addcslashes($form_subject, '"');
    $context['message'] = str_replace(array('"', '<', '>', '  '), array('&quot;', '&lt;', '&gt;', ' &nbsp;'), $form_message);
    $context['attached'] = '';
    $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', '));
    $context['make_poll'] = isset($_REQUEST['poll']);
    // Message icons - customized icons are off?
    if (empty($modSettings['messageIcons_enable'])) {
        $context['icons'] = array(array('value' => 'xx', 'name' => $txt[281]), array('value' => 'thumbup', 'name' => $txt[282]), array('value' => 'thumbdown', 'name' => $txt[283]), array('value' => 'exclamation', 'name' => $txt[284]), array('value' => 'question', 'name' => $txt[285]), array('value' => 'lamp', 'name' => $txt[286]), array('value' => 'smiley', 'name' => $txt[287]), array('value' => 'angry', 'name' => $txt[288]), array('value' => 'cheesy', 'name' => $txt[289]), array('value' => 'grin', 'name' => $txt[293]), array('value' => 'sad', 'name' => $txt[291]), array('value' => 'wink', 'name' => $txt[292]));
        foreach ($context['icons'] as $k => $dummy) {
            $context['icons'][$k]['url'] = $settings['images_url'] . '/post/' . $dummy['value'] . '.gif';
            $context['icons'][$k]['is_last'] = false;
        }
        $context['icon_url'] = $settings['images_url'] . '/post/' . $context['icon'] . '.gif';
    } else {
        // Regardless of what *should* exist, let's do this properly.
        $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
        $context['icon_sources'] = array();
        foreach ($stable_icons as $icon) {
            $context['icon_sources'][$icon] = 'images_url';
        }
        // Array for all icons that need to revert to the default theme!
        $context['javascript_icons'] = array();
        if (($temp = cache_get_data('posting_icons-' . $board, 480)) == null) {
            $request = db_query("\n\t\t\t\tSELECT title, filename\n\t\t\t\tFROM {$db_prefix}message_icons\n\t\t\t\tWHERE ID_BOARD IN (0, {$board})", __FILE__, __LINE__);
            $icon_data = array();
            while ($row = mysql_fetch_assoc($request)) {
                $icon_data[] = $row;
            }
            mysql_free_result($request);
            cache_put_data('posting_icons-' . $board, $icon_data, 480);
        } else {
            $icon_data = $temp;
        }
        $context['icons'] = array();
        foreach ($icon_data as $icon) {
            if (!isset($context['icon_sources'][$icon['filename']])) {
                $context['icon_sources'][$icon['filename']] = file_exists($settings['theme_dir'] . '/images/post/' . $icon['filename'] . '.gif') ? 'images_url' : 'default_images_url';
            }
            // If the icon exists only in the default theme, ensure the javascript popup respects this.
            if ($context['icon_sources'][$icon['filename']] == 'default_images_url') {
                $context['javascript_icons'][] = $icon['filename'];
            }
            $context['icons'][] = array('value' => $icon['filename'], 'name' => $icon['title'], 'url' => $settings[$context['icon_sources'][$icon['filename']]] . '/post/' . $icon['filename'] . '.gif', 'is_last' => false);
        }
        $context['icon_url'] = $settings[isset($context['icon_sources'][$context['icon']]) ? $context['icon_sources'][$context['icon']] : 'images_url'] . '/post/' . $context['icon'] . '.gif';
    }
    if (!empty($context['icons'])) {
        $context['icons'][count($context['icons']) - 1]['is_last'] = true;
    }
    $found = false;
    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']) {
            $found = true;
        }
    }
    if (!$found) {
        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)) {
        getTopic();
    }
    $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;
    // Register this form in the session variables.
    checkSubmitOnce('register');
    // Finally, load the template.
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_post';
    } elseif (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
}
Beispiel #27
0
/**
 * This helps organize things...
 * @todo this should be a simple dispatcher....
 */
function MessageMain()
{
    global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $smcFunc, $modSettings;
    // No guests!
    is_not_guest();
    // You're not supposed to be here at all, if you can't even read PMs.
    isAllowedTo('pm_read');
    // This file contains the basic functions for sending a PM.
    require_once $sourcedir . '/Subs-Post.php';
    loadLanguage('PersonalMessage+Drafts');
    if (WIRELESS && WIRELESS_PROTOCOL == 'wap') {
        fatal_lang_error('wireless_error_notyet', false);
    } elseif (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_pm';
    } elseif (!isset($_REQUEST['xml'])) {
        loadTemplate('PersonalMessage');
    }
    // Load up the members maximum message capacity.
    if ($user_info['is_admin']) {
        $context['message_limit'] = 0;
    } elseif (($context['message_limit'] = cache_get_data('msgLimit:' . $user_info['id'], 360)) === null) {
        // @todo Why do we do this?  It seems like if they have any limit we should use it.
        $request = $smcFunc['db_query']('', '
			SELECT MAX(max_messages) AS top_limit, MIN(max_messages) AS bottom_limit
			FROM {db_prefix}membergroups
			WHERE id_group IN ({array_int:users_groups})', array('users_groups' => $user_info['groups']));
        list($maxMessage, $minMessage) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage;
        // Save us doing it again!
        cache_put_data('msgLimit:' . $user_info['id'], $context['message_limit'], 360);
    }
    // Prepare the context for the capacity bar.
    if (!empty($context['message_limit'])) {
        $bar = $user_info['messages'] * 100 / $context['message_limit'];
        $context['limit_bar'] = array('messages' => $user_info['messages'], 'allowed' => $context['message_limit'], 'percent' => $bar, 'bar' => min(100, (int) $bar), 'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1)));
    }
    // a previous message was sent successfully? show a small indication.
    if (isset($_GET['done']) && $_GET['done'] == 'sent') {
        $context['pm_sent'] = true;
    }
    // Now we have the labels, and assuming we have unsorted mail, apply our rules!
    if ($user_settings['new_pm']) {
        $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']);
        foreach ($context['labels'] as $id_label => $label_name) {
            $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0);
        }
        $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0);
        ApplyRules();
        updateMemberData($user_info['id'], array('new_pm' => 0));
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}pm_recipients
			SET is_new = {int:not_new}
			WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'], 'not_new' => 0));
    }
    // Load the label data.
    if ($user_settings['new_pm'] || ($context['labels'] = cache_get_data('labelCounts:' . $user_info['id'], 720)) === null) {
        $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']);
        foreach ($context['labels'] as $id_label => $label_name) {
            $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0);
        }
        $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0);
        // Looks like we need to reseek!
        $result = $smcFunc['db_query']('', '
			SELECT labels, is_read, COUNT(*) AS num
			FROM {db_prefix}pm_recipients
			WHERE id_member = {int:current_member}
				AND deleted = {int:not_deleted}
			GROUP BY labels, is_read', array('current_member' => $user_info['id'], 'not_deleted' => 0));
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            $this_labels = explode(',', $row['labels']);
            foreach ($this_labels as $this_label) {
                $context['labels'][(int) $this_label]['messages'] += $row['num'];
                if (!($row['is_read'] & 1)) {
                    $context['labels'][(int) $this_label]['unread_messages'] += $row['num'];
                }
            }
        }
        $smcFunc['db_free_result']($result);
        // Store it please!
        cache_put_data('labelCounts:' . $user_info['id'], $context['labels'], 720);
    }
    // This determines if we have more labels than just the standard inbox.
    $context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0;
    // Some stuff for the labels...
    $context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][(int) $_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1;
    $context['current_label'] =& $context['labels'][(int) $context['current_label_id']]['name'];
    $context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'sent' ? 'inbox' : 'sent';
    // This is convenient.  Do you know how annoying it is to do this every time?!
    $context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : '');
    $context['can_issue_warning'] = in_array('w', $context['admin_features']) && allowedTo('issue_warning') && $modSettings['warning_settings'][0] == 1;
    // Build the linktree for all the actions...
    $context['linktree'][] = array('url' => $scripturl . '?action=pm', 'name' => $txt['personal_messages']);
    // Preferences...
    $context['display_mode'] = WIRELESS ? 0 : $user_settings['pm_prefs'] & 3;
    $subActions = array('addbuddy' => 'WirelessAddBuddy', 'manlabels' => 'ManageLabels', 'manrules' => 'ManageRules', 'pmactions' => 'MessageActionsApply', 'prune' => 'MessagePrune', 'removeall' => 'MessageKillAllQuery', 'removeall2' => 'MessageKillAll', 'report' => 'ReportMessage', 'search' => 'MessageSearch', 'search2' => 'MessageSearch2', 'send' => 'MessagePost', 'send2' => 'MessagePost2', 'settings' => 'MessageSettings', 'showpmdrafts' => 'MessageDrafts');
    if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) {
        MessageFolder();
    } else {
        if (!isset($_REQUEST['xml'])) {
            messageIndexBar($_REQUEST['sa']);
        }
        $subActions[$_REQUEST['sa']]();
    }
}
function AddPictureComment()
{
    global $txt, $context, $smcFunc, $sourcedir, $scripturl, $modSettings, $language;
    $memID = $context['member']['id'];
    // Guests are not allowed to comment.
    is_not_guest();
    if (empty($_POST['comment'])) {
        fatal_error($txt['Maximum_comment_field'], false);
    }
    // Integration with AEVA mod (Thanks Nao 尚 ;))
    if (isset($modSettings['aeva_enable']) && file_exists($sourcedir . '/Subs-Aeva.php')) {
        @(include_once $sourcedir . '/Subs-Aeva.php');
        if (function_exists('aeva_onposting')) {
            $_POST['comment'] = aeva_onposting($_POST['comment']);
        }
    }
    checkSession('post');
    // Only buddies can post comments?
    if (isset($context['member']['options']['comments_budd_only']) && $context['member']['options']['comments_budd_only'] == 1) {
        if (!is_buddy($memID, $context['user']['id']) && !allowedTo('edit_Maximum_Maximum_any')) {
            fatal_error($txt['Maximum_comments_buddies_only'], false);
        }
    }
    $request = $smcFunc['db_insert']('normal', '{db_prefix}picture_comments', array('id_member' => 'int', 'comment' => 'text', 'time' => 'int', 'comment_picture_id' => 'int'), array('id_member' => $context['user']['id'], 'title' => htmlspecialchars($_POST['comment']), 'time' => time(), 'comment_picture_id' => (int) $_GET['comment']), array('id_comment'));
    // Should we notify the user?
    if (@$context['member']['options']['comments_notif_disable'] != 1 && $context['user']['id'] != $memID) {
        $request = $smcFunc['db_query']('', '
			SELECT lngfile 
			FROM {db_prefix}members 
			WHERE id_member = {int:id_member}', array('id_member' => $memID));
        list($user_language) = $smcFunc['db_fetch_row']($request);
        loadLanguage('Maximumprofile', empty($user_language) || empty($modSettings['userLanguage']) ? $language : $user_language, false);
        require_once $sourcedir . '/Subs-Post.php';
        sendpm(array('to' => array($memID), 'bcc' => array()), sprintf($txt['Maximum_notif_piccom_subject'], $context['user']['name']), sprintf($txt['Maximum_notif_piccom_body'], $context['user']['name'], $scripturl . '?action=profile;area=pictures;view=' . (int) $_GET['comment']), false, array('id' => 0, 'name' => $txt['Maximum_notif_com_user'], 'username' => $txt['Maximum_notif_com_user']));
    }
    redirectexit('action=profile;area=pictures;u=' . $memID . ';view=' . (int) $_GET['comment']);
}
Beispiel #29
0
function loadBoard()
{
    global $txt, $db_prefix, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $ID_MEMBER, $user_info;
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Load this board only if the it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] == 3)) {
        // !!! SLOW?
        if (!empty($topic)) {
            $temp = cache_get_data('topic_board-' . $topic, 120);
        } else {
            $temp = cache_get_data('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tc.ID_CAT, b.name AS bname, b.description, b.numTopics, b.memberGroups,\n\t\t\t\tb.ID_PARENT, c.name AS cname, IFNULL(mem.ID_MEMBER, 0) AS ID_MODERATOR,\n\t\t\t\tmem.realName" . (!empty($topic) ? ", b.ID_BOARD" : '') . ", b.childLevel,\n\t\t\t\tb.ID_THEME, b.override_theme, b.permission_mode, b.countPosts\n\t\t\tFROM ({$db_prefix}boards AS b" . (!empty($topic) ? ", {$db_prefix}topics AS t" : '') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\t\tLEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = " . (empty($topic) ? $board : 't.ID_BOARD') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = mods.ID_MEMBER)\n\t\t\tWHERE b.ID_BOARD = " . (empty($topic) ? $board : "t.ID_BOARD\n\t\t\t\tAND t.ID_TOPIC = {$topic}"), __FILE__, __LINE__);
        // If there aren't any, skip.
        if (mysql_num_rows($request) > 0) {
            $row = mysql_fetch_assoc($request);
            // Set the current board.
            if (!empty($row['ID_BOARD'])) {
                $board = $row['ID_BOARD'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['ID_CAT'], 'name' => $row['cname']), 'name' => $row['bname'], 'description' => $row['description'], 'num_topics' => $row['numTopics'], 'parent_boards' => getBoardParents($row['ID_PARENT']), 'parent' => $row['ID_PARENT'], 'child_level' => $row['childLevel'], 'theme' => $row['ID_THEME'], 'override_theme' => !empty($row['override_theme']), 'use_local_permissions' => !empty($modSettings['permission_enable_by_board']) && $row['permission_mode'] == 1, 'permission_mode' => empty($modSettings['permission_enable_by_board']) ? empty($row['permission_mode']) ? 'normal' : ($row['permission_mode'] == 2 ? 'no_polls' : ($row['permission_mode'] == 3 ? 'reply_only' : 'read_only')) : 'normal', 'posts_count' => empty($row['countPosts']));
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['memberGroups'] == '' ? array() : explode(',', $row['memberGroups']);
            do {
                if (!empty($row['ID_MODERATOR'])) {
                    $board_info['moderators'][$row['ID_MODERATOR']] = array('id' => $row['ID_MODERATOR'], 'name' => $row['realName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row['realName'] . '</a>');
                }
            } while ($row = mysql_fetch_assoc($request));
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] == 3)) {
                // !!! SLOW?
                if (!empty($topic)) {
                    cache_put_data('topic_board-' . $topic, $board_info, 120);
                }
                cache_put_data('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        mysql_free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$ID_MEMBER]);
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], array(array('url' => $scripturl . '#' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name'])));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // If it's a prefetching agent, just make clear they're not allowed.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}
    /**
     * Creates a list of mentions for the user
     * Allows them to mark them read or unread
     * Can sort the various forms of mentions, likes or @mentions
     */
    public function action_list()
    {
        global $context, $txt, $scripturl;
        // Only registered members can be mentioned
        is_not_guest();
        require_once SUBSDIR . '/Mentions.subs.php';
        require_once SUBSDIR . '/GenericList.class.php';
        loadLanguage('Mentions');
        $this->_buildUrl();
        $list_options = array('id' => 'list_mentions', 'title' => empty($this->_all) ? $txt['my_unread_mentions'] : $txt['my_mentions'], 'items_per_page' => $this->_items_per_page, 'base_href' => $scripturl . '?action=mentions;sa=list' . $this->_url_param, 'default_sort_col' => $this->_default_sort, 'default_sort_dir' => 'default', 'no_items_label' => $this->_all ? $txt['no_mentions_yet'] : $txt['no_new_mentions'], 'get_items' => array('function' => array($this, 'list_loadMentions'), 'params' => array($this->_all, $this->_type)), 'get_count' => array('function' => array($this, 'list_getMentionCount'), 'params' => array($this->_all, $this->_type)), 'columns' => array('id_member_from' => array('header' => array('value' => $txt['mentions_from']), 'data' => array('function' => create_function('$row', '
							global $settings, $scripturl;

							if (isset($settings[\'mentions\'][\'mentioner_template\']))
								return str_replace(
									array(
										\'{avatar_img}\',
										\'{mem_url}\',
										\'{mem_name}\',
									),
									array(
										$row[\'avatar\'][\'image\'],
										!empty($row[\'id_member_from\']) ? $scripturl . \'?action=profile;u=\' . $row[\'id_member_from\'] : \'\',
										$row[\'mentioner\'],
									),
									$settings[\'mentions\'][\'mentioner_template\']);
						')), 'sort' => array('default' => 'mtn.id_member_from', 'reverse' => 'mtn.id_member_from DESC')), 'type' => array('header' => array('value' => $txt['mentions_what']), 'data' => array('db' => 'message'), 'sort' => array('default' => 'mtn.mention_type', 'reverse' => 'mtn.mention_type DESC')), 'log_time' => array('header' => array('value' => $txt['mentions_when'], 'class' => 'mention_log_time'), 'data' => array('db' => 'log_time', 'timeformat' => 'html_time', 'class' => 'mention_log_time'), 'sort' => array('default' => 'mtn.log_time DESC', 'reverse' => 'mtn.log_time')), 'action' => array('header' => array('value' => $txt['mentions_action'], 'class' => 'listaction'), 'data' => array('function' => create_function('$row', '
							global $txt, $settings, $context;

							$opts = \'\';

							if (empty($row[\'status\']))
								$opts = \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=read;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'mentions_markread\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/mark_read.png" alt="*" /></a>&nbsp;\';
							else
								$opts = \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=unread;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'mentions_markunread\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/mark_unread.png" alt="*" /></a>&nbsp;\';

							return $opts . \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=delete;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'delete\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/delete.png" alt="*" /></a>\';
						'), 'class' => 'listaction'))), 'list_menu' => array('show_on' => 'top', 'links' => array(array('href' => $scripturl . '?action=mentions' . (!empty($this->_all) ? ';all' : ''), 'is_selected' => empty($this->_type), 'label' => $txt['mentions_type_all']))), 'additional_rows' => array(array('position' => 'top_of_list', 'value' => '<a class="floatright linkbutton" href="' . $scripturl . '?action=mentions' . (!empty($this->_all) ? '' : ';all') . str_replace(';all', '', $this->_url_param) . '">' . (!empty($this->_all) ? $txt['mentions_unread'] : $txt['mentions_all']) . '</a>'), array('position' => 'bottom_of_list', 'value' => '<a class="floatright linkbutton" href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=readall' . str_replace(';all', '', $this->_url_param) . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['mentions_mark_all_read'] . '</a>')));
        foreach ($this->_known_mentions as $key => $mention) {
            if (!empty($mention['enabled'])) {
                $list_options['list_menu']['links'][] = array('href' => $scripturl . '?action=mentions;type=' . $key . (!empty($this->_all) ? ';all' : ''), 'is_selected' => $this->_type === $key, 'label' => $txt['mentions_type_' . $key]);
                $this->_callbacks[$key] = $mention['callback'];
            }
        }
        createList($list_options);
        $context['page_title'] = $txt['my_mentions'] . (!empty($this->_page) ? ' - ' . sprintf($txt['my_mentions_pages'], $this->_page) : '');
        $context['linktree'][] = array('url' => $scripturl . '?action=mentions', 'name' => $txt['my_mentions']);
        if (!empty($this->_type)) {
            $context['linktree'][] = array('url' => $scripturl . '?action=mentions;type=' . $this->_type, 'name' => $txt['mentions_type_' . $this->_type]);
        }
    }