Ejemplo n.º 1
0
function ShowAdminHelp()
{
    global $txt, $helptxt, $context, $scripturl;
    if (!isset($_GET['help']) || !is_string($_GET['help'])) {
        fatal_lang_error('no_access', false);
    }
    if (!isset($helptxt)) {
        $helptxt = array();
    }
    // Load the admin help language file and template.
    loadLanguage('Help');
    // Permission specific help?
    if (isset($_GET['help']) && substr($_GET['help'], 0, 14) == 'permissionhelp') {
        loadLanguage('ManagePermissions');
    }
    Eos_Smarty::loadTemplate('xml_blocks');
    $context['template_functions'] = array('help_popup');
    // Set the page title to something relevant.
    $context['page_title'] = $context['forum_name'] . ' - ' . $txt['help'];
    // Don't show any template layers, just the popup sub template.
    $context['template_layers'] = array();
    $context['sub_template'] = 'popup';
    // What help string should be used?
    if (isset($helptxt[$_GET['help']])) {
        $context['help_text'] = $helptxt[$_GET['help']];
    } elseif (isset($txt[$_GET['help']])) {
        $context['help_text'] = $txt[$_GET['help']];
    } else {
        $context['help_text'] = $_GET['help'];
    }
    // Does this text contain a link that we should fill in?
    if (preg_match('~%([0-9]+\\$)?s\\?~', $context['help_text'], $match)) {
        $context['help_text'] = sprintf($context['help_text'], $scripturl, $context['session_id'], $context['session_var']);
    }
}
Ejemplo n.º 2
0
/**
 * @param $memID	int member ID
 * 
 * show the settings to customize opt-outs for activity entries and notifications
 * to receive.
 * 
 * todo: we need to find a way to filter out notifications that are for
 * admins/mods only. probably needs a db scheme change...
 */
function showActivitiesProfileSettings($memID)
{
    global $modSettings, $context, $user_info, $txt, $user_profile, $scripturl;
    loadLanguage('Activities-Profile');
    if (empty($modSettings['astream_active']) || $user_info['id'] != $memID && !$user_info['is_admin']) {
        fatal_lang_error('no_access');
    }
    Eos_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'profile/astream_settings');
    $context['submiturl'] = $scripturl . '?action=profile;area=activities;sa=settings;save;u=' . $memID;
    $context['page_title'] = $txt['showActivities'] . ' - ' . $user_profile[$memID]['real_name'];
    $context[$context['profile_menu_name']]['tab_data'] = array('title' => $txt['showActivitiesSettings'], 'description' => $txt['showActivitiesSettings_desc'], 'tabs' => array());
    $result = smf_db_query('SELECT * FROM {db_prefix}activity_types ORDER BY id_type ASC');
    if ($user_info['id'] == $memID) {
        $my_act_optout = empty($user_info['act_optout']) ? array(0) : explode(',', $user_info['act_optout']);
        $my_notify_optout = empty($user_info['notify_optout']) ? array(0) : explode(',', $user_info['notify_optout']);
    } else {
        loadMemberData($memID, false, 'minimal');
        $my_act_optout = empty($user_profile[$memID]['act_optout']) ? array(0) : explode(',', $user_profile[$memID]['act_optout']);
        $my_notify_optout = empty($user_profile[$memID]['notify_optout']) ? array(0) : explode(',', $user_profile[$memID]['notify_optout']);
    }
    $context['activity_types'] = array();
    while ($row = mysql_fetch_assoc($result)) {
        $context['activity_types'][] = array('id' => $row['id_type'], 'shortdesc' => $row['id_desc'], 'longdesc_act' => $txt['actdesc_' . trim($row['id_desc'])], 'longdesc_not' => isset($txt['ndesc_' . trim($row['id_desc'])]) ? $txt['ndesc_' . trim($row['id_desc'])] : '', 'act_optout' => in_array($row['id_type'], $my_act_optout), 'notify_optout' => in_array($row['id_type'], $my_notify_optout));
    }
    mysql_free_result($result);
    if (isset($_GET['save'])) {
        $new_not_optout = array();
        $new_act_optout = array();
        $update_array = array();
        foreach ($context['activity_types'] as $t) {
            $_id = trim($t['id']);
            if (!empty($t['longdesc_act']) && (!isset($_REQUEST['act_check_' . $_id]) || empty($_REQUEST['act_check_' . $_id]))) {
                $new_act_optout[] = $_id;
            }
            if (!empty($t['longdesc_not']) && (!isset($_REQUEST['not_check_' . $_id]) || empty($_REQUEST['not_check_' . $_id]))) {
                $new_not_optout[] = $_id;
            }
        }
        //if(count(array_unique($new_act_optout)) > 0)
        $update_array['act_optout'] = implode(',', array_unique($new_act_optout));
        //if(count(array_unique($new_not_optout)) > 0)
        $update_array['notify_optout'] = implode(',', array_unique($new_not_optout));
        if (count($update_array)) {
            updateMemberData($memID, $update_array);
        }
        redirectexit($scripturl . '?action=profile;area=activities;sa=settings;u=' . $memID);
    }
}
Ejemplo n.º 3
0
function BoardNotify()
{
    global $scripturl, $txt, $board, $user_info, $context, $smcFunc;
    // Permissions are an important part of anything ;).
    is_not_guest();
    isAllowedTo('mark_notify');
    // You have to specify a board to turn notifications on!
    if (empty($board)) {
        fatal_lang_error('no_board', false);
    }
    // No subaction: find out what to do.
    if (empty($_GET['sa'])) {
        // We're gonna need the notify template...
        Eos_Smarty::loadTemplate('generic_skeleton');
        EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'notify/notify_board');
        // Find out if they have notification set for this topic already.
        $request = smf_db_query('
			SELECT id_member
			FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}
			LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id']));
        $context['notification_set'] = mysql_num_rows($request) != 0;
        mysql_free_result($request);
        // Set the template variables...
        $context['board_href'] = $scripturl . '?board=' . $board . '.' . $_REQUEST['start'];
        $context['start'] = $_REQUEST['start'];
        $context['page_title'] = $txt['notification'];
        return;
    } elseif ($_GET['sa'] == 'on') {
        checkSession('get');
        // Turn notification on.  (note this just blows smoke if it's already on.)
        smf_db_insert('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_board' => 'int'), array($user_info['id'], $board), array('id_member', 'id_board'));
    } else {
        checkSession('get');
        // Turn notification off for this board.
        smf_db_query('
			DELETE FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id']));
    }
    // Back to the board!
    redirectexit('board=' . $board . '.' . $_REQUEST['start']);
}
Ejemplo n.º 4
0
function ViewFile()
{
    global $context, $txt, $boarddir, $sourcedir;
    // Check for the administrative permission to do this.
    isAllowedTo('admin_forum');
    $context['need_synhlt'] = true;
    // decode the file and get the line
    $file = base64_decode($_REQUEST['file']);
    $line = isset($_REQUEST['line']) ? (int) $_REQUEST['line'] : 0;
    // Make sure the file we are looking for is one they are allowed to look at
    if (!is_readable($file) || strpos($file, '../') !== false && (strpos($file, $boarddir) === false || strpos($file, $sourcedir) === false)) {
        fatal_lang_error('error_bad_file', true, array(htmlspecialchars($file)));
    }
    // get the min and max lines
    $min = $line - 20 <= 0 ? 1 : $line - 20;
    $max = $line + 21;
    // One additional line to make everything work out correctly
    if ($max <= 0 || $min >= $max) {
        fatal_lang_error('error_bad_line');
    }
    $file_data = explode('<br />', highlight_php_code(htmlspecialchars(implode('', file($file)))));
    // We don't want to slice off too many so lets make sure we stop at the last one
    $max = min($max, max(array_keys($file_data)));
    $file_data = array_slice($file_data, $min - 1, $max - $min);
    $context['file_data'] = array('contents' => $file_data, 'min' => $min, 'target' => $line, 'file' => strtr($file, array('"' => '\\"')));
    Eos_Smarty::loadTemplate('admin/errors_show_file');
    //loadAdminTemplate('Errors');
}
Ejemplo n.º 5
0
function Memberlist()
{
    global $scripturl, $txt, $modSettings, $context, $settings, $modSettings;
    // Make sure they can view the memberlist.
    isAllowedTo('view_mlist');
    $context['listing_by'] = !empty($_GET['sa']) ? $_GET['sa'] : 'all';
    $context['show_sidebar'] = true;
    $context['sidebar_template'] = 'sidebars/sidebar_memberlist.tpl';
    MLSearch();
    // $subActions array format:
    // 'subaction' => array('label', 'function', 'is_selected')
    $subActions = array('all' => array($txt['view_all_members'], 'MLAll', $context['listing_by'] == 'all'), 'search' => array($txt['mlist_search'], 'MLSearch', $context['listing_by'] == 'search'));
    // Set up the sort links.
    $context['sort_links'] = array();
    foreach ($subActions as $act => $text) {
        $context['sort_links'][] = array('label' => $text[0], 'action' => $act, 'selected' => $text[2]);
    }
    $context['num_members'] = $modSettings['totalMembers'];
    // Set up the columns...
    $context['columns'] = array('is_online' => array('label' => $txt['status'], 'width' => '60', 'class' => 'first_th'), 'real_name' => array('label' => $txt['username']), 'id_group' => array('label' => $txt['position']), 'registered' => array('label' => $txt['date_registered']), 'posts' => array('label' => $txt['posts'], 'width' => '115', 'colspan' => '2', 'default_sort_rev' => true));
    $context['colspan'] = 0;
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
    foreach ($context['columns'] as $key => $column) {
        if (isset($context['disabled_fields'][$key]) || isset($column['link_with']) && isset($context['disabled_fields'][$column['link_with']])) {
            unset($context['columns'][$key]);
            continue;
        }
        $context['colspan'] += isset($column['colspan']) ? $column['colspan'] : 1;
    }
    // Aesthetic stuff.
    end($context['columns']);
    $context['columns'][key($context['columns'])]['class'] = 'last_th';
    $context['linktree'][] = array('url' => $scripturl . '?action=mlist', 'name' => $txt['members_list']);
    $context['can_send_pm'] = allowedTo('pm_send');
    // Jump to the sub action.
    if (isset($subActions[$context['listing_by']])) {
        $subActions[$context['listing_by']][1]();
    } else {
        $subActions['all'][1]();
    }
    Eos_Smarty::loadTemplate('memberlist');
}
Ejemplo n.º 6
0
function ReportsMain()
{
    global $txt, $modSettings, $context, $scripturl;
    // Only admins, only EVER admins!
    isAllowedTo('admin_forum');
    // Let's get our things running...
    //loadTemplate('Reports');
    Eos_Smarty::setActive();
    loadLanguage('Reports');
    $context['page_title'] = $txt['generate_reports'];
    // These are the types of reports which exist - and the functions to generate them.
    $context['report_types'] = array('boards' => 'BoardReport', 'board_perms' => 'BoardPermissionsReport', 'member_groups' => 'MemberGroupsReport', 'group_perms' => 'GroupPermissionsReport', 'staff' => 'StaffReport');
    $is_first = 0;
    foreach ($context['report_types'] as $k => $temp) {
        $context['report_types'][$k] = array('id' => $k, 'title' => isset($txt['gr_type_' . $k]) ? $txt['gr_type_' . $k] : $type['id'], 'description' => isset($txt['gr_type_desc_' . $k]) ? $txt['gr_type_desc_' . $k] : null, 'function' => $temp, 'is_first' => $is_first++ == 0);
    }
    // If they haven't choosen a report type which is valid, send them off to the report type chooser!
    if (empty($_REQUEST['rt']) || !isset($context['report_types'][$_REQUEST['rt']])) {
        $context['sub_template'] = 'report_type';
        Eos_Smarty::loadTemplate('reports/base');
        Eos_Smarty::getConfigInstance()->registerHookTemplate('reports_content_area', 'reports/choose_type');
        return;
    }
    $context['report_type'] = $_REQUEST['rt'];
    $context['report_buttons'] = array('generate_reports' => array('text' => 'generate_reports', 'image' => 'print.gif', 'lang' => true, 'url' => $scripturl . '?action=admin;area=reports', 'active' => true), 'print' => array('text' => 'print', 'image' => 'print.gif', 'lang' => true, 'url' => $scripturl . '?action=admin;area=reports;rt=' . $context['report_type'] . ';st=print', 'custom' => 'target="_blank"'));
    // What are valid templates for showing reports?
    $reportTemplates = array('main' => array('layers' => null), 'print' => array('layers' => array('print')));
    // Specific template? Use that instead of main!
    if (isset($_REQUEST['st']) && isset($reportTemplates[$_REQUEST['st']])) {
        // Are we disabling the other layers - print friendly for example?
        if ($reportTemplates[$_REQUEST['st']]['layers'] !== null) {
            Eos_Smarty::loadTemplate('reports/print');
            $context['template_layers'] = $reportTemplates[$_REQUEST['st']]['layers'];
        }
    } else {
        Eos_Smarty::loadTemplate('reports/base');
        Eos_Smarty::getConfigInstance()->registerHookTemplate('reports_content_area', 'reports/main');
    }
    // Make the page title more descriptive.
    $context['page_title'] .= ' - ' . (isset($txt['gr_type_' . $context['report_type']]) ? $txt['gr_type_' . $context['report_type']] : $context['report_type']);
    // Now generate the data.
    $context['report_types'][$context['report_type']]['function']();
    // Finish the tables before exiting - this is to help the templates a little more.
    finishTables();
}
Ejemplo n.º 7
0
function DisplayStats()
{
    global $txt, $scripturl, $modSettings, $user_info, $context, $smcFunc;
    isAllowedTo('view_stats');
    if (!empty($_REQUEST['expand'])) {
        $context['robot_no_index'] = true;
        $month = (int) substr($_REQUEST['expand'], 4);
        $year = (int) substr($_REQUEST['expand'], 0, 4);
        if ($year > 1900 && $year < 2200 && $month >= 1 && $month <= 12) {
            $_SESSION['expanded_stats'][$year][] = $month;
        }
    } elseif (!empty($_REQUEST['collapse'])) {
        $context['robot_no_index'] = true;
        $month = (int) substr($_REQUEST['collapse'], 4);
        $year = (int) substr($_REQUEST['collapse'], 0, 4);
        if (!empty($_SESSION['expanded_stats'][$year])) {
            $_SESSION['expanded_stats'][$year] = array_diff($_SESSION['expanded_stats'][$year], array($month));
        }
    }
    // Handle the XMLHttpRequest.
    if (isset($_REQUEST['xml'])) {
        // Collapsing stats only needs adjustments of the session variables.
        if (!empty($_REQUEST['collapse'])) {
            obExit(false);
        }
        $context['sub_template'] = 'stats';
        getDailyStats('YEAR(date) = {int:year} AND MONTH(date) = {int:month}', array('year' => $year, 'month' => $month));
        $context['yearly'][$year]['months'][$month]['date'] = array('month' => sprintf('%02d', $month), 'year' => $year);
        return;
    }
    loadLanguage('Stats');
    Eos_Smarty::loadTemplate('forumstats');
    // Build the link tree......
    $context['linktree'][] = array('url' => $scripturl . '?action=stats', 'name' => $txt['stats_center']);
    $context['page_title'] = $context['forum_name'] . ' - ' . $txt['stats_center'];
    $context['show_member_list'] = allowedTo('view_mlist');
    // Get averages...
    $result = smf_db_query('
		SELECT
			SUM(posts) AS posts, SUM(topics) AS topics, SUM(registers) AS registers,
			SUM(most_on) AS most_on, MIN(date) AS date, SUM(hits) AS hits
		FROM {db_prefix}log_activity', array());
    $row = mysql_fetch_assoc($result);
    mysql_free_result($result);
    // This would be the amount of time the forum has been up... in days...
    $total_days_up = ceil((time() - strtotime($row['date'])) / (60 * 60 * 24));
    $context['average_posts'] = comma_format(round($row['posts'] / $total_days_up, 2));
    $context['average_topics'] = comma_format(round($row['topics'] / $total_days_up, 2));
    $context['average_members'] = comma_format(round($row['registers'] / $total_days_up, 2));
    $context['average_online'] = comma_format(round($row['most_on'] / $total_days_up, 2));
    $context['average_hits'] = comma_format(round($row['hits'] / $total_days_up, 2));
    $context['num_hits'] = comma_format($row['hits'], 0);
    // How many users are online now.
    $result = smf_db_query('
		SELECT COUNT(*)
		FROM {db_prefix}log_online', array());
    list($context['users_online']) = mysql_fetch_row($result);
    mysql_free_result($result);
    // Statistics such as number of boards, categories, etc.
    $result = smf_db_query('
		SELECT COUNT(*)
		FROM {db_prefix}boards AS b
		WHERE b.redirect = {string:blank_redirect}', array('blank_redirect' => ''));
    list($context['num_boards']) = mysql_fetch_row($result);
    mysql_free_result($result);
    $result = smf_db_query('
		SELECT COUNT(*)
		FROM {db_prefix}categories AS c', array());
    list($context['num_categories']) = mysql_fetch_row($result);
    mysql_free_result($result);
    // Format the numbers nicely.
    $context['users_online'] = comma_format($context['users_online']);
    $context['num_boards'] = comma_format($context['num_boards']);
    $context['num_categories'] = comma_format($context['num_categories']);
    $context['num_members'] = comma_format($modSettings['totalMembers']);
    $context['num_posts'] = comma_format($modSettings['totalMessages']);
    $context['num_topics'] = comma_format($modSettings['totalTopics']);
    $context['most_members_online'] = array('number' => comma_format($modSettings['mostOnline']), 'date' => timeformat($modSettings['mostDate']));
    $context['latest_member'] =& $context['common_stats']['latest_member'];
    // Male vs. female ratio - let's calculate this only every four minutes.
    if (($context['gender'] = CacheAPI::getCache('stats_gender', 240)) == null) {
        $result = smf_db_query('
			SELECT COUNT(*) AS total_members, gender
			FROM {db_prefix}members
			GROUP BY gender', array());
        $context['gender'] = array();
        while ($row = mysql_fetch_assoc($result)) {
            // Assuming we're telling... male or female?
            if (!empty($row['gender'])) {
                $context['gender'][$row['gender'] == 2 ? 'females' : 'males'] = $row['total_members'];
            }
        }
        mysql_free_result($result);
        // Set these two zero if the didn't get set at all.
        if (empty($context['gender']['males'])) {
            $context['gender']['males'] = 0;
        }
        if (empty($context['gender']['females'])) {
            $context['gender']['females'] = 0;
        }
        // Try and come up with some "sensible" default states in case of a non-mixed board.
        if ($context['gender']['males'] == $context['gender']['females']) {
            $context['gender']['ratio'] = '1:1';
        } elseif ($context['gender']['males'] == 0) {
            $context['gender']['ratio'] = '0:1';
        } elseif ($context['gender']['females'] == 0) {
            $context['gender']['ratio'] = '1:0';
        } elseif ($context['gender']['males'] > $context['gender']['females']) {
            $context['gender']['ratio'] = round($context['gender']['males'] / $context['gender']['females'], 1) . ':1';
        } elseif ($context['gender']['females'] > $context['gender']['males']) {
            $context['gender']['ratio'] = '1:' . round($context['gender']['females'] / $context['gender']['males'], 1);
        }
        CacheAPI::putCache('stats_gender', $context['gender'], 240);
    }
    $date = strftime('%Y-%m-%d', forum_time(false));
    // Members online so far today.
    $result = smf_db_query('
		SELECT most_on
		FROM {db_prefix}log_activity
		WHERE date = {date:today_date}
		LIMIT 1', array('today_date' => $date));
    list($context['online_today']) = mysql_fetch_row($result);
    mysql_free_result($result);
    $context['online_today'] = comma_format((int) $context['online_today']);
    // Poster top 10.
    $members_result = smf_db_query('
		SELECT id_member, real_name, posts
		FROM {db_prefix}members
		WHERE posts > {int:no_posts}
		ORDER BY posts DESC
		LIMIT 10', array('no_posts' => 0));
    $context['top_posters'] = array();
    $max_num_posts = 1;
    while ($row_members = mysql_fetch_assoc($members_result)) {
        $context['top_posters'][] = array('name' => $row_members['real_name'], 'id' => $row_members['id_member'], 'num_posts' => $row_members['posts'], 'href' => $scripturl . '?action=profile;u=' . $row_members['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_members['id_member'] . '">' . $row_members['real_name'] . '</a>');
        if ($max_num_posts < $row_members['posts']) {
            $max_num_posts = $row_members['posts'];
        }
    }
    mysql_free_result($members_result);
    foreach ($context['top_posters'] as $i => $poster) {
        $context['top_posters'][$i]['post_percent'] = round($poster['num_posts'] * 100 / $max_num_posts);
        $context['top_posters'][$i]['num_posts'] = comma_format($context['top_posters'][$i]['num_posts']);
    }
    // Board top 10.
    $boards_result = smf_db_query('
		SELECT id_board, name, num_posts
		FROM {db_prefix}boards AS b
		WHERE {query_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
			AND b.id_board != {int:recycle_board}' : '') . '
			AND b.redirect = {string:blank_redirect}
		ORDER BY num_posts DESC
		LIMIT 10', array('recycle_board' => $modSettings['recycle_board'], 'blank_redirect' => ''));
    $context['top_boards'] = array();
    $max_num_posts = 1;
    while ($row_board = mysql_fetch_assoc($boards_result)) {
        $context['top_boards'][] = array('id' => $row_board['id_board'], 'name' => $row_board['name'], 'num_posts' => $row_board['num_posts'], 'href' => $scripturl . '?board=' . $row_board['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_board['id_board'] . '.0">' . $row_board['name'] . '</a>');
        if ($max_num_posts < $row_board['num_posts']) {
            $max_num_posts = $row_board['num_posts'];
        }
    }
    mysql_free_result($boards_result);
    foreach ($context['top_boards'] as $i => $board) {
        $context['top_boards'][$i]['post_percent'] = round($board['num_posts'] * 100 / $max_num_posts);
        $context['top_boards'][$i]['num_posts'] = comma_format($context['top_boards'][$i]['num_posts']);
    }
    // Are you on a larger forum?  If so, let's try to limit the number of topics we search through.
    if ($modSettings['totalMessages'] > 100000) {
        $request = smf_db_query('
			SELECT id_topic
			FROM {db_prefix}topics
			WHERE num_replies != {int:no_replies}' . ($modSettings['postmod_active'] ? '
				AND approved = {int:is_approved}' : '') . '
			ORDER BY num_replies DESC
			LIMIT 100', array('no_replies' => 0, 'is_approved' => 1));
        $topic_ids = array();
        while ($row = mysql_fetch_assoc($request)) {
            $topic_ids[] = $row['id_topic'];
        }
        mysql_free_result($request);
    } else {
        $topic_ids = array();
    }
    // Topic replies top 10.
    $topic_reply_result = smf_db_query('
		SELECT m.subject, t.num_replies, t.id_board, t.id_topic, b.name
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
			AND b.id_board != {int:recycle_board}' : '') . ')
		WHERE {query_see_board}' . (!empty($topic_ids) ? '
			AND t.id_topic IN ({array_int:topic_list})' : ($modSettings['postmod_active'] ? '
			AND t.approved = {int:is_approved}' : '')) . '
		ORDER BY t.num_replies DESC
		LIMIT 10', array('topic_list' => $topic_ids, 'recycle_board' => $modSettings['recycle_board'], 'is_approved' => 1));
    $context['top_topics_replies'] = array();
    $max_num_replies = 1;
    while ($row_topic_reply = mysql_fetch_assoc($topic_reply_result)) {
        censorText($row_topic_reply['subject']);
        $context['top_topics_replies'][] = array('id' => $row_topic_reply['id_topic'], 'board' => array('id' => $row_topic_reply['id_board'], 'name' => $row_topic_reply['name'], 'href' => $scripturl . '?board=' . $row_topic_reply['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_topic_reply['id_board'] . '.0">' . $row_topic_reply['name'] . '</a>'), 'subject' => $row_topic_reply['subject'], 'num_replies' => $row_topic_reply['num_replies'], 'href' => $scripturl . '?topic=' . $row_topic_reply['id_topic'] . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . $row_topic_reply['id_topic'] . '.0">' . $row_topic_reply['subject'] . '</a>');
        if ($max_num_replies < $row_topic_reply['num_replies']) {
            $max_num_replies = $row_topic_reply['num_replies'];
        }
    }
    mysql_free_result($topic_reply_result);
    foreach ($context['top_topics_replies'] as $i => $topic) {
        $context['top_topics_replies'][$i]['post_percent'] = round($topic['num_replies'] * 100 / $max_num_replies);
        $context['top_topics_replies'][$i]['num_replies'] = comma_format($context['top_topics_replies'][$i]['num_replies']);
    }
    // Large forums may need a bit more prodding...
    if ($modSettings['totalMessages'] > 100000) {
        $request = smf_db_query('
			SELECT id_topic
			FROM {db_prefix}topics
			WHERE num_views != {int:no_views}
			ORDER BY num_views DESC
			LIMIT 100', array('no_views' => 0));
        $topic_ids = array();
        while ($row = mysql_fetch_assoc($request)) {
            $topic_ids[] = $row['id_topic'];
        }
        mysql_free_result($request);
    } else {
        $topic_ids = array();
    }
    // Topic views top 10.
    $topic_view_result = smf_db_query('
		SELECT m.subject, t.num_views, t.id_board, t.id_topic, b.name
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
			AND b.id_board != {int:recycle_board}' : '') . ')
		WHERE {query_see_board}' . (!empty($topic_ids) ? '
			AND t.id_topic IN ({array_int:topic_list})' : ($modSettings['postmod_active'] ? '
			AND t.approved = {int:is_approved}' : '')) . '
		ORDER BY t.num_views DESC
		LIMIT 10', array('topic_list' => $topic_ids, 'recycle_board' => $modSettings['recycle_board'], 'is_approved' => 1));
    $context['top_topics_views'] = array();
    $max_num_views = 1;
    while ($row_topic_views = mysql_fetch_assoc($topic_view_result)) {
        censorText($row_topic_views['subject']);
        $context['top_topics_views'][] = array('id' => $row_topic_views['id_topic'], 'board' => array('id' => $row_topic_views['id_board'], 'name' => $row_topic_views['name'], 'href' => $scripturl . '?board=' . $row_topic_views['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row_topic_views['id_board'] . '.0">' . $row_topic_views['name'] . '</a>'), 'subject' => $row_topic_views['subject'], 'num_views' => $row_topic_views['num_views'], 'href' => $scripturl . '?topic=' . $row_topic_views['id_topic'] . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . $row_topic_views['id_topic'] . '.0">' . $row_topic_views['subject'] . '</a>');
        if ($max_num_views < $row_topic_views['num_views']) {
            $max_num_views = $row_topic_views['num_views'];
        }
    }
    mysql_free_result($topic_view_result);
    foreach ($context['top_topics_views'] as $i => $topic) {
        $context['top_topics_views'][$i]['post_percent'] = round($topic['num_views'] * 100 / $max_num_views);
        $context['top_topics_views'][$i]['num_views'] = comma_format($context['top_topics_views'][$i]['num_views']);
    }
    // Try to cache this when possible, because it's a little unavoidably slow.
    if (($members = CacheAPI::getCache('stats_top_starters', 360)) == null) {
        $request = smf_db_query('
			SELECT id_member_started, COUNT(*) AS hits
			FROM {db_prefix}topics' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
			WHERE id_board != {int:recycle_board}' : '') . '
			GROUP BY id_member_started
			ORDER BY hits DESC
			LIMIT 20', array('recycle_board' => $modSettings['recycle_board']));
        $members = array();
        while ($row = mysql_fetch_assoc($request)) {
            $members[$row['id_member_started']] = $row['hits'];
        }
        mysql_free_result($request);
        CacheAPI::putCache('stats_top_starters', $members, 360);
    }
    if (empty($members)) {
        $members = array(0 => 0);
    }
    // Topic poster top 10.
    $members_result = smf_db_query('
		SELECT id_member, real_name
		FROM {db_prefix}members
		WHERE id_member IN ({array_int:member_list})
		ORDER BY FIND_IN_SET(id_member, {string:top_topic_posters})
		LIMIT 10', array('member_list' => array_keys($members), 'top_topic_posters' => implode(',', array_keys($members))));
    $context['top_starters'] = array();
    $max_num_topics = 1;
    while ($row_members = mysql_fetch_assoc($members_result)) {
        $context['top_starters'][] = array('name' => $row_members['real_name'], 'id' => $row_members['id_member'], 'num_topics' => $members[$row_members['id_member']], 'href' => $scripturl . '?action=profile;u=' . $row_members['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_members['id_member'] . '">' . $row_members['real_name'] . '</a>');
        if ($max_num_topics < $members[$row_members['id_member']]) {
            $max_num_topics = $members[$row_members['id_member']];
        }
    }
    mysql_free_result($members_result);
    foreach ($context['top_starters'] as $i => $topic) {
        $context['top_starters'][$i]['post_percent'] = round($topic['num_topics'] * 100 / $max_num_topics);
        $context['top_starters'][$i]['num_topics'] = comma_format($context['top_starters'][$i]['num_topics']);
    }
    // Time online top 10.
    $temp = CacheAPI::getCache('stats_total_time_members', 600);
    $members_result = smf_db_query('
		SELECT id_member, real_name, total_time_logged_in
		FROM {db_prefix}members' . (!empty($temp) ? '
		WHERE id_member IN ({array_int:member_list_cached})' : '') . '
		ORDER BY total_time_logged_in DESC
		LIMIT 20', array('member_list_cached' => $temp));
    $context['top_time_online'] = array();
    $temp2 = array();
    $max_time_online = 1;
    while ($row_members = mysql_fetch_assoc($members_result)) {
        $temp2[] = (int) $row_members['id_member'];
        if (count($context['top_time_online']) >= 10) {
            continue;
        }
        // Figure out the days, hours and minutes.
        $timeDays = floor($row_members['total_time_logged_in'] / 86400);
        $timeHours = floor($row_members['total_time_logged_in'] % 86400 / 3600);
        // Figure out which things to show... (days, hours, minutes, etc.)
        $timelogged = '';
        if ($timeDays > 0) {
            $timelogged .= $timeDays . $txt['totalTimeLogged5'];
        }
        if ($timeHours > 0) {
            $timelogged .= $timeHours . $txt['totalTimeLogged6'];
        }
        $timelogged .= floor($row_members['total_time_logged_in'] % 3600 / 60) . $txt['totalTimeLogged7'];
        $context['top_time_online'][] = array('id' => $row_members['id_member'], 'name' => $row_members['real_name'], 'time_online' => $timelogged, 'seconds_online' => $row_members['total_time_logged_in'], 'href' => $scripturl . '?action=profile;u=' . $row_members['id_member'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_members['id_member'] . '">' . $row_members['real_name'] . '</a>');
        if ($max_time_online < $row_members['total_time_logged_in']) {
            $max_time_online = $row_members['total_time_logged_in'];
        }
    }
    mysql_free_result($members_result);
    foreach ($context['top_time_online'] as $i => $member) {
        $context['top_time_online'][$i]['time_percent'] = round($member['seconds_online'] * 100 / $max_time_online);
    }
    // Cache the ones we found for a bit, just so we don't have to look again.
    if ($temp !== $temp2) {
        CacheAPI::putCache('stats_total_time_members', $temp2, 480);
    }
    // Activity by month.
    $months_result = smf_db_query('
		SELECT
			YEAR(date) AS stats_year, MONTH(date) AS stats_month, SUM(hits) AS hits, SUM(registers) AS registers, SUM(topics) AS topics, SUM(posts) AS posts, MAX(most_on) AS most_on, COUNT(*) AS num_days
		FROM {db_prefix}log_activity
		GROUP BY stats_year, stats_month', array());
    $context['yearly'] = array();
    while ($row_months = mysql_fetch_assoc($months_result)) {
        $ID_MONTH = $row_months['stats_year'] . sprintf('%02d', $row_months['stats_month']);
        $expanded = !empty($_SESSION['expanded_stats'][$row_months['stats_year']]) && in_array($row_months['stats_month'], $_SESSION['expanded_stats'][$row_months['stats_year']]);
        if (!isset($context['yearly'][$row_months['stats_year']])) {
            $context['yearly'][$row_months['stats_year']] = array('year' => $row_months['stats_year'], 'new_topics' => 0, 'new_posts' => 0, 'new_members' => 0, 'most_members_online' => 0, 'hits' => 0, 'num_months' => 0, 'months' => array(), 'expanded' => false, 'current_year' => $row_months['stats_year'] == date('Y'));
        }
        $context['yearly'][$row_months['stats_year']]['months'][(int) $row_months['stats_month']] = array('id' => $ID_MONTH, 'date' => array('month' => sprintf('%02d', $row_months['stats_month']), 'year' => $row_months['stats_year']), 'href' => $scripturl . '?action=stats;' . ($expanded ? 'collapse' : 'expand') . '=' . $ID_MONTH . '#m' . $ID_MONTH, 'link' => '<a href="' . $scripturl . '?action=stats;' . ($expanded ? 'collapse' : 'expand') . '=' . $ID_MONTH . '#m' . $ID_MONTH . '">' . $txt['months'][(int) $row_months['stats_month']] . ' ' . $row_months['stats_year'] . '</a>', 'month' => $txt['months'][(int) $row_months['stats_month']], 'year' => $row_months['stats_year'], 'new_topics' => comma_format($row_months['topics']), 'new_posts' => comma_format($row_months['posts']), 'new_members' => comma_format($row_months['registers']), 'most_members_online' => comma_format($row_months['most_on']), 'hits' => comma_format($row_months['hits']), 'num_days' => $row_months['num_days'], 'days' => array(), 'expanded' => $expanded);
        $context['yearly'][$row_months['stats_year']]['new_topics'] += $row_months['topics'];
        $context['yearly'][$row_months['stats_year']]['new_posts'] += $row_months['posts'];
        $context['yearly'][$row_months['stats_year']]['new_members'] += $row_months['registers'];
        $context['yearly'][$row_months['stats_year']]['hits'] += $row_months['hits'];
        $context['yearly'][$row_months['stats_year']]['num_months']++;
        $context['yearly'][$row_months['stats_year']]['expanded'] |= $expanded;
        $context['yearly'][$row_months['stats_year']]['most_members_online'] = max($context['yearly'][$row_months['stats_year']]['most_members_online'], $row_months['most_on']);
    }
    krsort($context['yearly']);
    $context['collapsed_years'] = array();
    foreach ($context['yearly'] as $year => $data) {
        // This gets rid of the filesort on the query ;).
        krsort($context['yearly'][$year]['months']);
        $context['yearly'][$year]['new_topics'] = comma_format($data['new_topics']);
        $context['yearly'][$year]['new_posts'] = comma_format($data['new_posts']);
        $context['yearly'][$year]['new_members'] = comma_format($data['new_members']);
        $context['yearly'][$year]['most_members_online'] = comma_format($data['most_members_online']);
        $context['yearly'][$year]['hits'] = comma_format($data['hits']);
        // Keep a list of collapsed years.
        if (!$data['expanded'] && !$data['current_year']) {
            $context['collapsed_years'][] = $year;
        }
    }
    if (empty($_SESSION['expanded_stats'])) {
        return;
    }
    $condition_text = array();
    $condition_params = array();
    foreach ($_SESSION['expanded_stats'] as $year => $months) {
        if (!empty($months)) {
            $condition_text[] = 'YEAR(date) = {int:year_' . $year . '} AND MONTH(date) IN ({array_int:months_' . $year . '})';
            $condition_params['year_' . $year] = $year;
            $condition_params['months_' . $year] = $months;
        }
    }
    // No daily stats to even look at?
    if (empty($condition_text)) {
        return;
    }
    getDailyStats(implode(' OR ', $condition_text), $condition_params);
}