function getLastPosts($latestPostOptions) { global $scripturl, $txt, $user_info, $modSettings, $smcFunc, $context; // Find all the posts. Newer ones will have higher IDs. (assuming the last 20 * number are accessable...) // !!!SLOW This query is now slow, NEEDS to be fixed. Maybe break into two? $request = smf_db_query(' SELECT m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, b.name, m1.subject AS first_subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, t.id_board, b.name AS board_name, SUBSTRING(m.body, 1, 385) AS body, m.smileys_enabled FROM {db_prefix}messages AS m 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) INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_msg >= {int:likely_max_msg}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' AND b.id_board != {int:recycle_board}' : '') . ' AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved} AND m.approved = {int:is_approved}' : '') . ' ORDER BY m.id_msg DESC LIMIT ' . $latestPostOptions['number_posts'], array('likely_max_msg' => max(0, $modSettings['maxMsgID'] - 50 * $latestPostOptions['number_posts']), 'recycle_board' => $modSettings['recycle_board'], 'is_approved' => 1)); $posts = array(); while ($row = mysql_fetch_assoc($request)) { // Censor the subject and post for the preview ;). censorText($row['subject']); censorText($row['body']); $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br />' => ' '))); if (commonAPI::strlen($row['body']) > 128) { $row['body'] = commonAPI::substr($row['body'], 0, 128) . '...'; } $bhref = URL::board($row['id_board'], $row['board_name'], 0, true); $mhref = URL::user($row['id_member'], $row['poster_name']); $thref = URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['id_msg'], ';topicseen#msg' . $row['id_msg']); // Build the array. $posts[] = array('board' => array('id' => $row['id_board'], 'name' => $row['board_name'], 'href' => $bhref, 'link' => '<a href="' . $bhref . '">' . $row['board_name'] . '</a>'), 'topic' => $row['id_topic'], 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => empty($row['id_member']) ? '' : $mhref, 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $mhref . '">' . $row['poster_name'] . '</a>'), 'subject' => $row['subject'], 'short_subject' => shorten_subject($row['subject'], 35), 'preview' => $row['body'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'raw_timestamp' => $row['poster_time'], 'href' => $thref, 'link' => '<a href="' . $thref . '" rel="nofollow">' . $row['first_subject'] . '</a>'); } mysql_free_result($request); return $posts; }
function getBoardParents($id_parent) { // First check if we have this cached already. if (($boards = CacheAPI::getCache('board_parents-' . $id_parent, 480)) === null) { $boards = array(); $original_parent = $id_parent; // Loop while the parent is non-zero. while ($id_parent != 0) { $result = smf_db_query(' SELECT b.id_parent, b.name, {int:board_parent} AS id_board, IFNULL(mem.id_member, 0) AS id_moderator, mem.real_name, b.child_level FROM {db_prefix}boards AS b LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = b.id_board) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member) WHERE b.id_board = {int:board_parent}', array('board_parent' => $id_parent)); // In the EXTREMELY unlikely event this happens, give an error message. if (mysql_num_rows($result) == 0) { fatal_lang_error('parent_not_found', 'critical'); } while ($row = mysql_fetch_assoc($result)) { if (!isset($boards[$row['id_board']])) { $id_parent = $row['id_parent']; $boards[$row['id_board']] = array('url' => URL::board($row['id_board'], $row['name'], 0), 'name' => $row['name'], 'level' => $row['child_level'], 'moderators' => array()); } // If a moderator exists for this board, add that moderator for all children too. if (!empty($row['id_moderator'])) { foreach ($boards as $id => $dummy) { $mhref = URL::user($row['id_moderator'], $row['real_name']); $boards[$id]['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $mhref, 'link' => '<a href="' . $mhref . '">' . $row['real_name'] . '</a>'); } } } mysql_free_result($result); } CacheAPI::putCache('board_parents-' . $original_parent, $boards, 480); } return $boards; }
function getBoardIndex($boardIndexOptions) { global $smcFunc, $scripturl, $user_info, $modSettings, $txt; global $settings, $context; // For performance, track the latest post while going through the boards. if (!empty($boardIndexOptions['set_latest_post'])) { $latest_post = array('timestamp' => 0, 'ref' => 0); } // Find all boards and categories, as well as related information. This will be sorted by the natural order of boards and categories, which we control. $result_boards = smf_db_query(' SELECT' . ($boardIndexOptions['include_categories'] ? ' c.id_cat, c.name AS cat_name, c.description AS cat_desc,' : '') . ' b.id_board, b.name AS board_name, b.description, b.redirect, b.icon AS boardicon, CASE WHEN b.redirect != {string:blank_string} THEN 1 ELSE 0 END AS is_redirect, b.num_posts, b.num_topics, b.unapproved_posts, b.unapproved_topics, b.id_parent, b.allow_topics, IFNULL(m.poster_time, 0) AS poster_time, IFNULL(mem.member_name, m.poster_name) AS poster_name, m.subject, m1.subject AS first_subject, m.id_topic, t.id_first_msg AS id_first_msg, t.id_prefix, m1.icon AS icon, IFNULL(mem.real_name, m.poster_name) AS real_name, p.name as topic_prefix, ' . ($user_info['is_guest'] ? ' 1 AS is_read, 0 AS new_from,' : ' (IFNULL(lb.id_msg, 0) >= b.id_msg_updated) AS is_read, IFNULL(lb.id_msg, -1) + 1 AS new_from,' . ($boardIndexOptions['include_categories'] ? ' c.can_collapse, IFNULL(cc.id_member, 0) AS is_collapsed,' : '')) . ' IFNULL(mem.id_member, 0) AS id_member, m.id_msg, IFNULL(mods_mem.id_member, 0) AS id_moderator, mods_mem.real_name AS mod_real_name FROM {db_prefix}boards AS b' . ($boardIndexOptions['include_categories'] ? ' LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)' : '') . ' LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = b.id_last_msg) LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) LEFT JOIN {db_prefix}prefixes AS p ON (p.id_prefix = t.id_prefix) LEFT JOIN {db_prefix}messages AS m1 ON (m1.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_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})' . ($boardIndexOptions['include_categories'] ? ' LEFT JOIN {db_prefix}collapsed_categories AS cc ON (cc.id_cat = c.id_cat AND cc.id_member = {int:current_member})' : '')) . ' LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = b.id_board) LEFT JOIN {db_prefix}members AS mods_mem ON (mods_mem.id_member = mods.id_member) WHERE {query_see_board}' . (empty($boardIndexOptions['countChildPosts']) ? empty($boardIndexOptions['base_level']) ? '' : ' AND b.child_level >= {int:child_level}' : ' AND b.child_level BETWEEN ' . $boardIndexOptions['base_level'] . ' AND ' . ($boardIndexOptions['base_level'] + 1)), array('current_member' => $user_info['id'], 'child_level' => $boardIndexOptions['base_level'], 'blank_string' => '')); // Start with an empty array. if ($boardIndexOptions['include_categories']) { $categories = array(); } else { $this_category = array(); } $total_ignored_boards = 0; // Run through the categories and boards (or only boards).... while ($row_board = mysql_fetch_assoc($result_boards)) { // Perhaps we are ignoring this board? $ignoreThisBoard = in_array($row_board['id_board'], $user_info['ignoreboards']); $total_ignored_boards += $ignoreThisBoard ? 1 : 0; $row_board['is_read'] = !empty($row_board['is_read']) || $ignoreThisBoard ? '1' : '0'; if ($boardIndexOptions['include_categories']) { // Haven't set this category yet. if (empty($categories[$row_board['id_cat']])) { $categories[$row_board['id_cat']] = array('id' => $row_board['id_cat'], 'name' => $row_board['cat_name'], 'desc' => $row_board['cat_desc'], 'is_collapsed' => isset($row_board['can_collapse']) && $row_board['can_collapse'] == 1 && $row_board['is_collapsed'] > 0, 'can_collapse' => isset($row_board['can_collapse']) && $row_board['can_collapse'] == 1, 'collapse_href' => isset($row_board['can_collapse']) ? $scripturl . '?action=collapse;c=' . $row_board['id_cat'] . ';sa=' . ($row_board['is_collapsed'] > 0 ? 'expand;' : 'collapse;') . $context['session_var'] . '=' . $context['session_id'] . '#c' . $row_board['id_cat'] : '', 'collapse_image' => isset($row_board['can_collapse']) ? '<img class="clipsrc ' . ($row_board['is_collapsed'] ? ' _expand' : '_collapse') . '" src="' . $settings['images_url'] . '/clipsrc.png" alt="-" />' : '', 'href' => $scripturl . '#c' . $row_board['id_cat'], 'boards' => array(), 'is_root' => $row_board['cat_name'][0] === '!' ? true : false, 'new' => false); $categories[$row_board['id_cat']]['link'] = '<a id="c' . $row_board['id_cat'] . '"></a>' . ($categories[$row_board['id_cat']]['can_collapse'] ? '<a href="' . $categories[$row_board['id_cat']]['collapse_href'] . '">' . $row_board['cat_name'] . '</a>' : $row_board['cat_name']); } // If this board has new posts in it (and isn't the recycle bin!) then the category is new. if (empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $row_board['id_board']) { $categories[$row_board['id_cat']]['new'] |= empty($row_board['is_read']) && $row_board['poster_name'] != ''; } // Avoid showing category unread link where it only has redirection boards. $categories[$row_board['id_cat']]['show_unread'] = !empty($categories[$row_board['id_cat']]['show_unread']) ? 1 : !$row_board['is_redirect']; // Collapsed category - don't do any of this. //if ($categories[$row_board['id_cat']]['is_collapsed']) // continue; // Let's save some typing. Climbing the array might be slower, anyhow. $this_category =& $categories[$row_board['id_cat']]['boards']; } // This is a parent board. if ($row_board['id_parent'] == $boardIndexOptions['parent_id']) { // Is this a new board, or just another moderator? if (!isset($this_category[$row_board['id_board']])) { // Not a child. $isChild = false; $href = URL::board($row_board['id_board'], $row_board['board_name'], 0, false); $this_category[$row_board['id_board']] = array('new' => empty($row_board['is_read']), 'id' => $row_board['id_board'], 'name' => $row_board['board_name'], 'description' => $row_board['description'], 'moderators' => array(), 'link_moderators' => array(), 'children' => array(), 'link_children' => array(), 'children_new' => false, 'topics' => $row_board['num_topics'], 'posts' => $row_board['num_posts'], 'is_redirect' => $row_board['is_redirect'], 'is_page' => !empty($row_board['redirect']) && $row_board['redirect'][0] === '%' && intval(substr($row_board['redirect'], 1)) > 0, 'redirect' => $row_board['redirect'], 'boardicon' => $row_board['boardicon'], 'unapproved_topics' => $row_board['unapproved_topics'], 'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'], 'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])), 'href' => $href, 'link' => '<a href="' . $href . '">' . $row_board['board_name'] . '</a>', 'act_as_cat' => $row_board['allow_topics'] ? false : true, 'ignored' => $ignoreThisBoard); $this_category[$row_board['id_board']]['page_link'] = $this_category[$row_board['id_board']]['is_page'] ? URL::topic(intval(substr($this_category[$row_board['id_board']]['redirect'], 1)), $this_category[$row_board['id_board']]['name'], 0) : ''; } if (!empty($row_board['id_moderator'])) { $this_category[$row_board['id_board']]['moderators'][$row_board['id_moderator']] = array('id' => $row_board['id_moderator'], 'name' => $row_board['mod_real_name'], 'href' => $scripturl . '?action=profile;u=' . $row_board['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_board['id_moderator'] . '" title="' . $txt['board_moderator'] . '">' . $row_board['mod_real_name'] . '</a>'); $this_category[$row_board['id_board']]['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row_board['id_moderator'] . '" title="' . $txt['board_moderator'] . '">' . $row_board['mod_real_name'] . '</a>'; } } elseif (isset($this_category[$row_board['id_parent']]['children']) && !isset($this_category[$row_board['id_parent']]['children'][$row_board['id_board']])) { // A valid child! $isChild = true; $href = URL::board($row_board['id_board'], $row_board['board_name'], 0, false); $this_category[$row_board['id_parent']]['children'][$row_board['id_board']] = array('id' => $row_board['id_board'], 'name' => $row_board['board_name'], 'description' => $row_board['description'], 'short_description' => !empty($row_board['description']) ? $modSettings['child_board_desc_shortened'] ? '(' . commonAPI::substr($row_board['description'], 0, $modSettings['child_board_desc_shortened']) . '...)' : '(' . $row_board['description'] . ')' : '', 'new' => empty($row_board['is_read']) && $row_board['poster_name'] != '', 'topics' => $row_board['num_topics'], 'posts' => $row_board['num_posts'], 'is_redirect' => $row_board['is_redirect'], 'is_page' => !empty($row_board['redirect']) && $row_board['redirect'][0] === '%' && intval(substr($row_board['redirect'], 1)) > 0, 'redirect' => $row_board['redirect'], 'boardicon' => $row_board['boardicon'], 'unapproved_topics' => $row_board['unapproved_topics'], 'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'], 'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])), 'href' => $href, 'link' => '<a href="' . $href . '">' . $row_board['board_name'] . '</a>', 'act_as_cat' => $row_board['allow_topics'] ? false : true, 'ignored' => $ignoreThisBoard); $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['page_link'] = $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['is_page'] ? URL::topic(intval(substr($this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['redirect'], 1)), $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['name'], 0) : ''; // Counting child board posts is... slow :/. if (!empty($boardIndexOptions['countChildPosts']) && !$row_board['is_redirect']) { $this_category[$row_board['id_parent']]['posts'] += $row_board['num_posts']; $this_category[$row_board['id_parent']]['topics'] += $row_board['num_topics']; } // Does this board contain new boards? $this_category[$row_board['id_parent']]['children_new'] |= empty($row_board['is_read']); // This is easier to use in many cases for the theme.... $this_category[$row_board['id_parent']]['link_children'][] =& $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['link']; } elseif (!empty($boardIndexOptions['countChildPosts'])) { if (!isset($parent_map)) { $parent_map = array(); } if (!isset($parent_map[$row_board['id_parent']])) { foreach ($this_category as $id => $board) { if (!isset($board['children'][$row_board['id_parent']])) { continue; } $parent_map[$row_board['id_parent']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['id_parent']]); $parent_map[$row_board['id_board']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['id_parent']]); break; } } if (isset($parent_map[$row_board['id_parent']]) && !$row_board['is_redirect']) { $parent_map[$row_board['id_parent']][0]['posts'] += $row_board['num_posts']; $parent_map[$row_board['id_parent']][0]['topics'] += $row_board['num_topics']; $parent_map[$row_board['id_parent']][1]['posts'] += $row_board['num_posts']; $parent_map[$row_board['id_parent']][1]['topics'] += $row_board['num_topics']; continue; } continue; } else { continue; } // Prepare the subject, and make sure it's not too long. censorText($row_board['subject']); $mhref = $row_board['poster_name'] != '' && !empty($row_board['id_member']) ? URL::user($row_board['id_member'], $row_board['real_name']) : ''; $this_last_post = array('id' => $row_board['id_msg'], 'time' => $row_board['poster_time'] > 0 ? timeformat($row_board['poster_time']) : $txt['not_applicable'], 'timestamp' => forum_time(true, $row_board['poster_time']), 'member' => array('id' => $row_board['id_member'], 'username' => $row_board['poster_name'] != '' ? $row_board['poster_name'] : $txt['not_applicable'], 'name' => $row_board['real_name'], 'href' => $mhref, 'link' => $row_board['poster_name'] != '' ? !empty($row_board['id_member']) ? '<a onclick="getMcard(' . $row_board['id_member'] . ', $(this));return(false);" href="' . $mhref . '">' . $row_board['real_name'] . '</a>' : $row_board['real_name'] : $txt['not_applicable']), 'start' => 'msg' . $row_board['new_from'], 'topic' => $row_board['id_topic'], 'prefix' => !empty($row_board['topic_prefix']) ? html_entity_decode($row_board['topic_prefix']) . ' ' : ''); $row_board['short_subject'] = shorten_subject($row_board['subject'], 50); $this_last_post['subject'] = $row_board['short_subject']; $this_first_post = array('id' => $row_board['id_first_msg'], 'icon' => $row_board['icon'], 'icon_url' => getPostIcon($row_board['icon'])); // Provide the href and link. if ($row_board['subject'] != '') { $this_last_post['href'] = URL::topic($row_board['id_topic'], $row_board['first_subject'], 0, false, '.msg' . ($user_info['is_guest'] ? $row_board['id_msg'] : $row_board['new_from']), '#new'); if (empty($row_board['is_read'])) { $this_last_post['href'] = URL::addParam($this_last_post['href'], 'boardseen'); } //$this_last_post['href'] = $scripturl . '?topic=' . $row_board['id_topic'] . '.msg' . ($user_info['is_guest'] ? $row_board['id_msg'] : $row_board['new_from']) . (empty($row_board['is_read']) ? ';boardseen' : '') . '#new'; $this_last_post['link'] = '<a rel="nofollow" href="' . $this_last_post['href'] . '" title="' . $row_board['subject'] . '">' . $row_board['short_subject'] . '</a>'; $this_last_post['topichref'] = URL::topic($row_board['id_topic'], $row_board['first_subject'], 0); // $scripturl . '?topic=' . $row_board['id_topic']; $this_last_post['topiclink'] = '<a href="' . $this_last_post['topichref'] . '" title="' . $row_board['first_subject'] . '">' . $row_board['short_subject'] . '</a>'; } else { $this_last_post['href'] = ''; $this_last_post['link'] = $txt['not_applicable']; $this_last_post['topiclink'] = $txt['not_applicable']; } // Set the last post in the parent board. if ($row_board['id_parent'] == $boardIndexOptions['parent_id'] || $isChild && !empty($row_board['poster_time']) && $this_category[$row_board['id_parent']]['last_post']['timestamp'] < forum_time(true, $row_board['poster_time'])) { $this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['last_post'] = $this_last_post; $this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['first_post'] = $this_first_post; } // Just in the child...? if ($isChild) { $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['last_post'] = $this_last_post; $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['first_post'] = $this_first_post; // If there are no posts in this board, it really can't be new... $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['new'] &= $row_board['poster_name'] != ''; } elseif ($row_board['poster_name'] == '') { $this_category[$row_board['id_board']]['new'] = false; } // Determine a global most recent topic. if (!empty($boardIndexOptions['set_latest_post']) && !empty($row_board['poster_time']) && $row_board['poster_time'] > $latest_post['timestamp'] && !$ignoreThisBoard) { $latest_post = array('timestamp' => $row_board['poster_time'], 'ref' => &$this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['last_post']); } } mysql_free_result($result_boards); // By now we should know the most recent post...if we wanna know it that is. if (!empty($boardIndexOptions['set_latest_post']) && !empty($latest_post['ref'])) { $context['latest_post'] = $latest_post['ref']; } $hidden_boards = $visible_boards = 0; $context['hidden_boards']['id'] = $context['hidden_boards']['is_collapsed'] = 0; // only run this if we actually have some boards on the ignore list to save cycles. if ($total_ignored_boards) { if ($boardIndexOptions['include_categories']) { foreach ($categories as &$cat) { $hidden_boards += hideIgnoredBoards($cat['boards']); } } else { if (count($this_category)) { $hidden_boards += hideIgnoredBoards($this_category); } } $context['hidden_boards']['notice'] = $txt[$hidden_boards > 1 ? 'hidden_boards_notice_many' : 'hidden_boards_notice_one']; $context['hidden_boards']['setup_notice'] = sprintf($txt['hidden_boards_setup_notice'], $scripturl . '?action=profile;area=ignoreboards'); } $context['hidden_boards']['hidden_count'] = $hidden_boards; $context['hidden_boards']['visible_count'] = $visible_boards; return $boardIndexOptions['include_categories'] ? $categories : $this_category; }
function __construct($request, $total_items, $not_profile = false) { global $context, $txt, $user_info, $scripturl, $options, $memberContext, $modSettings; if (!isset($context['pageindex_multiplier'])) { $context['pageindex_multiplier'] = commonAPI::getMessagesPerPage(); } $cb_name = isset($context['cb_name']) ? $context['cb_name'] : 'topics[]'; while ($row = mysql_fetch_assoc($request)) { censorText($row['subject']); $this->topic_ids[] = $row['id_topic']; $f_post_mem_href = !empty($row['id_member']) ? URL::user($row['id_member'], $row['first_member_name']) : ''; $t_href = URL::topic($row['id_topic'], $row['subject'], 0); $l_post_mem_href = !empty($row['id_member_updated']) ? URL::user($row['id_member_updated'], $row['last_real_name']) : ''; $l_post_msg_href = URL::topic($row['id_topic'], $row['last_subject'], $user_info['is_guest'] ? !empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier'] : 0, $user_info['is_guest'] ? true : false, $user_info['is_guest'] ? '' : '.msg' . $row['id_last_msg'], $user_info['is_guest'] ? '#msg' . $row['id_last_msg'] : '#new'); $this->topiclist[$row['id_topic']] = array('id' => $row['id_topic'], 'id_member_started' => empty($row['id_member']) ? 0 : $row['id_member'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_member_name'], 'id' => empty($row['id_member']) ? 0 : $row['id_member'], 'href' => $f_post_mem_href, 'link' => !empty($row['id_member']) ? '<a onclick="getMcard(' . $row['id_member'] . ', $(this));return(false);" href="' . $f_post_mem_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_member_name'] . '">' . $row['first_member_name'] . '</a>' : $row['first_member_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['subject'], 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'href' => $t_href, 'link' => '<a href="' . $t_href . '">' . $row['subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_real_name'], 'name' => $row['last_real_name'], 'id' => $row['id_member_updated'], 'href' => $l_post_mem_href, 'link' => !empty($row['id_member_updated']) ? '<a onclick="getMcard(' . $row['id_member_updated'] . ', $(this));return(false);" href="' . $l_post_mem_href . '">' . $row['last_real_name'] . '</a>' : $row['last_real_name']), 'time' => timeformat($row['last_post_time']), 'timestamp' => forum_time(true, $row['last_post_time']), 'subject' => $row['last_subject'], 'href' => $l_post_msg_href, 'link' => '<a href="' . $l_post_msg_href . ($row['num_replies'] == 0 ? '' : ' rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'checkbox_name' => $cb_name, 'subject' => $row['subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'updated' => timeformat($row['poster_time']), 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new', 'new_link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new">' . $row['subject'] . '</a>', 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts'], 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_post_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'is_posted_in' => false, 'prefix' => '', 'pages' => '', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => false, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'board' => isset($row['id_board']) && !empty($row['id_board']) ? array('name' => $row['board_name'], 'id' => $row['id_board'], 'href' => URL::board($row['id_board'], $row['board_name'])) : array('name' => '', 'id' => 0, 'href' => '')); determineTopicClass($this->topiclist[$row['id_topic']]); if (!empty($row['id_member']) && ($row['id_member'] != $user_info['id'] || $not_profile)) { $this->users_to_load[$row['id_member']] = $row['id_member']; } } loadMemberData($this->users_to_load); foreach ($this->topiclist as &$topic) { if (!isset($memberContext[$topic['id_member_started']])) { loadMemberContext($topic['id_member_started']); } $topic['first_post']['member']['avatar'] =& $memberContext[$topic['id_member_started']]['avatar']['image']; } // figure out whether we have posted in a topic (but only if we are not the topic starter) if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($this->topic_ids)) { $result = smf_db_query(' SELECT id_topic FROM {db_prefix}messages WHERE id_topic IN ({array_int:topic_list}) AND id_member = {int:current_member} GROUP BY id_topic LIMIT ' . count($this->topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $this->topic_ids)); while ($row = mysql_fetch_assoc($result)) { if ($this->topiclist[$row['id_topic']]['first_post']['member']['id'] != $user_info['id']) { $this->topiclist[$row['id_topic']]['is_posted_in'] = true; } } mysql_free_result($result); } }
function prepareSearchContext($reset = false) { global $txt, $modSettings, $scripturl, $user_info, $sourcedir; global $memberContext, $context, $options, $messages_request; global $boards_can, $participants, $output; // Remember which message this is. (ie. reply #83) static $counter = null; if ($counter == null || $reset) { $counter = $_REQUEST['start'] + 1; } // If the query returned false, bail. if ($messages_request == false) { return false; } // Start from the beginning... if ($reset) { return @mysql_data_seek($messages_request, 0); } // Attempt to get the next message. $message = mysql_fetch_assoc($messages_request); if (!$message) { return false; } // Can't have an empty subject can we? $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; $message['first_subject'] = $message['first_subject'] != '' ? $message['first_subject'] : $txt['no_subject']; $message['last_subject'] = $message['last_subject'] != '' ? $message['last_subject'] : $txt['no_subject']; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'])) { // Notice this information isn't used anywhere else.... *cough guest table cough*. $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; // Do the censor thang... censorText($message['body']); censorText($message['subject']); censorText($message['first_subject']); censorText($message['last_subject']); // Shorten this message if necessary. if ($context['compact']) { // Set the number of characters before and after the searched keyword. $charLimit = 50; $message['body'] = strtr($message['body'], array("\n" => ' ', '<br />' => "\n")); $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); $message['body'] = strip_tags(strtr($message['body'], array('</div>' => '<br />', '</li>' => '<br />')), '<br>'); if (commonAPI::strlen($message['body']) > $charLimit) { if (empty($context['key_words'])) { $message['body'] = commonAPI::substr($message['body'], 0, $charLimit) . '<strong>...</strong>'; } else { $matchString = ''; $force_partial_word = false; foreach ($context['key_words'] as $keyword) { $keyword = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~e', 'commonAPI::entity_fix(\'\\1\')', strtr($keyword, array('\\\'' => '\'', '&' => '&'))); if (preg_match('~[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]$~', $keyword) != 0 || preg_match('~^[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]~', $keyword) != 0) { $force_partial_word = true; } $matchString .= strtr(preg_quote($keyword, '/'), array('\\*' => '.+?')) . '|'; } $matchString = substr($matchString, 0, -1); $message['body'] = un_htmlspecialchars(strtr($message['body'], array(' ' => ' ', '<br />' => "\n", '[' => '[', ']' => ']', ':' => ':', '@' => '@'))); if (empty($modSettings['search_method']) || $force_partial_word) { preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?|^)(' . $matchString . ')(.{0,' . $charLimit . '}[\\s\\W]|[^\\s\\W]{' . $charLimit . '})/isu', $message['body'], $matches); } else { preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?[\\s\\W]|^)(' . $matchString . ')([\\s\\W].{0,' . $charLimit . '}[\\s\\W]|[\\s\\W][^\\s\\W]{' . $charLimit . '})/isu', $message['body'], $matches); } $message['body'] = ''; foreach ($matches[0] as $index => $match) { $match = strtr(htmlspecialchars($match, ENT_QUOTES), array("\n" => ' ')); $message['body'] .= '<strong>......</strong> ' . $match . ' <strong>......</strong>'; } } // Re-fix the international characters. $message['body'] = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~e', 'commonAPI::entity_fix(\'\\1\')', $message['body']); } } else { // Run BBC interpreter on the message. $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); } // Make sure we don't end up with a practically empty message body. $message['body'] = preg_replace('~^(?: )+$~', '', $message['body']); // Do we have quote tag enabled? $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); $href = URL::topic($message['id_topic'], $message['first_subject'], 0); $mhref = URL::user($message['first_member_id'], $message['first_member_name']); $lhref = URL::topic($message['id_topic'], $message['last_subject'], 0, $message['num_replies'] == 0 ? true : false, $message['num_replies'] == 0 ? '' : '.msg' . $message['last_msg'], $message['num_replies'] == 0 ? '' : '#msg' . $message['last_msg']); $lmhref = URL::user($message['last_member_id'], $message['last_member_name']); $bhref = URL::board($message['id_board'], $message['board_name'], 0, true); $output = array_merge($context['topics'][$message['id_msg']], array('id' => $message['id_topic'], 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($message['is_sticky']), 'is_locked' => !empty($message['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $message['id_poll'] > 0, 'is_hot' => $message['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $message['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'posted_in' => !empty($participants[$message['id_topic']]), 'views' => $message['num_views'], 'replies' => $message['num_replies'], 'can_reply' => in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any']), 'can_quote' => (in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any'])) && $quote_enabled, 'can_mark_notify' => in_array($message['id_board'], $boards_can['mark_any_notify']) || in_array(0, $boards_can['mark_any_notify']) && !$context['user']['is_guest'], 'first_post' => array('id' => $message['first_msg'], 'time' => timeformat($message['first_poster_time']), 'timestamp' => forum_time(true, $message['first_poster_time']), 'subject' => $message['first_subject'], 'href' => $href, 'link' => '<a href="' . $href . '">' . $message['first_subject'] . '</a>', 'icon' => $message['first_icon'], 'icon_url' => getPostIcon($message['first_icon']), 'member' => array('id' => $message['first_member_id'], 'name' => $message['first_member_name'], 'href' => !empty($message['first_member_id']) ? $mhref : '', 'link' => !empty($message['first_member_id']) ? '<a href="' . $mhref . '" title="' . $txt['profile_of'] . ' ' . $message['first_member_name'] . '">' . $message['first_member_name'] . '</a>' : $message['first_member_name'])), 'last_post' => array('id' => $message['last_msg'], 'time' => timeformat($message['last_poster_time']), 'timestamp' => forum_time(true, $message['last_poster_time']), 'subject' => $message['last_subject'], 'href' => $lhref, 'link' => '<a href="' . $lhref . '">' . $message['last_subject'] . '</a>', 'icon' => $message['last_icon'], 'icon_url' => getPostIcon($message['last_icon']), 'member' => array('id' => $message['last_member_id'], 'name' => $message['last_member_name'], 'href' => !empty($message['last_member_id']) ? $lmhref : '', 'link' => !empty($message['last_member_id']) ? '<a href="' . $lmhref . '" title="' . $txt['profile_of'] . ' ' . $message['last_member_name'] . '">' . $message['last_member_name'] . '</a>' : $message['last_member_name'])), 'board' => array('id' => $message['id_board'], 'name' => $message['board_name'], 'href' => $bhref, 'link' => '<a href="' . $bhref . '">' . $message['board_name'] . '</a>'), 'category' => array('id' => $message['id_cat'], 'name' => $message['cat_name'], 'href' => $scripturl . '#c' . $message['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $message['id_cat'] . '">' . $message['cat_name'] . '</a>'))); determineTopicClass($output); if ($output['posted_in']) { $output['class'] = 'my_' . $output['class']; } $body_highlighted = $message['body']; $subject_highlighted = $message['subject']; if (!empty($options['display_quick_mod'])) { $started = $output['first_post']['member']['id'] == $user_info['id']; $output['quick_mod'] = array('lock' => in_array(0, $boards_can['lock_any']) || in_array($output['board']['id'], $boards_can['lock_any']) || $started && (in_array(0, $boards_can['lock_own']) || in_array($output['board']['id'], $boards_can['lock_own'])), 'sticky' => (in_array(0, $boards_can['make_sticky']) || in_array($output['board']['id'], $boards_can['make_sticky'])) && !empty($modSettings['enableStickyTopics']), 'move' => in_array(0, $boards_can['move_any']) || in_array($output['board']['id'], $boards_can['move_any']) || $started && (in_array(0, $boards_can['move_own']) || in_array($output['board']['id'], $boards_can['move_own'])), 'remove' => in_array(0, $boards_can['remove_any']) || in_array($output['board']['id'], $boards_can['remove_any']) || $started && (in_array(0, $boards_can['remove_own']) || in_array($output['board']['id'], $boards_can['remove_own']))); $context['can_lock'] |= $output['quick_mod']['lock']; $context['can_sticky'] |= $output['quick_mod']['sticky']; $context['can_move'] |= $output['quick_mod']['move']; $context['can_remove'] |= $output['quick_mod']['remove']; $context['can_merge'] |= in_array($output['board']['id'], $boards_can['merge_any']); // If we've found a message we can move, and we don't already have it, load the destinations. if ($options['display_quick_mod'] && !isset($context['move_to_boards']) && $context['can_move']) { require_once $sourcedir . '/lib/Subs-MessageIndex.php'; $boardListOptions = array('use_permissions' => true, 'not_redirection' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']); $context['move_to_boards'] = getBoardList($boardListOptions); } } foreach ($context['key_words'] as $query) { // Fix the international characters in the keyword too. $query = strtr(commonAPI::htmlspecialchars($query), array('\\\'' => '\'')); $body_highlighted = preg_replace('/((<[^>]*)|' . preg_quote(strtr($query, array('\'' => ''')), '/') . ')/ieu', "'\$2' == '\$1' ? stripslashes('\$1') : '<strong class=\"highlight\">\$1</strong>'", $body_highlighted); $subject_highlighted = preg_replace('/(' . preg_quote($query, '/') . ')/iu', '<strong class="highlight">$1</strong>', $subject_highlighted); } $mhref = URL::topic($message['id_topic'], $message['subject'], 0, false, '.msg' . $message['id_msg'], '#msg' . $message['id_msg']); $output['matches'][] = array('id' => $message['id_msg'], 'attachment' => loadAttachmentContext($message['id_msg']), 'alternate' => $counter % 2, 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => getPostIcon($message['icon']), 'subject' => $message['subject'], 'subject_highlighted' => $subject_highlighted, 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'counter' => $counter, 'modified' => array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'name' => $message['modified_name']), 'body' => $body_highlighted, 'body_highlighted' => $body_highlighted, 'start' => 'msg' . $message['id_msg'], 'href' => $mhref, 'link' => '<a href="' . $mhref . '">' . $message['subject'] . '</a>'); $counter++; return $output; }
function UnreadTopics() { global $board, $txt, $scripturl, $sourcedir; global $user_info, $context, $settings, $modSettings, $options, $memberContext; // Guests can't have unread things, we don't know anything about them. is_not_guest(); $context['current_action'] = 'whatsnew'; // Prefetching + lots of MySQL work = bad mojo. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { ob_end_clean(); header('HTTP/1.1 403 Forbidden'); die; } $context['showing_all_topics'] = isset($_GET['all']); $context['start'] = (int) $_REQUEST['start']; $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']; if ($_REQUEST['action'] == 'unread') { $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit']; } else { $context['page_title'] = $txt['unread_replies']; } if ($context['showing_all_topics'] && !empty($context['load_average']) && !empty($modSettings['loadavg_allunread']) && $context['load_average'] >= $modSettings['loadavg_allunread']) { fatal_lang_error('loadavg_allunread_disabled', false); } elseif ($_REQUEST['action'] != 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unreadreplies']) && $context['load_average'] >= $modSettings['loadavg_unreadreplies']) { fatal_lang_error('loadavg_unreadreplies_disabled', false); } elseif (!$context['showing_all_topics'] && $_REQUEST['action'] == 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unread']) && $context['load_average'] >= $modSettings['loadavg_unread']) { fatal_lang_error('loadavg_unread_disabled', false); } // Parameters for the main query. $query_parameters = array(); // Are we specifying any specific board? if (isset($_REQUEST['children']) && (!empty($board) || !empty($_REQUEST['boards']))) { $boards = array(); if (!empty($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $b) { $boards[] = (int) $b; } } if (!empty($board)) { $boards[] = (int) $board; } // The easiest thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them $request = smf_db_query(' SELECT b.id_board, b.id_parent FROM {db_prefix}boards AS b WHERE {query_wanna_see_board} AND b.child_level > {int:no_child} AND b.id_board NOT IN ({array_int:boards}) ORDER BY child_level ASC ', array('no_child' => 0, 'boards' => $boards)); while ($row = mysql_fetch_assoc($request)) { if (in_array($row['id_parent'], $boards)) { $boards[] = $row['id_board']; } } mysql_free_result($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'id_board IN ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%d'; } elseif (!empty($board)) { $query_this_board = 'id_board = {int:board}'; $query_parameters['board'] = $board; $context['querystring_board_limits'] = ';board=' . $board . '.%1$d'; } elseif (!empty($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $i => $b) { $_REQUEST['boards'][$i] = (int) $b; } $request = smf_db_query(' SELECT b.id_board FROM {db_prefix}boards AS b WHERE {query_see_board} AND b.id_board IN ({array_int:board_list})', array('board_list' => $_REQUEST['boards'])); $boards = array(); while ($row = 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 ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%1$d'; } elseif (!empty($_REQUEST['c'])) { $_REQUEST['c'] = explode(',', $_REQUEST['c']); foreach ($_REQUEST['c'] as $i => $c) { $_REQUEST['c'][$i] = (int) $c; } $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board'; $request = smf_db_query(' SELECT b.id_board FROM {db_prefix}boards AS b WHERE ' . $user_info[$see_board] . ' AND b.id_cat IN ({array_int:id_cat})', array('id_cat' => $_REQUEST['c'])); $boards = array(); while ($row = 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 ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';c=' . implode(',', $_REQUEST['c']) . ';start=%1$d'; } else { $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board'; // Don't bother to show deleted posts! $request = smf_db_query(' SELECT b.id_board FROM {db_prefix}boards AS b WHERE ' . $user_info[$see_board] . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' AND b.id_board != {int:recycle_board}' : ''), array('recycle_board' => (int) $modSettings['recycle_board'])); $boards = array(); while ($row = 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 ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';start=%1$d'; $context['no_board_limits'] = true; } $sort_methods = array('subject' => 'ms.subject', 'starter' => 'IFNULL(mems.real_name, ms.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg'); // The default is the most logical: newest first. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'last_post'; $_REQUEST['sort'] = 't.id_last_msg'; $ascending = isset($_REQUEST['asc']); $context['querystring_sort_limits'] = $ascending ? ';asc' : ''; } else { $context['sort_by'] = $_REQUEST['sort']; $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']]; $ascending = !isset($_REQUEST['desc']); $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc'); } $context['sort_direction'] = $ascending ? 'up' : 'down'; if (!empty($_REQUEST['c']) && is_array($_REQUEST['c']) && count($_REQUEST['c']) == 1) { $request = smf_db_query(' SELECT name FROM {db_prefix}categories WHERE id_cat = {int:id_cat} LIMIT 1', array('id_cat' => (int) $_REQUEST['c'][0])); list($name) = mysql_fetch_row($request); mysql_free_result($request); $context['linktree'][] = array('url' => $scripturl . '#c' . (int) $_REQUEST['c'][0], 'name' => $name); } $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $_REQUEST['action'] == 'unread' ? $txt['unread_topics_visit'] : $txt['unread_replies']); if ($context['showing_all_topics']) { $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $txt['unread_topics_all']); } else { $txt['unread_topics_visit_none'] = strtr($txt['unread_topics_visit_none'], array('?action=unread;all' => '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'])); } EoS_Smarty::loadTemplate('recent'); $context['template_functions'] = array($_REQUEST['action'] == 'unread' ? 'unread_topics' : 'unread_replies'); $is_topics = $_REQUEST['action'] == 'unread'; // This part is the same for each query. $select_clause = ' ms.subject AS first_subject, ms.poster_time AS first_poster_time, ms.id_topic, t.id_board, t.id_prefix, t.approved, b.name AS bname, t.num_replies, t.num_views, ms.id_member AS id_first_member, ml.id_member AS id_last_member, ml.poster_time AS last_poster_time, IFNULL(mems.real_name, ms.poster_name) AS first_poster_name, IFNULL(meml.real_name, ml.poster_name) AS last_poster_name, ml.subject AS last_subject, p.name as prefix_name, ml.icon AS last_icon, ms.icon AS first_icon, t.id_poll, t.is_sticky, t.locked, ml.modified_time AS last_modified_time, IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from, SUBSTRING(ml.body, 1, 385) AS last_body, SUBSTRING(ms.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, ms.smileys_enabled AS first_smileys, t.id_first_msg, t.id_last_msg'; if ($context['showing_all_topics']) { if (!empty($board)) { $request = smf_db_query(' SELECT MIN(id_msg) FROM {db_prefix}log_mark_read WHERE id_member = {int:current_member} AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'])); list($earliest_msg) = mysql_fetch_row($request); mysql_free_result($request); } else { $request = smf_db_query(' SELECT MIN(lmr.id_msg) FROM {db_prefix}boards AS b LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member}) WHERE {query_see_board}', array('current_member' => $user_info['id'])); list($earliest_msg) = 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 = smf_db_query(' SELECT MIN(id_msg) FROM {db_prefix}log_topics WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'])); list($earliest_msg2) = 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 modified_time in for log_time check? if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics']) { smf_db_query(' DROP TABLE IF EXISTS {db_prefix}log_topics_unread', array()); // Let's copy things out of the log_topics table, to reduce searching. $have_temp_table = smf_db_query(' CREATE TEMPORARY TABLE {db_prefix}log_topics_unread ( PRIMARY KEY (id_topic) ) SELECT lt.id_topic, lt.id_msg FROM {db_prefix}topics AS t INNER JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic) WHERE lt.id_member = {int:current_member} AND t.' . $query_this_board . (empty($earliest_msg) ? '' : ' AND t.id_last_msg > {int:earliest_msg}') . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1, 'db_error_skip' => true))) !== false; } else { $have_temp_table = false; } if ($context['showing_all_topics'] && $have_temp_table) { $request = smf_db_query(' SELECT COUNT(*), MIN(t.id_last_msg) FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . (!empty($earliest_msg) ? ' AND t.id_last_msg > {int:earliest_msg}' : '') . ' AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1))); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = $num_topics ? constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true) : ''; $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { // Mark the boards as read if there are no unread topics! require_once $sourcedir . '/lib/Subs-Boards.php'; markBoardsRead(empty($boards) ? $board : $boards); $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%1$d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = smf_db_query(' SELECT ' . $select_clause . ' FROM {db_prefix}messages AS ms INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}boards AS b ON (b.id_board = ms.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic) LEFT JOIN {db_prefix}prefixes AS p ON p.id_prefix = t.id_prefix LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE b.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND ms.approved = {int:is_approved}' : '') . ' ORDER BY {raw:sort} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'sort' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } elseif ($is_topics) { $request = smf_db_query(' SELECT COUNT(*), MIN(t.id_last_msg) FROM {db_prefix}topics AS t' . (!empty($have_temp_table) ? ' LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})') . ' LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ($context['showing_all_topics'] && !empty($earliest_msg) ? ' AND t.id_last_msg > {int:earliest_msg}' : (!$context['showing_all_topics'] && empty($_SESSION['first_login']) ? ' AND t.id_last_msg > {int:id_msg_last_visit}' : '')) . ' AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'id_msg_last_visit' => $_SESSION['id_msg_last_visit'], 'is_approved' => 1))); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = $num_topics ? constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true, true) : ''; $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { // Is this an all topics query? if ($context['showing_all_topics']) { // Since there are no unread topics, mark the boards as read! require_once $sourcedir . '/lib/Subs-Boards.php'; markBoardsRead(empty($boards) ? $board : $boards); } $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = smf_db_query(' SELECT ' . $select_clause . ' FROM {db_prefix}messages AS ms INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' . (!empty($have_temp_table) ? ' LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})') . ' LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) LEFT JOIN {db_prefix}prefixes AS p ON p.id_prefix = t.id_prefix WHERE t.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < ml.id_msg' . ($modSettings['postmod_active'] ? ' AND ms.approved = {int:is_approved}' : '') . ' ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } else { if ($modSettings['totalMessages'] > 100000) { smf_db_query(' DROP TABLE IF EXISTS {db_prefix}topics_posted_in', array()); smf_db_query(' DROP TABLE IF EXISTS {db_prefix}log_topics_posted_in', array()); $sortKey_joins = array('ms.subject' => ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)', 'IFNULL(mems.real_name, ms.poster_name)' => ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)'); // The main benefit of this temporary table is not that it's faster; it's that it avoids locks later. $have_temp_table = smf_db_query(' CREATE TEMPORARY TABLE {db_prefix}topics_posted_in ( id_topic mediumint(8) unsigned NOT NULL default {string:string_zero}, id_board smallint(5) unsigned NOT NULL default {string:string_zero}, id_last_msg int(10) unsigned NOT NULL default {string:string_zero}, id_msg int(10) unsigned NOT NULL default {string:string_zero}, PRIMARY KEY (id_topic) ) SELECT t.id_topic, t.id_board, t.id_last_msg, IFNULL(lmr.id_msg, 0) AS id_msg' . (!in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? ', ' . $_REQUEST['sort'] . ' AS sort_key' : '') . ' FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})' . (isset($sortKey_joins[$_REQUEST['sort']]) ? $sortKey_joins[$_REQUEST['sort']] : '') . ' WHERE m.id_member = {int:current_member}' . (!empty($board) ? ' AND t.id_board = {int:current_board}' : '') . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ' GROUP BY m.id_topic', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'string_zero' => '0', 'db_error_skip' => true)) !== false; // If that worked, create a sample of the log_topics table too. if ($have_temp_table) { $have_temp_table = smf_db_query(' CREATE TEMPORARY TABLE {db_prefix}log_topics_posted_in ( PRIMARY KEY (id_topic) ) SELECT lt.id_topic, lt.id_msg FROM {db_prefix}log_topics AS lt INNER JOIN {db_prefix}topics_posted_in AS pi ON (pi.id_topic = lt.id_topic) WHERE lt.id_member = {int:current_member}', array('current_member' => $user_info['id'], 'db_error_skip' => true)) !== false; } } if (!empty($have_temp_table)) { $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}topics_posted_in AS pi LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = pi.id_topic) WHERE pi.' . $query_this_board . ' AND IFNULL(lt.id_msg, pi.id_msg) < pi.id_last_msg', array_merge($query_parameters, array())); list($num_topics) = mysql_fetch_row($request); mysql_free_result($request); } else { $request = smf_db_query(' SELECT COUNT(DISTINCT t.id_topic), MIN(t.id_last_msg) FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic) LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ' AND m.id_member = {int:current_member} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'is_approved' => 1))); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); } // Make sure the starting place makes sense and construct the page index. $context['page_index'] = $num_topics ? constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true) : ''; $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } if (!empty($have_temp_table)) { $request = smf_db_query(' SELECT t.id_topic FROM {db_prefix}topics_posted_in AS t LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = t.id_topic) WHERE t.' . $query_this_board . ' AND IFNULL(lt.id_msg, t.id_msg) < t.id_last_msg ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('order' => (in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? $_REQUEST['sort'] : 't.sort_key') . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } else { $request = smf_db_query(' SELECT DISTINCT t.id_topic FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic AND m.id_member = {int:current_member})' . (strpos($_REQUEST['sort'], 'ms.') === false ? '' : ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)') . (strpos($_REQUEST['sort'], 'mems.') === false ? '' : ' LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)') . ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND (IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0))) < t.id_last_msg AND t.approved = {int:is_approved} ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => (int) $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'], 'sort' => $_REQUEST['sort']))); } $topics = array(); while ($row = 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 = smf_db_query(' SELECT ' . $select_clause . ' FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS ms ON (ms.id_topic = t.id_topic AND ms.id_msg = t.id_first_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}prefixes AS p ON (p.id_prefix = t.id_prefix) LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.id_topic IN ({array_int:topic_list}) ORDER BY ' . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . ' LIMIT ' . count($topics), array('current_member' => $user_info['id'], 'topic_list' => $topics)); } $context['topics'] = array(); $topic_ids = array(); $first_posters = array(); while ($row = mysql_fetch_assoc($request)) { if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') { continue; } $topic_ids[] = $row['id_topic']; $row['first_body'] = ''; $row['last_body'] = ''; censorText($row['first_subject']); if ($row['id_first_msg'] == $row['id_last_msg']) { $row['last_subject'] = $row['first_subject']; } else { censorText($row['last_subject']); } // Decide how many pages the topic should have. $topic_length = $row['num_replies'] + 1; $messages_per_page = commonAPI::getMessagesPerPage(); if ($topic_length > $messages_per_page) { $tmppages = array(); $tmpa = 1; for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $messages_per_page) { $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.' . $tmpb . ';topicseen">' . $tmpa . '</a>'; $tmpa++; } // Show links to all the pages? if (count($tmppages) <= 5) { $pages = '« ' . implode(' ', $tmppages); } else { $pages = '« ' . $tmppages[0] . ' ' . $tmppages[1] . ' ... ' . $tmppages[count($tmppages) - 2] . ' ' . $tmppages[count($tmppages) - 1]; } if (!empty($modSettings['enableAllMessages']) && $topic_length < $modSettings['enableAllMessages']) { $pages .= ' <a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;all">' . $txt['all'] . '</a>'; } $pages .= ' »'; } else { $pages = ''; } // And build the array. $first_posters[$row['id_topic']] = $row['id_first_member']; $f_user_href = !empty($row['id_first_member']) ? URL::user($row['id_first_member'], $row['first_poster_name']) : ''; $l_user_href = !empty($row['id_last_member']) ? URL::user($row['id_last_member'], $row['last_poster_name']) : ''; $b_href = URL::board($row['id_board'], $row['bname']); $f_post_href = URL::topic($row['id_topic'], $row['first_subject']); $l_post_href = URL::topic($row['id_topic'], $row['first_subject'], 0, $row['num_replies'] == 0 ? true : false, $row['num_replies'] > 0 ? '.msg' . $row['id_last_msg'] : '', $row['num_replies'] > 0 ? '#msg' . $row['id_last_msg'] : ''); $t_new_href = URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['new_from'], '#new'); $t_new_href = URL::addParam($t_new_href, 'topicseen'); $topic_href = URL::topic($row['id_topic'], $row['first_subject'], 0, $row['num_replies'] == 0 ? true : false, $row['num_replies'] > 0 ? '.msg' . $row['new_from'] : '', $row['num_replies'] > 0 ? '#msg' . $row['new_from'] : ''); $topic_href = URL::addParam($topic_href, 'topicseen'); $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('name' => $row['first_poster_name'], 'id' => $row['id_first_member'], 'href' => $f_user_href, 'link' => !empty($row['id_first_member']) ? '<a onclick="getMcard(' . $row['id_first_member'] . ', $(this));return(false);" href="' . $f_user_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_poster_name'] . '">' . $row['first_poster_name'] . '</a>' : $row['first_poster_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'preview' => $row['first_body'], 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'href' => $topic_href, 'link' => '<a href="' . $topic_href . '">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('name' => $row['last_poster_name'], 'id' => $row['id_last_member'], 'href' => $l_user_href, 'link' => !empty($row['id_last_member']) ? '<a onclick="getMcard(' . $row['id_last_member'] . ', $(this));return(false);" href="' . $l_user_href . '">' . $row['last_poster_name'] . '</a>' : $row['last_poster_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'preview' => $row['last_body'], 'icon' => $row['last_icon'], 'icon_url' => getPostIcon($row['last_icon']), 'href' => $l_post_href, 'link' => '<a href="' . $l_post_href . '" rel="nofollow">' . $row['last_subject'] . '</a>'), 'prefix' => $row['prefix_name'] ? html_entity_decode($row['prefix_name']) : '', 'new_from' => $row['new_from'], 'new_href' => $t_new_href, 'href' => $topic_href, 'link' => '<a href="' . $topic_href . '" rel="nofollow">' . $row['first_subject'] . '</a>', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_poster_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'is_posted_in' => false, 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'approved' => $row['approved'], 'subject' => $row['first_subject'], 'pages' => $pages, 'new' => 1, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $b_href, 'link' => '<a href="' . $b_href . '">' . $row['bname'] . '</a>')); determineTopicClass($context['topics'][$row['id_topic']]); } if (!empty($settings['show_user_images']) && empty($options['show_no_avatars'])) { loadMemberData($first_posters); foreach ($context['topics'] as &$_topic) { loadMemberContext($first_posters[$_topic['id']], true); if (isset($memberContext[$first_posters[$_topic['id']]]['avatar']['image'])) { $_topic['first_post']['member']['avatar'] =& $memberContext[$first_posters[$_topic['id']]]['avatar']['image']; } } } mysql_free_result($request); if ($is_topics && !empty($modSettings['enableParticipation']) && !empty($topic_ids)) { $result = smf_db_query(' SELECT id_topic FROM {db_prefix}messages WHERE id_topic IN ({array_int:topic_list}) AND id_member = {int:current_member} GROUP BY id_topic LIMIT {int:limit}', array('current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'limit' => count($topic_ids))); 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['can_approve_posts'] = allowedTo('approve_posts'); $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); $context['topics_to_mark'] = implode('-', $topic_ids); $context['mark_read_buttons'] = ''; if ($settings['show_mark_read']) { if ($is_topics) { $context['mark_read_buttons'] = array('markread' => array('text' => !empty($context['no_board_limits']) ? 'mark_as_read' : 'mark_read_short', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=' . (!empty($context['no_board_limits']) ? 'all' : 'board' . $context['querystring_board_limits']) . ';' . $context['session_var'] . '=' . $context['session_id'])); } else { $context['mark_read_buttons'] = array('markread' => array('text' => 'mark_replies_read', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=unreadreplies;topics=' . $context['topics_to_mark'] . ';' . $context['session_var'] . '=' . $context['session_id'])); } if (!empty($options['display_quick_mod'])) { $context['mark_read_buttons']['markselectread'] = array('text' => 'quick_mod_markread', 'image' => 'markselectedread.gif', 'lang' => true, 'url' => 'javascript:document.quickModForm.submit();'); } } $context['subject_sort_header'] = URL::parse('<a href="' . $scripturl . '?action=unread' . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . ';sort=subject' . ($context['sort_by'] == 'subject' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['subject'] . ($context['sort_by'] == 'subject' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'); $context['views_sort_header'] = URL::parse('<a href="' . $scripturl . '?action=unread' . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . ';sort=replies' . ($context['sort_by'] == 'replies' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['replies'] . ($context['sort_by'] == 'replies' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'); $context['lastpost_sort_header'] = URL::parse('<a href="' . $scripturl . '?action=unread' . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . ';sort=last_post' . ($context['sort_by'] == 'last_post' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['last_post'] . ($context['sort_by'] == 'last_post' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'); }
function showPosts($memID) { global $txt, $user_info, $scripturl, $modSettings; global $context, $user_profile, $sourcedir, $board, $memberContext, $options; EoS_Smarty::loadTemplate('profile/profile_base'); $context['need_synhlt'] = true; // Some initial context. $context['start'] = (int) $_REQUEST['start']; $context['current_member'] = $memID; // Create the tabs for the template. $context[$context['profile_menu_name']]['tab_data'] = array('title' => $txt['showPosts'], 'description' => $txt['showPosts_help'], 'tabs' => array('messages' => array(), 'topics' => array(), 'attach' => array())); // Set the page title $context['page_title'] = $txt['showPosts'] . ' - ' . $user_profile[$memID]['real_name']; $context['pageindex_multiplier'] = commonAPI::getMessagesPerPage(); $context['can_approve_posts'] = false; // Is the load average too high to allow searching just now? if (!empty($context['load_average']) && !empty($modSettings['loadavg_show_posts']) && $context['load_average'] >= $modSettings['loadavg_show_posts']) { fatal_lang_error('loadavg_show_posts_disabled', false); } if (isset($_GET['sa']) && !empty($modSettings['karmaMode']) && ($_GET['sa'] == 'likes' || $_GET['sa'] == 'likesout')) { require_once $sourcedir . '/Ratings.php'; return LikesByUser($memID); } EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'profile/show_content'); $boards_hidden_1 = boardsAllowedTo('see_hidden1'); $boards_hidden_2 = boardsAllowedTo('see_hidden2'); $boards_hidden_3 = boardsAllowedTo('see_hidden3'); // If we're specifically dealing with attachments use that function! if (isset($_GET['sa']) && $_GET['sa'] == 'attach') { return showAttachments($memID); } // Are we just viewing topics? $context['is_topics'] = isset($_GET['sa']) && $_GET['sa'] == 'topics' ? true : false; // If just deleting a message, do it and then redirect back. if (isset($_GET['delete']) && !$context['is_topics']) { checkSession('get'); // We need msg info for logging. $request = smf_db_query(' SELECT subject, id_member, id_topic, id_board FROM {db_prefix}messages WHERE id_msg = {int:id_msg}', array('id_msg' => (int) $_GET['delete'])); $info = mysql_fetch_row($request); mysql_free_result($request); // Trying to remove a message that doesn't exist. if (empty($info)) { redirectexit('action=profile;u=' . $memID . ';area=showposts;start=' . $_GET['start']); } // We can be lazy, since removeMessage() will check the permissions for us. require_once $sourcedir . '/RemoveTopic.php'; removeMessage((int) $_GET['delete']); // Add it to the mod log. if (allowedTo('delete_any') && (!allowedTo('delete_own') || $info[1] != $user_info['id'])) { logAction('delete', array('topic' => $info[2], 'subject' => $info[0], 'member' => $info[1], 'board' => $info[3])); } // Back to... where we are now ;). redirectexit('action=profile;u=' . $memID . ';area=showposts;start=' . $_GET['start']); } // Default to 10. if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount'])) { $_REQUEST['viewscount'] = '10'; } if ($context['is_topics']) { $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}topics AS t' . ($user_info['query_see_board'] == '1=1' ? '' : ' INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board AND {query_see_board})') . ' WHERE t.id_member_started = {int:current_member}' . (!empty($board) ? ' AND t.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : ' AND t.approved = {int:is_approved}'), array('current_member' => $memID, 'is_approved' => 1, 'board' => $board)); } else { $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}messages AS m' . ($user_info['query_see_board'] == '1=1' ? '' : ' INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})') . ' WHERE m.id_member = {int:current_member}' . (!empty($board) ? ' AND m.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : ' AND m.approved = {int:is_approved}'), array('current_member' => $memID, 'is_approved' => 1, 'board' => $board)); } list($msgCount) = mysql_fetch_row($request); mysql_free_result($request); $request = smf_db_query(' SELECT MIN(id_msg), MAX(id_msg) FROM {db_prefix}messages AS m WHERE m.id_member = {int:current_member}' . (!empty($board) ? ' AND m.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : ' AND m.approved = {int:is_approved}'), array('current_member' => $memID, 'is_approved' => 1, 'board' => $board)); list($min_msg_member, $max_msg_member) = mysql_fetch_row($request); mysql_free_result($request); $reverse = false; $range_limit = ''; $maxIndex = (int) $modSettings['defaultMaxMessages']; // Make sure the starting place makes sense and construct our friend the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';area=showposts' . ($context['is_topics'] ? ';sa=topics' : '') . (!empty($board) ? ';board=' . $board : ''), $context['start'], $msgCount, $maxIndex); $context['current_page'] = $context['start'] / $maxIndex; // Reverse the query if we're past 50% of the pages for better performance. $start = $context['start']; $reverse = $_REQUEST['start'] > $msgCount / 2; if ($reverse && !$context['is_topics']) { $maxIndex = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : (int) $modSettings['defaultMaxMessages']; $start = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 || $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] ? 0 : $msgCount - $context['start'] - $modSettings['defaultMaxMessages']; } // Guess the range of messages to be shown. if ($msgCount > 1000) { $margin = floor(($max_msg_member - $min_msg_member) * (($start + $modSettings['defaultMaxMessages']) / $msgCount) + 0.1 * ($max_msg_member - $min_msg_member)); // Make a bigger margin for topics only. if ($context['is_topics']) { $margin *= 5; $range_limit = $reverse ? 't.id_first_msg < ' . ($min_msg_member + $margin) : 't.id_first_msg > ' . ($max_msg_member - $margin); } else { $range_limit = $reverse ? 'm.id_msg < ' . ($min_msg_member + $margin) : 'm.id_msg > ' . ($max_msg_member - $margin); } } // Find this user's posts. The left join on categories somehow makes this faster, weird as it looks. $context['results_counter'] = 0; $topicids = array(); if ($context['is_topics']) { $context['postbit_callback'] = 'template_topicbit'; $prereq = smf_db_query(' SELECT t.id_topic FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) WHERE t.id_member_started = {int:current_member}' . (!empty($board) ? ' AND t.id_board = {int:board}' : '') . ' AND {query_see_board}' . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : ' AND t.approved = {int:is_approved}') . ' ORDER BY t.id_topic DESC LIMIT ' . $start . ', ' . $modSettings['defaultMaxMessages'], array('current_member' => $memID, 'is_approved' => 1, 'board' => $board)); while ($row = mysql_fetch_row($prereq)) { $topicids[] = $row[0]; } mysql_free_result($prereq); if (count($topicids)) { $request = smf_db_query(' SELECT b.id_board, b.name AS board_name, t.id_member_started, t.id_first_msg, t.id_last_msg, t.id_prefix, t.is_sticky, t.locked, t.num_views, t.num_replies, t.id_poll, t.approved, t.unapproved_posts, m.id_member, m.subject AS first_subject, m.poster_time, m.id_topic, m.id_msg, m.icon, m2.poster_name AS last_member_name, m2.id_member AS last_id_member, m2.poster_time AS last_post_time, IFNULL(meml.real_name, m2.poster_name) AS last_display_name, m2.subject AS last_subject, m2.icon AS last_icon, p.name AS prefix_name FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = t.id_member_updated) LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) LEFT JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}prefixes AS p ON (p.id_prefix = t.id_prefix) WHERE t.id_topic IN({array_int:topicids}) ORDER BY t.id_topic DESC', array('topicids' => $topicids)); } } else { $context['postbit_callback'] = 'template_postbit_compact'; $request = smf_db_query(' SELECT b.id_board, b.name AS bname, c.id_cat, c.name AS cname, m.id_topic, m.id_msg, t.id_member_started, t.id_first_msg, t.id_last_msg, m.body, m.smileys_enabled, m.id_member, m.icon, m.subject, m.poster_time, m.modified_time, m.approved, mc.body AS cached_body, ' . (!empty($modSettings['karmaMode']) ? 'c1.likes_count, c1.like_status, c1.updated AS like_updated, l.rtype AS liked, ' : '0 AS likes_count, 0 AS like_status, 0 AS like_updated, 0 AS liked, ') . ' m2.id_member AS id_first_member, m2.subject AS first_subject, m2.poster_time AS time_started, IFNULL(mem2.real_name, m2.poster_name) AS first_poster_name FROM {db_prefix}messages AS m 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) INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member) LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) ' . (!empty($modSettings['karmaMode']) ? ' LEFT JOIN {db_prefix}likes AS l ON (l.id_msg = m.id_msg AND l.ctype = 1 AND l.id_user = {int:id_user}) LEFT JOIN {db_prefix}like_cache AS c1 ON (c1.id_msg = m.id_msg AND c1.ctype = 1)' : '') . ' LEFT JOIN {db_prefix}messages_cache AS mc on mc.id_msg = m.id_msg AND mc.style = {int:style} AND mc.lang = {int:lang} WHERE m.id_member = {int:current_member}' . (!empty($board) ? ' AND b.id_board = {int:board}' : '') . (empty($range_limit) ? '' : ' AND ' . $range_limit) . ' AND {query_see_board}' . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : ' AND t.approved = {int:is_approved} AND m.approved = {int:is_approved}') . ' ORDER BY m.id_msg ' . ($reverse ? 'ASC' : 'DESC') . ' LIMIT ' . $start . ', ' . $maxIndex, array('current_member' => $memID, 'is_approved' => 1, 'board' => $board, 'style' => $user_info['smiley_set_id'], 'lang' => $user_info['language_id'], 'id_user' => $user_info['id'])); } // Start counting at the number of the first message displayed. $counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start']; $context['posts'] = array(); $board_ids = array('own' => array(), 'any' => array()); if (!empty($modSettings['karmaMode'])) { require_once $sourcedir . '/lib/Subs-Ratings.php'; $boards_like_see = boardsAllowedTo('like_see'); $boards_like_give = boardsAllowedTo('like_give'); } else { $boards_like_see = array(); $boards_like_give = array(); $context['can_see_like'] = $context['can_give_like'] = false; } $time_now = time(); if ($context['is_topics']) { $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']; $context['messages_per_page'] = commonAPI::getMessagesPerPage(); if (count($topicids)) { loadMemberContext($memID, true); while ($row = mysql_fetch_assoc($request)) { $context['results_counter']++; if ($row['num_replies'] + 1 > $context['messages_per_page']) { $pages = ' '; // We can't pass start by reference. $start = -1; $pages .= constructPageIndex(URL::topic($row['id_topic'], $row['first_subject'], '%1$d'), $start, $row['num_replies'] + 1, $context['messages_per_page'], true); // If we can use all, show all. if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages']) { $pages .= '<a class="navPages" href="' . URL::topic($row['id_topic'], $row['first_subject'], 0) . ';all">' . $txt['show_all'] . '</a>'; } $pages .= ' '; } else { $pages = ''; } $f_post_mem_href = !empty($row['id_member_started']) ? URL::user($row['id_member_started'], $memberContext[$memID]['name']) : ''; $t_href = URL::topic($row['id_topic'], $row['first_subject'], 0); $l_post_mem_href = !empty($row['last_id_member']) ? URL::user($row['last_id_member'], $row['last_display_name']) : ''; $l_post_msg_href = URL::topic($row['id_topic'], $row['last_subject'], $user_info['is_guest'] ? !empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier'] : 0, $user_info['is_guest'] ? true : false, $user_info['is_guest'] ? '' : '.msg' . $row['id_last_msg'], $user_info['is_guest'] ? '#msg' . $row['id_last_msg'] : '#new'); $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('member' => array('username' => $memberContext[$memID]['username'], 'name' => $memberContext[$memID]['name'], 'id' => $memID, 'href' => $f_post_mem_href, 'link' => !empty($row['first_id_member']) ? '<a onclick="getMcard(' . $row['id_member_started'] . ', $(this));return(false);" href="' . $f_post_mem_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '">' . $row['first_display_name'] . '</a>' : $memberContext[$memID]['name'], 'avatar' => &$memberContext[$memID]['avatar']['image']), 'icon_url' => getPostIcon($row['icon']), 'time' => timeformat($row['poster_time']), 'href' => $t_href, 'link' => '<a href="' . $t_href . '">' . $row['first_subject'] . '</a>', 'id' => $row['id_first_msg']), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => $l_post_mem_href, 'link' => !empty($row['last_id_member']) ? '<a onclick="getMcard(' . $row['last_id_member'] . ', $(this));return(false);" href="' . $l_post_mem_href . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']), 'time' => timeformat($row['last_post_time']), 'timestamp' => forum_time(true, $row['last_post_time']), 'subject' => $row['last_subject'], 'icon' => $row['last_icon'], 'icon_url' => getPostIcon($row['last_icon']), 'href' => $l_post_msg_href, 'link' => '<a href="' . $l_post_msg_href . ($row['num_replies'] == 0 ? '' : ' rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'is_posted_in' => false, 'new' => false, 'is_sticky' => $row['is_sticky'], 'is_locked' => $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'], 'views' => $row['num_views'], 'replies' => $row['num_replies'], 'prefix' => $row['prefix_name'] ? '<a href="' . $scripturl . '?board=' . $board . ';prefix=' . $row['id_prefix'] . '" class="prefix">' . (html_entity_decode($row['prefix_name']) . '</a>') : '', 'pages' => $pages, 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts'], 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_post_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'board' => isset($row['id_board']) && !empty($row['id_board']) ? array('name' => $row['board_name'], 'id' => $row['id_board'], 'href' => URL::board($row['id_board'], $row['board_name'])) : array('name' => '', 'id' => 0, 'href' => '')); determineTopicClass($context['topics'][$row['id_topic']]); } mysql_free_result($request); } } else { loadMemberContext($memID); while ($row = mysql_fetch_assoc($request)) { $context['results_counter']++; $check_boards = array(0, $row['id_board']); // 0 is for admin $context['can_see_hidden_level1'] = count(array_intersect($check_boards, $boards_hidden_1)) > 0; $context['can_see_hidden_level2'] = count(array_intersect($check_boards, $boards_hidden_2)) > 0; $context['can_see_hidden_level3'] = count(array_intersect($check_boards, $boards_hidden_3)) > 0; $context['can_see_like'] = count(array_intersect($check_boards, $boards_like_see)) > 0; $context['can_give_like'] = count(array_intersect($check_boards, $boards_like_give)) > 0; // Censor.... censorText($row['body']); censorText($row['subject']); getCachedPost($row); // And the array... $i = $counter += $reverse ? -1 : 1; $thref = URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['id_msg'], '#' . $row['id_msg']); $topichref = URL::topic($row['id_topic'], $row['first_subject'], 0); $bhref = URL::board($row['id_board'], $row['bname'], 0, false); $fhref = empty($row['id_first_member']) ? '' : URL::user($row['id_first_member'], $row['first_poster_name']); $context['posts'][$i] = array('body' => $row['body'], 'counter' => $counter, 'icon' => $row['icon'], 'icon_url' => getPostIcon($row['icon']), 'category' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'href' => $scripturl . '#c' . $row['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $row['id_cat'] . '">' . $row['cname'] . '</a>'), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $bhref, 'link' => '<a href="' . $bhref . '">' . $row['bname'] . '</a>'), 'member' => &$memberContext[$memID], 'href' => $thref, 'link' => '<a href="' . $thref . '" rel="nofollow">' . $row['subject'] . '</a>', 'subject' => $row['subject'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'first_poster' => array('id' => $row['id_first_member'], 'name' => $row['first_poster_name'], 'href' => $fhref, 'link' => empty($row['id_first_member']) ? $row['first_poster_name'] : '<a href="' . $fhref . '">' . $row['first_poster_name'] . '</a>', 'time' => timeformat($row['time_started'])), 'topic' => array('id' => $row['id_topic'], 'href' => $topichref, 'link' => '<a href="' . $topichref . '" rel="nofollow">' . $row['first_subject'] . '</a>'), 'permahref' => $scripturl . '?msg=' . $row['id_msg'], 'permalink' => $txt['view_in_thread'], 'id' => $row['id_msg'], 'id_member' => $memID, 'can_reply' => false, 'can_mark_notify' => false, 'can_delete' => false, 'delete_possible' => ($row['id_first_msg'] != $row['id_msg'] || $row['id_last_msg'] == $row['id_msg']) && (empty($modSettings['edit_disable_time']) || $row['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()), 'approved' => $row['approved'], 'likes_count' => $row['likes_count'], 'like_status' => $row['like_status'], 'liked' => $row['liked'], 'like_updated' => $row['like_updated'], 'likers' => '', 'likelink' => ''); if ($context['can_see_like']) { Ratings::addContent($context['posts'][$i], $context['can_give_like'], $time_now); } if ($user_info['id'] == $row['id_member_started']) { $board_ids['own'][$row['id_board']][] = $counter; } $board_ids['any'][$row['id_board']][] = $counter; } mysql_free_result($request); } // All posts were retrieved in reverse order, get them right again. if ($reverse) { $context['posts'] = array_reverse($context['posts'], true); } // These are all the permissions that are different from board to board.. if ($context['is_topics']) { $permissions = array('own' => array('post_reply_own' => 'can_reply'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify')); } else { $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify', 'delete_any' => 'can_delete')); } // For every permission in the own/any lists... foreach ($permissions as $type => $list) { foreach ($list as $permission => $allowed) { // Get the boards they can do this on... $boards = boardsAllowedTo($permission); // Hmm, they can do it on all boards, can they? if (!empty($boards) && $boards[0] == 0) { $boards = array_keys($board_ids[$type]); } // Now go through each board they can do the permission on. foreach ($boards as $board_id) { // There aren't any posts displayed from this board. if (!isset($board_ids[$type][$board_id])) { continue; } // Set the permission to true ;). foreach ($board_ids[$type][$board_id] as $counter) { $context['posts'][$counter][$allowed] = true; } } } } // Clean up after posts that cannot be deleted and quoted. $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); foreach ($context['posts'] as $counter => $dummy) { $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible']; $context['posts'][$counter]['can_quote'] = $context['posts'][$counter]['can_reply'] && $quote_enabled; } }
function MessageIndex() { global $txt, $scripturl, $board, $modSettings, $context; global $options, $settings, $board_info, $user_info, $smcFunc, $sourcedir; global $memberContext; // If this is a redirection board head off. if ($board_info['redirect']) { smf_db_query(' UPDATE {db_prefix}boards SET num_posts = num_posts + 1 WHERE id_board = {int:current_board}', array('current_board' => $board)); redirectexit($board_info['redirect']); } EoS_Smarty::loadTemplate('messageindex'); fetchNewsItems($board, 0); $context['act_as_cat'] = $board_info['allow_topics'] ? false : true; $context['name'] = $board_info['name']; $context['description'] = $board_info['description']; // How many topics do we have in total? $board_info['total_topics'] = allowedTo('approve_posts') ? $board_info['num_topics'] + $board_info['unapproved_topics'] : $board_info['num_topics'] + $board_info['unapproved_user_topics']; // View all the topics, or just a few? $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']; $context['messages_per_page'] = commonAPI::getMessagesPerPage(); $maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['total_topics'] : $context['topics_per_page']; // Right, let's only index normal stuff! if (count($_GET) > 1) { $session_name = session_name(); foreach ($_GET as $k => $v) { if (!in_array($k, array('board', 'start', $session_name))) { $context['robot_no_index'] = true; } } } if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) { $context['robot_no_index'] = true; } // If we can view unapproved messages and there are some build up a list. if (allowedTo('approve_posts') && ($board_info['unapproved_topics'] || $board_info['unapproved_posts'])) { $untopics = $board_info['unapproved_topics'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=topics;brd=' . $board . '">' . $board_info['unapproved_topics'] . '</a>' : 0; $unposts = $board_info['unapproved_posts'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=posts;brd=' . $board . '">' . ($board_info['unapproved_posts'] - $board_info['unapproved_topics']) . '</a>' : 0; $context['unapproved_posts_message'] = sprintf($txt['there_are_unapproved_topics'], $untopics, $unposts, $scripturl . '?action=moderate;area=postmod;sa=' . ($board_info['unapproved_topics'] ? 'topics' : 'posts') . ';brd=' . $board); } // Make sure the starting place makes sense and construct the page index. if (isset($_REQUEST['sort'])) { $context['page_index'] = constructPageIndex(URL::board($board_info['id'], $board_info['name'], '%1$d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), true), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true); } else { //$context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], $board_info['total_topics'], $maxindex, true); $context['page_index'] = constructPageIndex(URL::board($board_info['id'], $board_info['name'], '%1$d', true), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true); } $context['start'] =& $_REQUEST['start']; setcookie('smf_topicstart', intval($board) . '_' . $context['start'], time() + 86400, '/'); // Set a canonical URL for this page. $context['canonical_url'] = URL::board($board, $board_info['name'], $context['start'], true); $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $context['topics_per_page']) : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $context['topics_per_page']) : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) * $context['topics_per_page'] : '', 'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0'); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) + 1); if (isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages']) { $maxindex = $modSettings['enableAllMessages']; $_REQUEST['start'] = 0; } // Build a list of the board's moderators. $context['moderators'] =& $board_info['moderators']; $context['link_moderators'] = array(); if (!empty($board_info['moderators'])) { foreach ($board_info['moderators'] as $mod) { $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>'; } //$context['linktree'][count($context['linktree']) - 1]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')'; } // Mark current and parent boards as seen. if (!$user_info['is_guest']) { // We can't know they read it if we allow prefetches. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { ob_end_clean(); header('HTTP/1.1 403 Prefetch Forbidden'); die; } smf_db_insert('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board')); if (!empty($board_info['parent_boards'])) { smf_db_query(' UPDATE {db_prefix}log_boards SET id_msg = {int:id_msg} WHERE id_member = {int:current_member} AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID'])); // We've seen all these boards now! foreach ($board_info['parent_boards'] as $k => $dummy) { if (isset($_SESSION['topicseen_cache'][$k])) { unset($_SESSION['topicseen_cache'][$k]); } } } if (isset($_SESSION['topicseen_cache'][$board])) { unset($_SESSION['topicseen_cache'][$board]); } $request = smf_db_query(' SELECT sent FROM {db_prefix}log_notify WHERE id_board = {int:current_board} AND id_member = {int:current_member} LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'])); $context['is_marked_notify'] = mysql_num_rows($request) != 0; if ($context['is_marked_notify']) { list($sent) = mysql_fetch_row($request); if (!empty($sent)) { smf_db_query(' UPDATE {db_prefix}log_notify SET sent = {int:is_sent} WHERE id_board = {int:current_board} AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_sent' => 0)); } } mysql_free_result($request); } else { $context['is_marked_notify'] = false; } // 'Print' the header and board info. $context['page_number'] = isset($_REQUEST['start']) ? $_REQUEST['start'] / $context['topics_per_page'] : 0; $context['page_title'] = strip_tags($board_info['name'] . ((int) $context['page_number'] > 0 ? ' - ' . $txt['page'] . ' ' . ($context['page_number'] + 1) : '')); $context['meta_page_description'] = !empty($board_info['description']) ? $board_info['description'] : $context['page_title']; // Set the variables up for the template. $context['can_mark_notify'] = allowedTo('mark_notify') && !$user_info['is_guest']; $context['can_post_new'] = allowedTo('post_new') || $modSettings['postmod_active'] && allowedTo('post_unapproved_topics'); $context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post') && $context['can_post_new']; $context['can_moderate_forum'] = allowedTo('moderate_forum'); $context['can_approve_posts'] = allowedTo('approve_posts'); require_once $sourcedir . '/lib/Subs-BoardIndex.php'; $boardIndexOptions = array('include_categories' => false, 'base_level' => $board_info['child_level'] + 1, 'parent_id' => $board_info['id'], 'set_latest_post' => false, 'countChildPosts' => !empty($modSettings['countChildPosts'])); $context['boards'] = getBoardIndex($boardIndexOptions); // Nosey, nosey - who's viewing this topic? if (!empty($settings['display_who_viewing'])) { $context['view_members'] = array(); $context['view_members_list'] = array(); $context['view_num_hidden'] = 0; $request = smf_db_query(' SELECT lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online, mem.id_group, mem.id_post_group FROM {db_prefix}log_online AS lo LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member) WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_member_group' => 0, 'in_url_string' => 's:5:"board";i:' . $board . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id())); while ($row = mysql_fetch_assoc($request)) { if (empty($row['id_member'])) { continue; } $class = 'member group_' . (empty($row['id_group']) ? $row['id_post_group'] : $row['id_group']) . (in_array($row['id_member'], $user_info['buddies']) ? ' buddy' : ''); $href = URL::user($row['id_member'], $row['real_name']); if ($row['id_member'] == $user_info['id']) { $link = '<strong>' . $txt['you'] . '</strong>'; } else { $link = '<a onclick="getMcard(' . $row['id_member'] . ');return(false);" class="' . $class . '" href="' . $href . '">' . $row['real_name'] . '</a>'; } if (!empty($row['show_online']) || allowedTo('moderate_forum')) { $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link; } $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $href, 'link' => $link, 'hidden' => empty($row['show_online'])); if (empty($row['show_online'])) { $context['view_num_hidden']++; } } $context['view_num_guests'] = mysql_num_rows($request) - count($context['view_members']); mysql_free_result($request); // Put them in "last clicked" order. krsort($context['view_members_list']); krsort($context['view_members']); $context['full_members_viewing_list'] = empty($context['view_members_list']) ? '0 ' . $txt['members'] : implode(', ', $context['view_members_list']) . ((empty($context['view_num_hidden']) or $context['can_moderate_forum']) ? '' : ' (+ ' . $context['view_num_hidden'] . ' ' . $txt['hidden'] . ')'); } // Default sort methods. $sort_methods = array('subject' => 'mf.subject', 'starter' => 'IFNULL(memf.real_name, mf.poster_name)', 'last_poster' => 'IFNULL(meml.real_name, ml.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg'); // They didn't pick one, default to by last post descending. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'last_post'; $_REQUEST['sort'] = 'id_last_msg'; $ascending = isset($_REQUEST['asc']); } else { $context['sort_by'] = $_REQUEST['sort']; $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']]; $ascending = !isset($_REQUEST['desc']); } $context['sort_direction'] = $ascending ? 'up' : 'down'; // Calculate the fastest way to get the topics. $start = (int) $_REQUEST['start']; if ($start > ($board_info['total_topics'] - 1) / 2) { $ascending = !$ascending; $fake_ascending = true; $maxindex = $board_info['total_topics'] < $start + $maxindex + 1 ? $board_info['total_topics'] - $start : $maxindex; $start = $board_info['total_topics'] < $start + $maxindex + 1 ? 0 : $board_info['total_topics'] - $start - $maxindex; } else { $fake_ascending = false; } $topic_ids = array(); $context['topics'] = array(); $prefixid = isset($_REQUEST['prefix']) ? (int) $_REQUEST['prefix'] : 0; $prefixfilter = !empty($prefixid) ? 't.id_prefix = {int:id_prefix} AND ' : ''; // Sequential pages are often not optimized, so we add an additional query. $pre_query = $start > 0; if ($pre_query && $maxindex > 0) { $request = smf_db_query(' SELECT t.id_topic FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? ' INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? ' INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? ' LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? ' LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . ' WHERE ' . $prefixfilter . ' t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : ' AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . ' ORDER BY ' . (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . ' LIMIT {int:start}, {int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_guest' => 0, 'start' => $start, 'maxindex' => $maxindex, 'id_prefix' => $prefixid)); $topic_ids = array(); while ($row = mysql_fetch_assoc($request)) { $topic_ids[] = $row['id_topic']; } } // Grab the appropriate topic information... if (!$pre_query || !empty($topic_ids)) { // For search engine effectiveness we'll link guests differently. $context['pageindex_multiplier'] = commonAPI::getMessagesPerPage(); $result = smf_db_query(' SELECT t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board, ' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from, t.id_last_msg, t.approved, t.unapproved_posts, t.id_prefix, ml.poster_time AS last_poster_time, ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon, ml.poster_name AS last_member_name, ml.id_member AS last_id_member, IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg, mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon, mf.poster_name AS first_member_name, mf.id_member AS first_id_member, IFNULL(memf.real_name, mf.poster_name) AS first_display_name, ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys, p.name AS prefix_name FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . ' LEFT JOIN {db_prefix}prefixes AS p ON p.id_prefix = t.id_prefix WHERE ' . $prefixfilter . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : 't.id_board = {int:current_board}') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : ' AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . ' ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . ' LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}', array('current_board' => $board, 'current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'is_approved' => 1, 'find_set_topics' => implode(',', $topic_ids), 'start' => $start, 'maxindex' => $maxindex, 'id_prefix' => $prefixid)); // Begin 'printing' the message index for current board. $first_posters = array(); while ($row = mysql_fetch_assoc($result)) { if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') { continue; } if (!$pre_query) { $topic_ids[] = $row['id_topic']; } $row['first_body'] = ''; $row['last_body'] = ''; censorText($row['first_subject']); if ($row['id_first_msg'] == $row['id_last_msg']) { $row['last_subject'] = $row['first_subject']; } else { censorText($row['last_subject']); } // Decide how many pages the topic should have. if ($row['num_replies'] + 1 > $context['messages_per_page']) { $pages = ' '; // We can't pass start by reference. $start = -1; $pages .= constructPageIndex(URL::topic($row['id_topic'], $row['first_subject'], '%1$d'), $start, $row['num_replies'] + 1, $context['messages_per_page'], true, false, true); // If we can use all, show all. if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages']) { $pages .= '<a class="navPages compact" href="' . URL::topic($row['id_topic'], $row['first_subject'], 0) . ';all">' . $txt['show_all'] . '</a>'; } $pages .= ' '; } else { $pages = ''; } $first_posters[$row['id_topic']] = $row['first_id_member']; // 'Print' the topic info. $f_post_mem_href = !empty($row['first_id_member']) ? URL::user($row['first_id_member'], $row['first_display_name']) : ''; $t_href = URL::topic($row['id_topic'], $row['first_subject'], 0); $l_post_mem_href = !empty($row['last_id_member']) ? URL::user($row['last_id_member'], $row['last_display_name']) : ''; $l_post_msg_href = URL::topic($row['id_topic'], $row['last_subject'], $user_info['is_guest'] ? !empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier'] : 0, $user_info['is_guest'] ? true : false, $user_info['is_guest'] ? '' : '.msg' . $row['id_last_msg'], $user_info['is_guest'] ? '#msg' . $row['id_last_msg'] : '#new'); $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_display_name'], 'id' => $row['first_id_member'], 'href' => $f_post_mem_href, 'link' => !empty($row['first_id_member']) ? '<a onclick="getMcard(' . $row['first_id_member'] . ', $(this));return(false);" href="' . $f_post_mem_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '">' . $row['first_display_name'] . '</a>' : $row['first_display_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'href' => $t_href, 'link' => '<a href="' . $t_href . '">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => $l_post_mem_href, 'link' => !empty($row['last_id_member']) ? '<a onclick="getMcard(' . $row['last_id_member'] . ', $(this));return(false);" href="' . $l_post_mem_href . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'icon' => $row['last_icon'], 'icon_url' => getPostIcon($row['last_icon']), 'href' => $l_post_msg_href, 'link' => '<a href="' . $l_post_msg_href . ($row['num_replies'] == 0 ? '' : ' rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'prefix' => $row['prefix_name'] ? '<a href="' . $scripturl . '?board=' . $board . ';prefix=' . $row['id_prefix'] . '" class="prefix">' . (html_entity_decode($row['prefix_name']) . '</a>') : '', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_poster_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'subject' => $row['first_subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['new_from'], '#new'), 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts']); determineTopicClass($context['topics'][$row['id_topic']]); if (!empty($context['topics'][$row['id_topic']]['prefix'])) { $context['topics'][$row['id_topic']]['prefix'] .= ' '; } } if (!empty($settings['show_user_images']) && empty($options['show_no_avatars'])) { $all_posters = array_unique($first_posters); loadMemberData($all_posters); foreach ($context['topics'] as &$_topic) { if (!isset($memberContext[$first_posters[$_topic['id']]])) { loadMemberContext($first_posters[$_topic['id']], true); } if (isset($memberContext[$first_posters[$_topic['id']]]['avatar']['image'])) { $_topic['first_post']['member']['avatar'] =& $memberContext[$first_posters[$_topic['id']]]['avatar']['image']; } } } mysql_free_result($result); // Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...) if ($fake_ascending) { $context['topics'] = array_reverse($context['topics'], true); } if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids)) { $result = smf_db_query(' SELECT id_topic FROM {db_prefix}messages WHERE id_topic IN ({array_int:topic_list}) AND id_member = {int:current_member} GROUP BY id_topic LIMIT ' . count($topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $topic_ids)); while ($row = mysql_fetch_assoc($result)) { if ($context['topics'][$row['id_topic']]['first_post']['member']['id'] != $user_info['id']) { $context['topics'][$row['id_topic']]['is_posted_in'] = true; } } mysql_free_result($result); } } $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&' => '&'))), 'child_level' => $board_info['child_level']); // Is Quick Moderation active/needed? if (!empty($options['display_quick_mod']) && !empty($context['topics'])) { $context['can_lock'] = allowedTo('lock_any'); $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']); $context['can_move'] = allowedTo('move_any'); $context['can_remove'] = allowedTo('remove_any'); $context['can_merge'] = allowedTo('merge_any'); // Ignore approving own topics as it's unlikely to come up... $context['can_approve'] = $modSettings['postmod_active'] && allowedTo('approve_posts') && !empty($board_info['unapproved_topics']); // Can we restore topics? $context['can_restore'] = allowedTo('move_any') && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board; // Set permissions for all the topics. foreach ($context['topics'] as $t => $topic) { $started = $topic['first_post']['member']['id'] == $user_info['id']; $context['topics'][$t]['quick_mod'] = array('lock' => allowedTo('lock_any') || $started && allowedTo('lock_own'), 'sticky' => allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']), 'move' => allowedTo('move_any') || $started && allowedTo('move_own'), 'modify' => allowedTo('modify_any') || $started && allowedTo('modify_own'), 'remove' => allowedTo('remove_any') || $started && allowedTo('remove_own'), 'approve' => $context['can_approve'] && $topic['unapproved_posts']); $context['can_lock'] |= $started && allowedTo('lock_own'); $context['can_move'] |= $started && allowedTo('move_own'); $context['can_remove'] |= $started && allowedTo('remove_own'); } // Find the boards/cateogories they can move their topic to. if ($options['display_quick_mod'] && $context['can_move'] && !empty($context['topics'])) { require_once $sourcedir . '/lib/Subs-MessageIndex.php'; $boardListOptions = array('excluded_boards' => array($board), 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']); $context['move_to_boards'] = getBoardList($boardListOptions); // Make the boards safe for display. foreach ($context['move_to_boards'] as $id_cat => $cat) { $context['move_to_boards'][$id_cat]['name'] = strip_tags($cat['name']); foreach ($cat['boards'] as $id_board => $board) { $context['move_to_boards'][$id_cat]['boards'][$id_board]['name'] = strip_tags($board['name']); } } // With no other boards to see, it's useless to move. if (empty($context['move_to_boards'])) { $context['can_move'] = false; } } // Can we use quick moderation checkboxes? if ($options['display_quick_mod']) { $context['can_quick_mod'] = $context['user']['is_logged'] || $context['can_approve'] || $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'] || $context['can_merge'] || $context['can_restore']; } } // If there are children, but no topics and no ability to post topics... $context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new']; $context['normal_buttons'] = array('new_topic' => array('test' => 'can_post_new', 'text' => 'new_topic', 'image' => 'new_topic.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0', 'active' => true), 'post_poll' => array('test' => 'can_post_poll', 'text' => 'new_poll', 'image' => 'new_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0;poll'), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.gif', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . ($context['is_marked_notify'] ? $txt['notification_disable_board'] : $txt['notification_enable_board']) . '\');"', 'url' => $scripturl . '?action=notifyboard;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';board=' . $context['current_board'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'markread' => array('text' => 'mark_read_short', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=board;board=' . $context['current_board'] . '.0;' . $context['session_var'] . '=' . $context['session_id'])); if (!empty($context['topics'])) { $context['subject_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=subject' . ($context['sort_by'] == 'subject' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['subject'] . ($context['sort_by'] == 'subject' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a> / <a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=starter' . ($context['sort_by'] == 'starter' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['started_by'] . ($context['sort_by'] == 'starter' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'; $context['views_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=replies' . ($context['sort_by'] == 'replies' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['replies'] . ($context['sort_by'] == 'replies' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a> / <a href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=views' . ($context['sort_by'] == 'views' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['views'] . ($context['sort_by'] == 'views' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'; $context['lastpost_sort_header'] = '<a rel="nofollow" href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=last_post' . ($context['sort_by'] == 'last_post' && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt['last_post'] . ($context['sort_by'] == 'last_post' ? ' <img src="' . $settings['images_url'] . '/sort_' . $context['sort_direction'] . '.gif" alt="" />' : '') . '</a>'; } // They can only mark read if they are logged in and it's enabled! if (!$context['user']['is_logged'] || !$settings['show_mark_read']) { unset($context['normal_buttons']['markread']); } HookAPI::callHook('messageindex_buttons', array(&$normal_buttons)); enqueueThemeScript('topic', 'scripts/topic.js', true); HookAPI::callHook('messageindex', array(&$board_info)); }