diff options
-rw-r--r-- | phpBB/develop/create_schema_files.php | 4 | ||||
-rw-r--r-- | phpBB/docs/CHANGELOG.html | 1 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 337 | ||||
-rw-r--r-- | phpBB/includes/session.php | 9 | ||||
-rw-r--r-- | phpBB/install/database_update.php | 14 |
5 files changed, 232 insertions, 133 deletions
diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 375ea8588d..cefdf404dd 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1144,7 +1144,7 @@ function get_schema_struct() ), 'PRIMARY_KEY' => 'group_id', 'KEYS' => array( - 'group_legend' => array('INDEX', 'group_legend'), + 'group_legend_name' => array('INDEX', array('group_legend', 'group_name')), ), ); @@ -1520,6 +1520,7 @@ function get_schema_struct() 'COLUMNS' => array( 'session_id' => array('CHAR:32', ''), 'session_user_id' => array('UINT', 0), + 'session_forum_id' => array('UINT', 0), 'session_last_visit' => array('TIMESTAMP', 0), 'session_start' => array('TIMESTAMP', 0), 'session_time' => array('TIMESTAMP', 0), @@ -1535,6 +1536,7 @@ function get_schema_struct() 'KEYS' => array( 'session_time' => array('INDEX', 'session_time'), 'session_user_id' => array('INDEX', 'session_user_id'), + 'session_forum_id' => array('INDEX', 'session_forum_id'), ), ); diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index b50f5fcf8f..ea3986cdcc 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -137,6 +137,7 @@ <li>[Fix] Do not allow selecting non-authorized groups within memberlist by adjusting URL (Bug #22805 - patch provided by ToonArmy)</li> <li>[Fix] Correctly specify "close report action" (Bug #22685)</li> <li>[Fix] Display "empty password error" within the login box instead of issuing a general error (Bug #22525)</li> + <li>[Fix] Clean up who is online code in page_header (Bug #22715, thanks HighwayofLife)</li> </ul> diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e4e5d7b335..69a9cd5fcc 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3099,188 +3099,263 @@ function msg_handler($errno, $msg_text, $errfile, $errline) } /** -* Generate page header +* Queries the session table to get information about online guests +* @param int $forum_id Limits the search to the forum with this id +* @return int The number of active distinct guest sessions */ -function page_header($page_title = '', $display_online_list = true) +function obtain_guest_count($forum_id = 0) { - global $db, $config, $template, $SID, $_SID, $user, $auth, $phpEx, $phpbb_root_path; - - if (defined('HEADER_INC')) + global $db, $config; + + if ($forum_id) { - return; - } - - define('HEADER_INC', true); - - // gzip_compression - if ($config['gzip_compress']) + $reading_sql = ' AND s.session_forum_id = ' . (int) $f; + } + else { - if (@extension_loaded('zlib') && !headers_sent()) - { - ob_start('ob_gzhandler'); - } + $reading_sql = ''; } + $time = (time() - (intval($config['load_online_time']) * 60)); + + // Get number of online guests - // Generate logged in/logged out status - if ($user->data['user_id'] != ANONYMOUS) + if ($db->sql_layer === 'sqlite') { - $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout', true, $user->session_id); - $l_login_logout = sprintf($user->lang['LOGOUT_USER'], $user->data['username']); + $sql = 'SELECT COUNT(session_ip) as num_guests + FROM ( + SELECT DISTINCT s.session_ip + FROM ' . SESSIONS_TABLE . ' s + WHERE s.session_user_id = ' . ANONYMOUS . ' + AND s.session_time >= ' . ($time - ((int) ($time % 60))) . + $reading_sql . + ')'; } else { - $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'); - $l_login_logout = $user->lang['LOGIN']; + $sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests + FROM ' . SESSIONS_TABLE . ' s + WHERE s.session_user_id = ' . ANONYMOUS . ' + AND s.session_time >= ' . ($time - ((int) ($time % 60))) . + $reading_sql; } + $result = $db->sql_query($sql, 60); + $guests_online = (int) $db->sql_fetchfield('num_guests'); + $db->sql_freeresult($result); + + return $guests_online; +} - // Last visit date/time - $s_last_visit = ($user->data['user_id'] != ANONYMOUS) ? $user->format_date($user->data['session_last_visit']) : ''; - - // Get users online list ... if required - $l_online_users = $online_userlist = $l_online_record = ''; +/** +* Queries the session table to get information about online users +* @param int $forum_id Limits the search to the forum with this id +* @return array An array containing the ids of online, hidden and visible users, as well as statistical info +*/ +function obtain_users_online($forum_id = 0) +{ + global $db, $config, $user; + $logged_visible_online = $logged_hidden_online = $guests_online = $prev_user_id = 0; + $reading_sql = $prev_session_ip = ''; - if ($config['load_online'] && $config['load_online_time'] && $display_online_list) + if ($forum_id !== 0) { - $logged_visible_online = $logged_hidden_online = $guests_online = $prev_user_id = 0; - $prev_session_ip = $reading_sql = ''; - - if (!empty($_REQUEST['f'])) - { - $f = request_var('f', 0); + $reading_sql = ' AND s.session_forum_id = ' . (int) $forum_id; + } + $online_users = array( + 'online_users' => array(), + 'hidden_users' => array(), + 'total_online' => 0, + 'visible_online' => 0, + 'hidden_online' => 0, + 'guests_online' => 0, + ); + if ($config['load_online_guests']) + { + $online_users['guests_online'] = obtain_guest_count($forum_id); + } + + // a little discrete magic to cache this for 30 seconds + $time = (time() - (intval($config['load_online_time']) * 60)); + $sql = 'SELECT s.session_user_id, s.session_ip, s.session_viewonline + FROM ' . SESSIONS_TABLE . ' s + WHERE s.session_time >= ' . ($time - ((int) ($time % 30))) . + $reading_sql . + ' AND s.session_user_id <> ' . ANONYMOUS; + $result = $db->sql_query($sql, 30); - $reading_sql = ' AND s.session_page ' . $db->sql_like_expression("{$db->any_char}_f_={$f}x{$db->any_char}"); - } + while ($row = $db->sql_fetchrow($result)) + { - // Get number of online guests - if (!$config['load_online_guests']) + // Skip multiple sessions for one user + if (!isset($online_users['online_users'][$row['session_user_id']])) { - if ($db->sql_layer === 'sqlite') + $online_users['online_users'][$row['session_user_id']] = $row['session_user_id']; + if ($row['session_viewonline']) { - $sql = 'SELECT COUNT(session_ip) as num_guests - FROM ( - SELECT DISTINCT s.session_ip - FROM ' . SESSIONS_TABLE . ' s - WHERE s.session_user_id = ' . ANONYMOUS . ' - AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . - $reading_sql . - ')'; + $online_users['visible_online']++; } else { - $sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests - FROM ' . SESSIONS_TABLE . ' s - WHERE s.session_user_id = ' . ANONYMOUS . ' - AND s.session_time >= ' . (time() - ($config['load_online_time'] * 60)) . - $reading_sql; + $online_users['hidden_users'][$row['session_user_id']] = $row['session_user_id']; + $online_users['hidden_online']++; } - $result = $db->sql_query($sql); - $guests_online = (int) $db->sql_fetchfield('num_guests'); - $db->sql_freeresult($result); } + } + $online_users['total_online'] = $online_users['guests_online'] + $online_users['visible_online'] + $online_users['hidden_online']; + $db->sql_freeresult($result); + + return $online_users; +} - $sql = 'SELECT u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour, s.session_ip, s.session_viewonline - FROM ' . USERS_TABLE . ' u, ' . SESSIONS_TABLE . ' s - WHERE s.session_time >= ' . (time() - (intval($config['load_online_time']) * 60)) . - $reading_sql . - ((!$config['load_online_guests']) ? ' AND s.session_user_id <> ' . ANONYMOUS : '') . ' - AND u.user_id = s.session_user_id - ORDER BY u.username_clean ASC, s.session_ip ASC'; - $result = $db->sql_query($sql); +/** +* Uses the result of obtain_users_online to generate a localized, readable representation. +* @param mixed $online_users result of obtain_users_online - array with user_id lists for total, hidden and visible users, and statistics +* @param int $forum_id Indicate that the data is limited to one forum and not global. +* @return array An array containing the string for output to the template +*/ +function obtain_users_online_string($online_users, $forum_id = 0) +{ + global $db, $user, $auth; + $user_online_link = $online_userlist = ''; + + if (count($online_users['online_users'])) + { + $sql = 'SELECT u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour + FROM ' . USERS_TABLE . ' u + WHERE ' . $db->sql_in_set('u.user_id', $online_users['online_users']) . ' + ORDER BY u.username_clean ASC'; + $result = $db->sql_query($sql, 100); while ($row = $db->sql_fetchrow($result)) { // User is logged in and therefore not a guest if ($row['user_id'] != ANONYMOUS) { - // Skip multiple sessions for one user - if ($row['user_id'] != $prev_user_id) + if (isset($online_users['hidden_users'][$row['user_id']])) { - if ($row['session_viewonline']) - { - $logged_visible_online++; - } - else - { - $row['username'] = '<em>' . $row['username'] . '</em>'; - $logged_hidden_online++; - } - - if (($row['session_viewonline']) || $auth->acl_get('u_viewonline')) - { - $user_online_link = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']); - $online_userlist .= ($online_userlist != '') ? ', ' . $user_online_link : $user_online_link; - } + $row['username'] = '<em>' . $row['username'] . '</em>'; } - $prev_user_id = $row['user_id']; - } - else - { - // Skip multiple sessions for one user - if ($row['session_ip'] != $prev_session_ip) + if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline')) { - $guests_online++; + $user_online_link = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']); + $online_userlist .= ($online_userlist != '') ? ', ' . $user_online_link : $user_online_link; } } - - $prev_session_ip = $row['session_ip']; } $db->sql_freeresult($result); + } - if (!$online_userlist) - { - $online_userlist = $user->lang['NO_ONLINE_USERS']; - } + if (!$online_userlist) + { + $online_userlist = $user->lang['NO_ONLINE_USERS']; + } - if (empty($_REQUEST['f'])) - { - $online_userlist = $user->lang['REGISTERED_USERS'] . ' ' . $online_userlist; - } - else + if ($forum_id === 0) + { + $online_userlist = $user->lang['REGISTERED_USERS'] . ' ' . $online_userlist; + } + else + { + $l_online = ($online_users['guests_online'] === 1) ? $user->lang['BROWSING_FORUM_GUEST'] : $user->lang['BROWSING_FORUM_GUESTS']; + $online_userlist = sprintf($l_online, $online_userlist, $online_users['guests_online']); + } + + // Build online listing + $vars_online = array( + 'ONLINE' => array('total_online', 'l_t_user_s'), + 'REG' => array('visible_online', 'l_r_user_s'), + 'HIDDEN' => array('hidden_online', 'l_h_user_s'), + 'GUEST' => array('guests_online', 'l_g_user_s') + ); + + foreach ($vars_online as $l_prefix => $var_ary) + { + switch ($online_users[$var_ary[0]]) { - $l_online = ($guests_online == 1) ? $user->lang['BROWSING_FORUM_GUEST'] : $user->lang['BROWSING_FORUM_GUESTS']; - $online_userlist = sprintf($l_online, $online_userlist, $guests_online); + case 0: + ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_ZERO_TOTAL']; + break; + + case 1: + ${$var_ary[1]} = $user->lang[$l_prefix . '_USER_TOTAL']; + break; + + default: + ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_TOTAL']; + break; } + } + unset($vars_online); - $total_online_users = $logged_visible_online + $logged_hidden_online + $guests_online; + $l_online_users = sprintf($l_t_user_s, $online_users['total_online']); + $l_online_users .= sprintf($l_r_user_s, $online_users['visible_online']); + $l_online_users .= sprintf($l_h_user_s, $online_users['hidden_online']); + $l_online_users .= sprintf($l_g_user_s, $online_users['guests_online']); - if ($total_online_users > $config['record_online_users']) + return array( + 'online_userlist' => $online_userlist, + 'l_online_users' => $l_online_users, + ); +} + + +/** +* Generate page header +*/ +function page_header($page_title = '', $display_online_list = true) +{ + global $db, $config, $template, $SID, $_SID, $user, $auth, $phpEx, $phpbb_root_path; + + if (defined('HEADER_INC')) + { + return; + } + + define('HEADER_INC', true); + + // gzip_compression + if ($config['gzip_compress']) + { + if (@extension_loaded('zlib') && !headers_sent()) { - set_config('record_online_users', $total_online_users, true); - set_config('record_online_date', time(), true); + ob_start('ob_gzhandler'); } + } + + // Generate logged in/logged out status + if ($user->data['user_id'] != ANONYMOUS) + { + $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout', true, $user->session_id); + $l_login_logout = sprintf($user->lang['LOGOUT_USER'], $user->data['username']); + } + else + { + $u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'); + $l_login_logout = $user->lang['LOGIN']; + } - // Build online listing - $vars_online = array( - 'ONLINE' => array('total_online_users', 'l_t_user_s'), - 'REG' => array('logged_visible_online', 'l_r_user_s'), - 'HIDDEN' => array('logged_hidden_online', 'l_h_user_s'), - 'GUEST' => array('guests_online', 'l_g_user_s') - ); + // Last visit date/time + $s_last_visit = ($user->data['user_id'] != ANONYMOUS) ? $user->format_date($user->data['session_last_visit']) : ''; - foreach ($vars_online as $l_prefix => $var_ary) - { - switch (${$var_ary[0]}) - { - case 0: - ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_ZERO_TOTAL']; - break; + // Get users online list ... if required + $l_online_users = $online_userlist = $l_online_record = ''; - case 1: - ${$var_ary[1]} = $user->lang[$l_prefix . '_USER_TOTAL']; - break; + if ($config['load_online'] && $config['load_online_time'] && $display_online_list) + { + + $f = request_var('f', 0); + $f = max($f, 0); + $online_users = obtain_users_online($f); + $user_online_strings = obtain_users_online_string($online_users, $f); + $l_online_users = $user_online_strings['l_online_users']; + $online_userlist = $user_online_strings['online_userlist']; + $total_online_users = $online_users['total_online']; - default: - ${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_TOTAL']; - break; - } + if ($total_online_users > $config['record_online_users']) + { + set_config('record_online_users', $total_online_users, true); + set_config('record_online_date', time(), true); } - unset($vars_online); - - $l_online_users = sprintf($l_t_user_s, $total_online_users); - $l_online_users .= sprintf($l_r_user_s, $logged_visible_online); - $l_online_users .= sprintf($l_h_user_s, $logged_hidden_online); - $l_online_users .= sprintf($l_g_user_s, $guests_online); $l_online_record = sprintf($user->lang['RECORD_ONLINE_USERS'], $config['record_online_users'], $user->format_date($config['record_online_date'])); diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index affd447787..91b412b075 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -129,7 +129,8 @@ class session 'script_path' => str_replace(' ', '%20', htmlspecialchars($script_path)), 'root_script_path' => str_replace(' ', '%20', htmlspecialchars($root_script_path)), - 'page' => $page + 'page' => $page, + 'forum' => (isset($_REQUEST['f']) && $_REQUEST['f'] > 0) ? (int) $_REQUEST['f'] : 0, ); return $page_array; @@ -186,6 +187,8 @@ class session // Add forum to the page for tracking online users - also adding a "x" to the end to properly identify the number $this->page['page'] .= (isset($_REQUEST['f'])) ? ((strpos($this->page['page'], '?') !== false) ? '&' : '?') . '_f_=' . (int) $_REQUEST['f'] . 'x' : ''; + + if (isset($_COOKIE[$config['cookie_name'] . '_sid']) || isset($_COOKIE[$config['cookie_name'] . '_u'])) { @@ -310,6 +313,7 @@ class session if ($this->update_session_page) { $sql_ary['session_page'] = substr($this->page['page'], 0, 199); + $sql_ary['session_forum_id'] = $this->page['forum']; } $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " @@ -550,6 +554,7 @@ class session if ($this->update_session_page) { $sql_ary['session_page'] = substr($this->page['page'], 0, 199); + $sql_ary['session_forum_id'] = $this->page['forum']; } $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " @@ -594,6 +599,7 @@ class session if ($this->update_session_page) { $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199); + $sql_ary['session_forum_id'] = $this->page['forum']; } $db->sql_return_on_error(true); @@ -627,6 +633,7 @@ class session $sql_ary['session_id'] = (string) $this->session_id; $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199); + $sql_ary['session_forum_id'] = $this->page['forum']; $sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $db->sql_query($sql); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 85627b9327..39e0d8131e 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -480,6 +480,20 @@ $database_update_info = array( FORUMS_TABLE => array( 'display_subforum_list' => array('BOOL', 1), ), + SESSIONS_TABLE => array( + 'session_forum_id' => array('UINT', 0), + ), + ), + 'add_index' => array( + SESSIONS_TABLE => array( + 'session_forum_id' => 'session_forum_id', + ), + GROUP_TABLE => array( + 'group_legend_name' => array('group_legend', 'group_name'), + ), + ), + 'drop_keys' => array( + GROUP_TABLE => array('group_legend'), ), ), ); |