Helper methods for permission retrieval inside workers
authorAlexander Ebert <ebert@woltlab.com>
Mon, 29 Jan 2018 15:14:10 +0000 (16:14 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 29 Jan 2018 15:14:10 +0000 (16:14 +0100)
Their internals are rather hacky, but come with a only a minor impact on
the worker performance.

See #2524

wcfsetup/install/files/lib/system/worker/AbstractRebuildDataWorker.class.php

index 45fcc746b80078e57abf423a5087343ba96bcc57..d3b9d23ee4c4d171cd00f25a3cdc215c305a2101 100644 (file)
@@ -1,6 +1,9 @@
 <?php
 namespace wcf\system\worker;
 use wcf\data\DatabaseObjectList;
+use wcf\data\user\group\UserGroup;
+use wcf\system\cache\builder\UserGroupPermissionCacheBuilder;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\event\EventHandler;
 use wcf\system\exception\ParentClassException;
 use wcf\system\exception\SystemException;
@@ -100,6 +103,73 @@ abstract class AbstractRebuildDataWorker extends AbstractWorker implements IRebu
                $this->objectList->sqlOffset = $this->limit * $this->loopCount;
        }
        
+       /**
+        * Returns the value of the permissions for the provided user ids. The special index `0` is
+        * automatically added and represents a guest user.
+        * 
+        * @param       integer[]       $userIDs
+        * @param       string[]        $permissions
+        * @return      mixed[]         permission value per user id
+        */
+       protected function getBulkUserPermissions(array $userIDs, array $permissions) {
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add("userID IN (?)", [$userIDs]);
+               
+               $sql = "SELECT  userID, groupID
+                       FROM    wcf".WCF_N."_user_to_group
+                       ".$conditions;
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute($conditions->getParameters());
+               
+               $groupData = [];
+               while ($row = $statement->fetchArray()) {
+                       $userID = $row['userID'];
+                       if (!isset($groupData[$userID])) $groupData[$userID] = [];
+                       
+                       $groupData[$userID][] = $row['groupID'];
+               }
+               
+               $userPermissions = [];
+               foreach ($groupData as $userID => $groupIDs) {
+                       $data = UserGroupPermissionCacheBuilder::getInstance()->getData($groupIDs);
+                       
+                       $userPermissions[$userID] = [];
+                       foreach ($permissions as $permission) {
+                               $userPermissions[$userID][$permission] = (isset($data[$permission])) ? $data[$permission] : false;
+                       }
+               }
+               
+               // add guest user
+               $data = UserGroupPermissionCacheBuilder::getInstance()->getData(UserGroup::getGroupIDsByType([UserGroup::GUESTS, UserGroup::EVERYONE]));
+               $userPermissions[0] = [];
+               foreach ($permissions as $permission) {
+                       $userPermissions[0][$permission] = (isset($data[$permission])) ? $data[$permission] : false;
+               }
+               
+               return $userPermissions;
+       }
+       
+       /**
+        * Returns the permission value for the provided user id, will be treated as guest
+        * if the user id cannot be found or is invalid. This method is designed to be used
+        * with the return value of `getBulkUserPermissions()`.
+        * 
+        * @param       mixed[]         $userPermissions
+        * @param       integer         $userID
+        * @param       string          $permission
+        * @return      mixed
+        */
+       protected function getBulkUserPermissionValue(array &$userPermissions, $userID, $permission) {
+               $userID = intval($userID);
+               
+               // resolve non-existing users against the guest permission
+               if ($userID && !isset($userPermissions[$userID])) {
+                       return $this->getBulkUserPermissionValue($userPermissions, 0, $permission);
+               }
+               
+               return $userPermissions[$userID][$permission];
+       }
+       
        /**
         * @inheritDoc
         */