From a7a53de34d6372ccec79d3944741821b8592911e Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 14 May 2024 21:42:02 +0200 Subject: [PATCH 1/4] [ticket/17312] Add migration for user_last_active column PHPBB3-17312 --- .../data/v33x/add_user_last_active.php | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php diff --git a/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php b/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php new file mode 100644 index 00000000000..58cc4f02401 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php @@ -0,0 +1,48 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v33x; + +use phpbb\db\migration\migration; + +class add_user_last_active extends migration +{ + public static function depends_on() + { + return [ + '\phpbb\db\migration\data\v33x\v3311', + ]; + } + + public function update_schema() + { + return [ + 'add_columns' => [ + $this->table_prefix . 'users' => [ + 'user_last_active' => ['TIMESTAMP', 0], + ], + ], + ]; + } + + public function revert_schema() + { + return [ + 'drop_columns' => [ + $this->table_prefix . 'users' => [ + 'user_last_active' => ['TIMESTAMP', 0], + ], + ], + ]; + } +} From ed0b5020a9c2e2b1c7ee12ebf7ff0c3791f3f664 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 16 May 2024 20:40:56 +0200 Subject: [PATCH 2/4] [ticket/17312] Use user_last_active instead of user_lastvisit where possible PHPBB3-17312 --- phpBB/memberlist.php | 10 ++--- .../data/v33x/add_user_last_active.php | 39 +++++++++++++++-- phpBB/phpbb/session.php | 43 ++++++++++++++----- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index e9af6026d77..c36ebd697ac 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1036,7 +1036,7 @@ if ($auth->acl_get('u_viewonline')) { $sort_key_text['l'] = $user->lang['SORT_LAST_ACTIVE']; - $sort_key_sql['l'] = 'u.user_lastvisit'; + $sort_key_sql['l'] = 'u.user_last_active'; } $sort_key_text['m'] = $user->lang['SORT_RANK']; @@ -1138,15 +1138,15 @@ { if ($active_select === 'lt' && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0) { - $sql_where .= ' AND u.user_lastvisit = 0'; + $sql_where .= ' AND u.user_last_active = 0'; } else if ($active_select === 'gt') { - $sql_where .= ' AND u.user_lastvisit ' . $find_key_match[$active_select] . ' ' . $active_time; + $sql_where .= ' AND u.user_last_active ' . $find_key_match[$active_select] . ' ' . $active_time; } else { - $sql_where .= ' AND (u.user_lastvisit > 0 AND u.user_lastvisit < ' . $active_time . ')'; + $sql_where .= ' AND (u.user_last_active > 0 AND u.user_last_active < ' . $active_time . ')'; } } } @@ -1713,7 +1713,7 @@ { $row['session_time'] = $session_ary[$row['user_id']]['session_time'] ?? 0; $row['session_viewonline'] = $session_ary[$row['user_id']]['session_viewonline'] ?? 0; - $row['last_visit'] = (!empty($row['session_time'])) ? $row['session_time'] : $row['user_lastvisit']; + $row['last_visit'] = (!empty($row['session_time'])) ? $row['session_time'] : $row['user_last_active']; $id_cache[$row['user_id']] = $row; } diff --git a/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php b/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php index 58cc4f02401..d4506eea392 100644 --- a/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php +++ b/phpBB/phpbb/db/migration/data/v33x/add_user_last_active.php @@ -29,7 +29,7 @@ public function update_schema() return [ 'add_columns' => [ $this->table_prefix . 'users' => [ - 'user_last_active' => ['TIMESTAMP', 0], + 'user_last_active' => ['TIMESTAMP', 0, 'after' => 'user_lastvisit'], ], ], ]; @@ -39,10 +39,41 @@ public function revert_schema() { return [ 'drop_columns' => [ - $this->table_prefix . 'users' => [ - 'user_last_active' => ['TIMESTAMP', 0], - ], + $this->table_prefix . 'users' => ['user_last_active'], ], ]; } + + public function update_data() + { + return [ + ['custom', [[$this, 'set_user_last_active']]], + ]; + } + + public function set_user_last_active($start = 0) + { + // Get maximum user id from database + $sql = "SELECT MAX(user_id) AS max_user_id + FROM {$this->table_prefix}users"; + $result = $this->db->sql_query($sql); + $max_id = (int) $this->db->sql_fetchfield('max_user_id'); + $this->db->sql_freeresult($result); + + if ($start > $max_id) + { + return; + } + + // Keep setting user_last_active time + $next_start = $start + 10000; + + $sql = 'UPDATE ' . $this->table_prefix . 'users + SET user_last_active = user_lastvisit + WHERE user_id > ' . (int) $start . ' + AND user_id <= ' . (int) ($next_start); + $this->db->sql_query($sql); + + return $next_start; + } } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 7cb7e15d78f..af39ecf2fa0 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -440,10 +440,10 @@ function session_begin($update_session_page = true) // Is user banned? Are they excluded? Won't return on ban, exists within method $this->check_ban_for_current_session($config); - // Update user last visit time accordingly, but in a minute or so - if ((int) $this->data['session_time'] - (int) $this->data['user_lastvisit'] > 60) + // Update user last active time accordingly, but in a minute or so + if ((int) $this->data['session_time'] - (int) $this->data['user_last_active'] > 60) { - $this->update_user_lastvisit(); + $this->update_last_active_time(); } return true; @@ -690,8 +690,8 @@ function session_create($user_id = false, $set_admin = false, $persist_login = f { $this->session_id = $this->data['session_id']; - // Only sync user last visit time in a minute or so after last session data update or if the page changes - if ((int) $this->data['session_time'] - (int) $this->data['user_lastvisit'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) + // Only update session DB a minute or so after last update or if page changes + if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) { // Update the last visit time $this->update_user_lastvisit(); @@ -818,22 +818,26 @@ function session_create($user_id = false, $set_admin = false, $persist_login = f $this->data['user_form_salt'] = unique_id(); // Update the form key $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\' + SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\', + user_last_active = ' . (int) $this->data['session_time'] . ' WHERE user_id = ' . (int) $this->data['user_id']; $db->sql_query($sql); } + else + { + $this->update_last_active_time(); + } } else { $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now; + $this->update_user_lastvisit(); + $SID = '?sid='; $_SID = ''; } - // Update the last visit time - $this->update_user_lastvisit(); - $session_data = $sql_ary; /** * Event to send new session data to extension @@ -1807,7 +1811,26 @@ public function update_user_lastvisit() if (isset($this->data['session_time'], $this->data['user_id'])) { $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_lastvisit = ' . (int) $this->data['session_time'] . ' + SET user_lastvisit = ' . (int) $this->data['session_time'] . ', + user_last_active = ' . (int) $this->data['session_time'] . ' + WHERE user_id = ' . (int) $this->data['user_id']; + $db->sql_query($sql); + } + } + + /** + * Update user's last active time + * + * @return void + */ + public function update_last_active_time() + { + global $db; + + if (isset($this->data['session_time'], $this->data['user_id'])) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_last_active = ' . (int) $this->data['session_time'] . ' WHERE user_id = ' . (int) $this->data['user_id']; $db->sql_query($sql); } From f9861384675725466a5210e00ed33bd3712636f3 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 17 May 2024 16:41:40 +0200 Subject: [PATCH 3/4] [ticket/17312] Update tests for new column PHPBB3-17312 --- tests/auth/provider_apache_test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auth/provider_apache_test.php b/tests/auth/provider_apache_test.php index 567ec538f20..2dbb1f32a98 100644 --- a/tests/auth/provider_apache_test.php +++ b/tests/auth/provider_apache_test.php @@ -115,6 +115,7 @@ public function test_autologin() 'user_email' => 'example@example.com', 'user_birthday' => '', 'user_lastvisit' => 0, + 'user_last_active' => 0, 'user_lastmark' => 0, 'user_lastpost_time' => 0, 'user_lastpage' => '', From 9ecf09dbe8b88eef81e3a987cd30ece4e323ed98 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 18 May 2024 20:58:07 +0200 Subject: [PATCH 4/4] [ticket/17312] Add and use user_last_active where needed and useful PHPBB3-17312 --- phpBB/includes/acp/acp_users.php | 2 +- phpBB/includes/functions_display.php | 2 +- phpBB/includes/functions_user.php | 1 + phpBB/install/convertors/convert_phpbb20.php | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 14864cfdd48..7c3468f90df 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1084,7 +1084,7 @@ function main($id, $mode) $s_action_options .= ''; } - $last_active = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_lastvisit']; + $last_active = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_last_active']; $inactive_reason = ''; if ($user_row['user_type'] == USER_INACTIVE) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 8fd70855868..d995676e8fb 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1603,7 +1603,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl if ($data['user_allow_viewonline'] || $auth->acl_get('u_viewonline')) { - $last_active = (!empty($data['session_time'])) ? $data['session_time'] : $data['user_lastvisit']; + $last_active = (!empty($data['session_time'])) ? $data['session_time'] : $data['user_last_active']; } else { diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 0110034016e..25adf4215aa 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -227,6 +227,7 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) 'user_inactive_time' => 0, 'user_lastmark' => time(), 'user_lastvisit' => 0, + 'user_last_active' => 0, 'user_lastpost_time' => 0, 'user_lastpage' => '', 'user_posts' => 0, diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 2d6a868938d..7f9449609ef 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -901,6 +901,7 @@ array('user_email', 'users.user_email', 'strtolower'), array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'), array('user_lastvisit', 'users.user_lastvisit', 'intval'), + array('user_last_active', 'users.user_lastvisit', 'intval'), array('user_lastmark', 'users.user_lastvisit', 'intval'), array('user_lang', $config['default_lang'], ''), array('', 'users.user_lang', ''),