/**
  * Loads article previews for display with the portal index template
  */
 public function action_sportal_index()
 {
     global $context, $modSettings;
     // Showing articles on the index page?
     if (!empty($modSettings['sp_articles_index'])) {
         require_once SUBSDIR . '/PortalArticle.subs.php';
         $context['sub_template'] = 'portal_index';
         // Set up the pages
         $total_articles = sportal_get_articles_count();
         $total = min($total_articles, !empty($modSettings['sp_articles_index_total']) ? $modSettings['sp_articles_index_total'] : 20);
         $per_page = min($total, !empty($modSettings['sp_articles_index_per_page']) ? $modSettings['sp_articles_index_per_page'] : 5);
         $start = !empty($_REQUEST['articles']) ? (int) $_REQUEST['articles'] : 0;
         if ($total > $per_page) {
             $context['article_page_index'] = constructPageIndex($context['portal_url'] . '?articles=%1$d', $start, $total, $per_page, true);
         }
         // If we have some articles
         require_once SUBSDIR . '/PortalArticle.subs.php';
         $context['articles'] = sportal_get_articles(0, true, true, 'spa.id_article DESC', 0, $per_page, $start);
         foreach ($context['articles'] as $article) {
             if (empty($modSettings['sp_articles_length']) && ($cutoff = Util::strpos($article['body'], '[cutoff]')) !== false) {
                 $article['body'] = Util::substr($article['body'], 0, $cutoff);
                 if ($article['type'] === 'bbc') {
                     require_once SUBSDIR . '/Post.subs.php';
                     preparsecode($article['body']);
                 }
             }
             $context['articles'][$article['id']]['preview'] = sportal_parse_content($article['body'], $article['type'], 'return');
             $context['articles'][$article['id']]['date'] = htmlTime($article['date']);
             // Just want a shorter look on the index page
             if (!empty($modSettings['sp_articles_length'])) {
                 $context['articles'][$article['id']]['preview'] = Util::shorten_html($context['articles'][$article['id']]['preview'], $modSettings['sp_articles_length']);
             }
         }
     }
 }
Exemplo n.º 2
0
function ArcadeMatchList()
{
    global $scripturl, $txt, $db_prefix, $context, $smcFunc, $user_info, $modSettings;
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}arcade_matches AS m
			LEFT JOIN {db_prefix}arcade_matches_players AS me ON (me.id_match = m.id_match AND me.id_member = {int:member})
		WHERE ({query_see_match})', array('member' => $user_info['id']));
    list($matchCount) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['page_index'] = constructPageIndex($scripturl . '?action=arcade;sa=arena', $_REQUEST['start'], $matchCount, $modSettings['matchesPerPage'], false);
    $request = $smcFunc['db_query']('', '
		SELECT
			m.id_match, m.name, m.private_game, m.created, m.updated, m.status,
			m.num_players, m.current_players, m.num_rounds, m.current_round,
			IFNULL(me.id_member, 0) AS participation, me.status AS my_state,
			mem.id_member, mem.real_name
		FROM {db_prefix}arcade_matches AS m
			LEFT JOIN {db_prefix}arcade_matches_players AS me ON (me.id_match = m.id_match AND me.id_member = {int:member})
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
		WHERE {query_see_match}
		ORDER BY me.status = 1 DESC', array('member' => $user_info['id']));
    $context['matches'] = array();
    $status = array(10 => 'arcade_arena_waiting_players', 11 => 'arcade_arena_waiting_other_players', 20 => 'arcade_arena_started', 21 => 'arcade_arena_not_played', 22 => 'arcade_arena_not_played', 23 => 'arcade_arena_not_other_played', 24 => 'arcade_arena_dropped', 30 => 'arcade_arena_complete', 31 => 'arcade_arena_complete', 32 => 'arcade_arena_complete', 33 => 'arcade_arena_complete', 34 => 'arcade_arena_complete');
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['matches'][] = array('id' => $row['id_match'], 'name' => $row['name'], 'link' => '<a href="' . $scripturl . '?action=arcade;sa=viewMatch;match=' . $row['id_match'] . '">' . $row['name'] . '</a>', 'status' => $status[$row['my_state'] + ($row['status'] * 10 + 10)], 'joined' => (bool) $row['participation'], 'my_state' => $row['my_state'], 'is_private' => (bool) $row['private_game'], 'players' => $row['current_players'], 'players_limit' => $row['num_players'], 'round' => $row['current_round'], 'rounds' => $row['num_rounds'], 'starter' => array('id' => $row['id_member'], 'name' => $row['real_name'], 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>' : ''));
    }
    $smcFunc['db_free_result']($request);
    // Layout
    loadTemplate('ArcadeArena');
    $context['sub_template'] = 'arcade_arena_matches';
    $context['page_title'] = $txt['arcade_arena'];
    // Add Arena to link tree
    $context['linktree'][] = array('url' => $scripturl . '?action=arcade;sa=arena', 'name' => $txt['arcade_arena']);
}
Exemplo n.º 3
0
function ModifyHolidays()
{
    global $txt, $context, $db_prefix, $scripturl;
    loadTemplate('ManageCalendar');
    $context['page_title'] = $txt['manage_holidays'];
    $context['sub_template'] = 'manage_holidays';
    // Submitting something...
    if (isset($_REQUEST['delete']) && !empty($_REQUEST['holiday'])) {
        checkSession();
        foreach ($_REQUEST['holiday'] as $id => $value) {
            $_REQUEST['holiday'][$id] = (int) $id;
        }
        // Now the IDs are "safe" do the delete...
        db_query("\n\t\t\tDELETE FROM {$db_prefix}calendar_holidays\n\t\t\tWHERE ID_HOLIDAY IN (" . implode(', ', $_REQUEST['holiday']) . ")\n\t\t\tLIMIT " . count($_REQUEST['holiday']), __FILE__, __LINE__);
        updateStats('calendar');
    }
    // Total amount of holidays... for pagination.
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM {$db_prefix}calendar_holidays", __FILE__, __LINE__);
    list($context['holidayCount']) = mysql_fetch_row($request);
    mysql_free_result($request);
    $context['page_index'] = constructPageIndex($scripturl . '?action=managecalendar;sa=holidays', $_REQUEST['start'], $context['holidayCount'], 20);
    // Now load up all the holidays into a lovely large array.
    $request = db_query("\n\t\tSELECT ID_HOLIDAY, YEAR(eventDate) AS year, MONTH(eventDate) AS month, DAYOFMONTH(eventDate) AS day, title\n\t\tFROM {$db_prefix}calendar_holidays\n\t\tORDER BY title\n\t\tLIMIT {$_REQUEST['start']}, 20", __FILE__, __LINE__);
    $context['holidays'] = array();
    while ($row = mysql_fetch_assoc($request)) {
        $context['holidays'][] = array('id' => $row['ID_HOLIDAY'], 'date' => $row['day'] . ' ' . $txt['months'][$row['month']] . ' ' . ($row['year'] == '0004' ? '(' . $txt['every_year'] . ')' : $row['year']), 'title' => $row['title']);
    }
    mysql_free_result($request);
}
Exemplo n.º 4
0
 /**
  * Allows to pick a topic to merge the current topic with.
  * is accessed with ?action=mergetopics;sa=index
  * default sub action for ?action=mergetopics.
  * uses 'merge' sub template of the MergeTopics template.
  * allows to set a different target board.
  */
 public function action_mergeIndex()
 {
     global $txt, $board, $context, $scripturl, $user_info, $modSettings;
     if (!isset($_GET['from'])) {
         fatal_lang_error('no_access', false);
     }
     $_GET['from'] = (int) $_GET['from'];
     $_REQUEST['targetboard'] = isset($_REQUEST['targetboard']) ? (int) $_REQUEST['targetboard'] : $board;
     $context['target_board'] = $_REQUEST['targetboard'];
     // Prepare a handy query bit for approval...
     if ($modSettings['postmod_active']) {
         $can_approve_boards = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts');
         $onlyApproved = $can_approve_boards !== array(0) && !in_array($_REQUEST['targetboard'], $can_approve_boards);
     } else {
         $onlyApproved = false;
     }
     // How many topics are on this board?  (used for paging.)
     require_once SUBSDIR . '/Topic.subs.php';
     $topiccount = countTopicsByBoard($_REQUEST['targetboard'], $onlyApproved);
     // Make the page list.
     $context['page_index'] = constructPageIndex($scripturl . '?action=mergetopics;from=' . $_GET['from'] . ';targetboard=' . $_REQUEST['targetboard'] . ';board=' . $board . '.%1$d', $_REQUEST['start'], $topiccount, $modSettings['defaultMaxTopics'], true);
     // Get the topic's subject.
     $topic_info = getTopicInfo($_GET['from'], 'message');
     // @todo review: double check the logic
     if (empty($topic_info) || $topic_info['id_board'] != $board || $onlyApproved && empty($topic_info['approved'])) {
         fatal_lang_error('no_board');
     }
     // Tell the template a few things..
     $context['origin_topic'] = $_GET['from'];
     $context['origin_subject'] = $topic_info['subject'];
     $context['origin_js_subject'] = addcslashes(addslashes($topic_info['subject']), '/');
     $context['page_title'] = $txt['merge'];
     // Check which boards you have merge permissions on.
     $merge_boards = boardsAllowedTo('merge_any');
     if (empty($merge_boards)) {
         fatal_lang_error('cannot_merge_any', 'user');
     }
     // Get a list of boards they can navigate to to merge.
     require_once SUBSDIR . '/Boards.subs.php';
     $boardListOptions = array('not_redirection' => true);
     if (!in_array(0, $merge_boards)) {
         $boardListOptions['included_boards'] = $merge_boards;
     }
     $boards_list = getBoardList($boardListOptions, true);
     $context['boards'] = array();
     foreach ($boards_list as $board) {
         $context['boards'][] = array('id' => $board['id_board'], 'name' => $board['board_name'], 'category' => $board['cat_name']);
     }
     // Get some topics to merge it with.
     $context['topics'] = mergeableTopics($_REQUEST['targetboard'], $_GET['from'], $onlyApproved, $_REQUEST['start']);
     if (empty($context['topics']) && count($context['boards']) <= 1) {
         fatal_lang_error('merge_need_more_topics');
     }
     $context['sub_template'] = 'merge';
 }
Exemplo n.º 5
0
function PostSchedulerAdmin()
{
    global $txt, $mbname, $context, $smcFunc, $scripturl;
    // Get all the feeds
    $context['schedule_posts'] = array();
    $context['start'] = (int) $_REQUEST['start'];
    $request = $smcFunc['db_query']('', "\n\t\t\tSELECT \n\t\t\t\tCOUNT(*) as total\n\t\t\tFROM {db_prefix}postscheduler\n\t\t\tWHERE hasposted  = 0\n\t\t\t");
    $totalRow = $smcFunc['db_fetch_assoc']($request);
    $request = $smcFunc['db_query']('', "\n\t\t\tSELECT \n\t\t\t\tID_POST, subject, ID_MEMBER, postername, post_time\n\t\t\tFROM {db_prefix}postscheduler\n\t\t\tWHERE hasposted  = 0  \n\t\t\tORDER BY post_time ASC LIMIT {$context['start']},10");
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['schedule_posts'][] = $row;
    }
    $smcFunc['db_free_result']($request);
    // Setup the paging
    $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=postscheduler;sa=admin', $_REQUEST['start'], $totalRow['total'], 10);
    $context['sub_template'] = 'postmain';
    // Set the page title
    $context['page_title'] = $mbname . ' - ' . $txt['postscheduler_postlist'];
}
 /**
  * View a specific category, showing all articles it contains
  */
 public function action_sportal_category()
 {
     global $context, $scripturl, $modSettings;
     // Basic article support
     require_once SUBSDIR . '/PortalArticle.subs.php';
     $category_id = !empty($_REQUEST['category']) ? $_REQUEST['category'] : 0;
     if (is_int($category_id)) {
         $category_id = (int) $category_id;
     } else {
         $category_id = Util::htmlspecialchars($category_id, ENT_QUOTES);
     }
     $context['category'] = sportal_get_categories($category_id, true, true);
     if (empty($context['category']['id'])) {
         fatal_lang_error('error_sp_category_not_found', false);
     }
     // Set up the pages
     $total_articles = sportal_get_articles_in_cat_count($context['category']['id']);
     $per_page = min($total_articles, !empty($modSettings['sp_articles_per_page']) ? $modSettings['sp_articles_per_page'] : 10);
     $start = !empty($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
     if ($total_articles > $per_page) {
         $context['page_index'] = constructPageIndex($context['category']['href'] . ';start=%1$d', $start, $total_articles, $per_page, true);
     }
     // Load the articles in this category
     $context['articles'] = sportal_get_articles(0, true, true, 'spa.id_article DESC', $context['category']['id'], $per_page, $start);
     foreach ($context['articles'] as $article) {
         // Cut me mick
         if (($cutoff = Util::strpos($article['body'], '[cutoff]')) !== false) {
             $article['body'] = Util::substr($article['body'], 0, $cutoff);
             if ($article['type'] === 'bbc') {
                 require_once SUBSDIR . '/Post.subs.php';
                 preparsecode($article['body']);
             }
         }
         $context['articles'][$article['id']]['preview'] = sportal_parse_content($article['body'], $article['type'], 'return');
         $context['articles'][$article['id']]['date'] = htmlTime($article['date']);
     }
     $context['linktree'][] = array('url' => $scripturl . '?category=' . $context['category']['category_id'], 'name' => $context['category']['name']);
     $context['page_title'] = $context['category']['name'];
     $context['sub_template'] = 'view_category';
 }
Exemplo n.º 7
0
function adk_aportes_automaticos($array = '', $limit_body = '', $limit_query = '')
{
    global $context, $scripturl, $txt, $settings, $smcFunc, $boardurl, $adkportal, $current_load;
    global $modSettings;
    if (empty($array)) {
        $array = $adkportal['auto_news_id_boards'];
    }
    if (empty($limit_body)) {
        $limit_body = $adkportal['auto_news_limit_body'];
    }
    if (empty($limit_query)) {
        $limit_query = $adkportal['auto_news_limit_topics'];
    }
    if (!empty($adkportal['auto_news_size_img'])) {
        $size_img = 'style="max-width: ' . $adkportal['auto_news_size_img'] . 'px;"';
    }
    $context['start'] = isset($_REQUEST['adk']) && !empty($_REQUEST['start']) && !empty($_REQUEST['id']) && $_REQUEST['id'] == $context['block']['id'] ? (int) $_REQUEST['start'] : 0;
    $sql = $smcFunc['db_query']('', '
		SELECT COUNT(*) AS total 
		FROM {db_prefix}topics AS t
		INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
		WHERE ' . (!empty($array) ? 'b.id_board IN ({array_int:boards}) AND' : '') . ' {query_wanna_see_board}', array('boards' => explode(',', $array)));
    $row = $smcFunc['db_fetch_assoc']($sql);
    $smcFunc['db_free_result']($sql);
    $total = $row['total'];
    $context['page_index'] = constructPageIndex($scripturl . '?adk;id=' . $context['block']['id'], $context['start'], $total, $limit_query);
    $sql = $smcFunc['db_query']('', '
		SELECT m.id_topic, m.poster_time, m.id_member, m.poster_name,
		m.subject, m.body, m.icon, mg.online_color, t.num_replies, t.num_views, mem.real_name, mem.avatar,
		IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type
		FROM {db_prefix}messages AS m
		LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
		LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = mem.id_member)
					LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_mem_group} THEN mem.id_post_group ELSE mem.id_group END)
		INNER JOIN {db_prefix}topics AS t ON (t.id_first_msg = m.id_msg)
		INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
		WHERE ' . (!empty($array) ? 'm.id_board IN ({array_int:boards}) AND' : '') . ' {query_wanna_see_board}
		ORDER BY m.id_topic DESC LIMIT {int:uno}, {int:limit} ', array('limit' => $limit_query, 'uno' => $context['start'], 'boards' => explode(',', $array), 'reg_mem_group' => 0));
    $img = 'plugin.png';
    $topics = array();
    while ($row = $smcFunc['db_fetch_assoc']($sql)) {
        if (!empty($row['id_member'])) {
            $member = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
        } else {
            $member = $row['poster_name'];
        }
        $body = Adk_truncate(parse_bbc($row['body']), $limit_body, '...', false, true);
        if (!empty($size_img)) {
            $body = str_replace('class="', 'class="resize_auto_new ', $body);
            $body = str_replace('<img ', '<img ' . $size_img . '', $body);
        }
        $topics[] = array('v' => $row['num_views'], 'r' => $row['num_replies'], 'avatar' => $row['avatar'] == '' ? $row['id_attach'] > 0 ? '<img width="30" height="30" src="' . (empty($row['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $row['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $row['filename']) . '" alt="" border="0" />' : '' : (stristr($row['avatar'], 'http://') ? '<img width="30" height="30" src="' . $row['avatar'] . '" alt="" border="0" />' : '<img width="30" height="30" src="' . $modSettings['avatar_url'] . '/' . $smcFunc['htmlspecialchars']($row['avatar']) . '" alt="" border="0" />'), 'id_topic' => $row['id_topic'], 'img' => '<img style="vertical-align: middle;" src="' . $settings['images_url'] . '/post/' . $row['icon'] . '.gif" alt="" />', 'href' => $row['subject'], 'time' => timeformat($row['poster_time']), 'member' => $member, 'body' => $body);
    }
    //$averiguar = $avatar2,1,4);
    $smcFunc['db_free_result']($sql);
    foreach ($topics as $topic) {
        $title = '<a href="' . $scripturl . '?topic=' . $topic['id_topic'] . '.0"><b>' . $topic['href'] . '</b></a>';
        if (!empty($context['block']['b'])) {
            echo '
				<span class="clear upperframe">
					<span>&nbsp;</span>	
				</span>
				<div class="roundframe">
					<div>
						' . $topic['img'] . '
						<strong>' . $title . '</strong>
						<hr />';
        } else {
            echo '
						' . $topic['img'] . '
						<strong>' . $title . '</strong>
						<hr />';
        }
        echo '
		<div style="height: 40px;">
		
		<div class="smalltext adk_float_r">' . $txt['by'] . ' ' . $topic['member'] . ' - ' . $topic['time'] . '</div>';
        if (!empty($topic['avatar'])) {
            echo '
		<div class="adk_float_l">', $topic['avatar'], '</div>';
        }
        echo '
		</div>
		
		<div class="adk_padding_8">
			' . $topic['body'] . '
		</div>
		
		<br />';
        if (!empty($adkportal['adk_bookmarks_autonews'])) {
            adk_bookmarks('right', 'auto_news', $topic['id_topic']);
        }
        echo '
		<div class="smalltext adk_padding_5">
			<hr />
			<a href="' . $scripturl . '?topic=' . $topic['id_topic'] . '.0"><strong>' . $txt['adkmod_block_readmore'] . '...</strong></a>
			<div class="adk_float_r">
				' . $txt['views'] . ': ' . $topic['v'] . '  ' . $txt['replies'] . ': ' . $topic['r'] . '
			</div>
			<br /><br />
		</div>
		<div class="adk_height_3"></div>';
        if (!empty($context['block']['b'])) {
            echo '
				</div>
			</div>
			<span class="lowerframe">
				<span>&nbsp;</span>	
			</span>';
        } else {
            echo '
				<hr /><div class="adk_height_1"></div>';
        }
    }
    if ($current_load[0] == 'default') {
        if (!empty($context['block']['b'])) {
            echo '
			<span class="clear upperframe">
					<span>&nbsp;</span>	
			</span>
			<div class="roundframe">
				<div>';
        }
        echo '
					<div class="adk_align_right">' . $txt['pages'] . ': ' . $context['page_index'] . '</div>
					<div class="adk_height_1"></div>';
        if (!empty($context['block']['b'])) {
            echo '
				</div>
			</div>
			<span class="lowerframe">
				<span>&nbsp;</span>	
			</span>';
        }
    }
}
Exemplo n.º 8
0
function createList($listOptions)
{
    global $context, $settings, $options, $txt, $modSettings, $scripturl;
    assert(isset($listOptions['id']));
    assert(isset($listOptions['columns']));
    assert(is_array($listOptions['columns']));
    assert(empty($listOptions['items_per_page']) || isset($listOptions['get_count']['function'], $listOptions['base_href']) && is_numeric($listOptions['items_per_page']));
    assert(empty($listOptions['default_sort_col']) || isset($listOptions['columns'][$listOptions['default_sort_col']]));
    assert(!isset($listOptions['form']) || isset($listOptions['form']['href']));
    // All the context data will be easily accessible by using a reference.
    $context[$listOptions['id']] = array();
    $list_context =& $context[$listOptions['id']];
    // Figure out the sort.
    if (empty($listOptions['default_sort_col'])) {
        $list_context['sort'] = array();
        $sort = '1=1';
    } else {
        $request_var_sort = isset($listOptions['request_vars']['sort']) ? $listOptions['request_vars']['sort'] : 'sort';
        $request_var_desc = isset($listOptions['request_vars']['desc']) ? $listOptions['request_vars']['desc'] : 'desc';
        if (isset($_REQUEST[$request_var_sort], $listOptions['columns'][$_REQUEST[$request_var_sort]], $listOptions['columns'][$_REQUEST[$request_var_sort]]['sort'])) {
            $list_context['sort'] = array('id' => $_REQUEST[$request_var_sort], 'desc' => isset($_REQUEST[$request_var_desc]) && isset($listOptions['columns'][$_REQUEST[$request_var_sort]]['sort']['reverse']));
        } else {
            $list_context['sort'] = array('id' => $listOptions['default_sort_col'], 'desc' => !empty($listOptions['default_sort_dir']) && $listOptions['default_sort_dir'] == 'desc' || !empty($listOptions['columns'][$listOptions['default_sort_col']]['sort']['default']) && substr($listOptions['columns'][$listOptions['default_sort_col']]['sort']['default'], -4, 4) == 'desc' ? true : false);
        }
        // Set the database column sort.
        $sort = $listOptions['columns'][$list_context['sort']['id']]['sort'][$list_context['sort']['desc'] ? 'reverse' : 'default'];
    }
    $list_context['start_var_name'] = isset($listOptions['start_var_name']) ? $listOptions['start_var_name'] : 'start';
    // In some cases the full list must be shown, regardless of the amount of items.
    if (empty($listOptions['items_per_page'])) {
        $list_context['start'] = 0;
        $list_context['items_per_page'] = 0;
    } else {
        // First get an impression of how many items to expect.
        if (isset($listOptions['get_count']['file'])) {
            require_once $listOptions['get_count']['file'];
        }
        $list_context['total_num_items'] = call_user_func_array($listOptions['get_count']['function'], empty($listOptions['get_count']['params']) ? array() : $listOptions['get_count']['params']);
        // Default the start to the beginning...sounds logical.
        $list_context['start'] = isset($_REQUEST[$list_context['start_var_name']]) ? (int) $_REQUEST[$list_context['start_var_name']] : 0;
        $list_context['items_per_page'] = $listOptions['items_per_page'];
        // Then create a page index.
        $list_context['page_index'] = constructPageIndex($listOptions['base_href'] . (empty($list_context['sort']) ? '' : ';' . $request_var_sort . '=' . $list_context['sort']['id'] . ($list_context['sort']['desc'] ? ';' . $request_var_desc : '')) . ($list_context['start_var_name'] != 'start' ? ';' . $list_context['start_var_name'] . '=%1$d' : ''), $list_context['start'], $list_context['total_num_items'], $list_context['items_per_page'], $list_context['start_var_name'] != 'start');
    }
    // Prepare the headers of the table.
    $list_context['headers'] = array();
    foreach ($listOptions['columns'] as $column_id => $column) {
        $list_context['headers'][] = array('id' => $column_id, 'label' => isset($column['header']['eval']) ? eval($column['header']['eval']) : (isset($column['header']['value']) ? $column['header']['value'] : ''), 'href' => empty($listOptions['default_sort_col']) || empty($column['sort']) ? '' : $listOptions['base_href'] . ';' . $request_var_sort . '=' . $column_id . ($column_id === $list_context['sort']['id'] && !$list_context['sort']['desc'] && isset($column['sort']['reverse']) ? ';' . $request_var_desc : '') . (empty($list_context['start']) ? '' : ';' . $list_context['start_var_name'] . '=' . $list_context['start']), 'sort_image' => empty($listOptions['default_sort_col']) || empty($column['sort']) || $column_id !== $list_context['sort']['id'] ? null : ($list_context['sort']['desc'] ? 'down' : 'up'), 'class' => isset($column['header']['class']) ? $column['header']['class'] : '', 'style' => isset($column['header']['style']) ? $column['header']['style'] : '', 'colspan' => isset($column['header']['colspan']) ? $column['header']['colspan'] : '');
    }
    // We know the amount of columns, might be useful for the template.
    $list_context['num_columns'] = count($listOptions['columns']);
    $list_context['width'] = isset($listOptions['width']) ? $listOptions['width'] : '0';
    // Get the file with the function for the item list.
    if (isset($listOptions['get_items']['file'])) {
        require_once $listOptions['get_items']['file'];
    }
    // Call the function and include which items we want and in what order.
    $list_items = call_user_func_array($listOptions['get_items']['function'], array_merge(array($list_context['start'], $list_context['items_per_page'], $sort), empty($listOptions['get_items']['params']) ? array() : $listOptions['get_items']['params']));
    // Loop through the list items to be shown and construct the data values.
    $list_context['rows'] = array();
    foreach ($list_items as $item_id => $list_item) {
        $cur_row = array();
        foreach ($listOptions['columns'] as $column_id => $column) {
            $cur_data = array();
            // A value straight from the database?
            if (isset($column['data']['db'])) {
                $cur_data['value'] = $list_item[$column['data']['db']];
            } elseif (isset($column['data']['db_htmlsafe'])) {
                $cur_data['value'] = htmlspecialchars($list_item[$column['data']['db_htmlsafe']]);
            } elseif (isset($column['data']['sprintf'])) {
                $params = array();
                foreach ($column['data']['sprintf']['params'] as $sprintf_param => $htmlsafe) {
                    $params[] = $htmlsafe ? htmlspecialchars($list_item[$sprintf_param]) : $list_item[$sprintf_param];
                }
                $cur_data['value'] = vsprintf($column['data']['sprintf']['format'], $params);
            } elseif (isset($column['data']['function'])) {
                $cur_data['value'] = $column['data']['function']($list_item);
            } elseif (isset($column['data']['eval'])) {
                $cur_data['value'] = eval(preg_replace('~%([a-zA-Z0-9\\-_]+)%~', '$list_item[\'$1\']', $column['data']['eval']));
            } elseif (isset($column['data']['value'])) {
                $cur_data['value'] = $column['data']['value'];
            } else {
                $cur_data['value'] = '';
            }
            // Allow for basic formatting.
            if (!empty($column['data']['comma_format'])) {
                $cur_data['value'] = comma_format($cur_data['value']);
            } elseif (!empty($column['data']['timeformat'])) {
                $cur_data['value'] = timeformat($cur_data['value']);
            }
            // Set a style class for this column?
            if (isset($column['data']['class'])) {
                $cur_data['class'] = $column['data']['class'];
            }
            // Fully customized styling for the cells in this column only.
            if (isset($column['data']['style'])) {
                $cur_data['style'] = $column['data']['style'];
            }
            // Add the data cell properties to the current row.
            $cur_row[$column_id] = $cur_data;
        }
        // Insert the row into the list.
        $list_context['rows'][$item_id] = $cur_row;
    }
    // The title is currently optional.
    if (isset($listOptions['title'])) {
        $list_context['title'] = $listOptions['title'];
    }
    // In case there's a form, share it with the template context.
    if (isset($listOptions['form'])) {
        $list_context['form'] = $listOptions['form'];
        if (!isset($list_context['form']['hidden_fields'])) {
            $list_context['form']['hidden_fields'] = array();
        }
        // Always add a session check field.
        $list_context['form']['hidden_fields'][$context['session_var']] = $context['session_id'];
        // Include the starting page as hidden field?
        if (!empty($list_context['form']['include_start']) && !empty($list_context['start'])) {
            $list_context['form']['hidden_fields'][$list_context['start_var_name']] = $list_context['start'];
        }
        // If sorting needs to be the same after submitting, add the parameter.
        if (!empty($list_context['form']['include_sort']) && !empty($list_context['sort'])) {
            $list_context['form']['hidden_fields']['sort'] = $list_context['sort']['id'];
            if ($list_context['sort']['desc']) {
                $list_context['form']['hidden_fields']['desc'] = 1;
            }
        }
    }
    // Wanna say something nice in case there are no items?
    if (isset($listOptions['no_items_label'])) {
        $list_context['no_items_label'] = $listOptions['no_items_label'];
        $list_context['no_items_align'] = isset($listOptions['no_items_align']) ? $listOptions['no_items_align'] : '';
    }
    // A list can sometimes need a few extra rows above and below.
    if (isset($listOptions['additional_rows'])) {
        $list_context['additional_rows'] = array();
        foreach ($listOptions['additional_rows'] as $row) {
            if (empty($row)) {
                continue;
            }
            // Supported row positions: top_of_list, after_title,
            // above_column_headers, below_table_data, bottom_of_list.
            if (!isset($list_context['additional_rows'][$row['position']])) {
                $list_context['additional_rows'][$row['position']] = array();
            }
            $list_context['additional_rows'][$row['position']][] = $row;
        }
    }
    // Add an option for inline JavaScript.
    if (isset($listOptions['javascript'])) {
        $list_context['javascript'] = $listOptions['javascript'];
    }
    // We want a menu.
    if (isset($listOptions['list_menu'])) {
        $list_context['list_menu'] = $listOptions['list_menu'];
    }
    // Make sure the template is loaded.
    loadTemplate('GenericList');
}
Exemplo n.º 9
0
function Who()
{
    global $context, $scripturl, $user_info, $txt, $modSettings, $memberContext, $smcFunc;
    // Permissions, permissions, permissions.
    isAllowedTo('who_view');
    // You can't do anything if this is off.
    if (empty($modSettings['who_enabled'])) {
        fatal_lang_error('who_off', false);
    }
    // Load the 'Who' template.
    loadTemplate('Who');
    loadLanguage('Who');
    // Sort out... the column sorting.
    $sort_methods = array('user' => 'mem.real_name', 'time' => 'lo.log_time');
    $show_methods = array('members' => '(lo.id_member != 0)', 'guests' => '(lo.id_member = 0)', 'all' => '1=1');
    // Store the sort methods and the show types for use in the template.
    $context['sort_methods'] = array('user' => $txt['who_user'], 'time' => $txt['who_time']);
    $context['show_methods'] = array('all' => $txt['who_show_all'], 'members' => $txt['who_show_members_only'], 'guests' => $txt['who_show_guests_only']);
    // Can they see spiders too?
    if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) {
        $show_methods['spiders'] = '(lo.id_member = 0 AND lo.id_spider > 0)';
        $show_methods['guests'] = '(lo.id_member = 0 AND lo.id_spider = 0)';
        $context['show_methods']['spiders'] = $txt['who_show_spiders_only'];
    } elseif (empty($modSettings['show_spider_online']) && isset($_SESSION['who_online_filter']) && $_SESSION['who_online_filter'] == 'spiders') {
        unset($_SESSION['who_online_filter']);
    }
    // Does the user prefer a different sort direction?
    if (isset($_REQUEST['sort']) && isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = $_SESSION['who_online_sort_by'] = $_REQUEST['sort'];
        $sort_method = $sort_methods[$_REQUEST['sort']];
    } elseif (isset($_SESSION['who_online_sort_by'])) {
        $context['sort_by'] = $_SESSION['who_online_sort_by'];
        $sort_method = $sort_methods[$_SESSION['who_online_sort_by']];
    } else {
        $context['sort_by'] = $_SESSION['who_online_sort_by'] = 'time';
        $sort_method = 'lo.log_time';
    }
    $context['sort_direction'] = isset($_REQUEST['asc']) || isset($_REQUEST['sort_dir']) && $_REQUEST['sort_dir'] == 'asc' ? 'up' : 'down';
    $conditions = array();
    if (!allowedTo('moderate_forum')) {
        $conditions[] = '(IFNULL(mem.show_online, 1) = 1)';
    }
    // Fallback to top filter?
    if (isset($_REQUEST['submit_top']) && isset($_REQUEST['show_top'])) {
        $_REQUEST['show'] = $_REQUEST['show_top'];
    }
    // Does the user wish to apply a filter?
    if (isset($_REQUEST['show']) && isset($show_methods[$_REQUEST['show']])) {
        $context['show_by'] = $_SESSION['who_online_filter'] = $_REQUEST['show'];
        $conditions[] = $show_methods[$_REQUEST['show']];
    } elseif (isset($_SESSION['who_online_filter'])) {
        $context['show_by'] = $_SESSION['who_online_filter'];
        $conditions[] = $show_methods[$_SESSION['who_online_filter']];
    } else {
        $context['show_by'] = $_SESSION['who_online_filter'] = 'all';
    }
    // Get the total amount of members online.
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}log_online AS lo
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)' . (!empty($conditions) ? '
		WHERE ' . implode(' AND ', $conditions) : ''), array());
    list($totalMembers) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Prepare some page index variables.
    $context['page_index'] = constructPageIndex($scripturl . '?action=who;sort=' . $context['sort_by'] . ($context['sort_direction'] == 'up' ? ';asc' : '') . ';show=' . $context['show_by'], $_REQUEST['start'], $totalMembers, $modSettings['defaultMaxMembers']);
    $context['start'] = $_REQUEST['start'];
    // Look for people online, provided they don't mind if you see they are.
    $request = $smcFunc['db_query']('', '
		SELECT
			lo.log_time, lo.id_member, lo.url, INET_NTOA(lo.ip) AS ip, mem.real_name,
			lo.session, mg.online_color, IFNULL(mem.show_online, 1) AS show_online,
			lo.id_spider
		FROM {db_prefix}log_online AS lo
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)
			LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:regular_member} THEN mem.id_post_group ELSE mem.id_group END)' . (!empty($conditions) ? '
		WHERE ' . implode(' AND ', $conditions) : '') . '
		ORDER BY {raw:sort_method} {raw:sort_direction}
		LIMIT {int:offset}, {int:limit}', array('regular_member' => 0, 'sort_method' => $sort_method, 'sort_direction' => $context['sort_direction'] == 'up' ? 'ASC' : 'DESC', 'offset' => $context['start'], 'limit' => $modSettings['defaultMaxMembers']));
    $context['members'] = array();
    $member_ids = array();
    $url_data = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $actions = @unserialize($row['url']);
        if ($actions === false) {
            continue;
        }
        // Send the information to the template.
        $context['members'][$row['session']] = array('id' => $row['id_member'], 'ip' => allowedTo('moderate_forum') ? $row['ip'] : '', 'time' => strtr(timeformat($row['log_time']), array($txt['today'] => '', $txt['yesterday'] => '')), 'timestamp' => forum_time(true, $row['log_time']), 'query' => $actions, 'is_hidden' => $row['show_online'] == 0, 'id_spider' => $row['id_spider'], 'color' => empty($row['online_color']) ? '' : $row['online_color']);
        $url_data[$row['session']] = array($row['url'], $row['id_member']);
        $member_ids[] = $row['id_member'];
    }
    $smcFunc['db_free_result']($request);
    // Load the user data for these members.
    loadMemberData($member_ids);
    // Load up the guest user.
    $memberContext[0] = array('id' => 0, 'name' => $txt['guest_title'], 'group' => $txt['guest_title'], 'href' => '', 'link' => $txt['guest_title'], 'email' => $txt['guest_title'], 'is_guest' => true);
    // Are we showing spiders?
    $spiderContext = array();
    if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) {
        foreach (unserialize($modSettings['spider_name_cache']) as $id => $name) {
            $spiderContext[$id] = array('id' => 0, 'name' => $name, 'group' => $txt['spiders'], 'href' => '', 'link' => $name, 'email' => $name, 'is_guest' => true);
        }
    }
    $url_data = determineActions($url_data);
    // Setup the linktree and page title (do it down here because the language files are now loaded..)
    $context['page_title'] = $txt['who_title'];
    $context['linktree'][] = array('url' => $scripturl . '?action=who', 'name' => $txt['who_title']);
    // Put it in the context variables.
    foreach ($context['members'] as $i => $member) {
        if ($member['id'] != 0) {
            $member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0;
        }
        // Keep the IP that came from the database.
        $memberContext[$member['id']]['ip'] = $member['ip'];
        $context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : $txt['who_hidden'];
        if ($member['id'] == 0 && isset($spiderContext[$member['id_spider']])) {
            $context['members'][$i] += $spiderContext[$member['id_spider']];
        } else {
            $context['members'][$i] += $memberContext[$member['id']];
        }
    }
    // Some people can't send personal messages...
    $context['can_send_pm'] = allowedTo('pm_send');
    // any profile fields disabled?
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
}
Exemplo n.º 10
0
/**
 * Called by index.php?action=findmember.
 * - is used as a popup for searching members.
 * - uses sub template find_members of the Help template.
 * - also used to add members for PM's sent using wap2/imode protocol.
 */
function JSMembers()
{
    global $context, $scripturl, $user_info, $smcFunc;
    checkSession('get');
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_pm';
    } else {
        // Why is this in the Help template, you ask?  Well, erm... it helps you.  Does that work?
        loadTemplate('Help');
        $context['template_layers'] = array();
        $context['sub_template'] = 'find_members';
    }
    if (isset($_REQUEST['search'])) {
        $context['last_search'] = $smcFunc['htmlspecialchars']($_REQUEST['search'], ENT_QUOTES);
    } else {
        $_REQUEST['start'] = 0;
    }
    // Allow the user to pass the input to be added to to the box.
    $context['input_box_name'] = isset($_REQUEST['input']) && preg_match('~^[\\w-]+$~', $_REQUEST['input']) === 1 ? $_REQUEST['input'] : 'to';
    // Take the delimiter over GET in case it's \n or something.
    $context['delimiter'] = isset($_REQUEST['delim']) ? $_REQUEST['delim'] == 'LB' ? "\n" : $_REQUEST['delim'] : ', ';
    $context['quote_results'] = !empty($_REQUEST['quote']);
    // List all the results.
    $context['results'] = array();
    // Some buddy related settings ;)
    $context['show_buddies'] = !empty($user_info['buddies']);
    $context['buddy_search'] = isset($_REQUEST['buddies']);
    // If the user has done a search, well - search.
    if (isset($_REQUEST['search'])) {
        $_REQUEST['search'] = $smcFunc['htmlspecialchars']($_REQUEST['search'], ENT_QUOTES);
        $context['results'] = findMembers(array($_REQUEST['search']), true, $context['buddy_search']);
        $total_results = count($context['results']);
        $context['page_index'] = constructPageIndex($scripturl . '?action=findmember;search=' . $context['last_search'] . ';' . $context['session_var'] . '=' . $context['session_id'] . ';input=' . $context['input_box_name'] . ($context['quote_results'] ? ';quote=1' : '') . ($context['buddy_search'] ? ';buddies' : ''), $_REQUEST['start'], $total_results, 7);
        // Determine the navigation context (especially useful for the wireless template).
        $base_url = $scripturl . '?action=findmember;search=' . urlencode($context['last_search']) . (empty($_REQUEST['u']) ? '' : ';u=' . $_REQUEST['u']) . ';' . $context['session_var'] . '=' . $context['session_id'];
        $context['links'] = array('first' => $_REQUEST['start'] >= 7 ? $base_url . ';start=0' : '', 'prev' => $_REQUEST['start'] >= 7 ? $base_url . ';start=' . ($_REQUEST['start'] - 7) : '', 'next' => $_REQUEST['start'] + 7 < $total_results ? $base_url . ';start=' . ($_REQUEST['start'] + 7) : '', 'last' => $_REQUEST['start'] + 7 < $total_results ? $base_url . ';start=' . floor(($total_results - 1) / 7) * 7 : '', 'up' => $scripturl . '?action=pm;sa=send' . (empty($_REQUEST['u']) ? '' : ';u=' . $_REQUEST['u']));
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / 7 + 1, 'num_pages' => floor(($total_results - 1) / 7) + 1);
        $context['results'] = array_slice($context['results'], $_REQUEST['start'], 7);
    } else {
        $context['links']['up'] = $scripturl . '?action=pm;sa=send' . (empty($_REQUEST['u']) ? '' : ';u=' . $_REQUEST['u']);
    }
}
Exemplo n.º 11
0
    /**
     * The central part of the board - topic display.
     *
     * What it does:
     * - This function loads the posts in a topic up so they can be displayed.
     * - It uses the main sub template of the Display template.
     * - It requires a topic, and can go to the previous or next topic from it.
     * - It jumps to the correct post depending on a number/time/IS_MSG passed.
     * - It depends on the messages_per_page, defaultMaxMessages and enableAllMessages settings.
     * - It is accessed by ?topic=id_topic.START.
     */
    public function action_display()
    {
        global $scripturl, $txt, $modSettings, $context, $settings;
        global $options, $user_info, $board_info, $topic, $board;
        global $attachments, $messages_request;
        // What are you gonna display if these are empty?!
        if (empty($topic)) {
            fatal_lang_error('no_board', false);
        }
        // Load the template
        loadTemplate('Display');
        $context['sub_template'] = 'messages';
        // And the topic functions
        require_once SUBSDIR . '/Topic.subs.php';
        require_once SUBSDIR . '/Messages.subs.php';
        // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            @ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        // How much are we sticking on each page?
        $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        $template_layers = Template_Layers::getInstance();
        $template_layers->addEnd('messages_informations');
        $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
        // Let's do some work on what to search index.
        if (count($_GET) > 2) {
            foreach ($_GET as $k => $v) {
                if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                    $context['robot_no_index'] = true;
                }
            }
        }
        if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
            $context['robot_no_index'] = true;
        }
        // Find the previous or next topic.  Make a fuss if there are no more.
        if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
            // No use in calculating the next topic if there's only one.
            if ($board_info['num_topics'] > 1) {
                $includeStickies = !empty($modSettings['enableStickyTopics']);
                $topic = $_REQUEST['prev_next'] === 'prev' ? previousTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies) : nextTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies);
                $context['current_topic'] = $topic;
            }
            // Go to the newest message on this topic.
            $_REQUEST['start'] = 'new';
        }
        // Add 1 to the number of views of this topic (except for robots).
        if (!$user_info['possibly_robot'] && (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic)) {
            increaseViewCounter($topic);
            $_SESSION['last_read_topic'] = $topic;
        }
        $topic_selects = array();
        $topic_tables = array();
        $topic_parameters = array('topic' => $topic, 'member' => $user_info['id'], 'board' => (int) $board);
        // Allow addons to add additional details to the topic query
        call_integration_hook('integrate_topic_query', array(&$topic_selects, &$topic_tables, &$topic_parameters));
        // Load the topic details
        $topicinfo = getTopicInfo($topic_parameters, 'all', $topic_selects, $topic_tables);
        if (empty($topicinfo)) {
            fatal_lang_error('not_a_topic', false);
        }
        // Is this a moved topic that we are redirecting to?
        if (!empty($topicinfo['id_redirect_topic']) && !isset($_GET['noredir'])) {
            markTopicsRead(array($user_info['id'], $topic, $topicinfo['id_last_msg'], 0), $topicinfo['new_from'] !== 0);
            redirectexit('topic=' . $topicinfo['id_redirect_topic'] . '.0;redirfrom=' . $topicinfo['id_topic']);
        }
        $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
        $context['topic_first_message'] = $topicinfo['id_first_msg'];
        $context['topic_last_message'] = $topicinfo['id_last_msg'];
        $context['topic_unwatched'] = isset($topicinfo['unwatched']) ? $topicinfo['unwatched'] : 0;
        if (isset($_GET['redirfrom'])) {
            $redir_topics = topicsList(array((int) $_GET['redirfrom']));
            if (!empty($redir_topics[(int) $_GET['redirfrom']])) {
                $context['topic_redirected_from'] = $redir_topics[(int) $_GET['redirfrom']];
                $context['topic_redirected_from']['redir_href'] = $scripturl . '?topic=' . $context['topic_redirected_from']['id_topic'] . '.0;noredir';
            }
        }
        // Add up unapproved replies to get real number of replies...
        if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
            $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
        }
        // If this topic was derived from another, set the followup details
        if (!empty($topicinfo['derived_from'])) {
            require_once SUBSDIR . '/FollowUps.subs.php';
            $context['topic_derived_from'] = topicStartedHere($topic, $includeUnapproved);
        }
        // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
        if (!$includeUnapproved && $topicinfo['unapproved_posts'] && !$user_info['is_guest']) {
            $myUnapprovedPosts = unapprovedPosts($topic, $user_info['id']);
            $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
        } elseif ($user_info['is_guest']) {
            $context['total_visible_posts'] = $context['num_replies'] + ($topicinfo['approved'] ? 1 : 0);
        } else {
            $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
        }
        // When was the last time this topic was replied to?  Should we warn them about it?
        if (!empty($modSettings['oldTopicDays'])) {
            $mgsOptions = basicMessageInfo($topicinfo['id_last_msg'], true);
            $context['oldTopicError'] = $mgsOptions['poster_time'] + $modSettings['oldTopicDays'] * 86400 < time() && empty($topicinfo['is_sticky']);
        } else {
            $context['oldTopicError'] = false;
        }
        // The start isn't a number; it's information about what to do, where to go.
        if (!is_numeric($_REQUEST['start'])) {
            // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
            if ($_REQUEST['start'] == 'new') {
                // Guests automatically go to the last post.
                if ($user_info['is_guest']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                    $_REQUEST['start'] = $context['start_from'];
                } else {
                    // Fall through to the next if statement.
                    $_REQUEST['start'] = 'msg' . $topicinfo['new_from'];
                }
            }
            // Start from a certain time index, not a message.
            if (substr($_REQUEST['start'], 0, 4) == 'from') {
                $timestamp = (int) substr($_REQUEST['start'], 4);
                if ($timestamp === 0) {
                    $_REQUEST['start'] = 0;
                } else {
                    // Find the number of messages posted before said time...
                    $context['start_from'] = countNewPosts($topic, $topicinfo, $timestamp);
                    $_REQUEST['start'] = $context['start_from'];
                }
            } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
                $virtual_msg = (int) substr($_REQUEST['start'], 3);
                if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                    $context['start_from'] = 0;
                } else {
                    $only_approved = $modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts');
                    $context['start_from'] = countMessagesBefore($topic, $virtual_msg, false, $only_approved, !$user_info['is_guest']);
                }
                // We need to reverse the start as well in this case.
                $_REQUEST['start'] = $context['start_from'];
            }
        }
        // Mark the mention as read if requested
        if (isset($_REQUEST['mentionread']) && !empty($virtual_msg)) {
            require_once CONTROLLERDIR . '/Mentions.controller.php';
            $mentions = new Mentions_Controller();
            $mentions->setData(array('id_mention' => $_REQUEST['item'], 'mark' => $_REQUEST['mark']));
            $mentions->action_markread();
        }
        // Create a previous next string if the selected theme has it as a selected option.
        if ($modSettings['enablePreviousNext']) {
            $context['links'] += array('go_prev' => $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new', 'go_next' => $scripturl . '?topic=' . $topic . '.0;prev_next=next#new');
        }
        // Derived from, set the link back
        if (!empty($context['topic_derived_from'])) {
            $context['links']['derived_from'] = $scripturl . '?msg=' . $context['topic_derived_from']['derived_from'];
        }
        // Check if spellchecking is both enabled and actually working. (for quick reply.)
        $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
        if ($context['show_spellchecking']) {
            loadJavascriptFile('spellcheck.js', array('defer' => true));
        }
        // Do we need to show the visual verification image?
        $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
        if ($context['require_verification']) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions);
            $context['visual_verification_id'] = $verificationOptions['id'];
        }
        // Are we showing signatures - or disabled fields?
        $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
        $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
        // Censor the title...
        censorText($topicinfo['subject']);
        $context['page_title'] = $topicinfo['subject'];
        // Is this topic sticky, or can it even be?
        $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
        // Allow addons access to the topicinfo array
        call_integration_hook('integrate_display_topic', array($topicinfo));
        // Default this topic to not marked for notifications... of course...
        $context['is_marked_notify'] = false;
        // Did we report a post to a moderator just now?
        $context['report_sent'] = isset($_GET['reportsent']);
        if ($context['report_sent']) {
            $template_layers->add('report_sent');
        }
        // Let's get nosey, who is viewing this topic?
        if (!empty($settings['display_who_viewing'])) {
            require_once SUBSDIR . '/Who.subs.php';
            formatViewers($topic, 'topic');
        }
        // If all is set, but not allowed... just unset it.
        $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
        if (isset($_REQUEST['all']) && !$can_show_all) {
            unset($_REQUEST['all']);
        } elseif (isset($_REQUEST['all'])) {
            $_REQUEST['start'] = -1;
        }
        // Construct the page index, allowing for the .START method...
        $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true, array('all' => $can_show_all, 'all_selected' => isset($_REQUEST['all'])));
        $context['start'] = $_REQUEST['start'];
        // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
        // Figure out all the link to the next/prev
        $context['links'] += array('prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '');
        // If they are viewing all the posts, show all the posts, otherwise limit the number.
        if ($can_show_all && isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        }
        // Build the link tree.
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject']);
        // Build a list of this board's moderators.
        $context['moderators'] =& $board_info['moderators'];
        $context['link_moderators'] = array();
        // Information about the current topic...
        $context['is_locked'] = $topicinfo['locked'];
        $context['is_sticky'] = $topicinfo['is_sticky'];
        $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
        $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
        $context['is_approved'] = $topicinfo['approved'];
        $context['is_poll'] = $topicinfo['id_poll'] > 0 && !empty($modSettings['pollMode']) && allowedTo('poll_view');
        determineTopicClass($context);
        // Did this user start the topic or not?
        $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
        $context['topic_starter_id'] = $topicinfo['id_member_started'];
        // Set the topic's information for the template.
        $context['subject'] = $topicinfo['subject'];
        $context['num_views'] = $topicinfo['num_views'];
        $context['num_views_text'] = $context['num_views'] == 1 ? $txt['read_one_time'] : sprintf($txt['read_many_times'], $context['num_views']);
        $context['mark_unread_time'] = !empty($virtual_msg) ? $virtual_msg : $topicinfo['new_from'];
        // Set a canonical URL for this page.
        $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
        // For quick reply we need a response prefix in the default forum language.
        $context['response_prefix'] = response_prefix();
        // If we want to show event information in the topic, prepare the data.
        if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
            // We need events details and all that jazz
            require_once SUBSDIR . '/Calendar.subs.php';
            // First, try create a better time format, ignoring the "time" elements.
            if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
                $date_string = $user_info['time_format'];
            } else {
                $date_string = $matches[0];
            }
            // Get event information for this topic.
            $events = eventInfoForTopic($topic);
            $context['linked_calendar_events'] = array();
            foreach ($events as $event) {
                // Prepare the dates for being formatted.
                $start_date = sscanf($event['start_date'], '%04d-%02d-%02d');
                $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
                $end_date = sscanf($event['end_date'], '%04d-%02d-%02d');
                $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
                $context['linked_calendar_events'][] = array('id' => $event['id_event'], 'title' => $event['title'], 'can_edit' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'can_export' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => standardTime($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => standardTime($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
            }
            if (!empty($context['linked_calendar_events'])) {
                $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
                $template_layers->add('display_calendar');
            }
        }
        // Create the poll info if it exists.
        if ($context['is_poll']) {
            $template_layers->add('display_poll');
            require_once SUBSDIR . '/Poll.subs.php';
            loadPollContext($topicinfo['id_poll']);
            // Build the poll moderation button array.
            $context['poll_buttons'] = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'allow_poll_view', 'text' => 'poll_results', 'image' => 'poll_results.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start'] . ';viewresults'), 'change_vote' => array('test' => 'allow_change_vote', 'text' => 'poll_change_vote', 'image' => 'poll_change_vote.png', 'lang' => true, 'url' => $scripturl . '?action=poll;sa=vote;topic=' . $context['current_topic'] . '.' . $context['start'] . ';poll=' . $context['poll']['id'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'allow_lock_poll', 'text' => !$context['poll']['is_locked'] ? 'poll_lock' : 'poll_unlock', 'image' => 'poll_lock.png', 'lang' => true, 'url' => $scripturl . '?action=lockvoting;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'edit' => array('test' => 'allow_edit_poll', 'text' => 'poll_edit', 'image' => 'poll_edit.png', 'lang' => true, 'url' => $scripturl . '?action=editpoll;topic=' . $context['current_topic'] . '.' . $context['start']), 'remove_poll' => array('test' => 'can_remove_poll', 'text' => 'poll_remove', 'image' => 'admin_remove_poll.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['poll_remove_warn'] . '\');"', 'url' => $scripturl . '?action=poll;sa=remove;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']));
            // Allow mods to add additional buttons here
            call_integration_hook('integrate_poll_buttons');
        }
        // Calculate the fastest way to get the messages!
        $ascending = true;
        $start = $_REQUEST['start'];
        $limit = $context['messages_per_page'];
        $firstIndex = 0;
        if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
            $ascending = !$ascending;
            $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
            $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
            $firstIndex = $limit - 1;
        }
        // Taking care of member specific settings
        $limit_settings = array('messages_per_page' => $context['messages_per_page'], 'start' => $start, 'offset' => $limit);
        // Get each post and poster in this topic.
        $topic_details = getTopicsPostsAndPoster($topic, $limit_settings, $ascending);
        $messages = $topic_details['messages'];
        $posters = array_unique($topic_details['all_posters']);
        $all_posters = $topic_details['all_posters'];
        unset($topic_details);
        call_integration_hook('integrate_display_message_list', array(&$messages, &$posters));
        // Guests can't mark topics read or for notifications, just can't sorry.
        if (!$user_info['is_guest'] && !empty($messages)) {
            $mark_at_msg = max($messages);
            if ($mark_at_msg >= $topicinfo['id_last_msg']) {
                $mark_at_msg = $modSettings['maxMsgID'];
            }
            if ($mark_at_msg >= $topicinfo['new_from']) {
                markTopicsRead(array($user_info['id'], $topic, $mark_at_msg, $topicinfo['unwatched']), $topicinfo['new_from'] !== 0);
            }
            updateReadNotificationsFor($topic, $board);
            // Have we recently cached the number of new topics in this board, and it's still a lot?
            if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
                $_SESSION['topicseen_cache'][$board]--;
            } elseif (isset($_REQUEST['topicseen'])) {
                // Use the mark read tables... and the last visit to figure out if this should be read or not.
                $numNewTopics = getUnreadCountSince($board, empty($_SESSION['id_msg_last_visit']) ? 0 : $_SESSION['id_msg_last_visit']);
                // If there're no real new topics in this board, mark the board as seen.
                if (empty($numNewTopics)) {
                    $_REQUEST['boardseen'] = true;
                } else {
                    $_SESSION['topicseen_cache'][$board] = $numNewTopics;
                }
            } elseif (isset($_SESSION['topicseen_cache'][$board])) {
                $_SESSION['topicseen_cache'][$board]--;
            }
            // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
            if (isset($_REQUEST['boardseen'])) {
                require_once SUBSDIR . '/Boards.subs.php';
                markBoardsRead($board, false, false);
            }
        }
        $attachments = array();
        // If there _are_ messages here... (probably an error otherwise :!)
        if (!empty($messages)) {
            require_once SUBSDIR . '/Attachments.subs.php';
            // Fetch attachments.
            $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
            if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
                $attachments = getAttachments($messages, $includeUnapproved, 'filter_accessible_attachment', $all_posters);
            }
            $msg_parameters = array('message_list' => $messages, 'new_from' => $topicinfo['new_from']);
            $msg_selects = array();
            $msg_tables = array();
            call_integration_hook('integrate_message_query', array(&$msg_selects, &$msg_tables, &$msg_parameters));
            // What?  It's not like it *couldn't* be only guests in this topic...
            if (!empty($posters)) {
                loadMemberData($posters);
            }
            // Load in the likes for this group of messages
            if (!empty($modSettings['likes_enabled'])) {
                require_once SUBSDIR . '/Likes.subs.php';
                $context['likes'] = loadLikes($messages, true);
                // ajax controller for likes
                loadJavascriptFile('like_posts.js', array('defer' => true));
                loadLanguage('Errors');
                // Initiate likes and the tooltips for likes
                addInlineJavascript('
				$(document).ready(function () {
					var likePostInstance = likePosts.prototype.init({
						oTxt: ({
							btnText : ' . JavaScriptEscape($txt['ok_uppercase']) . ',
							likeHeadingError : ' . JavaScriptEscape($txt['like_heading_error']) . ',
							error_occurred : ' . JavaScriptEscape($txt['error_occurred']) . '
						}),
					});

					$(".like_button, .unlike_button").SiteTooltip({
						hoverIntent: {
							sensitivity: 10,
							interval: 150,
							timeout: 50
						}
					});
				});', true);
            }
            $messages_request = loadMessageRequest($msg_selects, $msg_tables, $msg_parameters);
            if (!empty($modSettings['enableFollowup'])) {
                require_once SUBSDIR . '/FollowUps.subs.php';
                $context['follow_ups'] = followupTopics($messages, $includeUnapproved);
            }
            // Go to the last message if the given time is beyond the time of the last message.
            if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
                $context['start_from'] = $topicinfo['num_replies'];
            }
            // Since the anchor information is needed on the top of the page we load these variables beforehand.
            $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $messages_request = false;
            $context['first_message'] = 0;
            $context['first_new_message'] = false;
        }
        $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&')), ENT_COMPAT, 'UTF-8'), 'child_level' => $board_info['child_level']);
        // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
        // This will be called from the template.
        $context['get_message'] = array($this, 'prepareDisplayContext_callback');
        // Now set all the wonderful, wonderful permissions... like moderation ones...
        $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_send_email' => 'send_email_to_members', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
        foreach ($common_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm);
        }
        // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
        $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
        foreach ($anyown_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
        }
        // Cleanup all the permissions with extra stuff...
        $context['can_mark_notify'] &= !$context['user']['is_guest'];
        $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
        $context['calendar_post'] &= !empty($modSettings['cal_enabled']) && (allowedTo('modify_any') || $context['user']['started'] && allowedTo('modify_own'));
        $context['can_add_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] <= 0;
        $context['can_remove_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] > 0;
        $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
        $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
        $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && !empty($modSettings['warning_enable']);
        // Handle approval flags...
        $context['can_reply_approved'] = $context['can_reply'];
        $context['can_reply'] |= $context['can_reply_unapproved'];
        $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
        $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
        $context['can_unwatch'] = !$user_info['is_guest'] && $modSettings['enable_unwatch'];
        $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
        $context['can_print'] = empty($modSettings['disable_print_topic']);
        // Start this off for quick moderation - it will be or'd for each post.
        $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
        // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
        $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
        $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
        $context['can_follow_up'] = !empty($modSettings['enableFollowup']) && boardsallowedto('post_new') !== array();
        // Check if the draft functions are enabled and that they have permission to use them (for quick reply.)
        $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft') && $context['can_reply'];
        $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
        if (!empty($context['drafts_save'])) {
            loadLanguage('Drafts');
        }
        if (!empty($context['drafts_autosave']) && empty($options['use_editor_quick_reply'])) {
            loadJavascriptFile('drafts.js');
        }
        if (!empty($modSettings['mentions_enabled'])) {
            $context['mentions_enabled'] = true;
            // Just using the plain text quick reply and not the editor
            if (empty($options['use_editor_quick_reply'])) {
                loadJavascriptFile(array('jquery.atwho.js', 'jquery.caret.min.js', 'mentioning.js'));
            }
            loadCSSFile('jquery.atwho.css');
            addInlineJavascript('
			$(document).ready(function () {
				for (var i = 0, count = all_elk_mentions.length; i < count; i++)
					all_elk_mentions[i].oMention = new elk_mentions(all_elk_mentions[i].oOptions);
			});');
        }
        // Load up the Quick ModifyTopic and Quick Reply scripts
        loadJavascriptFile('topic.js');
        // Auto video embeding enabled?
        if (!empty($modSettings['enableVideoEmbeding'])) {
            addInlineJavascript('
		$(document).ready(function() {
			$().linkifyvideo(oEmbedtext);
		});');
        }
        // Load up the "double post" sequencing magic.
        if (!empty($options['display_quick_reply'])) {
            checkSubmitOnce('register');
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
            if (!empty($options['use_editor_quick_reply']) && $context['can_reply']) {
                // Needed for the editor and message icons.
                require_once SUBSDIR . '/Editor.subs.php';
                // Now create the editor.
                $editorOptions = array('id' => 'message', 'value' => '', 'labels' => array('post_button' => $txt['post']), 'height' => '250px', 'width' => '100%', 'preview_type' => 0);
                create_control_richedit($editorOptions);
                $context['attached'] = '';
                $context['make_poll'] = isset($_REQUEST['poll']);
                // Message icons - customized icons are off?
                $context['icons'] = getMessageIcons($board);
                if (!empty($context['icons'])) {
                    $context['icons'][count($context['icons']) - 1]['is_last'] = true;
                }
            }
        }
        addJavascriptVar(array('notification_topic_notice' => $context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']), true);
        if ($context['can_send_topic']) {
            addJavascriptVar(array('sendtopic_cancel' => $txt['modify_cancel'], 'sendtopic_back' => $txt['back'], 'sendtopic_close' => $txt['find_close'], 'sendtopic_error' => $txt['send_error_occurred'], 'required_field' => $txt['require_field']), true);
        }
        // Build the normal button array.
        $context['normal_buttons'] = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'image' => 'reply.png', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return notifyButton(this);"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'unwatch' => array('test' => 'can_unwatch', 'text' => ($context['topic_unwatched'] ? '' : 'un') . 'watch', 'image' => ($context['topic_unwatched'] ? '' : 'un') . 'watched.png', 'lang' => true, 'custom' => 'onclick="return unwatchButton(this);"', 'url' => $scripturl . '?action=unwatchtopic;topic=' . $context['current_topic'] . '.' . $context['start'] . ';sa=' . ($context['topic_unwatched'] ? 'off' : 'on') . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0', 'custom' => 'onclick="return sendtopicOverlayDiv(this.href, \'' . $txt['send_topic'] . '\');"'), 'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="nofollow"', 'class' => 'new_win', 'url' => $scripturl . '?action=topic;sa=printpage;topic=' . $context['current_topic'] . '.0'));
        // Build the mod button array
        $context['mod_buttons'] = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.png', 'lang' => true, 'url' => $scripturl . '?action=movetopic;current_board=' . $context['current_board'] . ';topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', 'url' => $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=lock;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'sticky' => array('test' => 'can_sticky', 'text' => empty($context['is_sticky']) ? 'set_sticky' : 'set_nonsticky', 'image' => 'admin_sticky.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.png', 'lang' => true, 'url' => $scripturl . '?action=mergetopics;board=' . $context['current_board'] . '.0;from=' . $context['current_topic']), 'calendar' => array('test' => 'calendar_post', 'text' => 'calendar_link', 'image' => 'linktocal.png', 'lang' => true, 'url' => $scripturl . '?action=post;calendar;msg=' . $context['topic_first_message'] . ';topic=' . $context['current_topic'] . '.0'));
        // Restore topic. eh?  No monkey business.
        if ($context['can_restore_topic']) {
            $context['mod_buttons'][] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']);
        }
        if ($context['can_reply'] && !empty($options['display_quick_reply'])) {
            $template_layers->add('quickreply');
        }
        $template_layers->add('pages_and_buttons');
        // Allow adding new buttons easily.
        call_integration_hook('integrate_display_buttons');
        call_integration_hook('integrate_mod_buttons');
    }
Exemplo n.º 12
0
 /**
  * Allows the user to select the messages to be split.
  * is accessed with ?action=splittopics;sa=selectTopics.
  * uses 'select' sub template of the SplitTopics template or (for
  * XMLhttp) the 'split' sub template of the Xml template.
  * supports XMLhttp for adding/removing a message to the selection.
  * uses a session variable to store the selected topics.
  * shows two independent page indexes for both the selected and
  * not-selected messages (;topic=1.x;start2=y).
  */
 public function action_splitSelectTopics()
 {
     global $txt, $scripturl, $topic, $context, $modSettings, $options;
     $context['page_title'] = $txt['split_topic'] . ' - ' . $txt['select_split_posts'];
     $context['destination_board'] = !empty($_POST['move_to_board']) ? (int) $_POST['move_to_board'] : 0;
     // Haven't selected anything have we?
     $_SESSION['split_selection'][$topic] = empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic];
     // This is a special case for split topics from quick-moderation checkboxes
     if (isset($_REQUEST['subname_enc'])) {
         $this->_new_topic_subject = urldecode($_REQUEST['subname_enc']);
         $this->_set_session_values();
     }
     require_once SUBSDIR . '/Topic.subs.php';
     require_once SUBSDIR . '/Messages.subs.php';
     $context['not_selected'] = array('num_messages' => 0, 'start' => empty($_REQUEST['start']) ? 0 : (int) $_REQUEST['start'], 'messages' => array());
     $context['selected'] = array('num_messages' => 0, 'start' => empty($_REQUEST['start2']) ? 0 : (int) $_REQUEST['start2'], 'messages' => array());
     $context['topic'] = array('id' => $topic, 'subject' => urlencode($_SESSION['new_topic_subject']));
     // Some stuff for our favorite template.
     $context['new_subject'] = $_SESSION['new_topic_subject'];
     // Using the "select" sub template.
     $context['sub_template'] = isset($_REQUEST['xml']) ? 'split' : 'select';
     // All of the js for topic split selection is needed
     if (!isset($_REQUEST['xml'])) {
         loadJavascriptFile('topic.js');
     }
     // Are we using a custom messages per page?
     $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
     // Get the message ID's from before the move.
     if (isset($_REQUEST['xml'])) {
         $original_msgs = array('not_selected' => messageAt($context['not_selected']['start'], $topic, array('not_in' => empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic], 'only_approved' => !$modSettings['postmod_active'] || !allowedTo('approve_posts'), 'limit' => $context['messages_per_page'])), 'selected' => array());
         // You can't split the last message off.
         if (empty($context['not_selected']['start']) && count($original_msgs['not_selected']) <= 1 && $_REQUEST['move'] == 'down') {
             $_REQUEST['move'] = '';
         }
         if (!empty($_SESSION['split_selection'][$topic])) {
             $original_msgs['selected'] = messageAt($context['selected']['start'], $topic, array('include' => empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic], 'only_approved' => !$modSettings['postmod_active'] || !allowedTo('approve_posts'), 'limit' => $context['messages_per_page']));
         }
     }
     // (De)select a message..
     if (!empty($_REQUEST['move'])) {
         $_REQUEST['msg'] = (int) $_REQUEST['msg'];
         if ($_REQUEST['move'] == 'reset') {
             $_SESSION['split_selection'][$topic] = array();
         } elseif ($_REQUEST['move'] == 'up') {
             $_SESSION['split_selection'][$topic] = array_diff($_SESSION['split_selection'][$topic], array($_REQUEST['msg']));
         } else {
             $_SESSION['split_selection'][$topic][] = $_REQUEST['msg'];
         }
     }
     // Make sure the selection is still accurate.
     if (!empty($_SESSION['split_selection'][$topic])) {
         $_SESSION['split_selection'][$topic] = messageAt(0, $topic, array('include' => empty($_SESSION['split_selection'][$topic]) ? array() : $_SESSION['split_selection'][$topic], 'only_approved' => !$modSettings['postmod_active'] || !allowedTo('approve_posts'), 'limit' => false));
         $selection = $_SESSION['split_selection'][$topic];
     } else {
         $selection = array();
     }
     // Get the number of messages (not) selected to be split.
     $split_counts = countSplitMessages($topic, !$modSettings['postmod_active'] || allowedTo('approve_posts'), $selection);
     foreach ($split_counts as $key => $num_messages) {
         $context[$key]['num_messages'] = $num_messages;
     }
     // Fix an oversized starting page (to make sure both pageindexes are properly set).
     if ($context['selected']['start'] >= $context['selected']['num_messages']) {
         $context['selected']['start'] = $context['selected']['num_messages'] <= $context['messages_per_page'] ? 0 : $context['selected']['num_messages'] - ($context['selected']['num_messages'] % $context['messages_per_page'] == 0 ? $context['messages_per_page'] : $context['selected']['num_messages'] % $context['messages_per_page']);
     }
     $page_index_url = $scripturl . '?action=splittopics;sa=selectTopics;subname=' . strtr(urlencode($_SESSION['new_topic_subject']), array('%' => '%%')) . ';topic=' . $topic;
     // Build a page list of the not-selected topics...
     $context['not_selected']['page_index'] = constructPageIndex($page_index_url . '.%1$d;start2=' . $context['selected']['start'], $context['not_selected']['start'], $context['not_selected']['num_messages'], $context['messages_per_page'], true);
     // ...and one of the selected topics.
     $context['selected']['page_index'] = constructPageIndex($page_index_url . '.' . $context['not_selected']['start'] . ';start2=%1$d', $context['selected']['start'], $context['selected']['num_messages'], $context['messages_per_page'], true);
     // Retrieve the unselected messages.
     $context['not_selected']['messages'] = selectMessages($topic, $context['not_selected']['start'], $context['messages_per_page'], empty($_SESSION['split_selection'][$topic]) ? array() : array('excluded' => $_SESSION['split_selection'][$topic]), $modSettings['postmod_active'] && !allowedTo('approve_posts'));
     // Now retrieve the selected messages.
     if (!empty($_SESSION['split_selection'][$topic])) {
         $context['selected']['messages'] = selectMessages($topic, $context['selected']['start'], $context['messages_per_page'], array('included' => $_SESSION['split_selection'][$topic]), $modSettings['postmod_active'] && !allowedTo('approve_posts'));
     }
     // The XMLhttp method only needs the stuff that changed, so let's compare.
     if (isset($_REQUEST['xml'])) {
         $changes = array('remove' => array('not_selected' => array_diff($original_msgs['not_selected'], array_keys($context['not_selected']['messages'])), 'selected' => array_diff($original_msgs['selected'], array_keys($context['selected']['messages']))), 'insert' => array('not_selected' => array_diff(array_keys($context['not_selected']['messages']), $original_msgs['not_selected']), 'selected' => array_diff(array_keys($context['selected']['messages']), $original_msgs['selected'])));
         $context['changes'] = array();
         foreach ($changes as $change_type => $change_array) {
             foreach ($change_array as $section => $msg_array) {
                 if (empty($msg_array)) {
                     continue;
                 }
                 foreach ($msg_array as $id_msg) {
                     $context['changes'][$change_type . $id_msg] = array('id' => $id_msg, 'type' => $change_type, 'section' => $section);
                     if ($change_type == 'insert') {
                         $context['changes']['insert' . $id_msg]['insert_value'] = $context[$section]['messages'][$id_msg];
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 13
0
function MembergroupMembers()
{
    global $txt, $scripturl, $context, $modSettings, $sourcedir, $user_info, $settings, $smcFunc;
    $_REQUEST['group'] = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0;
    // No browsing of guests, membergroup 0 or moderators.
    if (in_array($_REQUEST['group'], array(-1, 0, 3))) {
        fatal_lang_error('membergroup_does_not_exist', false);
    }
    // Load up the group details.
    $request = $smcFunc['db_query']('', '
		SELECT id_group AS id, group_name AS name, CASE WHEN min_posts = {int:min_posts} THEN 1 ELSE 0 END AS assignable, hidden, online_color,
			stars, description, CASE WHEN min_posts != {int:min_posts} THEN 1 ELSE 0 END AS is_post_group
		FROM {db_prefix}membergroups
		WHERE id_group = {int:id_group}
		LIMIT 1', array('min_posts' => -1, 'id_group' => $_REQUEST['group']));
    // Doesn't exist?
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('membergroup_does_not_exist', false);
    }
    $context['group'] = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    // Fix the stars.
    $context['group']['stars'] = explode('#', $context['group']['stars']);
    $context['group']['stars'] = !empty($context['group']['stars'][0]) && !empty($context['group']['stars'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/' . $context['group']['stars'][1] . '" alt="*" border="0" />', $context['group']['stars'][0]) : '';
    $context['group']['can_moderate'] = allowedTo('manage_membergroups');
    $context['linktree'][] = array('url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'], 'name' => $context['group']['name']);
    // Load all the group moderators, for fun.
    $request = $smcFunc['db_query']('', '
		SELECT mem.id_member, mem.real_name
		FROM {db_prefix}group_moderators AS mods
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
		WHERE mods.id_group = {int:id_group}', array('id_group' => $_REQUEST['group']));
    $context['group']['moderators'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['MemberColor_ID_MEMBER'][$row['id_member']] = $row['id_member'];
        $context['group']['moderators'][] = array('id' => $row['id_member'], 'name' => $row['real_name']);
        if ($user_info['id'] == $row['id_member']) {
            $context['group']['can_moderate'] = true;
        }
    }
    $smcFunc['db_free_result']($request);
    // If this group is hidden then it can only "exists" if the user can moderate it!
    if ($context['group']['hidden'] && !$context['group']['can_moderate']) {
        fatal_lang_error('membergroup_does_not_exist', false);
    }
    // You can only assign membership if you are the moderator and/or can manage groups!
    if (!$context['group']['can_moderate']) {
        $context['group']['assignable'] = 0;
    } elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum')) {
        $context['group']['assignable'] = 0;
    }
    // Removing member from group?
    if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable']) {
        checkSession();
        // Make sure we're dealing with integers only.
        foreach ($_REQUEST['rem'] as $key => $group) {
            $_REQUEST['rem'][$key] = (int) $group;
        }
        require_once $sourcedir . '/Subs-Membergroups.php';
        removeMembersFromGroups($_REQUEST['rem'], $_REQUEST['group'], true);
    } elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable']) {
        checkSession();
        $member_query = array();
        $member_parameters = array();
        // Get all the members to be added... taking into account names can be quoted ;)
        $_REQUEST['toAdd'] = strtr($smcFunc['htmlspecialchars']($_REQUEST['toAdd'], ENT_QUOTES), array('&quot;' => '"'));
        preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches);
        $member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd']))));
        foreach ($member_names as $index => $member_name) {
            $member_names[$index] = trim($smcFunc['strtolower']($member_names[$index]));
            if (strlen($member_names[$index]) == 0) {
                unset($member_names[$index]);
            }
        }
        // Any passed by ID?
        $member_ids = array();
        if (!empty($_REQUEST['member_add'])) {
            foreach ($_REQUEST['member_add'] as $id) {
                if ($id > 0) {
                    $member_ids[] = (int) $id;
                }
            }
        }
        // Construct the query pelements.
        if (!empty($member_ids)) {
            $member_query[] = 'id_member IN ({array_int:member_ids})';
            $member_parameters['member_ids'] = $member_ids;
        }
        if (!empty($member_names)) {
            $member_query[] = 'LOWER(member_name) IN ({array_string:member_names})';
            $member_query[] = 'LOWER(real_name) IN ({array_string:member_names})';
            $member_parameters['member_names'] = $member_names;
        }
        $members = array();
        if (!empty($member_query)) {
            $request = $smcFunc['db_query']('', '
				SELECT id_member
				FROM {db_prefix}members
				WHERE (' . implode(' OR ', $member_query) . ')
					AND id_group != {int:id_group}
					AND FIND_IN_SET({int:id_group}, additional_groups) = 0', array_merge($member_parameters, array('id_group' => $_REQUEST['group'])));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $members[] = $row['id_member'];
            }
            $smcFunc['db_free_result']($request);
        }
        // !!! Add $_POST['additional'] to templates!
        // Do the updates...
        if (!empty($members)) {
            require_once $sourcedir . '/Subs-Membergroups.php';
            addMembersToGroup($members, $_REQUEST['group'], isset($_POST['additional']) || $context['group']['hidden'] ? 'only_additional' : 'auto', true);
        }
    }
    // Sort out the sorting!
    $sort_methods = array('name' => 'real_name', 'email' => allowedTo('moderate_forum') ? 'email_address' : 'hide_email ' . (isset($_REQUEST['desc']) ? 'DESC' : 'ASC') . ', email_address', 'active' => 'last_login', 'registered' => 'date_registered', 'posts' => 'posts');
    // They didn't pick one, default to by name..
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'name';
        $querySort = 'real_name';
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $querySort = $sort_methods[$_REQUEST['sort']];
    }
    $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up';
    // The where on the query is interesting. Non-moderators should only see people who are in this group as primary.
    if ($context['group']['can_moderate']) {
        $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group} OR FIND_IN_SET({int:group}, additional_groups) != 0';
    } else {
        $where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group}';
    }
    // Count members of the group.
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}members
		WHERE ' . $where, array('group' => $_REQUEST['group']));
    list($context['total_members']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['total_members'] = comma_format($context['total_members']);
    // Create the page index.
    $context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $_REQUEST['group'] . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']);
    $context['start'] = $_REQUEST['start'];
    $context['can_moderate_forum'] = allowedTo('moderate_forum');
    // Load up all members of this group.
    $request = $smcFunc['db_query']('', '
		SELECT id_member, member_name, real_name, email_address, member_ip, date_registered, last_login,
			hide_email, posts, is_activated, real_name
		FROM {db_prefix}members
		WHERE ' . $where . '
		ORDER BY ' . $querySort . ' ' . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC') . '
		LIMIT ' . $context['start'] . ', ' . $modSettings['defaultMaxMembers'], array('group' => $_REQUEST['group']));
    $context['members'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $last_online = empty($row['last_login']) ? $txt['never'] : timeformat($row['last_login']);
        // Italicize the online note if they aren't activated.
        if ($row['is_activated'] % 10 != 1) {
            $last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>';
        }
        if (!empty($row['id_member'])) {
            $context['MemberColor_ID_MEMBER'][$row['id_member']] = $row['id_member'];
        }
        $context['members'][] = array('id' => $row['id_member'], 'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', 'email' => $row['email_address'], 'show_email' => showEmailAddress(!empty($row['hide_email']), $row['id_member']), 'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>', 'registered' => timeformat($row['date_registered']), 'last_online' => $last_online, 'posts' => comma_format($row['posts']), 'is_activated' => $row['is_activated'] % 10 == 1);
    }
    $smcFunc['db_free_result']($request);
    //Color the Groups List ;D
    if (!empty($modSettings['MemberColorModCenter']) && !empty($context['MemberColor_ID_MEMBER'])) {
        $colorDatas = load_onlineColors($context['MemberColor_ID_MEMBER']);
        if (!empty($context['group']['moderators'])) {
            foreach ($context['group']['moderators'] as $key => $item) {
                if (!empty($colorDatas[$item['id']]['colored_link'])) {
                    $context['group']['moderators'][$key]['name'] = $colorDatas[$item['id']]['colored_name'];
                }
            }
        }
        if (!empty($context['members'])) {
            foreach ($context['members'] as $key => $item) {
                if (!empty($colorDatas[$item['id']]['colored_link'])) {
                    $context['members'][$key]['name'] = $colorDatas[$item['id']]['colored_link'];
                }
            }
        }
    }
    // Select the template.
    $context['sub_template'] = 'group_members';
    $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name'];
}
Exemplo n.º 14
0
/**
 * Actually do the search of personal messages.
 */
function MessageSearch2()
{
    global $scripturl, $modSettings, $user_info, $context, $txt;
    global $memberContext, $smcFunc;
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) {
        fatal_lang_error('loadavg_search_disabled', false);
    }
    /**
     * @todo For the moment force the folder to the inbox.
     * @todo Maybe set the inbox based on a cookie or theme setting?
     */
    $context['folder'] = 'inbox';
    // Some useful general permissions.
    $context['can_send_pm'] = allowedTo('pm_send');
    // Some hardcoded veriables that can be tweaked if required.
    $maxMembersToSearch = 500;
    // Extract all the search parameters.
    $search_params = array();
    if (isset($_REQUEST['params'])) {
        $temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+'))));
        foreach ($temp_params as $i => $data) {
            @(list($k, $v) = explode('|\'|', $data));
            $search_params[$k] = $v;
        }
    }
    $context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0;
    // Store whether simple search was used (needed if the user wants to do another query).
    if (!isset($search_params['advanced'])) {
        $search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1;
    }
    // 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'.
    if (!empty($search_params['searchtype']) || !empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2) {
        $search_params['searchtype'] = 2;
    }
    // Minimum age of messages. Default to zero (don't set param in that case).
    if (!empty($search_params['minage']) || !empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0) {
        $search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage'];
    }
    // Maximum age of messages. Default to infinite (9999 days: param not set).
    if (!empty($search_params['maxage']) || !empty($_REQUEST['maxage']) && $_REQUEST['maxage'] != 9999) {
        $search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage'];
    }
    $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']);
    $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']);
    // Default the user name to a wildcard matching every user (*).
    if (!empty($search_params['user_spec']) || !empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*') {
        $search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec'];
    }
    // This will be full of all kinds of parameters!
    $searchq_parameters = array();
    // If there's no specific user, then don't mention it in the main query.
    if (empty($search_params['userspec'])) {
        $userQuery = '';
    } else {
        $userString = strtr($smcFunc['htmlspecialchars']($search_params['userspec'], ENT_QUOTES), array('&quot;' => '"'));
        $userString = strtr($userString, array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_'));
        preg_match_all('~"([^"]+)"~', $userString, $matches);
        $possible_users = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $userString)));
        for ($k = 0, $n = count($possible_users); $k < $n; $k++) {
            $possible_users[$k] = trim($possible_users[$k]);
            if (strlen($possible_users[$k]) == 0) {
                unset($possible_users[$k]);
            }
        }
        // Who matches those criteria?
        // @todo This doesn't support sent item searching.
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}members
			WHERE real_name LIKE {raw:real_name_implode}', array('real_name_implode' => '\'' . implode('\' OR real_name LIKE \'', $possible_users) . '\''));
        // Simply do nothing if there're too many members matching the criteria.
        if ($smcFunc['db_num_rows']($request) > $maxMembersToSearch) {
            $userQuery = '';
        } elseif ($smcFunc['db_num_rows']($request) == 0) {
            $userQuery = 'AND pm.id_member_from = 0 AND (pm.from_name LIKE {raw:guest_user_name_implode})';
            $searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR pm.from_name LIKE \'', $possible_users) . '\'';
        } else {
            $memberlist = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $memberlist[] = $row['id_member'];
            }
            $userQuery = 'AND (pm.id_member_from IN ({array_int:member_list}) OR (pm.id_member_from = 0 AND (pm.from_name LIKE {raw:guest_user_name_implode})))';
            $searchq_parameters['guest_user_name_implode'] = '\'' . implode('\' OR pm.from_name LIKE \'', $possible_users) . '\'';
            $searchq_parameters['member_list'] = $memberlist;
        }
        $smcFunc['db_free_result']($request);
    }
    // Setup the sorting variables...
    // @todo Add more in here!
    $sort_columns = array('pm.id_pm');
    if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) {
        list($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, '');
    }
    $search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'pm.id_pm';
    $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc';
    // Sort out any labels we may be searching by.
    $labelQuery = '';
    if ($context['folder'] == 'inbox' && !empty($search_params['advanced']) && $context['currently_using_labels']) {
        // Came here from pagination?  Put them back into $_REQUEST for sanitization.
        if (isset($search_params['labels'])) {
            $_REQUEST['searchlabel'] = explode(',', $search_params['labels']);
        }
        // Assuming we have some labels - make them all integers.
        if (!empty($_REQUEST['searchlabel']) && is_array($_REQUEST['searchlabel'])) {
            foreach ($_REQUEST['searchlabel'] as $key => $id) {
                $_REQUEST['searchlabel'][$key] = (int) $id;
            }
        } else {
            $_REQUEST['searchlabel'] = array();
        }
        // Now that everything is cleaned up a bit, make the labels a param.
        $search_params['labels'] = implode(',', $_REQUEST['searchlabel']);
        // No labels selected? That must be an error!
        if (empty($_REQUEST['searchlabel'])) {
            $context['search_errors']['no_labels_selected'] = true;
        } elseif (count($_REQUEST['searchlabel']) != count($context['labels'])) {
            $labelQuery = '
			AND {raw:label_implode}';
            $labelStatements = array();
            foreach ($_REQUEST['searchlabel'] as $label) {
                $labelStatements[] = $smcFunc['db_quote']('FIND_IN_SET({string:label}, pmr.labels) != 0', array('label' => $label));
            }
            $searchq_parameters['label_implode'] = '(' . implode(' OR ', $labelStatements) . ')';
        }
    }
    // What are we actually searching for?
    $search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? $_REQUEST['search'] : '');
    // If we ain't got nothing - we should error!
    if (!isset($search_params['search']) || $search_params['search'] == '') {
        $context['search_errors']['invalid_search_string'] = true;
    }
    // Extract phrase parts first (e.g. some words "this is a phrase" some more words.)
    preg_match_all('~(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), $search_params['search'], $matches, PREG_PATTERN_ORDER);
    $searchArray = $matches[2];
    // Remove the phrase parts and extract the words.
    $tempSearch = explode(' ', preg_replace('~(?:^|\\s)(?:[-]?)"(?:[^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']));
    // A minus sign in front of a word excludes the word.... so...
    $excludedWords = array();
    // .. first, we check for things like -"some words", but not "-some words".
    foreach ($matches[1] as $index => $word) {
        if ($word == '-') {
            $word = $smcFunc['strtolower'](trim($searchArray[$index]));
            if (strlen($word) > 0) {
                $excludedWords[] = $word;
            }
            unset($searchArray[$index]);
        }
    }
    // Now we look for -test, etc.... normaller.
    foreach ($tempSearch as $index => $word) {
        if (strpos(trim($word), '-') === 0) {
            $word = substr($smcFunc['strtolower']($word), 1);
            if (strlen($word) > 0) {
                $excludedWords[] = $word;
            }
            unset($tempSearch[$index]);
        }
    }
    $searchArray = array_merge($searchArray, $tempSearch);
    // Trim everything and make sure there are no words that are the same.
    foreach ($searchArray as $index => $value) {
        $searchArray[$index] = $smcFunc['strtolower'](trim($value));
        if ($searchArray[$index] == '') {
            unset($searchArray[$index]);
        } else {
            // Sort out entities first.
            $searchArray[$index] = $smcFunc['htmlspecialchars']($searchArray[$index]);
        }
    }
    $searchArray = array_unique($searchArray);
    // Create an array of replacements for highlighting.
    $context['mark'] = array();
    foreach ($searchArray as $word) {
        $context['mark'][$word] = '<strong class="highlight">' . $word . '</strong>';
    }
    // This contains *everything*
    $searchWords = array_merge($searchArray, $excludedWords);
    // Make sure at least one word is being searched for.
    if (empty($searchArray)) {
        $context['search_errors']['invalid_search_string'] = true;
    }
    // Sort out the search query so the user can edit it - if they want.
    $context['search_params'] = $search_params;
    if (isset($context['search_params']['search'])) {
        $context['search_params']['search'] = htmlspecialchars($context['search_params']['search']);
    }
    if (isset($context['search_params']['userspec'])) {
        $context['search_params']['userspec'] = htmlspecialchars($context['search_params']['userspec']);
    }
    // Now we have all the parameters, combine them together for pagination and the like...
    $context['params'] = array();
    foreach ($search_params as $k => $v) {
        $context['params'][] = $k . '|\'|' . $v;
    }
    $context['params'] = base64_encode(implode('|"|', $context['params']));
    // Compile the subject query part.
    $andQueryParts = array();
    foreach ($searchWords as $index => $word) {
        if ($word == '') {
            continue;
        }
        if ($search_params['subject_only']) {
            $andQueryParts[] = 'pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '}';
        } else {
            $andQueryParts[] = '(pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . ' LIKE {string:search_' . $index . '} ' . (in_array($word, $excludedWords) ? 'AND pm.body NOT' : 'OR pm.body') . ' LIKE {string:search_' . $index . '})';
        }
        $searchq_parameters['search_' . $index] = '%' . strtr($word, array('_' => '\\_', '%' => '\\%')) . '%';
    }
    $searchQuery = ' 1=1';
    if (!empty($andQueryParts)) {
        $searchQuery = implode(!empty($search_params['searchtype']) && $search_params['searchtype'] == 2 ? ' OR ' : ' AND ', $andQueryParts);
    }
    // Age limits?
    $timeQuery = '';
    if (!empty($search_params['minage'])) {
        $timeQuery .= ' AND pm.msgtime < ' . (time() - $search_params['minage'] * 86400);
    }
    if (!empty($search_params['maxage'])) {
        $timeQuery .= ' AND pm.msgtime > ' . (time() - $search_params['maxage'] * 86400);
    }
    // If we have errors - return back to the first screen...
    if (!empty($context['search_errors'])) {
        $_REQUEST['params'] = $context['params'];
        return MessageSearch();
    }
    // Get the amount of results.
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}pm_recipients AS pmr
			INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)
		WHERE ' . ($context['folder'] == 'inbox' ? '
			pmr.id_member = {int:current_member}
			AND pmr.deleted = {int:not_deleted}' : '
			pm.id_member_from = {int:current_member}
			AND pm.deleted_by_sender = {int:not_deleted}') . '
			' . $userQuery . $labelQuery . $timeQuery . '
			AND (' . $searchQuery . ')', array_merge($searchq_parameters, array('current_member' => $user_info['id'], 'not_deleted' => 0)));
    list($numResults) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Get all the matching messages... using standard search only (No caching and the like!)
    // @todo This doesn't support sent item searching yet.
    $request = $smcFunc['db_query']('', '
		SELECT pm.id_pm, pm.id_pm_head, pm.id_member_from
		FROM {db_prefix}pm_recipients AS pmr
			INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm)
		WHERE ' . ($context['folder'] == 'inbox' ? '
			pmr.id_member = {int:current_member}
			AND pmr.deleted = {int:not_deleted}' : '
			pm.id_member_from = {int:current_member}
			AND pm.deleted_by_sender = {int:not_deleted}') . '
			' . $userQuery . $labelQuery . $timeQuery . '
			AND (' . $searchQuery . ')
		ORDER BY ' . $search_params['sort'] . ' ' . $search_params['sort_dir'] . '
		LIMIT ' . $context['start'] . ', ' . $modSettings['search_results_per_page'], array_merge($searchq_parameters, array('current_member' => $user_info['id'], 'not_deleted' => 0)));
    $foundMessages = array();
    $posters = array();
    $head_pms = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $foundMessages[] = $row['id_pm'];
        $posters[] = $row['id_member_from'];
        $head_pms[$row['id_pm']] = $row['id_pm_head'];
    }
    $smcFunc['db_free_result']($request);
    // Find the real head pms!
    if ($context['display_mode'] == 2 && !empty($head_pms)) {
        $request = $smcFunc['db_query']('', '
			SELECT MAX(pm.id_pm) AS id_pm, pm.id_pm_head
			FROM {db_prefix}personal_messages AS pm
				INNER JOIN {db_prefix}pm_recipients AS pmr ON (pmr.id_pm = pm.id_pm)
			WHERE pm.id_pm_head IN ({array_int:head_pms})
				AND pmr.id_member = {int:current_member}
				AND pmr.deleted = {int:not_deleted}
			GROUP BY pm.id_pm_head
			LIMIT {int:limit}', array('head_pms' => array_unique($head_pms), 'current_member' => $user_info['id'], 'not_deleted' => 0, 'limit' => count($head_pms)));
        $real_pm_ids = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $real_pm_ids[$row['id_pm_head']] = $row['id_pm'];
        }
        $smcFunc['db_free_result']($request);
    }
    // Load the users...
    $posters = array_unique($posters);
    if (!empty($posters)) {
        loadMemberData($posters);
    }
    // Sort out the page index.
    $context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=search2;params=' . $context['params'], $_GET['start'], $numResults, $modSettings['search_results_per_page'], false);
    $context['message_labels'] = array();
    $context['message_replied'] = array();
    $context['personal_messages'] = array();
    if (!empty($foundMessages)) {
        // Now get recipients (but don't include bcc-recipients for your inbox, you're not supposed to know :P!)
        $request = $smcFunc['db_query']('', '
			SELECT
				pmr.id_pm, mem_to.id_member AS id_member_to, mem_to.real_name AS to_name,
				pmr.bcc, pmr.labels, pmr.is_read
			FROM {db_prefix}pm_recipients AS pmr
				LEFT JOIN {db_prefix}members AS mem_to ON (mem_to.id_member = pmr.id_member)
			WHERE pmr.id_pm IN ({array_int:message_list})', array('message_list' => $foundMessages));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if ($context['folder'] == 'sent' || empty($row['bcc'])) {
                $recipients[$row['id_pm']][empty($row['bcc']) ? 'to' : 'bcc'][] = empty($row['id_member_to']) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_to'] . '">' . $row['to_name'] . '</a>';
            }
            if ($row['id_member_to'] == $user_info['id'] && $context['folder'] != 'sent') {
                $context['message_replied'][$row['id_pm']] = $row['is_read'] & 2;
                $row['labels'] = $row['labels'] == '' ? array() : explode(',', $row['labels']);
                // This is a special need for linking to messages.
                foreach ($row['labels'] as $v) {
                    if (isset($context['labels'][(int) $v])) {
                        $context['message_labels'][$row['id_pm']][(int) $v] = array('id' => $v, 'name' => $context['labels'][(int) $v]['name']);
                    }
                    // Here we find the first label on a message - for linking to posts in results
                    if (!isset($context['first_label'][$row['id_pm']]) && !in_array('-1', $row['labels'])) {
                        $context['first_label'][$row['id_pm']] = (int) $v;
                    }
                }
            }
        }
        // Prepare the query for the callback!
        $request = $smcFunc['db_query']('', '
			SELECT pm.id_pm, pm.subject, pm.id_member_from, pm.body, pm.msgtime, pm.from_name
			FROM {db_prefix}personal_messages AS pm
			WHERE pm.id_pm IN ({array_int:message_list})
			ORDER BY ' . $search_params['sort'] . ' ' . $search_params['sort_dir'] . '
			LIMIT ' . count($foundMessages), array('message_list' => $foundMessages));
        $counter = 0;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // If there's no message subject, use the default.
            $row['subject'] = $row['subject'] == '' ? $txt['no_subject'] : $row['subject'];
            // Load this posters context info, if it ain't there then fill in the essentials...
            if (!loadMemberContext($row['id_member_from'], true)) {
                $memberContext[$row['id_member_from']]['name'] = $row['from_name'];
                $memberContext[$row['id_member_from']]['id'] = 0;
                $memberContext[$row['id_member_from']]['group'] = $txt['guest_title'];
                $memberContext[$row['id_member_from']]['link'] = $row['from_name'];
                $memberContext[$row['id_member_from']]['email'] = '';
                $memberContext[$row['id_member_from']]['show_email'] = showEmailAddress(true, 0);
                $memberContext[$row['id_member_from']]['is_guest'] = true;
            }
            // Censor anything we don't want to see...
            censorText($row['body']);
            censorText($row['subject']);
            // Parse out any BBC...
            $row['body'] = parse_bbc($row['body'], true, 'pm' . $row['id_pm']);
            $href = $scripturl . '?action=pm;f=' . $context['folder'] . (isset($context['first_label'][$row['id_pm']]) ? ';l=' . $context['first_label'][$row['id_pm']] : '') . ';pmid=' . ($context['display_mode'] == 2 && isset($real_pm_ids[$head_pms[$row['id_pm']]]) ? $real_pm_ids[$head_pms[$row['id_pm']]] : $row['id_pm']) . '#msg' . $row['id_pm'];
            $context['personal_messages'][] = array('id' => $row['id_pm'], 'member' => &$memberContext[$row['id_member_from']], 'subject' => $row['subject'], 'body' => $row['body'], 'time' => timeformat($row['msgtime']), 'recipients' => &$recipients[$row['id_pm']], 'labels' => &$context['message_labels'][$row['id_pm']], 'fully_labeled' => count($context['message_labels'][$row['id_pm']]) == count($context['labels']), 'is_replied_to' => &$context['message_replied'][$row['id_pm']], 'href' => $href, 'link' => '<a href="' . $href . '">' . $row['subject'] . '</a>', 'counter' => ++$counter);
        }
        $smcFunc['db_free_result']($request);
    }
    // Finish off the context.
    $context['page_title'] = $txt['pm_search_title'];
    $context['sub_template'] = 'search_results';
    $context['menu_data_' . $context['pm_menu_id']]['current_area'] = 'search';
    $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=search', 'name' => $txt['pm_search_bar_title']);
}
function upSSI_BoardNews($num_recent = 8, $exclude_boards = null, $include_boards = null, $length, $bkcall = '')
{
    global $context, $settings, $scripturl, $txt, $user_info, $modSettings, $smcFunc;
    loadLanguage('Stats');
    if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0) {
        $exclude_boards = array($modSettings['recycle_board']);
    } else {
        $exclude_boards = empty($exclude_boards) ? array() : (is_array($exclude_boards) ? $exclude_boards : array($exclude_boards));
    }
    // Only some boards?.
    if (is_array($include_boards) || (int) $include_boards === $include_boards) {
        $include_boards = is_array($include_boards) ? $include_boards : array($include_boards);
    } elseif ($include_boards != null) {
        $output_method = $include_boards;
        $include_boards = array();
    }
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
    $icon_sources = array();
    foreach ($stable_icons as $icon) {
        $icon_sources[$icon] = 'images_url';
    }
    //Prepare the constructPageIndex() function
    $start = !empty($_REQUEST['sa']) && $_REQUEST['sa'] == $bkcall . 'boardnews' ? (int) $_REQUEST['start'] : 0;
    $db_count = $smcFunc['db_query']('', '
		SELECT count(m.id_topic)
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member})' : '') . '
		WHERE m.id_topic > 0
			' . (empty($exclude_boards) ? '' : '
			AND b.id_board NOT IN ({array_int:exclude_boards})') . '
			' . (empty($include_boards) ? '' : '
			AND b.id_board IN ({array_int:include_boards})') . '
			AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
			AND t.approved = {int:is_approved}
			AND m.approved = {int:is_approved}' : '') . '
		ORDER BY t.id_first_msg DESC', array('current_member' => $user_info['id'], 'include_boards' => empty($include_boards) ? '' : $include_boards, 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, 'is_approved' => 1));
    $numNews = array();
    list($numNews) = $smcFunc['db_fetch_row']($db_count);
    $smcFunc['db_free_result']($db_count);
    $context['page_index'] = constructPageIndex($scripturl . '?sa=' . $bkcall . 'boardnews', $start, $numNews, $num_recent);
    // Find all the posts in distinct topics.  Newer ones will have higher IDs.
    $request = $smcFunc['db_query']('', '
		SELECT
			m.poster_time, ms.subject, m.id_topic, m.id_member, m.id_msg, b.id_board, b.name AS board_name, t.num_replies, t.num_views,
			t.locked,
			IFNULL(mem.real_name, m.poster_name) AS poster_name, ' . ($user_info['is_guest'] ? '1 AS is_read, 0 AS new_from' : '
			IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) >= m.id_msg_modified AS is_read,
			IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from') . ', m.body AS body, m.smileys_enabled, m.icon
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (!$user_info['is_guest'] ? '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member})' : '') . '
		WHERE m.id_topic > 0
			' . (empty($exclude_boards) ? '' : '
			AND b.id_board NOT IN ({array_int:exclude_boards})') . '
			' . (empty($include_boards) ? '' : '
			AND b.id_board IN ({array_int:include_boards})') . '
			AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
			AND t.approved = {int:is_approved}
			AND m.approved = {int:is_approved}' : '') . '
		ORDER BY t.id_first_msg DESC
		 ' . ($num_recent < 0 ? "" : " LIMIT {int:start}, {int:limit} ") . '', array('current_member' => $user_info['id'], 'include_boards' => empty($include_boards) ? '' : $include_boards, 'exclude_boards' => empty($exclude_boards) ? '' : $exclude_boards, 'is_approved' => 1, 'start' => $start, 'limit' => $num_recent));
    $return = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // If we want to limit the length of the post.
        if (!empty($length) && $smcFunc['strlen']($row['body']) > $length) {
            $row['body'] = $smcFunc['substr']($row['body'], 0, $length);
            // The first space or line break. (<br />, etc.)
            $cutoff = max(strrpos($row['body'], ' '), strrpos($row['body'], '<'));
            if ($cutoff !== false) {
                $row['body'] = $smcFunc['substr']($row['body'], 0, $cutoff);
            }
            $row['body'] .= '...';
        }
        $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
        // Censor the subject.
        censorText($row['subject']);
        censorText($row['body']);
        if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']])) {
            $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url';
        }
        // Build the array.
        $return[] = array('board' => array('id' => $row['id_board'], 'name' => $row['board_name'], 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>'), 'topic' => $row['id_topic'], 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'), 'subject' => $row['subject'], 'replies' => $row['num_replies'], 'views' => $row['num_views'], 'short_subject' => shorten_subject($row['subject'], 25), 'preview' => $row['body'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#new', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#new" rel="nofollow">' . $row['subject'] . '</a>', 'new' => !empty($row['is_read']), 'is_new' => empty($row['is_read']), 'new_from' => $row['new_from'], 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" align="middle" alt="' . $row['icon'] . '" border="0" />', 'comment_link' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';num_replies=' . $row['num_replies'] . '">' . $txt['ssi_write_comment'] . '</a>');
    }
    $smcFunc['db_free_result']($request);
    //ok return now
    return $return;
}
Exemplo n.º 16
0
function template_approvelinks()
{
    global $scripturl, $txt, $context;
    // Edit and Delete permissions
    $editlink = allowedTo('edit_links_any');
    $deletelink = allowedTo('delete_links_any');
    // Show all the links waiting for approval.
    echo '
	<table border="0" width="80%" cellspacing="0" align="center" cellpadding="4" class="tborder">
		<tr class="titlebg">
			<td>' . $txt['smflinks_approvelinks'] . '</td>
		</tr>
		<tr class="windowbg">
			<td class="windowbg">
<table cellspacing="0" align="center" cellpadding="4" class="tborder" width="100%">
  <tr>
    <td class="catbg"><strong>' . $txt['smflinks_url'] . '</strong></td>
    <td class="catbg"><strong>' . $txt['smflinks_ctitle'] . '</strong></td>
    <td class="catbg"><strong>' . $txt['smflinks_description'] . '</strong></td>
    <td class="catbg"><strong>' . $txt['smflinks_category'] . '</strong></td>
    <td class="catbg"><strong>' . $txt['smflinks_submittedby'] . '</strong></td>
    <td class="catbg"><strong>' . $txt['smflinks_options'] . '</strong></td>
  </tr>';
    // Get Total Pages
    $total = $context['approvetotal'];
    if (!empty($_REQUEST['start'])) {
        $context['start'] = (int) $_REQUEST['start'];
    } else {
        $context['start'] = 0;
    }
    foreach ($context['linksapprovallist'] as $row) {
        echo '<tr>';
        echo '<td class="windowbg2"><a href="' . $row['url'] . '" target="blank">' . $row['url'] . '</a></td>';
        echo '<td class="windowbg2">' . $row['title'] . '</td>';
        echo '<td class="windowbg2">' . $row['description'] . '</td>';
        echo '<td class="windowbg2">' . $row['catname'] . '</td>';
        if ($row['realName'] == '') {
            echo '<td class="windowbg2">' . $txt['smflinks_txtguest'] . '</td>';
        } else {
            echo '<td class="windowbg2"><a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['realName'] . '</a></td>';
        }
        echo '<td class="windowbg2"><a href="' . $scripturl . '?action=links;sa=approve&id=' . $row['ID_LINK'] . ';sesc=' . $context['session_id'] . '">' . $txt['smflinks_txtapprove'] . '</a>&nbsp;';
        if ($editlink) {
            echo '<a href="' . $scripturl . '?action=links;sa=editlink&id=' . $row['ID_LINK'] . '">' . $txt['smflinks_txtedit'] . '</a>&nbsp;';
        }
        if ($deletelink) {
            echo '<a href="' . $scripturl . '?action=links;sa=deletelink&id=' . $row['ID_LINK'] . '">' . $txt['smflinks_txtdel'] . '</a>';
        }
        echo '</td>';
        echo '</tr>';
    }
    // Show the pages
    echo '<tr class="titlebg">
						<td align="left" colspan="6">
						' . $txt['smflinks_pages'];
    $context['page_index'] = constructPageIndex($scripturl . '?action=links;sa=alist', $context['start'], $total, 20);
    echo $context['page_index'];
    echo '
						</td>
					</tr>';
    echo '
	</table>
	</td>
	</tr>
		<tr>
		<td class="windowbg">
		<strong>Has SMF Links helped you?</strong> Then support the developers:<br />
    <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
	<input type="hidden" name="cmd" value="_xclick">
	<input type="hidden" name="business" value="*****@*****.**">
	<input type="hidden" name="item_name" value="SMF Links">
	<input type="hidden" name="no_shipping" value="1">
	<input type="hidden" name="no_note" value="1">
	<input type="hidden" name="currency_code" value="USD">
	<input type="hidden" name="tax" value="0">
	<input type="hidden" name="bn" value="PP-DonationsBF">
	<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" border="0" name="submit" alt="Make payments with PayPal - it is fast, free and secure!">
	<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>
	</td>
	</tr>
	</table>
	';
    LinksCopyright();
}
Exemplo n.º 17
0
function MembersAwaitingActivation()
{
    global $txt, $context, $db_prefix, $scripturl, $modSettings;
    // Not a lot here!
    $context['page_title'] = $txt[9];
    $context['sub_template'] = 'admin_browse';
    $context['browse_type'] = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve');
    if (isset($context['admin_tabs']['tabs'][$context['browse_type']])) {
        $context['admin_tabs']['tabs'][$context['browse_type']]['is_selected'] = true;
    }
    // Allowed filters are those we can have, in theory.
    $context['allowed_filters'] = $context['browse_type'] == 'approve' ? array(3, 4, 5) : array(0, 2);
    $context['current_filter'] = isset($_REQUEST['filter']) && in_array($_REQUEST['filter'], $context['allowed_filters']) && !empty($context['activation_numbers'][$_REQUEST['filter']]) ? (int) $_REQUEST['filter'] : -1;
    // Sort out the different sub areas that we can actually filter by.
    $context['available_filters'] = array();
    foreach ($context['activation_numbers'] as $type => $amount) {
        // We have some of these...
        if (in_array($type, $context['allowed_filters']) && $amount > 0) {
            $context['available_filters'][] = array('type' => $type, 'amount' => $amount, 'desc' => isset($txt['admin_browse_filter_type_' . $type]) ? $txt['admin_browse_filter_type_' . $type] : '?', 'selected' => $type == $context['current_filter']);
        }
    }
    // If the filter was not sent, set it to whatever has people in it!
    if ($context['current_filter'] == -1 && !empty($context['available_filters'][0]['amount'])) {
        $context['current_filter'] = $context['available_filters'][0]['type'];
    }
    // This little variable is used to determine if we should flag where we are looking.
    if ($context['current_filter'] != 0 && $context['current_filter'] != 3 && count($context['available_filters']) == 1) {
        $context['show_filter'] = true;
    }
    // The columns that can be sorted.
    $context['columns'] = array('ID_MEMBER' => array('label' => $txt['admin_browse_id']), 'memberName' => array('label' => $txt['admin_browse_username']), 'emailAddress' => array('label' => $txt['admin_browse_email']), 'memberIP' => array('label' => $txt['admin_browse_ip']), 'dateRegistered' => array('label' => $txt['admin_browse_registered']));
    // Default sort column to 'dateRegistered' if the current one is unknown or not set.
    if (!isset($_REQUEST['sort']) || !isset($context['columns'][$_REQUEST['sort']])) {
        $_REQUEST['sort'] = 'dateRegistered';
    }
    // Provide extra information about each column - the link, whether it's selected, etc.
    foreach ($context['columns'] as $col => $dummy) {
        $context['columns'][$col]['href'] = $scripturl . '?action=viewmembers;sa=browse;type=' . $context['browse_type'] . ';sort=' . $col . ';start=0';
        if (!isset($_REQUEST['desc']) && $col == $_REQUEST['sort']) {
            $context['columns'][$col]['href'] .= ';desc';
        }
        $context['columns'][$col]['link'] = '<a href="' . $context['columns'][$col]['href'] . '">' . $context['columns'][$col]['label'] . '</a>';
        $context['columns'][$col]['selected'] = $_REQUEST['sort'] == $col;
    }
    $context['sort_by'] = $_REQUEST['sort'];
    $context['sort_direction'] = !isset($_REQUEST['desc']) ? 'down' : 'up';
    // Calculate the number of results.
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM {$db_prefix}members\n\t\tWHERE is_activated = {$context['current_filter']}", __FILE__, __LINE__);
    list($context['num_members']) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Construct the page links.
    $context['page_index'] = constructPageIndex($scripturl . '?action=viewmembers;sa=browse;type=' . $context['browse_type'] . ';sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['num_members'], $modSettings['defaultMaxMembers']);
    $context['start'] = (int) $_REQUEST['start'];
    // Determine which actions we should allow on this page.
    if ($context['browse_type'] == 'approve') {
        // If we are approving deleted accounts we have a slightly different list... actually a mirror ;)
        if ($context['current_filter'] == 4) {
            $context['allowed_actions'] = array('reject' => $txt['admin_browse_w_approve_deletion'], 'ok' => $txt['admin_browse_w_reject']);
        } else {
            $context['allowed_actions'] = array('ok' => $txt['admin_browse_w_approve'], 'okemail' => $txt['admin_browse_w_approve'] . ' ' . $txt['admin_browse_w_email'], 'require_activation' => $txt['admin_browse_w_approve_require_activate'], 'reject' => $txt['admin_browse_w_reject'], 'rejectemail' => $txt['admin_browse_w_reject'] . ' ' . $txt['admin_browse_w_email']);
        }
    } elseif ($context['browse_type'] == 'activate') {
        $context['allowed_actions'] = array('ok' => $txt['admin_browse_w_activate'], 'okemail' => $txt['admin_browse_w_activate'] . ' ' . $txt['admin_browse_w_email'], 'delete' => $txt['admin_browse_w_delete'], 'deleteemail' => $txt['admin_browse_w_delete'] . ' ' . $txt['admin_browse_w_email'], 'remind' => $txt['admin_browse_w_remind'] . ' ' . $txt['admin_browse_w_email']);
    }
    $request = db_query("\n\t\tSELECT ID_MEMBER, memberName, emailAddress, memberIP, dateRegistered\n\t\tFROM {$db_prefix}members\n\t\tWHERE is_activated = {$context['current_filter']}\n\t\tORDER BY {$_REQUEST['sort']}" . (!isset($_REQUEST['desc']) ? '' : ' DESC') . "\n\t\tLIMIT {$context['start']}, {$modSettings['defaultMaxMembers']}", __FILE__, __LINE__);
    while ($row = mysql_fetch_assoc($request)) {
        $context['members'][] = array('id' => $row['ID_MEMBER'], 'username' => $row['memberName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['memberName'] . '</a>', 'email' => $row['emailAddress'], 'ip' => $row['memberIP'], 'dateRegistered' => timeformat($row['dateRegistered']));
    }
    mysql_free_result($request);
}
Exemplo n.º 18
0
function MergeIndex()
{
    global $txt, $board, $context;
    global $scripturl, $topic, $db_prefix, $user_info, $modSettings;
    $_REQUEST['targetboard'] = isset($_REQUEST['targetboard']) ? (int) $_REQUEST['targetboard'] : $board;
    $context['target_board'] = $_REQUEST['targetboard'];
    if (!isset($_GET['from'])) {
        fatal_lang_error(1);
    }
    $_GET['from'] = (int) $_GET['from'];
    // How many topics are on this board?  (used for paging.)
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_BOARD = {$_REQUEST['targetboard']}", __FILE__, __LINE__);
    list($topiccount) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Make the page list.
    $context['page_index'] = constructPageIndex($scripturl . '?action=mergetopics;from=' . $_GET['from'] . ';targetboard=' . $_REQUEST['targetboard'] . ';board=' . $board . '.%d', $_REQUEST['start'], $topiccount, $modSettings['defaultMaxTopics'], true);
    // Get the topic's subject.
    $request = db_query("\n\t\tSELECT m.subject\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\tWHERE m.ID_MSG = t.ID_FIRST_MSG\n\t\t\tAND t.ID_TOPIC = {$_GET['from']}\n\t\t\tAND t.ID_BOARD = {$board}\n\t\tLIMIT 1", __FILE__, __LINE__);
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('smf232');
    }
    list($subject) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Tell the template a few things..
    $context['origin_topic'] = $_GET['from'];
    $context['origin_subject'] = $subject;
    $context['origin_js_subject'] = addcslashes(addslashes($subject), '/');
    $context['page_title'] = $txt['smf252'];
    // Check which boards you have merge permissions on.
    $merge_boards = boardsAllowedTo('merge_any');
    if (empty($merge_boards)) {
        fatal_lang_error('cannot_merge_any');
    }
    // Get a list of boards they can navigate to to merge.
    $request = db_query("\n\t\tSELECT b.ID_BOARD, b.name AS bName, c.name AS cName\n\t\tFROM {$db_prefix}boards AS b\n\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\tWHERE {$user_info['query_see_board']}" . (!in_array(0, $merge_boards) ? "\n\t\t\tAND b.ID_BOARD IN (" . implode(', ', $merge_boards) . ")" : ''), __FILE__, __LINE__);
    $context['boards'] = array();
    while ($row = mysql_fetch_assoc($request)) {
        $context['boards'][] = array('id' => $row['ID_BOARD'], 'name' => $row['bName'], 'category' => $row['cName']);
    }
    mysql_free_result($request);
    // Get some topics to merge it with.
    $request = db_query("\n\t\tSELECT t.ID_TOPIC, m.subject, m.ID_MEMBER, IFNULL(mem.realName, m.posterName) AS posterName\n\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)\n\t\tWHERE m.ID_MSG = t.ID_FIRST_MSG\n\t\t\tAND t.ID_BOARD = {$_REQUEST['targetboard']}\n\t\t\tAND t.ID_TOPIC != {$_GET['from']}\n\t\tORDER BY " . (!empty($modSettings['enableStickyTopics']) ? 't.isSticky DESC, ' : '') . "t.ID_LAST_MSG DESC\n\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__);
    $context['topics'] = array();
    while ($row = mysql_fetch_assoc($request)) {
        censorText($row['subject']);
        $context['topics'][] = array('id' => $row['ID_TOPIC'], 'poster' => array('id' => $row['ID_MEMBER'], 'name' => $row['posterName'], 'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '" target="_blank">' . $row['posterName'] . '</a>'), 'subject' => $row['subject'], 'js_subject' => addcslashes(addslashes($row['subject']), '/'));
    }
    mysql_free_result($request);
    if (empty($context['topics']) && count($context['boards']) <= 1) {
        fatal_lang_error('merge_need_more_topics');
    }
    $context['sub_template'] = 'merge';
}
Exemplo n.º 19
0
function view_icons()
{
    global $context, $txt, $smcFunc, $scripturl;
    checkSession('get');
    $context['sub_template'] = 'view_icons';
    $context['page_title'] = $txt['adkadmin_name'] . ': ' . $txt['adkadmin_icons'];
    $context['start'] = !empty($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    $limit = 10;
    $total = getTotal('adk_icons');
    $context['load_icons'] = getIcons('', array(), 'id_icon ASC', $context['start'], $limit);
    $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=adkadmin;sa=manageicons;' . $context['session_var'] . '=' . $context['session_id'], $context['start'], $total, $limit);
}
Exemplo n.º 20
0
/**
 * Show the list of topics in this board, along with any child boards.
 */
function MessageIndex()
{
    global $txt, $scripturl, $board, $modSettings, $context;
    global $options, $settings, $board_info, $user_info, $smcFunc, $sourcedir;
    // If this is a redirection board head off.
    if ($board_info['redirect']) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}boards
			SET num_posts = num_posts + 1
			WHERE id_board = {int:current_board}', array('current_board' => $board));
        redirectexit($board_info['redirect']);
    }
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_messageindex';
    } else {
        loadTemplate('MessageIndex');
    }
    $context['name'] = $board_info['name'];
    $context['description'] = $board_info['description'];
    // How many topics do we have in total?
    $board_info['total_topics'] = allowedTo('approve_posts') ? $board_info['num_topics'] + $board_info['unapproved_topics'] : $board_info['num_topics'] + $board_info['unapproved_user_topics'];
    // View all the topics, or just a few?
    $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) && !WIRELESS ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    $maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['total_topics'] : $context['topics_per_page'];
    // Right, let's only index normal stuff!
    if (count($_GET) > 1) {
        $session_name = session_name();
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('board', 'start', $session_name))) {
                $context['robot_no_index'] = true;
            }
        }
    }
    if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
        $context['robot_no_index'] = true;
    }
    // If we can view unapproved messages and there are some build up a list.
    if (allowedTo('approve_posts') && ($board_info['unapproved_topics'] || $board_info['unapproved_posts'])) {
        $untopics = $board_info['unapproved_topics'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=topics;brd=' . $board . '">' . $board_info['unapproved_topics'] . '</a>' : 0;
        $unposts = $board_info['unapproved_posts'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=posts;brd=' . $board . '">' . ($board_info['unapproved_posts'] - $board_info['unapproved_topics']) . '</a>' : 0;
        $context['unapproved_posts_message'] = sprintf($txt['there_are_unapproved_topics'], $untopics, $unposts, $scripturl . '?action=moderate;area=postmod;sa=' . ($board_info['unapproved_topics'] ? 'topics' : 'posts') . ';brd=' . $board);
    }
    // Make sure the starting place makes sense and construct the page index.
    if (isset($_REQUEST['sort'])) {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    } else {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
    }
    $context['start'] =& $_REQUEST['start'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?board=' . $board . '.' . $context['start'];
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $context['topics_per_page']) : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $context['topics_per_page']) : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) * $context['topics_per_page'] : '', 'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0');
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) + 1);
    if (isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages']) {
        $maxindex = $modSettings['enableAllMessages'];
        $_REQUEST['start'] = 0;
    }
    // Build a list of the board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        $context['linktree'][count($context['linktree']) - 1]['extra_after'] = '<span class="board_moderators"> (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')</span>';
    }
    // Mark current and parent boards as seen.
    if (!$user_info['is_guest']) {
        // We can't know they read it if we allow prefetches.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board'));
        if (!empty($board_info['parent_boards'])) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}log_boards
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
            // We've seen all these boards now!
            foreach ($board_info['parent_boards'] as $k => $dummy) {
                if (isset($_SESSION['topicseen_cache'][$k])) {
                    unset($_SESSION['topicseen_cache'][$k]);
                }
            }
        }
        if (isset($_SESSION['topicseen_cache'][$board])) {
            unset($_SESSION['topicseen_cache'][$board]);
        }
        $request = $smcFunc['db_query']('', '
			SELECT sent
			FROM {db_prefix}log_notify
			WHERE id_board = {int:current_board}
				AND id_member = {int:current_member}
			LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id']));
        $context['is_marked_notify'] = $smcFunc['db_num_rows']($request) != 0;
        if ($context['is_marked_notify']) {
            list($sent) = $smcFunc['db_fetch_row']($request);
            if (!empty($sent)) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_sent}
					WHERE id_board = {int:current_board}
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_sent' => 0));
            }
        }
        $smcFunc['db_free_result']($request);
    } else {
        $context['is_marked_notify'] = false;
    }
    // 'Print' the header and board info.
    $context['page_title'] = strip_tags($board_info['name']);
    // Set the variables up for the template.
    $context['can_mark_notify'] = allowedTo('mark_notify') && !$user_info['is_guest'];
    $context['can_post_new'] = allowedTo('post_new') || $modSettings['postmod_active'] && allowedTo('post_unapproved_topics');
    $context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post') && $context['can_post_new'];
    $context['can_moderate_forum'] = allowedTo('moderate_forum');
    $context['can_approve_posts'] = allowedTo('approve_posts');
    require_once $sourcedir . '/Subs-BoardIndex.php';
    $boardIndexOptions = array('include_categories' => false, 'base_level' => $board_info['child_level'] + 1, 'parent_id' => $board_info['id'], 'set_latest_post' => false, 'countChildPosts' => !empty($modSettings['countChildPosts']));
    $context['boards'] = getBoardIndex($boardIndexOptions);
    // Nosey, nosey - who's viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        $request = $smcFunc['db_query']('', '
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_member_group} THEN mem.id_post_group ELSE mem.id_group END)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_member_group' => 0, 'in_url_string' => 's:5:"board";i:' . $board . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            if (!empty($row['online_color'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
            }
            $is_buddy = in_array($row['id_member'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<strong>' . $link . '</strong>';
            }
            if (!empty($row['show_online']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
            }
            $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Put them in "last clicked" order.
        krsort($context['view_members_list']);
        krsort($context['view_members']);
    }
    // Default sort methods.
    $sort_methods = array('subject' => 'mf.subject', 'starter' => 'IFNULL(memf.real_name, mf.poster_name)', 'last_poster' => 'IFNULL(meml.real_name, ml.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg');
    // They didn't pick one, default to by last post descending.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 'id_last_msg';
        $ascending = isset($_REQUEST['asc']);
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    // Calculate the fastest way to get the topics.
    $start = (int) $_REQUEST['start'];
    if ($start > ($board_info['total_topics'] - 1) / 2) {
        $ascending = !$ascending;
        $fake_ascending = true;
        $maxindex = $board_info['total_topics'] < $start + $maxindex + 1 ? $board_info['total_topics'] - $start : $maxindex;
        $start = $board_info['total_topics'] < $start + $maxindex + 1 ? 0 : $board_info['total_topics'] - $start - $maxindex;
    } else {
        $fake_ascending = false;
    }
    // Setup the default topic icons...
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'poll', 'moved', 'recycled', 'wireless', 'clip');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $topic_ids = array();
    $context['topics'] = array();
    // Sequential pages are often not optimized, so we add an additional query.
    $pre_query = $start > 0;
    if ($pre_query && $maxindex > 0) {
        $request = $smcFunc['db_query']('', '
			SELECT t.id_topic
			FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? '
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? '
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? '
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? '
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . '
			WHERE t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . '
			LIMIT {int:start}, {int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_guest' => 0, 'start' => $start, 'maxindex' => $maxindex));
        $topic_ids = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $topic_ids[] = $row['id_topic'];
        }
    }
    // Grab the appropriate topic information...
    if (!$pre_query || !empty($topic_ids)) {
        // For search engine effectiveness we'll link guests differently.
        $context['pageindex_multiplier'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        $result = $smcFunc['db_query']('substring', '
			SELECT
				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
				' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
				t.id_last_msg, t.approved, t.unapproved_posts, t.id_redirect_topic, ml.poster_time AS last_poster_time,
				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
				ml.poster_name AS last_member_name, ml.id_member AS last_id_member, ' . (!empty($settings['avatars_on_indexes']) ? 'meml.avatar,' : '') . '
				IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
				mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon,
				mf.poster_name AS first_member_name, mf.id_member AS first_id_member,
				IFNULL(memf.real_name, mf.poster_name) AS first_display_name, ' . (!empty($modSettings['preview_characters']) ? '
				SUBSTRING(ml.body, 1, ' . ($modSettings['preview_characters'] + 256) . ') AS last_body,
				SUBSTRING(mf.body, 1, ' . ($modSettings['preview_characters'] + 256) . ') AS first_body,' : '') . 'ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys' . (!empty($settings['avatars_on_indexes']) ? ',
				IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type' : '') . '
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : '
				LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
				LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . (!empty($settings['avatars_on_indexes']) ? '
				LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = ml.id_member)' : '') . '
			WHERE ' . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : 't.id_board = {int:current_board}') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
			ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . '
			LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'is_approved' => 1, 'find_set_topics' => implode(',', $topic_ids), 'start' => $start, 'maxindex' => $maxindex));
        // Begin 'printing' the message index for current board.
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') {
                continue;
            }
            if (!$pre_query) {
                $topic_ids[] = $row['id_topic'];
            }
            // Does the theme support message previews?
            if (!empty($settings['message_index_preview']) && !empty($modSettings['preview_characters'])) {
                // Limit them to $modSettings['preview_characters'] characters
                $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']) > $modSettings['preview_characters']) {
                    $row['first_body'] = $smcFunc['substr']($row['first_body'], 0, $modSettings['preview_characters']) . '...';
                }
                $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']) > $modSettings['preview_characters']) {
                    $row['last_body'] = $smcFunc['substr']($row['last_body'], 0, $modSettings['preview_characters']) . '...';
                }
                // Censor the subject and message preview.
                censorText($row['first_subject']);
                censorText($row['first_body']);
                // Don't censor them twice!
                if ($row['id_first_msg'] == $row['id_last_msg']) {
                    $row['last_subject'] = $row['first_subject'];
                    $row['last_body'] = $row['first_body'];
                } else {
                    censorText($row['last_subject']);
                    censorText($row['last_body']);
                }
            } else {
                $row['first_body'] = '';
                $row['last_body'] = '';
                censorText($row['first_subject']);
                if ($row['id_first_msg'] == $row['id_last_msg']) {
                    $row['last_subject'] = $row['first_subject'];
                } else {
                    censorText($row['last_subject']);
                }
            }
            // Decide how many pages the topic should have.
            if ($row['num_replies'] + 1 > $context['messages_per_page']) {
                $pages = '&#171; ';
                // We can't pass start by reference.
                $start = -1;
                $pages .= constructPageIndex($scripturl . '?topic=' . $row['id_topic'] . '.%1$d', $start, $row['num_replies'] + 1, $context['messages_per_page'], true, false);
                // If we can use all, show all.
                if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages']) {
                    $pages .= ' &nbsp;<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;all">' . $txt['all'] . '</a>';
                }
                $pages .= ' &#187;';
            } else {
                $pages = '';
            }
            // We need to check the topic icons exist...
            if (!empty($modSettings['messageIconChecks_enable'])) {
                if (!isset($context['icon_sources'][$row['first_icon']])) {
                    $context['icon_sources'][$row['first_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['first_icon'] . '.png') ? 'images_url' : 'default_images_url';
                }
                if (!isset($context['icon_sources'][$row['last_icon']])) {
                    $context['icon_sources'][$row['last_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['last_icon'] . '.png') ? 'images_url' : 'default_images_url';
                }
            } else {
                if (!isset($context['icon_sources'][$row['first_icon']])) {
                    $context['icon_sources'][$row['first_icon']] = 'images_url';
                }
                if (!isset($context['icon_sources'][$row['last_icon']])) {
                    $context['icon_sources'][$row['last_icon']] = 'images_url';
                }
            }
            if (!empty($settings['avatars_on_indexes'])) {
                // Allow themers to show the latest poster's avatar along with the topic
                if (!empty($row['avatar'])) {
                    if ($modSettings['avatar_action_too_large'] == 'option_html_resize' || $modSettings['avatar_action_too_large'] == 'option_js_resize') {
                        $avatar_width = !empty($modSettings['avatar_max_width_external']) ? ' width="' . $modSettings['avatar_max_width_external'] . '"' : '';
                        $avatar_height = !empty($modSettings['avatar_max_height_external']) ? ' height="' . $modSettings['avatar_max_height_external'] . '"' : '';
                    } else {
                        $avatar_width = '';
                        $avatar_height = '';
                    }
                }
            }
            // 'Print' the topic info.
            $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_display_name'], 'id' => $row['first_id_member'], 'href' => !empty($row['first_id_member']) ? $scripturl . '?action=profile;u=' . $row['first_id_member'] : '', 'link' => !empty($row['first_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['first_id_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '" class="preview">' . $row['first_display_name'] . '</a>' : $row['first_display_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'preview' => $row['first_body'], 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png', 'href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . '.0">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => !empty($row['last_id_member']) ? $scripturl . '?action=profile;u=' . $row['last_id_member'] : '', 'link' => !empty($row['last_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['last_id_member'] . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'preview' => $row['last_body'], 'icon' => $row['last_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.png', 'href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . ($user_info['is_guest'] ? '.' . (!empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg'] : ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new'), 'link' => '<a href="' . $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . ($user_info['is_guest'] ? '.' . (!empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg'] : ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new') . '" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png', 'subject' => $row['first_subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . (empty($row['id_redirect_topic']) ? $row['id_topic'] : $row['id_redirect_topic']) . '.msg' . $row['new_from'] . '#new', 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts']);
            if (!empty($settings['avatars_on_indexes'])) {
                $context['topics'][$row['id_topic']]['last_post']['member']['avatar'] = array('name' => $row['avatar'], 'image' => $row['avatar'] == '' ? $row['id_attach'] > 0 ? '<img class="avatar" src="' . (empty($row['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $row['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $row['filename']) . '" alt="" />' : '' : (stristr($row['avatar'], 'http://') ? '<img class="avatar" src="' . $row['avatar'] . '"' . $avatar_width . $avatar_height . ' alt="" />' : '<img class="avatar" src="' . $modSettings['avatar_url'] . '/' . htmlspecialchars($row['avatar']) . '" alt="" />'), 'href' => $row['avatar'] == '' ? $row['id_attach'] > 0 ? empty($row['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $row['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $row['filename'] : '' : (stristr($row['avatar'], 'http://') ? $row['avatar'] : $modSettings['avatar_url'] . '/' . $row['avatar']), 'url' => $row['avatar'] == '' ? '' : (stristr($row['avatar'], 'http://') ? $row['avatar'] : $modSettings['avatar_url'] . '/' . $row['avatar']));
            }
            determineTopicClass($context['topics'][$row['id_topic']]);
        }
        $smcFunc['db_free_result']($result);
        // Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...)
        if ($fake_ascending) {
            $context['topics'] = array_reverse($context['topics'], true);
        }
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids)) {
            $result = $smcFunc['db_query']('', '
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_topic IN ({array_int:topic_list})
					AND id_member = {int:current_member}
				GROUP BY id_topic
				LIMIT ' . count($topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $topic_ids));
            while ($row = $smcFunc['db_fetch_assoc']($result)) {
                $context['topics'][$row['id_topic']]['is_posted_in'] = true;
                $context['topics'][$row['id_topic']]['class'] = 'my_' . $context['topics'][$row['id_topic']]['class'];
            }
            $smcFunc['db_free_result']($result);
        }
    }
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&'))), 'child_level' => $board_info['child_level']);
    // Is Quick Moderation active/needed?
    if (!empty($options['display_quick_mod']) && !empty($context['topics'])) {
        $context['can_markread'] = $context['user']['is_logged'];
        $context['can_lock'] = allowedTo('lock_any');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['can_move'] = allowedTo('move_any');
        $context['can_remove'] = allowedTo('remove_any');
        $context['can_merge'] = allowedTo('merge_any');
        // Ignore approving own topics as it's unlikely to come up...
        $context['can_approve'] = $modSettings['postmod_active'] && allowedTo('approve_posts') && !empty($board_info['unapproved_topics']);
        // Can we restore topics?
        $context['can_restore'] = allowedTo('move_any') && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board;
        // Set permissions for all the topics.
        foreach ($context['topics'] as $t => $topic) {
            $started = $topic['first_post']['member']['id'] == $user_info['id'];
            $context['topics'][$t]['quick_mod'] = array('lock' => allowedTo('lock_any') || $started && allowedTo('lock_own'), 'sticky' => allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']), 'move' => allowedTo('move_any') || $started && allowedTo('move_own'), 'modify' => allowedTo('modify_any') || $started && allowedTo('modify_own'), 'remove' => allowedTo('remove_any') || $started && allowedTo('remove_own'), 'approve' => $context['can_approve'] && $topic['unapproved_posts']);
            $context['can_lock'] |= $started && allowedTo('lock_own');
            $context['can_move'] |= $started && allowedTo('move_own');
            $context['can_remove'] |= $started && allowedTo('remove_own');
        }
        // Find the boards/cateogories they can move their topic to.
        if ($options['display_quick_mod'] == 1 && $context['can_move'] && !empty($context['topics'])) {
            require_once $sourcedir . '/Subs-MessageIndex.php';
            $boardListOptions = array('excluded_boards' => array($board), 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']);
            // With no other boards to see, it's useless to move.
            if (empty($context['move_to_boards'])) {
                $context['can_move'] = false;
            }
        }
        // Can we use quick moderation checkboxes?
        if ($options['display_quick_mod'] == 1) {
            $context['can_quick_mod'] = $context['user']['is_logged'] || $context['can_approve'] || $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'] || $context['can_merge'] || $context['can_restore'];
        } else {
            $context['can_quick_mod'] = $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'];
        }
    }
    if (!empty($context['can_quick_mod']) && $options['display_quick_mod'] == 1) {
        $context['qmod_actions'] = array('approve', 'remove', 'lock', 'sticky', 'move', 'merge', 'restore', 'markread');
        call_integration_hook('integrate_quick_mod_actions');
    }
    // If there are children, but no topics and no ability to post topics...
    $context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new'];
    // Build the message index button array.
    $context['normal_buttons'] = array('new_topic' => array('test' => 'can_post_new', 'text' => 'new_topic', 'image' => 'new_topic.png', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0', 'active' => true), 'post_poll' => array('test' => 'can_post_poll', 'text' => 'new_poll', 'image' => 'new_poll.png', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0;poll'), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_board'] : $txt['notification_enable_board']) . '\');"', 'url' => $scripturl . '?action=notifyboard;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';board=' . $context['current_board'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'markread' => array('text' => 'mark_read_short', 'image' => 'markread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=board;board=' . $context['current_board'] . '.0;' . $context['session_var'] . '=' . $context['session_id']));
    // Allow adding new buttons easily.
    call_integration_hook('integrate_messageindex_buttons');
}
Exemplo n.º 21
0
function Who()
{
    global $db_prefix, $context, $scripturl, $user_info, $txt, $modSettings, $ID_MEMBER, $memberContext;
    // Permissions, permissions, permissions.
    isAllowedTo('who_view');
    // You can't do anything if this is off.
    if (empty($modSettings['who_enabled'])) {
        fatal_lang_error('who_off', false);
    }
    // Load the 'Who' template.
    loadTemplate('Who');
    // Sort out... the column sorting.
    $sort_methods = array('user' => 'mem.realName', 'time' => 'lo.logTime');
    // By default order by last time online.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'time';
        $_REQUEST['sort'] = 'lo.logTime';
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
    }
    $context['sort_direction'] = isset($_REQUEST['asc']) ? 'up' : 'down';
    // Get the total amount of members online.
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM {$db_prefix}log_online AS lo\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (lo.ID_MEMBER = mem.ID_MEMBER)" . (!allowedTo('moderate_forum') ? "\n\t\tWHERE IFNULL(mem.showOnline, 1) = 1" : ''), __FILE__, __LINE__);
    list($totalMembers) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Prepare some page index variables.
    $context['page_index'] = constructPageIndex($scripturl . '?action=who;sort=' . $context['sort_by'] . (isset($_REQUEST['asc']) ? ';asc' : ''), $_REQUEST['start'], $totalMembers, $modSettings['defaultMaxMembers']);
    $context['start'] = $_REQUEST['start'];
    // Look for people online, provided they don't mind if you see they are.
    $request = db_query("\n\t\tSELECT\n\t\t\t(UNIX_TIMESTAMP(lo.logTime) - UNIX_TIMESTAMP() + " . time() . ") AS logTime,\n\t\t\tlo.ID_MEMBER, lo.url, INET_NTOA(lo.ip) AS ip, mem.realName, lo.session,\n\t\t\tmg.onlineColor, IFNULL(mem.showOnline, 1) AS showOnline\n\t\tFROM {$db_prefix}log_online AS lo\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (lo.ID_MEMBER = mem.ID_MEMBER)\n\t\t\tLEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = IF(mem.ID_GROUP = 0, mem.ID_POST_GROUP, mem.ID_GROUP))" . (!allowedTo('moderate_forum') ? "\n\t\tWHERE IFNULL(mem.showOnline, 1) = 1" : '') . "\n\t\tORDER BY {$_REQUEST['sort']} " . (isset($_REQUEST['asc']) ? 'ASC' : 'DESC') . "\n\t\tLIMIT {$context['start']}, {$modSettings['defaultMaxMembers']}", __FILE__, __LINE__);
    $context['members'] = array();
    $member_ids = array();
    $url_data = array();
    while ($row = mysql_fetch_assoc($request)) {
        $actions = @unserialize($row['url']);
        if ($actions === false) {
            continue;
        }
        // Send the information to the template.
        $context['members'][$row['session']] = array('id' => $row['ID_MEMBER'], 'ip' => allowedTo('moderate_forum') ? $row['ip'] : '', 'time' => strtr(timeformat($row['logTime']), array($txt['smf10'] => '', $txt['smf10b'] => '')), 'timestamp' => forum_time(true, $row['logTime']), 'query' => $actions, 'is_hidden' => $row['showOnline'] == 0, 'color' => empty($row['onlineColor']) ? '' : $row['onlineColor']);
        $url_data[$row['session']] = array($row['url'], $row['ID_MEMBER']);
        $member_ids[] = $row['ID_MEMBER'];
    }
    mysql_free_result($request);
    // Load the user data for these members.
    loadMemberData($member_ids);
    // Load up the guest user.
    $memberContext[0] = array('id' => 0, 'name' => $txt[28], 'group' => $txt[28], 'href' => '', 'link' => $txt[28], 'email' => $txt[28], 'is_guest' => true);
    $url_data = determineActions($url_data);
    // Setup the linktree and page title (do it down here because the language files are now loaded..)
    $context['page_title'] = $txt['who_title'];
    $context['linktree'][] = array('url' => $scripturl . '?action=who', 'name' => $txt['who_title']);
    // Put it in the context variables.
    foreach ($context['members'] as $i => $member) {
        if ($member['id'] != 0) {
            $member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0;
        }
        // Keep the IP that came from the database.
        $memberContext[$member['id']]['ip'] = $member['ip'];
        $context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : $txt['who_hidden'];
        $context['members'][$i] += $memberContext[$member['id']];
    }
    // Some people can't send personal messages...
    $context['can_send_pm'] = allowedTo('pm_send');
}
Exemplo n.º 22
0
/**
 * @param $memID 		int id_member
 *
 * fetch all likes received by the given user and display them
 * part of the profile -> show content area.
 */
function LikesByUser($memID)
{
    global $context, $user_info, $scripturl, $memberContext, $txt, $modSettings, $options;
    if ($memID != $user_info['id']) {
        isAllowedTo('can_view_ratings');
    }
    // let us use the same value as for topics per page here.
    $perpage = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    $out = $_GET['sa'] === 'likesout';
    // display likes *given* instead of received ones
    $is_owner = $user_info['id'] == $memID;
    // we are the owner of this profile, this is important for proper formatting (you/yours etc.)
    $boards_like_see = boardsAllowedTo('like_see');
    // respect permissions
    $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    if (!($user_info['is_admin'] || allowedTo('moderate_forum'))) {
        // admins and global mods can see everything
        $bq = ' AND b.id_board IN({array_int:boards})';
    } else {
        $bq = '';
    }
    $q = $out ? 'l.id_user = {int:id_user}' : 'l.id_receiver = {int:id_user}';
    $request = smf_db_query('SELECT count(l.id_msg) FROM {db_prefix}likes AS l
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = l.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE ' . $q . ' AND {query_see_board}' . $bq, array('id_user' => $memID, 'boards' => $boards_like_see));
    list($context['total_likes']) = mysql_fetch_row($request);
    mysql_free_result($request);
    $request = smf_db_query('SELECT m.subject, m.id_topic, l.id_user, l.id_receiver, l.updated, l.id_msg, l.rtype, mfirst.subject AS first_subject, SUBSTRING(m.body, 1, 150) AS body FROM {db_prefix}likes AS l
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = l.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}messages AS mfirst ON (mfirst.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE ' . $q . ' AND {query_see_board} ' . $bq . ' ORDER BY l.id_like DESC LIMIT {int:startwith}, {int:perpage}', array('id_user' => $memID, 'startwith' => $start, 'perpage' => $perpage, 'boards' => $boards_like_see));
    $context['results_count'] = 0;
    $context['likes'] = array();
    $context['displaymode'] = $out ? true : false;
    $context['pages'] = '';
    if ($context['total_likes'] > $perpage) {
        $context['pages'] = constructPageIndex($scripturl . '?action=profile;area=showposts;sa=' . $_GET['sa'] . ';u=' . trim($memID), $start, $context['total_likes'], $perpage);
    }
    $users = array();
    while ($row = mysql_fetch_assoc($request)) {
        $context['results_count']++;
        $thref = URL::topic($row['id_topic'], $row['first_subject'], 0);
        $phref = URL::topic($row['id_topic'], $row['subject'], 0, false, '.msg' . $row['id_msg'], '#msg' . $row['id_msg']);
        $users[] = $out ? $row['id_receiver'] : $row['id_user'];
        $context['likes'][] = array('id_user' => $out ? $row['id_receiver'] : $row['id_user'], 'time' => timeformat($row['updated']), 'topic' => array('href' => $thref, 'link' => '<a href="' . $thref . '">' . $row['first_subject'] . '</a>', 'subject' => $row['first_subject']), 'post' => array('href' => $phref, 'link' => '<a href="' . $phref . '">' . $row['subject'] . '</a>', 'subject' => $row['subject'], 'id' => $row['id_msg']), 'rtype' => $row['rtype'], 'teaser' => strip_tags(preg_replace('~[[\\/\\!]*?[^\\[\\]]*?]~si', '', $row['body'])) . '...', 'morelink' => URL::parse('?msg=' . $row['id_msg'] . ';perma'));
    }
    loadMemberData(array_unique($users));
    foreach ($context['likes'] as &$like) {
        loadMemberContext($like['id_user']);
        $like['member'] =& $memberContext[$like['id_user']];
        $like['text'] = $out ? $is_owner ? sprintf($txt['liked_a_post'], $is_owner ? $txt['you_liker'] : $memberContext[$memID]['name'], $memberContext[$like['id_user']]['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : sprintf($txt['liked_a_post'], $is_owner ? $txt['you_liker'] : $memberContext[$memID]['name'], $memberContext[$like['id_user']]['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : ($is_owner ? sprintf($txt['liked_your_post'], $like['id_user'] == $user_info['id'] ? $txt['you_liker'] : $like['member']['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : sprintf($txt['liked_a_post'], $like['id_user'] == $user_info['id'] ? $txt['you_liker'] : $like['member']['link'], $memberContext[$memID]['name'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']));
    }
    mysql_free_result($request);
    EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'ratings/profile_display');
}
function ReportedPosts()
{
    global $txt, $context, $scripturl, $modSettings, $user_info, $smcFunc;
    loadTemplate('ModerationCenter');
    // Put the open and closed options into tabs, because we can...
    $context[$context['moderation_menu_name']]['tab_data'] = array('title' => $txt['mc_reported_posts'], 'help' => '', 'description' => $txt['mc_reported_posts_desc']);
    // This comes under the umbrella of moderating posts.
    if ($user_info['mod_cache']['bq'] == '0=1') {
        isAllowedTo('moderate_forum');
    }
    // Are they wanting to view a particular report?
    if (!empty($_REQUEST['report'])) {
        return ModReport();
    }
    // Set up the comforting bits...
    $context['page_title'] = $txt['mc_reported_posts'];
    $context['sub_template'] = 'reported_posts';
    // Are we viewing open or closed reports?
    $context['view_closed'] = isset($_GET['sa']) && $_GET['sa'] == 'closed' ? 1 : 0;
    // Are we doing any work?
    if ((isset($_GET['ignore']) || isset($_GET['close'])) && isset($_GET['rid'])) {
        checkSession('get');
        $_GET['rid'] = (int) $_GET['rid'];
        // Update the report...
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}log_reported
			SET ' . (isset($_GET['ignore']) ? 'ignore_all = {int:ignore_all}' : 'closed = {int:closed}') . '
			WHERE id_report = {int:id_report}
				AND ' . $user_info['mod_cache']['bq'], array('ignore_all' => isset($_GET['ignore']) ? (int) $_GET['ignore'] : 0, 'closed' => isset($_GET['close']) ? (int) $_GET['close'] : 0, 'id_report' => $_GET['rid']));
        // Time to update.
        updateSettings(array('last_mod_report_action' => time()));
        recountOpenReports();
    } elseif (isset($_POST['close']) && isset($_POST['close_selected'])) {
        checkSession('post');
        // All the ones to update...
        $toClose = array();
        foreach ($_POST['close'] as $rid) {
            $toClose[] = (int) $rid;
        }
        if (!empty($toClose)) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}log_reported
				SET closed = {int:is_closed}
				WHERE id_report IN ({array_int:report_list})
					AND ' . $user_info['mod_cache']['bq'], array('report_list' => $toClose, 'is_closed' => 1));
            // Time to update.
            updateSettings(array('last_mod_report_action' => time()));
            recountOpenReports();
        }
    }
    // How many entries are we viewing?
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}log_reported AS lr
		WHERE lr.closed = {int:view_closed}
			AND ' . ($user_info['mod_cache']['bq'] == '1=1' || $user_info['mod_cache']['bq'] == '0=1' ? $user_info['mod_cache']['bq'] : 'lr.' . $user_info['mod_cache']['bq']), array('view_closed' => $context['view_closed']));
    list($context['total_reports']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // So, that means we can page index, yes?
    $context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=reports' . ($context['view_closed'] ? ';sa=closed' : ''), $_GET['start'], $context['total_reports'], 10);
    $context['start'] = $_GET['start'];
    // By George, that means we in a position to get the reports, golly good.
    $request = $smcFunc['db_query']('', '
		SELECT lr.id_report, lr.id_msg, lr.id_topic, lr.id_board, lr.id_member, lr.subject, lr.body,
			lr.time_started, lr.time_updated, lr.num_reports, lr.closed, lr.ignore_all,
			IFNULL(mem.real_name, lr.membername) AS author_name, IFNULL(mem.id_member, 0) AS id_author
		FROM {db_prefix}log_reported AS lr
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lr.id_member)
		WHERE lr.closed = {int:view_closed}
			AND ' . ($user_info['mod_cache']['bq'] == '1=1' || $user_info['mod_cache']['bq'] == '0=1' ? $user_info['mod_cache']['bq'] : 'lr.' . $user_info['mod_cache']['bq']) . '
		ORDER BY lr.time_updated DESC
		LIMIT ' . $context['start'] . ', 10', array('view_closed' => $context['view_closed']));
    $context['reports'] = array();
    $report_ids = array();
    for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i++) {
        $report_ids[] = $row['id_report'];
        $context['reports'][$row['id_report']] = array('id' => $row['id_report'], 'alternate' => $i % 2, 'topic_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'report_href' => $scripturl . '?action=moderate;area=reports;report=' . $row['id_report'], 'author' => array('id' => $row['id_author'], 'name' => $row['author_name'], 'link' => $row['id_author'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_author'] . '">' . $row['author_name'] . '</a>' : $row['author_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_author']), 'comments' => array(), 'time_started' => timeformat($row['time_started']), 'last_updated' => timeformat($row['time_updated']), 'subject' => $row['subject'], 'body' => parse_bbc($row['body']), 'num_reports' => $row['num_reports'], 'closed' => $row['closed'], 'ignore' => $row['ignore_all']);
    }
    $smcFunc['db_free_result']($request);
    // Now get all the people who reported it.
    if (!empty($report_ids)) {
        $request = $smcFunc['db_query']('', '
			SELECT lrc.id_comment, lrc.id_report, lrc.time_sent, lrc.comment,
				IFNULL(mem.id_member, 0) AS id_member, IFNULL(mem.real_name, lrc.membername) AS reporter
			FROM {db_prefix}log_reported_comments AS lrc
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lrc.id_member)
			WHERE lrc.id_report IN ({array_int:report_list})', array('report_list' => $report_ids));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $context['reports'][$row['id_report']]['comments'][] = array('id' => $row['id_comment'], 'message' => $row['comment'], 'time' => timeformat($row['time_sent']), 'member' => array('id' => $row['id_member'], 'name' => empty($row['reporter']) ? $txt['guest'] : $row['reporter'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['reporter'] . '</a>' : (empty($row['reporter']) ? $txt['guest'] : $row['reporter']), 'href' => $row['id_member'] ? $scripturl . '?action=profile;u=' . $row['id_member'] : ''));
        }
        $smcFunc['db_free_result']($request);
    }
}
function sportal_admin_page_list()
{
    global $txt, $smcFunc, $context, $scripturl;
    if (!empty($_POST['remove_pages']) && !empty($_POST['remove']) && is_array($_POST['remove'])) {
        checkSession();
        foreach ($_POST['remove'] as $index => $page_id) {
            $_POST['remove'][(int) $index] = (int) $page_id;
        }
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}sp_pages
			WHERE id_page IN ({array_int:pages})', array('pages' => $_POST['remove']));
    }
    $sort_methods = array('title' => array('down' => 'title ASC', 'up' => 'title DESC'), 'namespace' => array('down' => 'namespace ASC', 'up' => 'namespace DESC'), 'type' => array('down' => 'type ASC', 'up' => 'type DESC'), 'views' => array('down' => 'views ASC', 'up' => 'views DESC'), 'status' => array('down' => 'status ASC', 'up' => 'status DESC'));
    $context['columns'] = array('title' => array('width' => '45%', 'label' => $txt['sp_admin_pages_col_title'], 'class' => 'first_th', 'sortable' => true), 'namespace' => array('width' => '25%', 'label' => $txt['sp_admin_pages_col_namespace'], 'sortable' => true), 'type' => array('width' => '8%', 'label' => $txt['sp_admin_pages_col_type'], 'sortable' => true), 'views' => array('width' => '6%', 'label' => $txt['sp_admin_pages_col_views'], 'sortable' => true), 'status' => array('width' => '6%', 'label' => $txt['sp_admin_pages_col_status'], 'sortable' => true), 'actions' => array('width' => '10%', 'label' => $txt['sp_admin_pages_col_actions'], 'sortable' => false));
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $_REQUEST['sort'] = 'title';
    }
    foreach ($context['columns'] as $col => $dummy) {
        $context['columns'][$col]['selected'] = $col == $_REQUEST['sort'];
        $context['columns'][$col]['href'] = $scripturl . '?action=admin;area=portalpages;sa=list;sort=' . $col;
        if (!isset($_REQUEST['desc']) && $col == $_REQUEST['sort']) {
            $context['columns'][$col]['href'] .= ';desc';
        }
        $context['columns'][$col]['link'] = '<a href="' . $context['columns'][$col]['href'] . '">' . $context['columns'][$col]['label'] . '</a>';
    }
    $context['sort_by'] = $_REQUEST['sort'];
    $context['sort_direction'] = !isset($_REQUEST['desc']) ? 'down' : 'up';
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}sp_pages');
    list($total_pages) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=portalpages;sa=list;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $total_pages, 20);
    $context['start'] = $_REQUEST['start'];
    $request = $smcFunc['db_query']('', '
		SELECT id_page, namespace, title, type, views, status
		FROM {db_prefix}sp_pages
		ORDER BY {raw:sort}
		LIMIT {int:start}, {int:limit}', array('sort' => $sort_methods[$_REQUEST['sort']][$context['sort_direction']], 'start' => $context['start'], 'limit' => 20));
    $context['pages'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['pages'][$row['id_page']] = array('id' => $row['id_page'], 'page_id' => $row['namespace'], 'title' => $row['title'], 'href' => $scripturl . '?page=' . $row['namespace'], 'link' => '<a href="' . $scripturl . '?page=' . $row['namespace'] . '">' . $row['title'] . '</a>', 'type' => $row['type'], 'type_text' => $txt['sp_pages_type_' . $row['type']], 'views' => $row['views'], 'status' => $row['status'], 'status_image' => '<a href="' . $scripturl . '?action=admin;area=portalpages;sa=status;page_id=' . $row['id_page'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . sp_embed_image(empty($row['status']) ? 'deactive' : 'active', $txt['sp_admin_pages_' . (!empty($row['status']) ? 'de' : '') . 'activate']) . '</a>', 'actions' => array('edit' => '<a href="' . $scripturl . '?action=admin;area=portalpages;sa=edit;page_id=' . $row['id_page'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . sp_embed_image('modify') . '</a>', 'delete' => '<a href="' . $scripturl . '?action=admin;area=portalpages;sa=delete;page_id=' . $row['id_page'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" onclick="return confirm(\'', $txt['sp_admin_pages_delete_confirm'], '\');">' . sp_embed_image('delete') . '</a>'));
    }
    $smcFunc['db_free_result']($request);
    $context['sub_template'] = 'pages_list';
    $context['page_title'] = $txt['sp_admin_pages_list'];
}
Exemplo n.º 25
0
function Display()
{
    global $scripturl, $txt, $modSettings, $context, $settings;
    global $options, $sourcedir, $user_info, $board_info, $topic, $board;
    global $attachments, $messages_request, $topicinfo, $language, $smcFunc;
    // What are you gonna display if these are empty?!
    if (empty($topic)) {
        fatal_lang_error('no_board', false);
    }
    // Load the proper template and/or sub template.
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_display';
    } else {
        loadTemplate('Display');
    }
    // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Prefetch Forbidden');
        die;
    }
    // How much are we sticking on each page?
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    // Let's do some work on what to search index.
    if (count($_GET) > 2) {
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                $context['robot_no_index'] = true;
            }
        }
    }
    if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
        $context['robot_no_index'] = true;
    }
    // Find the previous or next topic.  Make a fuss if there are no more.
    if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
        // No use in calculating the next topic if there's only one.
        if ($board_info['num_topics'] > 1) {
            // Just prepare some variables that are used in the query.
            $gt_lt = $_REQUEST['prev_next'] == 'prev' ? '>' : '<';
            $order = $_REQUEST['prev_next'] == 'prev' ? '' : ' DESC';
            $request = $smcFunc['db_query']('', '
				SELECT t2.id_topic
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}topics AS t2 ON (' . (empty($modSettings['enableStickyTopics']) ? '
					t2.id_last_msg ' . $gt_lt . ' t.id_last_msg' : '
					(t2.id_last_msg ' . $gt_lt . ' t.id_last_msg AND t2.is_sticky ' . $gt_lt . '= t.is_sticky) OR t2.is_sticky ' . $gt_lt . ' t.is_sticky') . ')
				WHERE t.id_topic = {int:current_topic}
					AND t2.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND (t2.approved = {int:is_approved} OR (t2.id_member_started != {int:id_member_started} AND t2.id_member_started = {int:current_member}))') . '
				ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' t2.is_sticky' . $order . ',') . ' t2.id_last_msg' . $order . '
				LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'id_member_started' => 0));
            // No more left.
            if ($smcFunc['db_num_rows']($request) == 0) {
                $smcFunc['db_free_result']($request);
                // Roll over - if we're going prev, get the last - otherwise the first.
                $request = $smcFunc['db_query']('', '
					SELECT id_topic
					FROM {db_prefix}topics
					WHERE id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
						AND (approved = {int:is_approved} OR (id_member_started != {int:id_member_started} AND id_member_started = {int:current_member}))') . '
					ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' is_sticky' . $order . ',') . ' id_last_msg' . $order . '
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_started' => 0));
            }
            // Now you can be sure $topic is the id_topic to view.
            list($topic) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            $context['current_topic'] = $topic;
        }
        // Go to the newest message on this topic.
        $_REQUEST['start'] = 'new';
    }
    // Add 1 to the number of views of this topic.
    if (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET num_views = num_views + 1
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic));
        $_SESSION['last_read_topic'] = $topic;
    }
    // Get all the important topic info.
    $request = $smcFunc['db_query']('', '
		SELECT
			t.num_replies, t.num_views, t.locked, ms.subject, t.is_sticky, t.id_poll,
			t.id_member_started, t.id_first_msg, t.id_last_msg, t.approved, t.unapproved_posts,
			' . ($user_info['is_guest'] ? 't.id_last_msg + 1' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from
			' . (!empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $board ? ', id_previous_board, id_previous_topic' : '') . '
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)' . ($user_info['is_guest'] ? '' : '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . '
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic, 'current_board' => $board));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('not_a_topic', false);
    }
    $topicinfo = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
    $context['topic_first_message'] = $topicinfo['id_first_msg'];
    $context['topic_last_message'] = $topicinfo['id_last_msg'];
    // Add up unapproved replies to get real number of replies...
    if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
        $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
    }
    // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
    if ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !$user_info['is_guest'] && !allowedTo('approve_posts')) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(id_member) AS my_unapproved_posts
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND id_member = {int:current_member}
				AND approved = 0', array('current_topic' => $topic, 'current_member' => $user_info['id']));
        list($myUnapprovedPosts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
    } else {
        $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
    }
    // When was the last time this topic was replied to?  Should we warn them about it?
    $request = $smcFunc['db_query']('', '
		SELECT poster_time
		FROM {db_prefix}messages
		WHERE id_msg = {int:id_last_msg}
		LIMIT 1', array('id_last_msg' => $topicinfo['id_last_msg']));
    list($lastPostTime) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['oldTopicError'] = !empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky);
    // The start isn't a number; it's information about what to do, where to go.
    if (!is_numeric($_REQUEST['start'])) {
        // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
        if ($_REQUEST['start'] == 'new') {
            // Guests automatically go to the last post.
            if ($user_info['is_guest']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : 0;
            } else {
                // Find the earliest unread message in the topic. (the use of topics here is just for both tables.)
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from
					FROM {db_prefix}topics AS t
						LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
						LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})
					WHERE t.id_topic = {int:current_topic}
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
                list($new_from) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Fall through to the next if statement.
                $_REQUEST['start'] = 'msg' . $new_from;
            }
        }
        // Start from a certain time index, not a message.
        if (substr($_REQUEST['start'], 0, 4) == 'from') {
            $timestamp = (int) substr($_REQUEST['start'], 4);
            if ($timestamp === 0) {
                $_REQUEST['start'] = 0;
            } else {
                // Find the number of messages posted before said time...
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE poster_time < {int:timestamp}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_topic' => $topic, 'current_member' => $user_info['id'], 'is_approved' => 1, 'timestamp' => $timestamp));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Handle view_newest_first options, and get the correct start value.
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
            }
        } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
            $virtual_msg = (int) substr($_REQUEST['start'], 3);
            if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
            } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                $context['start_from'] = 0;
            } else {
                // Find the start value for that message......
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE id_msg < {int:virtual_msg}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'virtual_msg' => $virtual_msg, 'is_approved' => 1, 'no_member' => 0));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
            }
            // We need to reverse the start as well in this case.
            $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
        }
    }
    // Create a previous next string if the selected theme has it as a selected option.
    $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
    // Check if spellchecking is both enabled and actually working. (for quick reply.)
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // Are we showing signatures - or disabled fields?
    $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
    // Censor the title...
    censorText($topicinfo['subject']);
    $context['page_title'] = $topicinfo['subject'];
    // Is this already an article?
    $request = $smcFunc['db_query']('', '
		SELECT id_message
		FROM {db_prefix}sp_articles
		WHERE id_message = {int:message}', array('message' => $context['topic_first_message']));
    list($context['topic_is_article']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Is this topic sticky, or can it even be?
    $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
    // Default this topic to not marked for notifications... of course...
    $context['is_marked_notify'] = false;
    // Did we report a post to a moderator just now?
    $context['report_sent'] = isset($_GET['reportsent']);
    // Let's get nosey, who is viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        // Start out with no one at all viewing it.
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        // Search for members who have this topic set in their GET data.
        $request = $smcFunc['db_query']('', '
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_id_group} THEN mem.id_post_group ELSE mem.id_group END)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_id_group' => 0, 'in_url_string' => 's:5:"topic";i:' . $topic . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            if (!empty($row['online_color'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
            }
            $is_buddy = in_array($row['id_member'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<strong>' . $link . '</strong>';
            }
            // Add them both to the list and to the more detailed list.
            if (!empty($row['show_online']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
            }
            $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        // The number of guests is equal to the rows minus the ones we actually used ;).
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Sort the list.
        krsort($context['view_members']);
        krsort($context['view_members_list']);
    }
    // If all is set, but not allowed... just unset it.
    $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
    if (isset($_REQUEST['all']) && !$can_show_all) {
        unset($_REQUEST['all']);
    } elseif (isset($_REQUEST['all'])) {
        $_REQUEST['start'] = -1;
    }
    // Construct the page index, allowing for the .START method...
    $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true);
    $context['start'] = $_REQUEST['start'];
    // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
    // Figure out all the link to the next/prev/first/last/etc. for wireless mainly.
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '', 'last' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . floor($context['total_visible_posts'] / $context['messages_per_page']) * $context['messages_per_page'] : '', 'up' => $scripturl . '?board=' . $board . '.0');
    // If they are viewing all the posts, show all the posts, otherwise limit the number.
    if ($can_show_all) {
        if (isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            $context['page_index'] .= empty($modSettings['compactTopicPagesEnable']) ? '<strong>' . $txt['all'] . '</strong> ' : '[<strong>' . $txt['all'] . '</strong>] ';
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        } else {
            $context['page_index'] .= '&nbsp;<a href="' . $scripturl . '?topic=' . $topic . '.0;all">' . $txt['all'] . '</a> ';
        }
    }
    // Build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject'], 'extra_before' => $settings['linktree_inline'] ? $txt['topic'] . ': ' : '');
    // Build a list of this board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        // Add a link for each moderator...
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        // And show it after the board's name.
        $context['linktree'][count($context['linktree']) - 2]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Information about the current topic...
    $context['is_locked'] = $topicinfo['locked'];
    $context['is_sticky'] = $topicinfo['is_sticky'];
    $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
    $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
    $context['is_approved'] = $topicinfo['approved'];
    // We don't want to show the poll icon in the topic class here, so pretend it's not one.
    $context['is_poll'] = false;
    determineTopicClass($context);
    $context['is_poll'] = $topicinfo['id_poll'] > 0 && $modSettings['pollMode'] == '1' && allowedTo('poll_view');
    // Did this user start the topic or not?
    $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
    $context['topic_starter_id'] = $topicinfo['id_member_started'];
    // Set the topic's information for the template.
    $context['subject'] = $topicinfo['subject'];
    $context['num_views'] = $topicinfo['num_views'];
    $context['mark_unread_time'] = $topicinfo['new_from'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
    // For quick reply we need a response prefix in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix', 600))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // If we want to show event information in the topic, prepare the data.
    if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
        // First, try create a better time format, ignoring the "time" elements.
        if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
            $date_string = $user_info['time_format'];
        } else {
            $date_string = $matches[0];
        }
        // Any calendar information for this topic?
        $request = $smcFunc['db_query']('', '
			SELECT cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, mem.real_name
			FROM {db_prefix}calendar AS cal
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = cal.id_member)
			WHERE cal.id_topic = {int:current_topic}
			ORDER BY start_date', array('current_topic' => $topic));
        $context['linked_calendar_events'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Prepare the dates for being formatted.
            $start_date = sscanf($row['start_date'], '%04d-%02d-%02d');
            $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
            $end_date = sscanf($row['end_date'], '%04d-%02d-%02d');
            $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
            $context['linked_calendar_events'][] = array('id' => $row['id_event'], 'title' => $row['title'], 'can_edit' => allowedTo('calendar_edit_any') || $row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => timeformat($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => timeformat($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
        }
        $smcFunc['db_free_result']($request);
        if (!empty($context['linked_calendar_events'])) {
            $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
        }
    }
    // Create the poll info if it exists.
    if ($context['is_poll']) {
        // Get the question and if it's locked.
        $request = $smcFunc['db_query']('', '
			SELECT
				p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote,
				p.guest_vote, p.id_member, IFNULL(mem.real_name, p.poster_name) AS poster_name, p.num_guest_voters, p.reset_poll
			FROM {db_prefix}polls AS p
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)
			WHERE p.id_poll = {int:id_poll}
			LIMIT 1', array('id_poll' => $topicinfo['id_poll']));
        $pollinfo = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(DISTINCT id_member) AS total
			FROM {db_prefix}log_polls
			WHERE id_poll = {int:id_poll}
				AND id_member != {int:not_guest}', array('id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        list($pollinfo['total']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Total voters needs to include guest voters
        $pollinfo['total'] += $pollinfo['num_guest_voters'];
        // Get all the options, and calculate the total votes.
        $request = $smcFunc['db_query']('', '
			SELECT pc.id_choice, pc.label, pc.votes, IFNULL(lp.id_choice, -1) AS voted_this
			FROM {db_prefix}poll_choices AS pc
				LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest})
			WHERE pc.id_poll = {int:id_poll}', array('current_member' => $user_info['id'], 'id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        $pollOptions = array();
        $realtotal = 0;
        $pollinfo['has_voted'] = false;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            censorText($row['label']);
            $pollOptions[$row['id_choice']] = $row;
            $realtotal += $row['votes'];
            $pollinfo['has_voted'] |= $row['voted_this'] != -1;
        }
        $smcFunc['db_free_result']($request);
        // If this is a guest we need to do our best to work out if they have voted, and what they voted for.
        if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote')) {
            if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $topicinfo['id_poll'] . ',') !== false) {
                // ;id,timestamp,[vote,vote...]; etc
                $guestinfo = explode(';', $_COOKIE['guest_poll_vote']);
                // Find the poll we're after.
                foreach ($guestinfo as $i => $guestvoted) {
                    $guestvoted = explode(',', $guestvoted);
                    if ($guestvoted[0] == $topicinfo['id_poll']) {
                        break;
                    }
                }
                // Has the poll been reset since guest voted?
                if ($pollinfo['reset_poll'] > $guestvoted[1]) {
                    // Remove the poll info from the cookie to allow guest to vote again
                    unset($guestinfo[$i]);
                    if (!empty($guestinfo)) {
                        $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
                    } else {
                        unset($_COOKIE['guest_poll_vote']);
                    }
                } else {
                    // What did they vote for?
                    unset($guestvoted[0], $guestvoted[1]);
                    foreach ($pollOptions as $choice => $details) {
                        $pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1;
                        $pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1;
                    }
                    unset($choice, $details, $guestvoted);
                }
                unset($guestinfo, $guestvoted, $i);
            }
        }
        // Set up the basic poll information.
        $context['poll'] = array('id' => $topicinfo['id_poll'], 'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'), 'question' => parse_bbc($pollinfo['question']), 'total_votes' => $pollinfo['total'], 'change_vote' => !empty($pollinfo['change_vote']), 'is_locked' => !empty($pollinfo['voting_locked']), 'options' => array(), 'lock' => allowedTo('poll_lock_any') || $context['user']['started'] && allowedTo('poll_lock_own'), 'edit' => allowedTo('poll_edit_any') || $context['user']['started'] && allowedTo('poll_edit_own'), 'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '', 'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(), 'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0, 'has_voted' => !empty($pollinfo['has_voted']), 'starter' => array('id' => $pollinfo['id_member'], 'name' => $row['poster_name'], 'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'], 'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'));
        // Make the lock and edit permissions defined above more directly accessible.
        $context['allow_lock_poll'] = $context['poll']['lock'];
        $context['allow_edit_poll'] = $context['poll']['edit'];
        // You're allowed to vote if:
        // 1. the poll did not expire, and
        // 2. you're either not a guest OR guest voting is enabled... and
        // 3. you're not trying to view the results, and
        // 4. the poll is not locked, and
        // 5. you have the proper permissions, and
        // 6. you haven't already voted before.
        $context['allow_vote'] = !$context['poll']['is_expired'] && (!$user_info['is_guest'] || $pollinfo['guest_vote'] && allowedTo('poll_vote')) && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && !$context['poll']['has_voted'];
        // You're allowed to view the results if:
        // 1. you're just a super-nice-guy, or
        // 2. anyone can see them (hide_results == 0), or
        // 3. you can see them after you voted (hide_results == 1), or
        // 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.)
        $context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || $pollinfo['hide_results'] == 1 && $context['poll']['has_voted'] || $context['poll']['is_expired'];
        $context['poll']['show_results'] = $context['allow_poll_view'] && (isset($_REQUEST['viewresults']) || isset($_REQUEST['viewResults']));
        $context['show_view_results_button'] = $context['allow_vote'] && (!$context['allow_poll_view'] || !$context['poll']['show_results'] || !$context['poll']['has_voted']);
        // You're allowed to change your vote if:
        // 1. the poll did not expire, and
        // 2. you're not a guest... and
        // 3. the poll is not locked, and
        // 4. you have the proper permissions, and
        // 5. you have already voted, and
        // 6. the poll creator has said you can!
        $context['allow_change_vote'] = !$context['poll']['is_expired'] && !$user_info['is_guest'] && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && $context['poll']['has_voted'] && $context['poll']['change_vote'];
        // You're allowed to return to voting options if:
        // 1. you are (still) allowed to vote.
        // 2. you are currently seeing the results.
        $context['allow_return_vote'] = $context['allow_vote'] && $context['poll']['show_results'];
        // Calculate the percentages and bar lengths...
        $divisor = $realtotal == 0 ? 1 : $realtotal;
        // Determine if a decimal point is needed in order for the options to add to 100%.
        $precision = $realtotal == 100 ? 0 : 1;
        // Now look through each option, and...
        foreach ($pollOptions as $i => $option) {
            // First calculate the percentage, and then the width of the bar...
            $bar = round($option['votes'] * 100 / $divisor, $precision);
            $barWide = $bar == 0 ? 1 : floor($bar * 8 / 3);
            // Now add it to the poll's contextual theme data.
            $context['poll']['options'][$i] = array('id' => 'options-' . $i, 'percent' => $bar, 'votes' => $option['votes'], 'voted_this' => $option['voted_this'] != -1, 'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.gif" alt="" /></span>', 'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '', 'bar_width' => $barWide, 'option' => parse_bbc($option['label']), 'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '" />');
        }
    }
    // Calculate the fastest way to get the messages!
    $ascending = empty($options['view_newest_first']);
    $start = $_REQUEST['start'];
    $limit = $context['messages_per_page'];
    $firstIndex = 0;
    if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
        $ascending = !$ascending;
        $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
        $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
        $firstIndex = $limit - 1;
    }
    // Get each post and poster in this topic.
    $request = $smcFunc['db_query']('display_get_post_poster', '
		SELECT id_msg, id_member, approved
		FROM {db_prefix}messages
		WHERE id_topic = {int:current_topic}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : (!empty($modSettings['db_mysql_group_by_fix']) ? '' : '
		GROUP BY id_msg') . '
		HAVING (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')') . '
		ORDER BY id_msg ' . ($ascending ? '' : 'DESC') . ($context['messages_per_page'] == -1 ? '' : '
		LIMIT ' . $start . ', ' . $limit), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'blank_id_member' => 0));
    $messages = array();
    $all_posters = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        if (!empty($row['id_member'])) {
            $all_posters[$row['id_msg']] = $row['id_member'];
        }
        $messages[] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    $posters = array_unique($all_posters);
    // Guests can't mark topics read or for notifications, just can't sorry.
    if (!$user_info['is_guest']) {
        $mark_at_msg = max($messages);
        if ($mark_at_msg >= $topicinfo['id_last_msg']) {
            $mark_at_msg = $modSettings['maxMsgID'];
        }
        if ($mark_at_msg >= $topicinfo['new_from']) {
            $smcFunc['db_insert']($topicinfo['new_from'] == 0 ? 'ignore' : 'replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), array($user_info['id'], $topic, $mark_at_msg), array('id_member', 'id_topic'));
        }
        // Check for notifications on this topic OR board.
        $request = $smcFunc['db_query']('', '
			SELECT sent, id_topic
			FROM {db_prefix}log_notify
			WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
				AND id_member = {int:current_member}
			LIMIT 2', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
        $do_once = true;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Find if this topic is marked for notification...
            if (!empty($row['id_topic'])) {
                $context['is_marked_notify'] = true;
            }
            // Only do this once, but mark the notifications as "not sent yet" for next time.
            if (!empty($row['sent']) && $do_once) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_not_sent}
					WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_not_sent' => 0));
                $do_once = false;
            }
        }
        // Have we recently cached the number of new topics in this board, and it's still a lot?
        if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
            $_SESSION['topicseen_cache'][$board]--;
        } elseif (isset($_REQUEST['topicseen'])) {
            // Use the mark read tables... and the last visit to figure out if this should be read or not.
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}topics AS t
					LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = {int:current_board} AND lb.id_member = {int:current_member})
					LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
				WHERE t.id_board = {int:current_board}
					AND t.id_last_msg > IFNULL(lb.id_msg, 0)
					AND t.id_last_msg > IFNULL(lt.id_msg, 0)' . (empty($_SESSION['id_msg_last_visit']) ? '' : '
					AND t.id_last_msg > {int:id_msg_last_visit}'), array('current_board' => $board, 'current_member' => $user_info['id'], 'id_msg_last_visit' => (int) $_SESSION['id_msg_last_visit']));
            list($numNewTopics) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // If there're no real new topics in this board, mark the board as seen.
            if (empty($numNewTopics)) {
                $_REQUEST['boardseen'] = true;
            } else {
                $_SESSION['topicseen_cache'][$board] = $numNewTopics;
            }
        } elseif (isset($_SESSION['topicseen_cache'][$board])) {
            $_SESSION['topicseen_cache'][$board]--;
        }
        // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
        if (isset($_REQUEST['boardseen'])) {
            $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board'));
        }
    }
    $attachments = array();
    // If there _are_ messages here... (probably an error otherwise :!)
    if (!empty($messages)) {
        // Fetch attachments.
        if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
            $request = $smcFunc['db_query']('', '
				SELECT
					a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
					a.width, a.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ',
					IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
				FROM {db_prefix}attachments AS a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
					LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
				WHERE a.id_msg IN ({array_int:message_list})
					AND a.attachment_type = {int:attachment_type}', array('message_list' => $messages, 'attachment_type' => 0, 'is_approved' => 1));
            $temp = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id'])) {
                    continue;
                }
                $temp[$row['id_attach']] = $row;
                if (!isset($attachments[$row['id_msg']])) {
                    $attachments[$row['id_msg']] = array();
                }
            }
            $smcFunc['db_free_result']($request);
            // This is better than sorting it with the query...
            ksort($temp);
            foreach ($temp as $row) {
                $attachments[$row['id_msg']][] = $row;
            }
        }
        // What?  It's not like it *couldn't* be only guests in this topic...
        if (!empty($posters)) {
            loadMemberData($posters);
        }
        $messages_request = $smcFunc['db_query']('', '
			SELECT
				id_msg, icon, subject, poster_time, poster_ip, id_member, modified_time, modified_name, body,
				smileys_enabled, poster_name, poster_email, approved,
				id_msg_modified < {int:new_from} AS is_read
			FROM {db_prefix}messages
			WHERE id_msg IN ({array_int:message_list})
			ORDER BY id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'), array('message_list' => $messages, 'new_from' => $topicinfo['new_from']));
        // Go to the last message if the given time is beyond the time of the last message.
        if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
            $context['start_from'] = $topicinfo['num_replies'];
        }
        // Since the anchor information is needed on the top of the page we load these variables beforehand.
        $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
        if (empty($options['view_newest_first'])) {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $topicinfo['num_replies'] - $context['start_from'];
        }
    } else {
        $messages_request = false;
        $context['first_message'] = 0;
        $context['first_new_message'] = false;
    }
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&'))), 'child_level' => $board_info['child_level']);
    // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
    $context['get_message'] = 'prepareDisplayContext';
    // Now set all the wonderful, wonderful permissions... like moderation ones...
    $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
    foreach ($common_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm);
    }
    // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
    $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
    foreach ($anyown_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
    }
    // Cleanup all the permissions with extra stuff...
    $context['can_mark_notify'] &= !$context['user']['is_guest'];
    $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
    $context['calendar_post'] &= !empty($modSettings['cal_enabled']);
    $context['can_add_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] <= 0;
    $context['can_remove_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] > 0;
    $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
    $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
    $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1;
    // Handle approval flags...
    $context['can_reply_approved'] = $context['can_reply'];
    $context['can_reply'] |= $context['can_reply_unapproved'];
    $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
    $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
    $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
    // Start this off for quick moderation - it will be or'd for each post.
    $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
    // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
    $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
    $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
    // Wireless shows a "more" if you can do anything special.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['wireless_more'] = $context['can_sticky'] || $context['can_lock'] || allowedTo('modify_any');
        $context['wireless_moderate'] = isset($_GET['moderate']) ? ';moderate' : '';
    }
    // Load up the "double post" sequencing magic.
    if (!empty($options['display_quick_reply'])) {
        checkSubmitOnce('register');
        $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
        $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
    }
}
Exemplo n.º 26
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);
}
Exemplo n.º 27
0
function ViewTags()
{
    global $context, $txt, $mbname, $scripturl, $user_info, $smcFunc, $modSettings;
    // Views that tag results and popular tags
    if (isset($_REQUEST['tagid'])) {
        // Show the tag results for that tag
        $id = (int) $_REQUEST['tagid'];
        // Find Tag Name
        $dbresult = $smcFunc['db_query']('', "\n\t\tSELECT\n\t\t\ttag\n\t\tFROM {db_prefix}tags\n\t\tWHERE ID_TAG = {$id} LIMIT 1");
        $row = $smcFunc['db_fetch_assoc']($dbresult);
        $smcFunc['db_free_result']($dbresult);
        $context['tag_search'] = $row['tag'];
        $context['page_title'] = $mbname . ' - ' . $txt['smftags_resultsfor'] . $context['tag_search'];
        $context['start'] = (int) $_REQUEST['start'];
        $dbresult = $smcFunc['db_query']('', "\n\t\tSELECT count(*) as total \n\t\tFROM ({db_prefix}tags_log as l, {db_prefix}boards AS b, {db_prefix}topics as t, {db_prefix}messages as m)\n\t\t\n\t\tWHERE l.ID_TAG = {$id} AND b.ID_BOARD = t.ID_BOARD AND l.ID_TOPIC = t.id_topic  AND t.approved = 1 \n\t\tAND t.ID_FIRST_MSG = m.ID_MSG AND " . $user_info['query_see_board'] . " \n\t\t");
        $totalRow = $smcFunc['db_fetch_assoc']($dbresult);
        $numofrows = $totalRow['total'];
        // Find Results
        $dbresult = $smcFunc['db_query']('', "\n\t\tSELECT t.num_replies,t.num_views,m.id_member,m.poster_name,m.subject,m.id_topic,m.poster_time, t.ID_BOARD\n\t\tFROM ({db_prefix}tags_log as l, {db_prefix}boards AS b, {db_prefix}topics as t, {db_prefix}messages as m)\n\t\t\n\t\tWHERE l.ID_TAG = {$id} AND b.ID_BOARD = t.ID_BOARD AND l.ID_TOPIC = t.id_topic  AND t.approved = 1 \n\t\tAND t.ID_FIRST_MSG = m.ID_MSG AND " . $user_info['query_see_board'] . " \n\t\tORDER BY m.ID_MSG DESC LIMIT {$context['start']},25 ");
        $context['tags_topics'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($dbresult)) {
            $context['tags_topics'][] = array('id_member' => $row['id_member'], 'poster_name' => $row['poster_name'], 'subject' => $row['subject'], 'id_topic' => $row['id_topic'], 'poster_time' => $row['poster_time'], 'num_views' => $row['num_views'], 'num_replies' => $row['num_replies']);
        }
        $smcFunc['db_free_result']($dbresult);
        $context['sub_template'] = 'results';
        $context['page_index'] = constructPageIndex($scripturl . '?action=tags;tagid=' . $id, $_REQUEST['start'], $numofrows, 25);
    } else {
        $context['page_title'] = $mbname . ' - ' . $txt['smftags_popular'];
        // Tag cloud from http://www.prism-perfect.net/archive/php-tag-cloud-tutorial/
        $result = $smcFunc['db_query']('', "\n\t\tSELECT \n\t\t\tt.tag AS tag, l.ID_TAG, COUNT(l.ID_TAG) AS quantity\n\t\t FROM {db_prefix}tags as t, {db_prefix}tags_log as l WHERE t.ID_TAG = l.ID_TAG\n\t\t  GROUP BY l.ID_TAG\n\t\t  ORDER BY COUNT(l.ID_TAG) DESC, RAND() LIMIT " . $modSettings['smftags_set_cloud_tags_to_show']);
        // here we loop through the results and put them into a simple array:
        // $tag['thing1'] = 12;
        // $tag['thing2'] = 25;
        // etc. so we can use all the nifty array functions
        // to calculate the font-size of each tag
        $tags = array();
        $tags2 = array();
        while ($row = $smcFunc['db_fetch_assoc']($result)) {
            $tags[$row['tag']] = $row['quantity'];
            $tags2[$row['tag']] = $row['ID_TAG'];
        }
        if (count($tags2) > 0) {
            // change these font sizes if you will
            $max_size = $modSettings['smftags_set_cloud_max_font_size_precent'];
            // max font size in %
            $min_size = $modSettings['smftags_set_cloud_min_font_size_precent'];
            // min font size in %
            // get the largest and smallest array values
            $max_qty = max(array_values($tags));
            $min_qty = min(array_values($tags));
            // find the range of values
            $spread = $max_qty - $min_qty;
            if (0 == $spread) {
                // we don't want to divide by zero
                $spread = 1;
            }
            // determine the font-size increment
            // this is the increase per tag quantity (times used)
            $step = ($max_size - $min_size) / $spread;
            // loop through our tag array
            $context['poptags'] = '';
            $row_count = 0;
            foreach ($tags as $key => $value) {
                $row_count++;
                // calculate CSS font-size
                // find the $value in excess of $min_qty
                // multiply by the font-size increment ($size)
                // and add the $min_size set above
                $size = $min_size + ($value - $min_qty) * $step;
                // uncomment if you want sizes in whole %:
                // $size = ceil($size);
                // you'll need to put the link destination in place of the #
                // (assuming your tag links to some sort of details page)
                $context['poptags'] .= '<a href="' . $scripturl . '?action=tags;tagid=' . $tags2[$key] . '" style="font-size: ' . $size . '%"';
                // perhaps adjust this title attribute for the things that are tagged
                $context['poptags'] .= ' title="' . $value . ' things tagged with ' . $key . '"';
                $context['poptags'] .= '>' . $key . '</a> ';
                if ($row_count > $modSettings['smftags_set_cloud_tags_per_row'] - 1) {
                    $context['poptags'] .= '<br />';
                    $row_count = 0;
                }
                // notice the space at the end of the link
            }
        }
        // Find Results
        $dbresult = $smcFunc['db_query']('', "\n\t\tSELECT DISTINCT l.ID_TOPIC, t.num_replies,t.num_views,m.id_member,\n\t\tm.poster_name,m.subject,m.id_topic,m.poster_time, \n\t\tt.id_board, g.tag, g.ID_TAG \n\t\t FROM ({db_prefix}tags_log as l, {db_prefix}boards AS b, {db_prefix}topics as t, {db_prefix}messages as m) \n\t\t  LEFT JOIN {db_prefix}tags AS g ON (l.ID_TAG = g.ID_TAG)\n\t\t WHERE b.ID_BOARD = t.id_board AND l.ID_TOPIC = t.id_topic AND t.approved = 1 AND t.id_first_msg = m.id_msg AND " . $user_info['query_see_board'] . " ORDER BY l.ID DESC LIMIT 20");
        $context['tags_topics'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($dbresult)) {
            $context['tags_topics'][] = array('id_member' => $row['id_member'], 'poster_name' => $row['poster_name'], 'subject' => $row['subject'], 'id_topic' => $row['id_topic'], 'poster_time' => $row['poster_time'], 'num_views' => $row['num_views'], 'num_replies' => $row['num_replies'], 'ID_TAG' => $row['ID_TAG'], 'tag' => $row['tag']);
        }
        $smcFunc['db_free_result']($dbresult);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=tags', 'name' => $txt['smftags_menu']);
}
Exemplo n.º 28
0
function aStreamGet($b = 0, $xml = false, $global = false)
{
    global $board, $context, $user_info, $modSettings, $options, $scripturl;
    if (!isset($board) || !$board) {
        $board = $b;
    }
    $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    $context['xml'] = $xml;
    $context['act_global'] = false;
    $total = 0;
    $context['sef_full_rewrite'] = true;
    $perpage = $xml ? 15 : (empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']);
    if ($user_info['is_admin']) {
        $pquery = ' AND (a.is_private <= ' . ACT_PLEVEL_ADMIN . ' OR a.id_member = {int:id_user} OR a.id_owner = {int:id_user}) ';
    } else {
        $pquery = ' AND (a.is_private = 0 OR a.id_member = {int:id_user} OR a.id_owner = {int:id_user}) ';
    }
    $filterby = '';
    if (isset($_REQUEST['filter'])) {
        $filterby = normalizeCommaDelimitedList($_REQUEST['filter']);
        if (strlen($filterby)) {
            $pquery .= ' AND a.id_type IN({string:filter})';
        }
    }
    $uquery = '';
    if (isset($_REQUEST['u']) && (int) $_REQUEST['u'] > 0) {
        $uquery .= 'a.id_member = {int:id_user} AND ';
    } else {
        $uquery = !empty($user_info['ignoreusers']) ? 'a.id_member NOT IN({array_int:ignoredusers}) AND ' : '';
    }
    if ($global) {
        if (!$xml) {
            $result = smf_db_query('SELECT COUNT(a.id_act) FROM {db_prefix}log_activities AS a
				LEFT JOIN {db_prefix}boards AS b ON(b.id_board = a.id_board)
				WHERE ' . $uquery . ' ({query_wanna_see_board} OR a.id_board = 0)' . $pquery, array('start' => 0, 'id_user' => $user_info['id'], 'filter' => $filterby, 'perpage' => $perpage, 'ignoredusers' => $user_info['ignoreusers']));
            list($total) = mysql_fetch_row($result);
            mysql_free_result($result);
        }
        $result = smf_db_query('SELECT a.*, t.*, b.name AS board_name FROM {db_prefix}log_activities AS a
			LEFT JOIN {db_prefix}activity_types AS t ON (t.id_type = a.id_type)
			LEFT JOIN {db_prefix}boards AS b ON(b.id_board = a.id_board)
			WHERE ' . $uquery . ' ({query_wanna_see_board} OR a.id_board = 0)' . $pquery . ' ORDER BY a.id_act DESC LIMIT {int:start}, {int:perpage}', array('start' => $start, 'id_user' => $user_info['id'], 'filter' => $filterby, 'perpage' => $perpage, 'ignoredusers' => $user_info['ignoreusers']));
        $context['act_global'] = true;
        $context['viewall_url'] = URL::parse($scripturl . '?action=astream;sa=get;all');
    } else {
        if (!$xml) {
            $result = smf_db_query('SELECT COUNT(a.id_act) FROM {db_prefix}log_activities AS a
				LEFT JOIN {db_prefix}boards AS b ON(b.id_board = a.id_board)
				WHERE ' . $uquery . ' a.id_board = {int:id_board} AND {query_wanna_see_board} ' . $pquery, array('id_board' => $board, 'start' => 0, 'id_user' => $user_info['id'], 'filter' => $filterby, 'perpage' => $perpage, 'ignoredusers' => $user_info['ignoreusers']));
            list($total) = mysql_fetch_row($result);
            mysql_free_result($result);
        }
        $result = smf_db_query('SELECT a.*, t.*, b.name AS board_name FROM {db_prefix}log_activities AS a
			LEFT JOIN {db_prefix}activity_types AS t ON (t.id_type = a.id_type)
			LEFT JOIN {db_prefix}boards AS b ON(b.id_board = a.id_board)
			WHERE ' . $uquery . ' a.id_board = {int:id_board} AND {query_wanna_see_board}' . $pquery . ' ORDER BY a.id_act DESC LIMIT {int:start}, {int:perpage}', array('id_board' => $board, 'start' => $start, 'id_user' => $user_info['id'], 'filter' => $filterby, 'perpage' => $perpage, 'ignoredusers' => $user_info['ignoreusers']));
        $context['viewall_url'] = URL::parse($scripturl . '?action=astream;sa=get;b=' . $board);
    }
    $pages_base = URL::parse($scripturl . '?action=astream;sa=get;all;');
    $pages_base = URL::addParam($pages_base, 'start=%1$d', true);
    $context['pages'] = $total ? constructPageIndex($pages_base, $start, $total, $perpage, true) : '';
    if ($xml) {
        header('Content-Type: text/xml; charset=UTF-8');
    }
    aStreamOutput($result);
}
Exemplo n.º 29
0
function ViewErrorLog()
{
    global $scripturl, $txt, $context, $modSettings, $user_profile, $filter, $boarddir, $sourcedir, $themedir, $smcFunc;
    // Viewing contents of a file?
    if (isset($_GET['file'])) {
        return ViewFile();
    }
    // Check for the administrative permission to do this.
    isAllowedTo('admin_forum');
    // Templates, etc...
    loadLanguage('ManageMaintenance');
    loadTemplate('Errors');
    // You can filter by any of the following columns:
    $filters = array('id_member' => $txt['username'], 'ip' => $txt['ip_address'], 'session' => $txt['session'], 'url' => $txt['error_url'], 'message' => $txt['error_message'], 'error_type' => $txt['error_type'], 'file' => $txt['file'], 'line' => $txt['line']);
    // Set up the filtering...
    if (isset($_GET['value'], $_GET['filter']) && isset($filters[$_GET['filter']])) {
        $filter = array('variable' => $_GET['filter'], 'value' => array('sql' => in_array($_GET['filter'], array('message', 'url', 'file')) ? base64_decode(strtr($_GET['value'], array(' ' => '+'))) : $smcFunc['db_escape_wildcard_string']($_GET['value'])), 'href' => ';filter=' . $_GET['filter'] . ';value=' . $_GET['value'], 'entity' => $filters[$_GET['filter']]);
    }
    // Deleting, are we?
    if (isset($_POST['delall']) || isset($_POST['delete'])) {
        deleteErrors();
    }
    // Just how many errors are there?
    $result = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}log_errors' . (isset($filter) ? '
		WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : ''), array('filter' => isset($filter) ? $filter['value']['sql'] : ''));
    list($num_errors) = $smcFunc['db_fetch_row']($result);
    $smcFunc['db_free_result']($result);
    // If this filter is empty...
    if ($num_errors == 0 && isset($filter)) {
        redirectexit('action=admin;area=logs;sa=errorlog' . (isset($_REQUEST['desc']) ? ';desc' : ''));
    }
    // Clean up start.
    if (!isset($_GET['start']) || $_GET['start'] < 0) {
        $_GET['start'] = 0;
    }
    // Do we want to reverse error listing?
    $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up';
    // Set the page listing up.
    $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . (isset($filter) ? $filter['href'] : ''), $_GET['start'], $num_errors, $modSettings['defaultMaxMessages']);
    $context['start'] = $_GET['start'];
    // Find and sort out the errors.
    $request = $smcFunc['db_query']('', '
		SELECT id_error, id_member, ip, url, log_time, message, session, error_type, file, line
		FROM {db_prefix}log_errors' . (isset($filter) ? '
		WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : '') . '
		ORDER BY id_error ' . ($context['sort_direction'] == 'down' ? 'DESC' : '') . '
		LIMIT ' . $_GET['start'] . ', ' . $modSettings['defaultMaxMessages'], array('filter' => isset($filter) ? $filter['value']['sql'] : ''));
    $context['errors'] = array();
    $members = array();
    for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i++) {
        $search_message = preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '%', $smcFunc['db_escape_wildcard_string']($row['message']));
        if ($search_message == $filter['value']['sql']) {
            $search_message = $smcFunc['db_escape_wildcard_string']($row['message']);
        }
        $show_message = strtr(strtr(preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '$1', $row['message']), array("\r" => '', '<br />' => "\n", '<' => '&lt;', '>' => '&gt;', '"' => '&quot;')), array("\n" => '<br />'));
        $context['errors'][$row['id_error']] = array('alternate' => $i % 2 == 0, 'member' => array('id' => $row['id_member'], 'ip' => $row['ip'], 'session' => $row['session']), 'time' => timeformat($row['log_time']), 'timestamp' => $row['log_time'], 'url' => array('html' => htmlspecialchars((substr($row['url'], 0, 1) == '?' ? $scripturl : '') . $row['url']), 'href' => base64_encode($smcFunc['db_escape_wildcard_string']($row['url']))), 'message' => array('html' => $show_message, 'href' => base64_encode($search_message)), 'id' => $row['id_error'], 'error_type' => array('type' => $row['error_type'], 'name' => isset($txt['errortype_' . $row['error_type']]) ? $txt['errortype_' . $row['error_type']] : $row['error_type']), 'file' => array());
        if (!empty($row['file']) && !empty($row['line'])) {
            // Eval'd files rarely point to the right location and cause havoc for linking, so don't link them.
            $linkfile = strpos($row['file'], 'eval') === false || strpos($row['file'], '?') === false;
            // De Morgan's Law.  Want this true unless both are present.
            $context['errors'][$row['id_error']]['file'] = array('file' => $row['file'], 'line' => $row['line'], 'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'], 'link' => $linkfile ? '<a href="' . $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'] . '" onclick="return reqWin(this.href, 600, 400, false);">' . $row['file'] . '</a>' : $row['file'], 'search' => base64_encode($row['file']));
        }
        // Make a list of members to load later.
        $members[$row['id_member']] = $row['id_member'];
    }
    $smcFunc['db_free_result']($request);
    // Load the member data.
    if (!empty($members)) {
        // Get some additional member info...
        $request = $smcFunc['db_query']('', '
			SELECT id_member, member_name, real_name
			FROM {db_prefix}members
			WHERE id_member IN ({array_int:member_list})
			LIMIT ' . count($members), array('member_list' => $members));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $members[$row['id_member']] = $row;
        }
        $smcFunc['db_free_result']($request);
        // This is a guest...
        $members[0] = array('id_member' => 0, 'member_name' => '', 'real_name' => $txt['guest_title']);
        // Go through each error and tack the data on.
        foreach ($context['errors'] as $id => $dummy) {
            $memID = $context['errors'][$id]['member']['id'];
            $context['errors'][$id]['member']['username'] = $members[$memID]['member_name'];
            $context['errors'][$id]['member']['name'] = $members[$memID]['real_name'];
            $context['errors'][$id]['member']['href'] = empty($memID) ? '' : $scripturl . '?action=profile;u=' . $memID;
            $context['errors'][$id]['member']['link'] = empty($memID) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $memID . '">' . $context['errors'][$id]['member']['name'] . '</a>';
        }
    }
    // Filtering anything?
    if (isset($filter)) {
        $context['filter'] =& $filter;
        // Set the filtering context.
        if ($filter['variable'] == 'id_member') {
            $id = $filter['value']['sql'];
            loadMemberData($id, false, 'minimal');
            $context['filter']['value']['html'] = '<a href="' . $scripturl . '?action=profile;u=' . $id . '">' . $user_profile[$id]['real_name'] . '</a>';
        } elseif ($filter['variable'] == 'url') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars((substr($filter['value']['sql'], 0, 1) == '?' ? $scripturl : '') . $filter['value']['sql']), array('\\_' => '_')) . '\'';
        } elseif ($filter['variable'] == 'message') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '&lt;br /&gt;' => '<br />', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\'';
            $context['filter']['value']['html'] = preg_replace('~&amp;lt;span class=&amp;quot;remove&amp;quot;&amp;gt;(.+?)&amp;lt;/span&amp;gt;~', '$1', $context['filter']['value']['html']);
        } elseif ($filter['variable'] == 'error_type') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '&lt;br /&gt;' => '<br />', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\'';
        } else {
            $context['filter']['value']['html'] =& $filter['value']['sql'];
        }
    }
    $context['error_types'] = array();
    $context['error_types']['all'] = array('label' => $txt['errortype_all'], 'description' => isset($txt['errortype_all_desc']) ? $txt['errortype_all_desc'] : '', 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : ''), 'is_selected' => empty($filter));
    $sum = 0;
    // What type of errors do we have and how many do we have?
    $request = $smcFunc['db_query']('', '
		SELECT error_type, COUNT(*) AS num_errors
		FROM {db_prefix}log_errors
		GROUP BY error_type
		ORDER BY error_type = {string:critical_type} DESC, error_type ASC', array('critical_type' => 'critical'));
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // Total errors so far?
        $sum += $row['num_errors'];
        $context['error_types'][$sum] = array('label' => (isset($txt['errortype_' . $row['error_type']]) ? $txt['errortype_' . $row['error_type']] : $row['error_type']) . ' (' . $row['num_errors'] . ')', 'description' => isset($txt['errortype_' . $row['error_type'] . '_desc']) ? $txt['errortype_' . $row['error_type'] . '_desc'] : '', 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . ';filter=error_type;value=' . $row['error_type'], 'is_selected' => isset($filter) && $filter['value']['sql'] == $smcFunc['db_escape_wildcard_string']($row['error_type']));
    }
    $smcFunc['db_free_result']($request);
    // Update the all errors tab with the total number of errors
    $context['error_types']['all']['label'] .= ' (' . $sum . ')';
    // Finally, work out what is the last tab!
    if (isset($context['error_types'][$sum])) {
        $context['error_types'][$sum]['is_last'] = true;
    } else {
        $context['error_types']['all']['is_last'] = true;
    }
    // And this is pretty basic ;).
    $context['page_title'] = $txt['errlog'];
    $context['has_filter'] = isset($filter);
    $context['sub_template'] = 'error_log';
}
Exemplo n.º 30
0
function MessageIndex()
{
    global $txt, $scripturl, $board, $db_prefix;
    global $modSettings, $ID_MEMBER;
    global $context, $options, $settings, $board_info, $user_info, $func;
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_messageindex';
    } else {
        loadTemplate('MessageIndex');
    }
    $context['name'] = $board_info['name'];
    $context['description'] = $board_info['description'];
    // View all the topics, or just a few?
    $maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['num_topics'] : $modSettings['defaultMaxTopics'];
    // Make sure the starting place makes sense and construct the page index.
    if (isset($_REQUEST['sort'])) {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $board_info['num_topics'], $maxindex, true);
    } else {
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%d', $_REQUEST['start'], $board_info['num_topics'], $maxindex, true);
    }
    $context['start'] =& $_REQUEST['start'];
    $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?board=' . $board . '.0' : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $modSettings['defaultMaxTopics']) : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $board_info['num_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $modSettings['defaultMaxTopics']) : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $board_info['num_topics'] ? $scripturl . '?board=' . $board . '.' . floor(($board_info['num_topics'] - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics'] : '', 'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0');
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($board_info['num_topics'] - 1) / $modSettings['defaultMaxTopics']) + 1);
    if (isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages']) {
        $maxindex = $modSettings['enableAllMessages'];
        $_REQUEST['start'] = 0;
    }
    // Build a list of the board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt[62] . '">' . $mod['name'] . '</a>';
        }
        $context['linktree'][count($context['linktree']) - 1]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt[298] : $txt[299]) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Mark current and parent boards as seen.
    if (!$user_info['is_guest']) {
        // We can't know they read it if we allow prefetches.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        db_query("\n\t\t\tREPLACE INTO {$db_prefix}log_boards\n\t\t\t\t(ID_MSG, ID_MEMBER, ID_BOARD)\n\t\t\tVALUES ({$modSettings['maxMsgID']}, {$ID_MEMBER}, {$board})", __FILE__, __LINE__);
        if (!empty($board_info['parent_boards'])) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}log_boards\n\t\t\t\tSET ID_MSG = {$modSettings['maxMsgID']}\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_BOARD IN (" . implode(',', array_keys($board_info['parent_boards'])) . ")\n\t\t\t\tLIMIT " . count($board_info['parent_boards']), __FILE__, __LINE__);
            // We've seen all these boards now!
            foreach ($board_info['parent_boards'] as $k => $dummy) {
                if (isset($_SESSION['topicseen_cache'][$k])) {
                    unset($_SESSION['topicseen_cache'][$k]);
                }
            }
        }
        if (isset($_SESSION['topicseen_cache'][$board])) {
            unset($_SESSION['topicseen_cache'][$board]);
        }
        $request = db_query("\n\t\t\tSELECT sent\n\t\t\tFROM {$db_prefix}log_notify\n\t\t\tWHERE ID_BOARD = {$board}\n\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        $context['is_marked_notify'] = mysql_num_rows($request) != 0;
        if ($context['is_marked_notify']) {
            list($sent) = mysql_fetch_row($request);
            if (!empty($sent)) {
                db_query("\n\t\t\t\t\tUPDATE {$db_prefix}log_notify\n\t\t\t\t\tSET sent = 0\n\t\t\t\t\tWHERE ID_BOARD = {$board}\n\t\t\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            }
        }
        mysql_free_result($request);
    } else {
        $context['is_marked_notify'] = false;
    }
    // 'Print' the header and board info.
    $context['page_title'] = strip_tags($board_info['name']);
    // Set the variables up for the template.
    $context['can_mark_notify'] = allowedTo('mark_notify') && !$user_info['is_guest'];
    $context['can_post_new'] = allowedTo('post_new');
    $context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post');
    $context['can_moderate_forum'] = allowedTo('moderate_forum');
    // Aren't children wonderful things?
    $result = db_query("\n\t\tSELECT\n\t\t\tb.ID_BOARD, b.name, b.description, b.numTopics, b.numPosts,\n\t\t\tm.posterName, m.posterTime, m.subject, m.ID_MSG, m.ID_TOPIC,\n\t\t\tIFNULL(mem.realName, m.posterName) AS realName, " . (!$user_info['is_guest'] ? "\n\t\t\t(IFNULL(lb.ID_MSG, 0) >= b.ID_MSG_UPDATED) AS isRead," : "1 AS isRead,") . "\n\t\t\tIFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER, IFNULL(mem2.ID_MEMBER, 0) AS ID_MODERATOR,\n\t\t\tmem2.realName AS modRealName\n\t\tFROM {$db_prefix}boards AS b\n\t\t\tLEFT JOIN {$db_prefix}messages AS m ON (m.ID_MSG = b.ID_LAST_MSG)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)" . (!$user_info['is_guest'] ? "\n\t\t\tLEFT JOIN {$db_prefix}log_boards AS lb ON (lb.ID_BOARD = b.ID_BOARD AND lb.ID_MEMBER = {$ID_MEMBER})" : '') . "\n\t\t\tLEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = b.ID_BOARD)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem2 ON (mem2.ID_MEMBER = mods.ID_MEMBER)\n\t\tWHERE b.ID_PARENT = {$board}\n\t\t\tAND {$user_info['query_see_board']}", __FILE__, __LINE__);
    if (mysql_num_rows($result) != 0) {
        $theboards = array();
        while ($row_board = mysql_fetch_assoc($result)) {
            if (!isset($context['boards'][$row_board['ID_BOARD']])) {
                $theboards[] = $row_board['ID_BOARD'];
                // Make sure the subject isn't too long.
                censorText($row_board['subject']);
                $short_subject = shorten_subject($row_board['subject'], 24);
                $context['boards'][$row_board['ID_BOARD']] = array('id' => $row_board['ID_BOARD'], 'last_post' => array('id' => $row_board['ID_MSG'], 'time' => $row_board['posterTime'] > 0 ? timeformat($row_board['posterTime']) : $txt[470], 'timestamp' => forum_time(true, $row_board['posterTime']), 'subject' => $short_subject, 'member' => array('id' => $row_board['ID_MEMBER'], 'username' => $row_board['posterName'] != '' ? $row_board['posterName'] : $txt[470], 'name' => $row_board['realName'], 'href' => !empty($row_board['ID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row_board['ID_MEMBER'] : '', 'link' => $row_board['posterName'] != '' ? !empty($row_board['ID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MEMBER'] . '">' . $row_board['realName'] . '</a>' : $row_board['realName'] : $txt[470]), 'start' => 'new', 'topic' => $row_board['ID_TOPIC'], 'href' => $row_board['subject'] != '' ? $scripturl . '?topic=' . $row_board['ID_TOPIC'] . '.new' . (empty($row_board['isRead']) ? ';boardseen' : '') . '#new' : '', 'link' => $row_board['subject'] != '' ? '<a href="' . $scripturl . '?topic=' . $row_board['ID_TOPIC'] . '.new' . (empty($row_board['isRead']) ? ';boardseen' : '') . '#new" title="' . $row_board['subject'] . '">' . $short_subject . '</a>' : $txt[470]), 'new' => empty($row_board['isRead']) && $row_board['posterName'] != '', 'name' => $row_board['name'], 'description' => $row_board['description'], 'moderators' => array(), 'link_moderators' => array(), 'children' => array(), 'link_children' => array(), 'children_new' => false, 'topics' => $row_board['numTopics'], 'posts' => $row_board['numPosts'], 'href' => $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_board['ID_BOARD'] . '.0">' . $row_board['name'] . '</a>');
            }
            if (!empty($row_board['ID_MODERATOR'])) {
                $context['boards'][$row_board['ID_BOARD']]['moderators'][$row_board['ID_MODERATOR']] = array('id' => $row_board['ID_MODERATOR'], 'name' => $row_board['modRealName'], 'href' => $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row_board['modRealName'] . '</a>');
                $context['boards'][$row_board['ID_BOARD']]['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row_board['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row_board['modRealName'] . '</a>';
            }
        }
        mysql_free_result($result);
        // Load up the child boards.
        $result = db_query("\n\t\t\tSELECT\n\t\t\t\tb.ID_BOARD, b.ID_PARENT, b.name, b.description, b.numTopics, b.numPosts,\n\t\t\t\tm.posterName, IFNULL(m.posterTime, 0) AS posterTime, m.subject, m.ID_MSG, m.ID_TOPIC,\n\t\t\t\tIFNULL(mem.realName, m.posterName) AS realName, ID_PARENT, \n\t\t\t\t" . ($user_info['is_guest'] ? '1' : '(IFNULL(lb.ID_MSG, 0) >= b.ID_MSG_UPDATED)') . " AS isRead,\n\t\t\t\tIFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\tLEFT JOIN {$db_prefix}messages AS m ON (m.ID_MSG = b.ID_LAST_MSG)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)" . (!$user_info['is_guest'] ? "\n\t\t\t\tLEFT JOIN {$db_prefix}log_boards AS lb ON (lb.ID_BOARD = b.ID_BOARD AND lb.ID_MEMBER = {$ID_MEMBER})" : '') . "\n\t\t\tWHERE " . (empty($modSettings['countChildPosts']) ? "b.ID_PARENT IN (" . implode(',', $theboards) . ")" : "childLevel > 0") . "\n\t\t\t\tAND {$user_info['query_see_board']}", __FILE__, __LINE__);
        $parent_map = array();
        while ($row = mysql_fetch_assoc($result)) {
            // We've got a child of a child, then... possibly.
            if (!in_array($row['ID_PARENT'], $theboards)) {
                if (!isset($parent_map[$row['ID_PARENT']])) {
                    continue;
                }
                $parent_map[$row['ID_PARENT']][0]['posts'] += $row['numPosts'];
                $parent_map[$row['ID_PARENT']][0]['topics'] += $row['numTopics'];
                $parent_map[$row['ID_PARENT']][1]['posts'] += $row['numPosts'];
                $parent_map[$row['ID_PARENT']][1]['topics'] += $row['numTopics'];
                $parent_map[$row['ID_BOARD']] = $parent_map[$row['ID_PARENT']];
                continue;
            }
            if ($context['boards'][$row['ID_PARENT']]['last_post']['timestamp'] < forum_time(true, $row['posterTime'])) {
                // Make sure the subject isn't too long.
                censorText($row['subject']);
                $short_subject = shorten_subject($row['subject'], 24);
                $context['boards'][$row['ID_PARENT']]['last_post'] = array('id' => $row['ID_MSG'], 'time' => $row['posterTime'] > 0 ? timeformat($row['posterTime']) : $txt[470], 'timestamp' => forum_time(true, $row['posterTime']), 'subject' => $short_subject, 'member' => array('username' => $row['posterName'] != '' ? $row['posterName'] : $txt[470], 'name' => $row['realName'], 'id' => $row['ID_MEMBER'], 'href' => !empty($row['ID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] : '', 'link' => $row['posterName'] != '' ? !empty($row['ID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['realName'] . '</a>' : $row['realName'] : $txt[470]), 'start' => 'new', 'topic' => $row['ID_TOPIC'], 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.new' . (empty($row['isRead']) ? ';boardseen' : '') . '#new');
                $context['boards'][$row['ID_PARENT']]['last_post']['link'] = $row['subject'] != '' ? '<a href="' . $context['boards'][$row['ID_PARENT']]['last_post']['href'] . '" title="' . $row['subject'] . '">' . $short_subject . '</a>' : $txt[470];
            }
            $context['boards'][$row['ID_PARENT']]['children'][$row['ID_BOARD']] = array('id' => $row['ID_BOARD'], 'name' => $row['name'], 'description' => $row['description'], 'new' => empty($row['isRead']) && $row['posterName'] != '', 'topics' => $row['numTopics'], 'posts' => $row['numPosts'], 'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['name'] . '</a>');
            $context['boards'][$row['ID_PARENT']]['link_children'][] = '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['name'] . '</a>';
            $context['boards'][$row['ID_PARENT']]['children_new'] |= empty($row['isRead']) && $row['posterName'] != '';
            if (!empty($modSettings['countChildPosts'])) {
                $context['boards'][$row['ID_PARENT']]['posts'] += $row['numPosts'];
                $context['boards'][$row['ID_PARENT']]['topics'] += $row['numTopics'];
                $parent_map[$row['ID_BOARD']] = array(&$context['boards'][$row['ID_PARENT']], &$context['boards'][$row['ID_PARENT']]['children'][$row['ID_BOARD']]);
            }
        }
    }
    mysql_free_result($result);
    // Nosey, nosey - who's viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tlo.ID_MEMBER, lo.logTime, mem.realName, mem.memberName, mem.showOnline,\n\t\t\t\tmg.onlineColor, mg.ID_GROUP, mg.groupName\n\t\t\tFROM {$db_prefix}log_online AS lo\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = lo.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = IF(mem.ID_GROUP = 0, mem.ID_POST_GROUP, mem.ID_GROUP))\n\t\t\tWHERE INSTR(lo.url, 's:5:\"board\";i:{$board};') OR lo.session = '" . ($user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()) . "'", __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            if (empty($row['ID_MEMBER'])) {
                continue;
            }
            if (!empty($row['onlineColor'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '" style="color: ' . $row['onlineColor'] . ';">' . $row['realName'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['realName'] . '</a>';
            }
            $is_buddy = in_array($row['ID_MEMBER'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<b>' . $link . '</b>';
            }
            if (!empty($row['showOnline']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['logTime'] . $row['memberName']] = empty($row['showOnline']) ? '<i>' . $link . '</i>' : $link;
            }
            $context['view_members'][$row['logTime'] . $row['memberName']] = array('id' => $row['ID_MEMBER'], 'username' => $row['memberName'], 'name' => $row['realName'], 'group' => $row['ID_GROUP'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['showOnline']));
            if (empty($row['showOnline'])) {
                $context['view_num_hidden']++;
            }
        }
        $context['view_num_guests'] = mysql_num_rows($request) - count($context['view_members']);
        mysql_free_result($request);
        // Put them in "last clicked" order.
        krsort($context['view_members_list']);
        krsort($context['view_members']);
    }
    // Default sort methods.
    $sort_methods = array('subject' => 'mf.subject', 'starter' => 'IFNULL(memf.realName, mf.posterName)', 'last_poster' => 'IFNULL(meml.realName, ml.posterName)', 'replies' => 't.numReplies', 'views' => 't.numViews', 'first_post' => 't.ID_TOPIC', 'last_post' => 't.ID_LAST_MSG');
    // They didn't pick one, default to by last post descending.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'last_post';
        $_REQUEST['sort'] = 'ID_LAST_MSG';
        $ascending = isset($_REQUEST['asc']);
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
        $ascending = !isset($_REQUEST['desc']);
    }
    $context['sort_direction'] = $ascending ? 'up' : 'down';
    // Calculate the fastest way to get the topics.
    $start = $_REQUEST['start'];
    if ($start > ($board_info['num_topics'] - 1) / 2) {
        $ascending = !$ascending;
        $fake_ascending = true;
        $maxindex = $board_info['num_topics'] < $start + $maxindex + 1 ? $board_info['num_topics'] - $start : $maxindex;
        $start = $board_info['num_topics'] < $start + $maxindex + 1 ? 0 : $board_info['num_topics'] - $start - $maxindex;
    } else {
        $fake_ascending = false;
    }
    // Setup the default topic icons...
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $topic_ids = array();
    $context['topics'] = array();
    // Sequential pages are often not optimized, so we add an additional query.
    $pre_query = $start > 0;
    if ($pre_query) {
        $request = db_query("\n\t\t\tSELECT t.ID_TOPIC\n\t\t\tFROM ({$db_prefix}topics AS t" . ($context['sort_by'] === 'last_poster' ? ", {$db_prefix}messages AS ml" : (in_array($context['sort_by'], array('starter', 'subject')) ? ", {$db_prefix}messages AS mf" : '')) . ')' . ($context['sort_by'] === 'starter' ? "\n\t\t\t\tLEFT JOIN {$db_prefix}members AS memf ON (memf.ID_MEMBER = mf.ID_MEMBER)" : '') . ($context['sort_by'] === 'last_poster' ? "\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)" : '') . "\n\t\t\tWHERE t.ID_BOARD = {$board}" . ($context['sort_by'] === 'last_poster' ? "\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG" : (in_array($context['sort_by'], array('starter', 'subject')) ? "\n\t\t\t\tAND mf.ID_MSG = t.ID_FIRST_MSG" : '')) . "\n\t\t\tORDER BY " . (!empty($modSettings['enableStickyTopics']) ? 'isSticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT {$start}, {$maxindex}", __FILE__, __LINE__);
        $topic_ids = array();
        while ($row = mysql_fetch_assoc($request)) {
            $topic_ids[] = $row['ID_TOPIC'];
        }
    }
    // Grab the appropriate topic information...
    if (!$pre_query || !empty($topic_ids)) {
        $result = db_query("\n\t\t\tSELECT\n\t\t\t\tt.ID_TOPIC, t.numReplies, t.locked, t.numViews, t.isSticky, t.ID_POLL,\n\t\t\t\t" . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1') . " AS new_from,\n\t\t\t\tt.ID_LAST_MSG, ml.posterTime AS lastPosterTime, ml.ID_MSG_MODIFIED,\n\t\t\t\tml.subject AS lastSubject, ml.icon AS lastIcon, ml.posterName AS lastMemberName,\n\t\t\t\tml.ID_MEMBER AS lastID_MEMBER, IFNULL(meml.realName, ml.posterName) AS lastDisplayName,\n\t\t\t\tt.ID_FIRST_MSG, mf.posterTime AS firstPosterTime,\n\t\t\t\tmf.subject AS firstSubject, mf.icon AS firstIcon, mf.posterName AS firstMemberName,\n\t\t\t\tmf.ID_MEMBER AS firstID_MEMBER, IFNULL(memf.realName, mf.posterName) AS firstDisplayName,\n\t\t\t\tLEFT(ml.body, 384) AS lastBody, LEFT(mf.body, 384) AS firstBody, ml.smileysEnabled AS lastSmileys,\n\t\t\t\tmf.smileysEnabled AS firstSmileys\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS ml, {$db_prefix}messages AS mf)\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}members AS memf ON (memf.ID_MEMBER = mf.ID_MEMBER)" . ($user_info['is_guest'] ? '' : "\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 = {$board} AND lmr.ID_MEMBER = {$ID_MEMBER})") . "\n\t\t\tWHERE " . ($pre_query ? 't.ID_TOPIC IN (' . implode(', ', $topic_ids) . ')' : "t.ID_BOARD = {$board}") . "\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\t\tAND mf.ID_MSG = t.ID_FIRST_MSG\n\t\t\tORDER BY " . ($pre_query ? "FIND_IN_SET(t.ID_TOPIC, '" . implode(',', $topic_ids) . "')" : (!empty($modSettings['enableStickyTopics']) ? 'isSticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . "\n\t\t\tLIMIT " . ($pre_query ? '' : "{$start}, ") . "{$maxindex}", __FILE__, __LINE__);
        // Begin 'printing' the message index for current board.
        while ($row = mysql_fetch_assoc($result)) {
            if ($row['ID_POLL'] > 0 && $modSettings['pollMode'] == '0') {
                continue;
            }
            if (!$pre_query) {
                $topic_ids[] = $row['ID_TOPIC'];
            }
            // Limit them to 128 characters - do this FIRST because it's a lot of wasted censoring otherwise.
            $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) . '...';
            }
            // Censor the subject and message preview.
            censorText($row['firstSubject']);
            censorText($row['firstBody']);
            // Don't censor them twice!
            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 . '">' . $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...
            if (empty($modSettings['messageIconChecks_disable'])) {
                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';
                }
                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';
                }
            } else {
                if (!isset($context['icon_sources'][$row['firstIcon']])) {
                    $context['icon_sources'][$row['firstIcon']] = 'images_url';
                }
                if (!isset($context['icon_sources'][$row['lastIcon']])) {
                    $context['icon_sources'][$row['lastIcon']] = 'images_url';
                }
            }
            // 'Print' the topic info.
            $context['topics'][$row['ID_TOPIC']] = array('id' => $row['ID_TOPIC'], 'first_post' => array('id' => $row['ID_FIRST_MSG'], 'member' => array('username' => $row['firstMemberName'], 'name' => $row['firstDisplayName'], 'id' => $row['firstID_MEMBER'], 'href' => !empty($row['firstID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row['firstID_MEMBER'] : '', 'link' => !empty($row['firstID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['firstID_MEMBER'] . '" title="' . $txt[92] . ' ' . $row['firstDisplayName'] . '">' . $row['firstDisplayName'] . '</a>' : $row['firstDisplayName']), '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', 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0">' . $row['firstSubject'] . '</a>'), 'last_post' => array('id' => $row['ID_LAST_MSG'], 'member' => array('username' => $row['lastMemberName'], 'name' => $row['lastDisplayName'], 'id' => $row['lastID_MEMBER'], 'href' => !empty($row['lastID_MEMBER']) ? $scripturl . '?action=profile;u=' . $row['lastID_MEMBER'] : '', 'link' => !empty($row['lastID_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['lastID_MEMBER'] . '">' . $row['lastDisplayName'] . '</a>' : $row['lastDisplayName']), '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']) . '#new', 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['ID_LAST_MSG']) . '#new">' . $row['lastSubject'] . '</a>'), 'tagCount' => 0, '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'], 'new' => $row['new_from'] <= $row['ID_MSG_MODIFIED'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['new_from'] . '#new', 'pages' => $pages, 'replies' => $row['numReplies'], 'views' => $row['numViews']);
            determineTopicClass($context['topics'][$row['ID_TOPIC']]);
        }
        mysql_free_result($result);
        // Tagging system
        if ($modSettings['smftags_set_display_messageindex'] && in_array($context['current_board'], explode(" ", $modSettings['smftags_set_taggable'])) && !empty($topic_ids)) {
            // this query is seperated due to lack of optimisation if integrated in to the main query above
            $result = db_query('
				SELECT ID_TOPIC, COUNT(ID_TAG) AS tagCount
				FROM smf_tags_log
				WHERE ID_TOPIC IN (' . implode(', ', $topic_ids) . ')
				GROUP BY ID_TOPIC
				', __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($result)) {
                $context['topics'][$row['ID_TOPIC']]['tagCount'] = !empty($row['tagCount']) ? $row['tagCount'] : 0;
            }
            mysql_free_result($result);
        }
        // End tagging system
        // Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...)
        if ($fake_ascending) {
            $context['topics'] = array_reverse($context['topics'], true);
        }
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids)) {
            $result = db_query("\n\t\t\t\tSELECT ID_TOPIC\n\t\t\t\tFROM {$db_prefix}messages\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $topic_ids) . ")\n\t\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tGROUP BY ID_TOPIC\n\t\t\t\tLIMIT " . count($topic_ids), __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($result)) {
                $context['topics'][$row['ID_TOPIC']]['is_posted_in'] = true;
                $context['topics'][$row['ID_TOPIC']]['class'] = 'my_' . $context['topics'][$row['ID_TOPIC']]['class'];
            }
            mysql_free_result($result);
        }
    }
    loadJumpTo();
    // Is Quick Moderation active?
    if (!empty($options['display_quick_mod'])) {
        $context['can_lock'] = allowedTo('lock_any');
        $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']);
        $context['can_move'] = allowedTo('move_any');
        $context['can_remove'] = allowedTo('remove_any');
        $context['can_merge'] = allowedTo('merge_any');
        // Set permissions for all the topics.
        foreach ($context['topics'] as $t => $topic) {
            $started = $topic['first_post']['member']['id'] == $ID_MEMBER;
            $context['topics'][$t]['quick_mod'] = array('lock' => allowedTo('lock_any') || $started && allowedTo('lock_own'), 'sticky' => allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']), 'move' => allowedTo('move_any') || $started && allowedTo('move_own'), 'modify' => allowedTo('modify_any') || $started && allowedTo('modify_own'), 'remove' => allowedTo('remove_any') || $started && allowedTo('remove_own'));
            $context['can_lock'] |= $started && allowedTo('lock_own');
            $context['can_move'] |= $started && allowedTo('move_own');
            $context['can_remove'] |= $started && allowedTo('remove_own');
        }
        $board_count = 0;
        foreach ($context['jump_to'] as $id => $cat) {
            if (!empty($_SESSION['move_to_topic']) && isset($context['jump_to'][$id]['boards'][$_SESSION['move_to_topic']])) {
                $context['jump_to'][$id]['boards'][$_SESSION['move_to_topic']]['selected'] = true;
            }
            $board_count += count($context['jump_to'][$id]['boards']);
        }
        // You can only see just this one board?
        if ($board_count <= 1) {
            $context['can_move'] = false;
        }
    }
    // If there are children, but no topics and no ability to post topics...
    $context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new'];
}