From 5bc2f27b25eaf7c1fca105521654c4faf493f706 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Fri, 24 Apr 2020 17:02:40 +0200 Subject: [PATCH] Avoid potential race condition when saving profile visitors --- .../visitor/UserProfileVisitorAction.class.php | 17 +++++++++++++++++ .../install/files/lib/page/UserPage.class.php | 16 +++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/wcfsetup/install/files/lib/data/user/profile/visitor/UserProfileVisitorAction.class.php b/wcfsetup/install/files/lib/data/user/profile/visitor/UserProfileVisitorAction.class.php index dbdf785ad0..2f7f6d4f12 100644 --- a/wcfsetup/install/files/lib/data/user/profile/visitor/UserProfileVisitorAction.class.php +++ b/wcfsetup/install/files/lib/data/user/profile/visitor/UserProfileVisitorAction.class.php @@ -82,4 +82,21 @@ class UserProfileVisitorAction extends AbstractDatabaseObjectAction implements I 'template' => WCF::getTPL()->fetch('groupedUserList') ]; } + + /** + * Inserts a new visitor if it does not already exist, or updates it if it does. + * @since 5.2 + */ + public function registerVisitor() { + $sql = "INSERT INTO wcf".WCF_N."_user_profile_visitor + (ownerID, userID, time) + VALUES (?, ?, ?) + ON DUPLICATE KEY UPDATE time = VALUES(time)"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute([ + $this->parameters['data']['ownerID'], + $this->parameters['data']['userID'], + $this->parameters['data']['time'] ?? TIME_NOW, + ]); + } } diff --git a/wcfsetup/install/files/lib/page/UserPage.class.php b/wcfsetup/install/files/lib/page/UserPage.class.php index 96c7c6574a..072232effe 100644 --- a/wcfsetup/install/files/lib/page/UserPage.class.php +++ b/wcfsetup/install/files/lib/page/UserPage.class.php @@ -6,8 +6,7 @@ use wcf\data\user\cover\photo\UserCoverPhoto; use wcf\data\user\follow\UserFollowerList; use wcf\data\user\follow\UserFollowingList; use wcf\data\user\group\UserGroup; -use wcf\data\user\profile\visitor\UserProfileVisitor; -use wcf\data\user\profile\visitor\UserProfileVisitorEditor; +use wcf\data\user\profile\visitor\UserProfileVisitorAction; use wcf\data\user\profile\visitor\UserProfileVisitorList; use wcf\data\user\UserEditor; use wcf\data\user\UserProfile; @@ -180,17 +179,12 @@ class UserPage extends AbstractPage { // save visitor /** @noinspection PhpUndefinedFieldInspection */ if (PROFILE_ENABLE_VISITORS && WCF::getUser()->userID && !WCF::getUser()->canViewOnlineStatus) { - if (($visitor = UserProfileVisitor::getObject($this->user->userID, WCF::getUser()->userID)) !== null) { - $editor = new UserProfileVisitorEditor($visitor); - $editor->update(['time' => TIME_NOW]); - } - else { - UserProfileVisitorEditor::create([ + (new UserProfileVisitorAction([], 'registerVisitor', [ + 'data' => [ 'ownerID' => $this->user->userID, 'userID' => WCF::getUser()->userID, - 'time' => TIME_NOW - ]); - } + ] + ]))->executeAction(); } } -- 2.20.1