Exemplo n.º 1
0
function loadBoard()
{
    global $txt, $db_prefix, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $ID_MEMBER, $user_info;
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Load this board only if the it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] == 3)) {
        // !!! SLOW?
        if (!empty($topic)) {
            $temp = cache_get_data('topic_board-' . $topic, 120);
        } else {
            $temp = cache_get_data('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tc.ID_CAT, b.name AS bname, b.description, b.numTopics, b.memberGroups,\n\t\t\t\tb.ID_PARENT, c.name AS cname, IFNULL(mem.ID_MEMBER, 0) AS ID_MODERATOR,\n\t\t\t\tmem.realName" . (!empty($topic) ? ", b.ID_BOARD" : '') . ", b.childLevel,\n\t\t\t\tb.ID_THEME, b.override_theme, b.permission_mode, b.countPosts\n\t\t\tFROM ({$db_prefix}boards AS b" . (!empty($topic) ? ", {$db_prefix}topics AS t" : '') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\t\tLEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = " . (empty($topic) ? $board : 't.ID_BOARD') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = mods.ID_MEMBER)\n\t\t\tWHERE b.ID_BOARD = " . (empty($topic) ? $board : "t.ID_BOARD\n\t\t\t\tAND t.ID_TOPIC = {$topic}"), __FILE__, __LINE__);
        // If there aren't any, skip.
        if (mysql_num_rows($request) > 0) {
            $row = mysql_fetch_assoc($request);
            // Set the current board.
            if (!empty($row['ID_BOARD'])) {
                $board = $row['ID_BOARD'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['ID_CAT'], 'name' => $row['cname']), 'name' => $row['bname'], 'description' => $row['description'], 'num_topics' => $row['numTopics'], 'parent_boards' => getBoardParents($row['ID_PARENT']), 'parent' => $row['ID_PARENT'], 'child_level' => $row['childLevel'], 'theme' => $row['ID_THEME'], 'override_theme' => !empty($row['override_theme']), 'use_local_permissions' => !empty($modSettings['permission_enable_by_board']) && $row['permission_mode'] == 1, 'permission_mode' => empty($modSettings['permission_enable_by_board']) ? empty($row['permission_mode']) ? 'normal' : ($row['permission_mode'] == 2 ? 'no_polls' : ($row['permission_mode'] == 3 ? 'reply_only' : 'read_only')) : 'normal', 'posts_count' => empty($row['countPosts']));
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['memberGroups'] == '' ? array() : explode(',', $row['memberGroups']);
            do {
                if (!empty($row['ID_MODERATOR'])) {
                    $board_info['moderators'][$row['ID_MODERATOR']] = array('id' => $row['ID_MODERATOR'], 'name' => $row['realName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row['realName'] . '</a>');
                }
            } while ($row = mysql_fetch_assoc($request));
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] == 3)) {
                // !!! SLOW?
                if (!empty($topic)) {
                    cache_put_data('topic_board-' . $topic, $board_info, 120);
                }
                cache_put_data('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        mysql_free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$ID_MEMBER]);
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], array(array('url' => $scripturl . '#' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name'])));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // If it's a prefetching agent, just make clear they're not allowed.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}
Exemplo n.º 2
0
function loadBoard()
{
    global $txt, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $user_info, $db_show_debug;
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Have they by chance specified a message id but nothing else?
    if (empty($_REQUEST['action']) && empty($topic) && empty($board) && !empty($_REQUEST['msg'])) {
        // Make sure the message id is really an int.
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Looking through the message table can be slow, so try using the cache first.
        if (($topic = CacheAPI::getCache('msg_topic-' . $_REQUEST['msg'], 120)) === NULL) {
            $request = smf_db_query('
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_msg = {int:id_msg}
				LIMIT 1', array('id_msg' => $_REQUEST['msg']));
            // So did it find anything?
            if (mysql_num_rows($request)) {
                list($topic) = mysql_fetch_row($request);
                mysql_free_result($request);
                // Save save save.
                CacheAPI::putCache('msg_topic-' . $_REQUEST['msg'], $topic, 120);
            }
        }
        // Remember redirection is the key to avoiding fallout from your bosses.
        if (!empty($topic)) {
            if (isset($_REQUEST['perma'])) {
                redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . ';perma' . (isset($_REQUEST['xml']) ? ';xml' : ''));
            } else {
                redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']);
            }
        } else {
            loadPermissions();
            loadTheme();
            EoS_Smarty::init($db_show_debug);
            fatal_lang_error('topic_gone', false);
        }
    }
    // Load this board only if it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
        // !!! SLOW?
        if (!empty($topic)) {
            $temp = CacheAPI::getCache('topic_board-' . $topic, 120);
        } else {
            $temp = CacheAPI::getCache('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $request = smf_db_query('
			SELECT
				c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups,
				b.id_parent, c.name AS cname, IFNULL(mem.id_member, 0) AS id_moderator,
				mem.real_name' . (!empty($topic) ? ', b.id_board' : '') . ', b.child_level,
				b.id_theme, b.override_theme, b.count_posts, b.id_profile, b.redirect, b.allow_topics,
				b.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . '
			FROM {db_prefix}boards AS b' . (!empty($topic) ? '
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . '
				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = {raw:board_link})
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
			WHERE b.id_board = {raw:board_link}', array('current_topic' => $topic, 'board_link' => empty($topic) ? smf_db_quote('{int:current_board}', array('current_board' => $board)) : 't.id_board'));
        // If there aren't any, skip.
        if (mysql_num_rows($request) > 0) {
            $row = mysql_fetch_assoc($request);
            // Set the current board.
            if (!empty($row['id_board'])) {
                $board = $row['id_board'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'is_root' => $row['cname'][0] === '!' ? true : false), 'name' => $row['bname'], 'allow_topics' => $row['allow_topics'], 'description' => $row['description'], 'num_topics' => $row['num_topics'], 'unapproved_topics' => $row['unapproved_topics'], 'unapproved_posts' => $row['unapproved_posts'], 'unapproved_user_topics' => 0, 'parent_boards' => getBoardParents($row['id_parent']), 'parent' => $row['id_parent'], 'child_level' => $row['child_level'], 'theme' => $row['id_theme'], 'override_theme' => !empty($row['override_theme']), 'profile' => $row['id_profile'], 'redirect' => $row['redirect'], 'posts_count' => empty($row['count_posts']), 'cur_topic_approved' => empty($topic) || $row['approved'], 'cur_topic_starter' => empty($topic) ? 0 : $row['id_member_started']);
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['member_groups'] == '' ? array() : explode(',', $row['member_groups']);
            do {
                if (!empty($row['id_moderator'])) {
                    $board_info['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_moderator'] . '">' . $row['real_name'] . '</a>');
                }
            } while ($row = mysql_fetch_assoc($request));
            // If the board only contains unapproved posts and the user isn't an approver then they can't see any topics.
            // If that is the case do an additional check to see if they have any topics waiting to be approved.
            if ($board_info['num_topics'] == 0 && $modSettings['postmod_active'] && !allowedTo('approve_posts')) {
                mysql_free_result($request);
                // Free the previous result
                $request = smf_db_query('
					SELECT COUNT(id_topic)
					FROM {db_prefix}topics
					WHERE id_member_started={int:id_member}
						AND approved = {int:unapproved}
						AND id_board = {int:board}', array('id_member' => $user_info['id'], 'unapproved' => 0, 'board' => $board));
                list($board_info['unapproved_user_topics']) = mysql_fetch_row($request);
            }
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
                // !!! SLOW?
                if (!empty($topic)) {
                    CacheAPI::putCache('topic_board-' . $topic, $board_info, 120);
                }
                CacheAPI::putCache('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        mysql_free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    /*
     * if we are in topic view, set up the breadcrumb so that it
     * gives a link back to the last active message index page instead of
     * always pointing back to page one, but ignore the cookie when the board has changed.
     * the cookie is set in MessageIndex.php
     */
    $stored_topicstart = 0;
    if (isset($_COOKIE['smf_topicstart']) && !empty($topic)) {
        $topicstart_cookie = $_COOKIE['smf_topicstart'];
        $_t = explode('_', $topicstart_cookie);
        if (isset($_t[0]) && isset($_t[1]) && intval($_t[1]) > 0) {
            if ($_t[0] == $board) {
                $stored_topicstart = $_t[1];
            }
            $topics_per_page = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
        }
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]);
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], $board_info['cat']['is_root'] ? array() : array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => URL::board($board, $board_info['name'], $stored_topicstart > 0 ? $stored_topicstart : 0, false), 'name' => $board_info['name'] . ($stored_topicstart > 0 ? ' [' . ($stored_topicstart / $topics_per_page + 1) . ']' : ''))));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        EoS_Smarty::init($db_show_debug);
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // The linktree should not give the game away mate!
        $context['linktree'] = array(array('url' => URL::home(), 'name' => $context['forum_name_html_safe']));
        // If it's a prefetching agent or we're requesting an attachment.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch' || !empty($_REQUEST['action']) && $_REQUEST['action'] === 'dlattach') {
            ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}
Exemplo n.º 3
0
/**
 * Takes an array of board IDs and updates their last messages.
 *
 * - If the board has a parent, that parent board is also automatically updated.
 * - The columns updated are id_last_msg and last_updated.
 * - Note that id_last_msg should always be updated using this function,
 * and is not automatically updated upon other changes.
 *
 * @package Posts
 * @param int[]|int $setboards
 * @param int $id_msg = 0
 */
function updateLastMessages($setboards, $id_msg = 0)
{
    global $board_info, $board;
    $db = database();
    // Please - let's be sane.
    if (empty($setboards)) {
        return false;
    }
    if (!is_array($setboards)) {
        $setboards = array($setboards);
    }
    $lastMsg = array();
    // If we don't know the id_msg we need to find it.
    if (!$id_msg) {
        // Find the latest message on this board (highest id_msg.)
        $request = $db->query('', '
			SELECT id_board, MAX(id_last_msg) AS id_msg
			FROM {db_prefix}topics
			WHERE id_board IN ({array_int:board_list})
				AND approved = {int:approved}
			GROUP BY id_board', array('board_list' => $setboards, 'approved' => 1));
        while ($row = $db->fetch_assoc($request)) {
            $lastMsg[$row['id_board']] = $row['id_msg'];
        }
        $db->free_result($request);
    } else {
        // Just to note - there should only be one board passed if we are doing this.
        foreach ($setboards as $id_board) {
            $lastMsg[$id_board] = $id_msg;
        }
    }
    $parent_boards = array();
    // Keep track of last modified dates.
    $lastModified = $lastMsg;
    // Get all the sub-boards for the parents, if they have some...
    foreach ($setboards as $id_board) {
        if (!isset($lastMsg[$id_board])) {
            $lastMsg[$id_board] = 0;
            $lastModified[$id_board] = 0;
        }
        if (!empty($board) && $id_board == $board) {
            $parents = $board_info['parent_boards'];
        } else {
            $parents = getBoardParents($id_board);
        }
        // Ignore any parents on the top child level.
        foreach ($parents as $id => $parent) {
            if ($parent['level'] != 0) {
                // If we're already doing this one as a board, is this a higher last modified?
                if (isset($lastModified[$id]) && $lastModified[$id_board] > $lastModified[$id]) {
                    $lastModified[$id] = $lastModified[$id_board];
                } elseif (!isset($lastModified[$id]) && (!isset($parent_boards[$id]) || $parent_boards[$id] < $lastModified[$id_board])) {
                    $parent_boards[$id] = $lastModified[$id_board];
                }
            }
        }
    }
    // Note to help understand what is happening here. For parents we update the timestamp of the last message for determining
    // whether there are sub-boards which have not been read. For the boards themselves we update both this and id_last_msg.
    $board_updates = array();
    $parent_updates = array();
    // Finally, to save on queries make the changes...
    foreach ($parent_boards as $id => $msg) {
        if (!isset($parent_updates[$msg])) {
            $parent_updates[$msg] = array($id);
        } else {
            $parent_updates[$msg][] = $id;
        }
    }
    foreach ($lastMsg as $id => $msg) {
        if (!isset($board_updates[$msg . '-' . $lastModified[$id]])) {
            $board_updates[$msg . '-' . $lastModified[$id]] = array('id' => $msg, 'updated' => $lastModified[$id], 'boards' => array($id));
        } else {
            $board_updates[$msg . '-' . $lastModified[$id]]['boards'][] = $id;
        }
    }
    // Now commit the changes!
    foreach ($parent_updates as $id_msg => $boards) {
        $db->query('', '
			UPDATE {db_prefix}boards
			SET id_msg_updated = {int:id_msg_updated}
			WHERE id_board IN ({array_int:board_list})
				AND id_msg_updated < {int:id_msg_updated}', array('board_list' => $boards, 'id_msg_updated' => $id_msg));
    }
    foreach ($board_updates as $board_data) {
        $db->query('', '
			UPDATE {db_prefix}boards
			SET id_last_msg = {int:id_last_msg}, id_msg_updated = {int:id_msg_updated}
			WHERE id_board IN ({array_int:board_list})', array('board_list' => $board_data['boards'], 'id_last_msg' => $board_data['id'], 'id_msg_updated' => $board_data['updated']));
    }
}
Exemplo n.º 4
0
function updateLastMessages($setboards, $ID_MSG = 0)
{
    global $db_prefix, $board_info, $board, $modSettings;
    // Please - let's be sane.
    if (empty($setboards)) {
        return false;
    }
    if (!is_array($setboards)) {
        $setboards = array($setboards);
    }
    // If we don't know the ID_MSG we need to find it.
    if (!$ID_MSG) {
        // Find the latest message on this board (highest ID_MSG.)
        $request = db_query("\n\t\t\tSELECT ID_BOARD, MAX(ID_LAST_MSG) AS ID_MSG\n\t\t\tFROM {$db_prefix}topics\n\t\t\tWHERE ID_BOARD IN (" . implode(', ', $setboards) . ")\n\t\t\tGROUP BY ID_BOARD", __FILE__, __LINE__);
        $lastMsg = array();
        while ($row = mysql_fetch_assoc($request)) {
            $lastMsg[$row['ID_BOARD']] = $row['ID_MSG'];
        }
        mysql_free_result($request);
    } else {
        foreach ($setboards as $ID_BOARD) {
            $lastMsg[$ID_BOARD] = $ID_MSG;
        }
    }
    $parent_boards = array();
    // Get all the child boards for the parents, if they have some...
    foreach ($setboards as $ID_BOARD) {
        if (!isset($lastMsg[$ID_BOARD])) {
            $lastMsg[$ID_BOARD] = 0;
        }
        if (!empty($board) && $ID_BOARD == $board) {
            $parents = $board_info['parent_boards'];
        } else {
            $parents = getBoardParents($ID_BOARD);
        }
        // Ignore any parents on the top child level.
        foreach ($parents as $id => $parent) {
            if ($parent['level'] == 0) {
                unset($parent[$id]);
            } else {
                // If we're already doing this one as a board, is this a higher last modified?
                if (isset($lastMsg[$id]) && $lastMsg[$ID_BOARD] > $lastMsg[$id]) {
                    $lastMsg[$id] = $lastMsg[$ID_BOARD];
                } elseif (!isset($lastMsg[$id]) && (!isset($parent_boards[$id]) || $parent_boards[$id] < $lastMsg[$ID_BOARD])) {
                    $parent_boards[$id] = $lastMsg[$ID_BOARD];
                }
            }
        }
    }
    $board_updates = array();
    $parent_updates = array();
    // Finally, to save on queries make the changes...
    foreach ($parent_boards as $id => $msg) {
        if (!isset($parent_updates[$msg])) {
            $parent_updates[$msg] = array($id);
        } else {
            $parent_updates[$msg][] = $id;
        }
    }
    foreach ($lastMsg as $id => $msg) {
        if (!isset($board_updates[$msg])) {
            $board_updates[$msg] = array($id);
        } else {
            $board_updates[$msg][] = $id;
        }
    }
    // Now commit the changes!
    foreach ($parent_updates as $ID_MSG => $boards) {
        db_query("\n\t\t\tUPDATE {$db_prefix}boards\n\t\t\tSET ID_MSG_UPDATED = {$ID_MSG}\n\t\t\tWHERE ID_BOARD IN (" . implode(',', $boards) . ")\n\t\t\t\tAND ID_MSG_UPDATED < {$ID_MSG}\n\t\t\tLIMIT " . count($boards), __FILE__, __LINE__);
    }
    foreach ($board_updates as $ID_MSG => $boards) {
        db_query("\n\t\t\tUPDATE {$db_prefix}boards\n\t\t\tSET ID_LAST_MSG = {$ID_MSG}, ID_MSG_UPDATED = {$ID_MSG}\n\t\t\tWHERE ID_BOARD IN (" . implode(',', $boards) . ")\n\t\t\tLIMIT " . count($boards), __FILE__, __LINE__);
    }
}
Exemplo n.º 5
0
/**
 * Check for moderators and see if they have access to the board.
 *
 * What it does:
 * - sets up the $board_info array for current board information.
 * - if cache is enabled, the $board_info array is stored in cache.
 * - redirects to appropriate post if only message id is requested.
 * - is only used when inside a topic or board.
 * - determines the local moderators for the board.
 * - adds group id 3 if the user is a local moderator for the board they are in.
 * - prevents access if user is not in proper group nor a local moderator of the board.
 */
function loadBoard()
{
    global $txt, $scripturl, $context, $modSettings;
    global $board_info, $board, $topic, $user_info;
    $db = database();
    // Assume they are not a moderator.
    $user_info['is_mod'] = false;
    $context['user']['is_mod'] =& $user_info['is_mod'];
    // @since 1.0.5 - is_mod takes into account only local (board) moderators,
    // and not global moderators, is_moderator is meant to take into account both.
    $user_info['is_moderator'] = false;
    $context['user']['is_moderator'] =& $user_info['is_moderator'];
    // Start the linktree off empty..
    $context['linktree'] = array();
    // Have they by chance specified a message id but nothing else?
    if (empty($_REQUEST['action']) && empty($topic) && empty($board) && !empty($_REQUEST['msg'])) {
        // Make sure the message id is really an int.
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        // Looking through the message table can be slow, so try using the cache first.
        if (($topic = cache_get_data('msg_topic-' . $_REQUEST['msg'], 120)) === null) {
            require_once SUBSDIR . '/Messages.subs.php';
            $topic = associatedTopic($_REQUEST['msg']);
            // So did it find anything?
            if ($topic !== false) {
                // Save save save.
                cache_put_data('msg_topic-' . $_REQUEST['msg'], $topic, 120);
            }
        }
        // Remember redirection is the key to avoiding fallout from your bosses.
        if (!empty($topic)) {
            redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']);
        } else {
            loadPermissions();
            loadTheme();
            fatal_lang_error('topic_gone', false);
        }
    }
    // Load this board only if it is specified.
    if (empty($board) && empty($topic)) {
        $board_info = array('moderators' => array());
        return;
    }
    if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
        // @todo SLOW?
        if (!empty($topic)) {
            $temp = cache_get_data('topic_board-' . $topic, 120);
        } else {
            $temp = cache_get_data('board-' . $board, 120);
        }
        if (!empty($temp)) {
            $board_info = $temp;
            $board = $board_info['id'];
        }
    }
    if (empty($temp)) {
        $select_columns = array();
        $select_tables = array();
        // Wanna grab something more from the boards table or another table at all?
        call_integration_hook('integrate_load_board_query', array(&$select_columns, &$select_tables));
        $request = $db->query('', '
			SELECT
				c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups, b.deny_member_groups,
				b.id_parent, c.name AS cname, IFNULL(mem.id_member, 0) AS id_moderator,
				mem.real_name' . (!empty($topic) ? ', b.id_board' : '') . ', b.child_level,
				b.id_theme, b.override_theme, b.count_posts, b.id_profile, b.redirect,
				b.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . (!empty($select_columns) ? ', ' . implode(', ', $select_columns) : '') . '
			FROM {db_prefix}boards AS b' . (!empty($topic) ? '
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . (!empty($select_tables) ? '
				' . implode("\n\t\t\t\t", $select_tables) : '') . '
				LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = {raw:board_link})
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
			WHERE b.id_board = {raw:board_link}', array('current_topic' => $topic, 'board_link' => empty($topic) ? $db->quote('{int:current_board}', array('current_board' => $board)) : 't.id_board'));
        // If there aren't any, skip.
        if ($db->num_rows($request) > 0) {
            $row = $db->fetch_assoc($request);
            // Set the current board.
            if (!empty($row['id_board'])) {
                $board = $row['id_board'];
            }
            // Basic operating information. (globals... :/)
            $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['id_cat'], 'name' => $row['cname']), 'name' => $row['bname'], 'description' => $row['description'], 'num_topics' => $row['num_topics'], 'unapproved_topics' => $row['unapproved_topics'], 'unapproved_posts' => $row['unapproved_posts'], 'unapproved_user_topics' => 0, 'parent_boards' => getBoardParents($row['id_parent']), 'parent' => $row['id_parent'], 'child_level' => $row['child_level'], 'theme' => $row['id_theme'], 'override_theme' => !empty($row['override_theme']), 'profile' => $row['id_profile'], 'redirect' => $row['redirect'], 'posts_count' => empty($row['count_posts']), 'cur_topic_approved' => empty($topic) || $row['approved'], 'cur_topic_starter' => empty($topic) ? 0 : $row['id_member_started']);
            // Load the membergroups allowed, and check permissions.
            $board_info['groups'] = $row['member_groups'] == '' ? array() : explode(',', $row['member_groups']);
            $board_info['deny_groups'] = $row['deny_member_groups'] == '' ? array() : explode(',', $row['deny_member_groups']);
            do {
                if (!empty($row['id_moderator'])) {
                    $board_info['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_moderator'] . '">' . $row['real_name'] . '</a>');
                }
            } while ($row = $db->fetch_assoc($request));
            // If the board only contains unapproved posts and the user isn't an approver then they can't see any topics.
            // If that is the case do an additional check to see if they have any topics waiting to be approved.
            if ($board_info['num_topics'] == 0 && $modSettings['postmod_active'] && !allowedTo('approve_posts')) {
                // Free the previous result
                $db->free_result($request);
                // @todo why is this using id_topic?
                // @todo Can this get cached?
                $request = $db->query('', '
					SELECT COUNT(id_topic)
					FROM {db_prefix}topics
					WHERE id_member_started={int:id_member}
						AND approved = {int:unapproved}
						AND id_board = {int:board}', array('id_member' => $user_info['id'], 'unapproved' => 0, 'board' => $board));
                list($board_info['unapproved_user_topics']) = $db->fetch_row($request);
            }
            call_integration_hook('integrate_loaded_board', array(&$board_info, &$row));
            if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) {
                // @todo SLOW?
                if (!empty($topic)) {
                    cache_put_data('topic_board-' . $topic, $board_info, 120);
                }
                cache_put_data('board-' . $board, $board_info, 120);
            }
        } else {
            // Otherwise the topic is invalid, there are no moderators, etc.
            $board_info = array('moderators' => array(), 'error' => 'exist');
            $topic = null;
            $board = 0;
        }
        $db->free_result($request);
    }
    if (!empty($topic)) {
        $_GET['board'] = (int) $board;
    }
    if (!empty($board)) {
        // Now check if the user is a moderator.
        $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]);
        $user_info['is_moderator'] = $user_info['is_mod'] || allowedTo('moderate_board');
        if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        if (!empty($modSettings['deny_boards_access']) && count(array_intersect($user_info['groups'], $board_info['deny_groups'])) != 0 && !$user_info['is_admin']) {
            $board_info['error'] = 'access';
        }
        // Build up the linktree.
        $context['linktree'] = array_merge($context['linktree'], array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name'])));
    }
    // Set the template contextual information.
    $context['user']['is_mod'] =& $user_info['is_mod'];
    $context['user']['is_moderator'] =& $user_info['is_moderator'];
    $context['current_topic'] = $topic;
    $context['current_board'] = $board;
    // Hacker... you can't see this topic, I'll tell you that. (but moderators can!)
    if (!empty($board_info['error']) && (!empty($modSettings['deny_boards_access']) || $board_info['error'] != 'access' || !$user_info['is_moderator'])) {
        // The permissions and theme need loading, just to make sure everything goes smoothly.
        loadPermissions();
        loadTheme();
        $_GET['board'] = '';
        $_GET['topic'] = '';
        // The linktree should not give the game away mate!
        $context['linktree'] = array(array('url' => $scripturl, 'name' => $context['forum_name_html_safe']));
        // If it's a prefetching agent or we're requesting an attachment.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch' || !empty($_REQUEST['action']) && $_REQUEST['action'] === 'dlattach') {
            @ob_end_clean();
            header('HTTP/1.1 403 Forbidden');
            die;
        } elseif ($user_info['is_guest']) {
            loadLanguage('Errors');
            is_not_guest($txt['topic_gone']);
        } else {
            fatal_lang_error('topic_gone', false);
        }
    }
    if ($user_info['is_mod']) {
        $user_info['groups'][] = 3;
    }
}