Fix performance of user online list
authorjoshuaruesweg <ruesweg@woltlab.com>
Tue, 12 Jan 2021 13:45:33 +0000 (14:45 +0100)
committerjoshuaruesweg <ruesweg@woltlab.com>
Wed, 20 Jan 2021 14:34:56 +0000 (15:34 +0100)
If the UserStorageHandler has to load all users that are online, this is quite resource intensive in larger communities and the query is very slow. The UserStorageHandler must actually be loaded so that the permissions of the users can be checked to see if they can make themselves invisible. We switch off this check with this commit and assume that users who cannot change this setting are always online.

wcfsetup/install/files/lib/data/user/online/UserOnline.class.php
wcfsetup/install/files/lib/data/user/online/UsersOnlineList.class.php

index bc36c76f0e5db17a201bfa3f79814d4c245015ea..c478d8c7610f3dc2d5df5000704d71fe0237fdca 100644 (file)
@@ -48,10 +48,7 @@ class UserOnline extends UserProfile {
                        $username = str_replace('%s', $username, $this->userOnlineMarking);
                }
                
-               if (
-                       $this->getPermission('user.profile.canHideOnlineStatus')
-                       && $this->canViewOnlineStatus == UserProfile::ACCESS_NOBODY
-               ) {
+               if ($this->canViewOnlineStatus == UserProfile::ACCESS_NOBODY) {
                        $username .= WCF::getLanguage()->get('wcf.user.usersOnline.invisible');
                }
                
index 9aed41014b01876397edfdf90ebf8213745d9d92..f41dd21bdf41849694218bf07f5f0a85dfc038d9 100644 (file)
@@ -6,7 +6,6 @@ use wcf\data\user\group\UserGroup;
 use wcf\data\user\User;
 use wcf\data\user\UserProfile;
 use wcf\system\event\EventHandler;
-use wcf\system\user\storage\UserStorageHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -72,8 +71,6 @@ class UsersOnlineList extends SessionList {
                $objects = $this->objects;
                $this->indexToObject = $this->objects = [];
                
-               UserStorageHandler::getInstance()->loadStorage($this->objectIDs);
-               
                foreach ($objects as $object) {
                        $object = new UserOnline(new User(null, null, $object));
                        if (!$object->userID || self::isVisibleUser($object)) {
@@ -115,8 +112,6 @@ class UsersOnlineList extends SessionList {
                        }
                }
                
-               UserStorageHandler::getInstance()->loadStorage($userIDs);
-               
                foreach ($users as $user) {
                        if ($user->canViewOnlineStatus && !self::isVisibleUser($user)) {
                                $this->stats['invisible']++;
@@ -219,24 +214,19 @@ class UsersOnlineList extends SessionList {
                        'userOnline' => $userOnline,
                ];
                
-               if ($userOnline->getPermission('user.profile.canHideOnlineStatus')) {
-                       switch ($userOnline->canViewOnlineStatus) {
-                               case UserProfile::ACCESS_EVERYONE:
-                                       $data['result'] = true;
-                                       break;
-                               
-                               case UserProfile::ACCESS_REGISTERED:
-                                       if (WCF::getUser()->userID) $data['result'] = true;
-                                       break;
-                               
-                               case UserProfile::ACCESS_FOLLOWING:
-                                       /** @noinspection PhpUndefinedMethodInspection */
-                                       if (WCF::getUserProfileHandler()->isFollower($userOnline->userID)) $data['result'] = true;
-                                       break;
-                       }
-               }
-               else {
-                       $data['result'] = true;
+               switch ($userOnline->canViewOnlineStatus) {
+                       case UserProfile::ACCESS_EVERYONE:
+                               $data['result'] = true;
+                               break;
+                       
+                       case UserProfile::ACCESS_REGISTERED:
+                               if (WCF::getUser()->userID) $data['result'] = true;
+                               break;
+                       
+                       case UserProfile::ACCESS_FOLLOWING:
+                               /** @noinspection PhpUndefinedMethodInspection */
+                               if (WCF::getUserProfileHandler()->isFollower($userOnline->userID)) $data['result'] = true;
+                               break;
                }
                
                EventHandler::getInstance()->fireAction(get_called_class(), 'isVisibleUser', $data);