diff --git a/wcfsetup/install/files/acp/install_com.woltlab.wcf_step2.php b/wcfsetup/install/files/acp/install_com.woltlab.wcf_step2.php index 7f0455495b0..baaae8b3700 100644 --- a/wcfsetup/install/files/acp/install_com.woltlab.wcf_step2.php +++ b/wcfsetup/install/files/acp/install_com.woltlab.wcf_step2.php @@ -1,11 +1,12 @@ executeAction(); -$action = new UserProfileAction([$editor], 'updateUserOnlineMarking'); -$action->executeAction(); +(new UpdateUserRank(WCF::getUser()))(); +(new UpdateUserOnlineMarking(WCF::getUser()))(); // install default reactions foreach ([ diff --git a/wcfsetup/install/files/lib/acp/form/UserEditForm.class.php b/wcfsetup/install/files/lib/acp/form/UserEditForm.class.php index 1aedd29006a..6584e7317cc 100755 --- a/wcfsetup/install/files/lib/acp/form/UserEditForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/UserEditForm.class.php @@ -2,6 +2,8 @@ namespace wcf\acp\form; +use wcf\command\user\UpdateUserOnlineMarking; +use wcf\command\user\UpdateUserRank; use wcf\data\file\File; use wcf\data\style\Style; use wcf\data\user\cover\photo\IUserCoverPhoto; @@ -9,7 +11,6 @@ use wcf\data\user\User; use wcf\data\user\UserAction; use wcf\data\user\UserEditor; -use wcf\data\user\UserProfileAction; use wcf\form\AbstractForm; use wcf\system\cache\runtime\FileRuntimeCache; use wcf\system\cache\runtime\UserProfileRuntimeCache; @@ -19,7 +20,6 @@ use wcf\system\html\upcast\HtmlUpcastProcessor; use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; use wcf\system\moderation\queue\ModerationQueueManager; -use wcf\system\option\user\UserOptionHandler; use wcf\system\style\StyleHandler; use wcf\system\user\command\SetColorScheme; use wcf\system\user\multifactor\Setup; @@ -500,12 +500,10 @@ public function save() // update user rank if (MODULE_USER_RANK) { - $action = new UserProfileAction([$this->user], 'updateUserRank'); - $action->executeAction(); + (new UpdateUserRank($this->user->getDecoratedObject()))(); } if (MODULE_USERS_ONLINE) { - $action = new UserProfileAction([$this->user], 'updateUserOnlineMarking'); - $action->executeAction(); + (new UpdateUserOnlineMarking($this->user->getDecoratedObject()))(); } // remove assignments diff --git a/wcfsetup/install/files/lib/command/user/UpdateMandatoryUserGroups.class.php b/wcfsetup/install/files/lib/command/user/UpdateMandatoryUserGroups.class.php new file mode 100644 index 00000000000..b0995ef5668 --- /dev/null +++ b/wcfsetup/install/files/lib/command/user/UpdateMandatoryUserGroups.class.php @@ -0,0 +1,91 @@ + + * @since 6.3 + */ +final class UpdateMandatoryUserGroups +{ + public function __construct( + private readonly User $user + ) {} + + /** + * @return list + */ + public function __invoke(): array + { + $groupIDs = $this->user->getGroupIDs(); + + $fixGroupIDs = []; + $removeGroupIDs = []; + + if (!\in_array(UserGroup::EVERYONE, $groupIDs)) { + $fixGroupIDs[] = UserGroup::EVERYONE; + $groupIDs[] = UserGroup::EVERYONE; + } + + if ($this->user->pendingActivation()) { + if (!\in_array(UserGroup::GUESTS, $groupIDs)) { + $fixGroupIDs[] = UserGroup::GUESTS; + $groupIDs[] = UserGroup::GUESTS; + } + + if (\in_array(UserGroup::USERS, $groupIDs)) { + $removeGroupIDs[] = UserGroup::USERS; + } + } else { + if (!\in_array(UserGroup::USERS, $groupIDs)) { + $fixGroupIDs[] = UserGroup::USERS; + $groupIDs[] = UserGroup::USERS; + } + + if (\in_array(UserGroup::GUESTS, $groupIDs)) { + $removeGroupIDs[] = UserGroup::GUESTS; + } + } + + $this->addUserGroups($fixGroupIDs); + $this->removeUserGroups($removeGroupIDs); + + UserStorageHandler::getInstance()->update($this->user->userID, 'groupIDs', \serialize($groupIDs)); + + return $groupIDs; + } + + /** + * @param list $groupIDs + */ + private function addUserGroups(array $groupIDs): void + { + if ($groupIDs === []) { + return; + } + + (new UserEditor($this->user))->addToGroups($groupIDs, false, false); + } + + /** + * @param list $groupIDs + */ + private function removeUserGroups(array $groupIDs): void + { + if ($groupIDs === []) { + return; + } + + (new UserEditor($this->user))->removeFromGroups($groupIDs); + } +} diff --git a/wcfsetup/install/files/lib/command/user/UpdateUserOnlineMarking.class.php b/wcfsetup/install/files/lib/command/user/UpdateUserOnlineMarking.class.php new file mode 100644 index 00000000000..51204269abe --- /dev/null +++ b/wcfsetup/install/files/lib/command/user/UpdateUserOnlineMarking.class.php @@ -0,0 +1,62 @@ + + * @since 6.3 + */ +final class UpdateUserOnlineMarking +{ + public function __construct( + private readonly User $user + ) {} + + public function __invoke(): void + { + $groupIDs = (new UpdateMandatoryUserGroups($this->user))(); + + $newOnlineGroupID = $this->newOnlineGroupID($groupIDs); + + $this->updateOnlineGroupID($newOnlineGroupID); + + $event = new UserOnlineMarkingUpdated($this->user, $newOnlineGroupID); + EventHandler::getInstance()->fire($event); + } + + /** + * @param list $groupIDs + */ + private function newOnlineGroupID(array $groupIDs): ?int + { + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('groupID IN (?)', [$groupIDs]); + + $sql = "SELECT groupID + FROM wcf1_user_group + " . $conditionBuilder . " + ORDER BY priority DESC"; + $statement = WCF::getDB()->prepare($sql, 1); + $statement->execute($conditionBuilder->getParameters()); + + return $statement->fetchSingleColumn() ?: null; + } + + private function updateOnlineGroupID(?int $newOnlineGroupID): void + { + $sql = "UPDATE wcf1_user SET userOnlineGroupID = ? WHERE userID = ?"; + $statement = WCF::getDB()->prepare($sql); + + $statement->execute([$newOnlineGroupID, $this->user->userID]); + } +} diff --git a/wcfsetup/install/files/lib/command/user/UpdateUserRank.class.php b/wcfsetup/install/files/lib/command/user/UpdateUserRank.class.php new file mode 100644 index 00000000000..4a471432780 --- /dev/null +++ b/wcfsetup/install/files/lib/command/user/UpdateUserRank.class.php @@ -0,0 +1,64 @@ + + * @since 6.3 + */ +final class UpdateUserRank +{ + public function __construct( + private readonly User $user + ) {} + + public function __invoke(): void + { + $newRankID = $this->getNewRankId(); + + $this->updateUserRank($this->user, $newRankID); + + $event = new UserRankUpdated($this->user, $newRankID); + EventHandler::getInstance()->fire($event); + } + + private function getNewRankId(): ?int + { + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('user_rank.groupID IN (?)', [$this->user->getGroupIDs()]); + $conditionBuilder->add('user_rank.requiredPoints <= ?', [$this->user->activityPoints]); + + if ($this->user->gender) { + $conditionBuilder->add('user_rank.requiredGender IN (?)', [[0, $this->user->gender]]); + } else { + $conditionBuilder->add('user_rank.requiredGender = ?', [0]); + } + + $sql = "SELECT user_rank.rankID + FROM wcf1_user_rank user_rank + LEFT JOIN wcf1_user_group user_group + ON user_group.groupID = user_rank.groupID + " . $conditionBuilder . " + ORDER BY user_group.priority DESC, user_rank.requiredPoints DESC, user_rank.requiredGender DESC"; + $statement = WCF::getDB()->prepare($sql, 1); + $statement->execute($conditionBuilder->getParameters()); + + return $statement->fetchSingleColumn() ?: null; + } + + private function updateUserRank(User $user, ?int $rankID): void + { + (new UserEditor($user))->update(['rankID' => $rankID]); + } +} diff --git a/wcfsetup/install/files/lib/command/user/UpdateUserSpecialTrophies.class.php b/wcfsetup/install/files/lib/command/user/UpdateUserSpecialTrophies.class.php new file mode 100644 index 00000000000..ff84649c7d4 --- /dev/null +++ b/wcfsetup/install/files/lib/command/user/UpdateUserSpecialTrophies.class.php @@ -0,0 +1,65 @@ + + * @since 6.3 + */ +final class UpdateUserSpecialTrophies +{ + public function __construct( + private readonly User $user, + /** @var int[] */ + private readonly array $trophyIDs + ) { + } + + public function __invoke(): void + { + $this->deleteExistingSpecialTrophies(); + $this->insertSpecialTrophies(); + + UserStorageHandler::getInstance()->reset([$this->user->userID], 'specialTrophies'); + + $event = new UserSpecialTrophiesUpdated($this->user, $this->trophyIDs); + EventHandler::getInstance()->fire($event); + } + + private function deleteExistingSpecialTrophies(): void + { + $sql = "DELETE FROM wcf1_user_special_trophy + WHERE userID = ?"; + $statement = WCF::getDB()->prepare($sql); + $statement->execute([$this->user->userID]); + } + + private function insertSpecialTrophies(): void + { + if ($this->trophyIDs === []) { + return; + } + + $sql = "INSERT INTO wcf1_user_special_trophy + (userID, trophyID) + VALUES (?, ?)"; + $statement = WCF::getDB()->prepare($sql); + + foreach ($this->trophyIDs as $trophyID) { + $statement->execute([ + $this->user->userID, + $trophyID, + ]); + } + } +} diff --git a/wcfsetup/install/files/lib/data/user/UserAction.class.php b/wcfsetup/install/files/lib/data/user/UserAction.class.php index f74ac389fac..31cb8b1c1a0 100644 --- a/wcfsetup/install/files/lib/data/user/UserAction.class.php +++ b/wcfsetup/install/files/lib/data/user/UserAction.class.php @@ -3,6 +3,8 @@ namespace wcf\data\user; use ParagonIE\ConstantTime\Hex; +use wcf\command\user\UpdateUserOnlineMarking; +use wcf\command\user\UpdateUserRank; use wcf\data\AbstractDatabaseObjectAction; use wcf\data\file\FileAction; use wcf\data\IClipboardAction; @@ -323,12 +325,11 @@ public function create() // update user rank if (MODULE_USER_RANK) { - $action = new UserProfileAction([$userEditor], 'updateUserRank'); - $action->executeAction(); + (new UpdateUserRank($userEditor->getDecoratedObject()))(); + } + if (MODULE_USERS_ONLINE) { + (new UpdateUserOnlineMarking($userEditor->getDecoratedObject()))(); } - // update user online marking - $action = new UserProfileAction([$userEditor], 'updateUserOnlineMarking'); - $action->executeAction(); } return $user; @@ -475,13 +476,13 @@ public function removeFromGroups() UserEditor::resetCache(); $this->readObjects(); - if (MODULE_USER_RANK) { - $action = new UserProfileAction($this->objects, 'updateUserRank'); - $action->executeAction(); - } - if (MODULE_USERS_ONLINE) { - $action = new UserProfileAction($this->objects, 'updateUserOnlineMarking'); - $action->executeAction(); + foreach ($this->objects as $userEditor) { + if (MODULE_USER_RANK) { + (new UpdateUserRank($userEditor->getDecoratedObject()))(); + } + if (MODULE_USERS_ONLINE) { + (new UpdateUserOnlineMarking($userEditor->getDecoratedObject()))(); + } } } @@ -520,13 +521,13 @@ public function addToGroups() UserEditor::resetCache(); $this->readObjects(); - if (MODULE_USER_RANK) { - $action = new UserProfileAction($this->objects, 'updateUserRank'); - $action->executeAction(); - } - if (MODULE_USERS_ONLINE) { - $action = new UserProfileAction($this->objects, 'updateUserOnlineMarking'); - $action->executeAction(); + foreach ($this->objects as $userEditor) { + if (MODULE_USER_RANK) { + (new UpdateUserRank($userEditor->getDecoratedObject()))(); + } + if (MODULE_USERS_ONLINE) { + (new UpdateUserOnlineMarking($userEditor->getDecoratedObject()))(); + } } } diff --git a/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php b/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php index 60f19bde719..081dbfdf79f 100644 --- a/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php +++ b/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php @@ -2,8 +2,10 @@ namespace wcf\data\user; +use wcf\command\user\UpdateUserOnlineMarking; +use wcf\command\user\UpdateUserRank; +use wcf\command\user\UpdateUserSpecialTrophies; use wcf\data\object\type\ObjectTypeCache; -use wcf\data\user\group\UserGroup; use wcf\system\bbcode\BBCodeHandler; use wcf\system\cache\runtime\UserProfileRuntimeCache; use wcf\system\database\util\PreparedStatementConditionBuilder; @@ -15,7 +17,6 @@ use wcf\system\option\user\UserOptionHandler; use wcf\system\upload\UploadFile; use wcf\system\user\group\assignment\UserGroupAssignmentHandler; -use wcf\system\user\storage\UserStorageHandler; use wcf\system\WCF; use wcf\util\ArrayUtil; use wcf\util\MessageUtil; @@ -292,8 +293,7 @@ public function save() // update user rank if (MODULE_USER_RANK) { - $action = new self([new UserEditor($user)], 'updateUserRank'); - $action->executeAction(); + (new UpdateUserRank($user))(); } // reload option handler @@ -326,6 +326,8 @@ public function save() * Updates user ranks. * * @return void + * + * @deprecated 6.3 use the `UpdateUserRank` command instead. */ public function updateUserRank() { @@ -333,51 +335,8 @@ public function updateUserRank() $this->readObjects(); } - $userToRank = []; - foreach ($this->getObjects() as $user) { - $conditionBuilder = new PreparedStatementConditionBuilder(); - $conditionBuilder->add('user_rank.groupID IN (?)', [$user->getGroupIDs()]); - $conditionBuilder->add('user_rank.requiredPoints <= ?', [$user->activityPoints]); - if ($user->gender) { - $conditionBuilder->add('user_rank.requiredGender IN (?)', [[0, $user->gender]]); - } else { - $conditionBuilder->add('user_rank.requiredGender = ?', [0]); - } - - $sql = "SELECT user_rank.rankID - FROM wcf1_user_rank user_rank - LEFT JOIN wcf1_user_group user_group - ON user_group.groupID = user_rank.groupID - " . $conditionBuilder . " - ORDER BY user_group.priority DESC, user_rank.requiredPoints DESC, user_rank.requiredGender DESC"; - $statement = WCF::getDB()->prepare($sql, 1); - $statement->execute($conditionBuilder->getParameters()); - $row = $statement->fetchArray(); - if ($row === false) { - if ($user->rankID) { - $userToRank[$user->userID] = null; - } - } else { - if ($row['rankID'] != $user->rankID) { - $userToRank[$user->userID] = $row['rankID']; - } - } - } - - if (!empty($userToRank)) { - $sql = "UPDATE wcf1_user - SET rankID = ? - WHERE userID = ?"; - $statement = WCF::getDB()->prepare($sql); - - WCF::getDB()->beginTransaction(); - foreach ($userToRank as $userID => $rankID) { - $statement->execute([ - $rankID, - $userID, - ]); - } - WCF::getDB()->commitTransaction(); + foreach ($this->getObjects() as $editor) { + (new UpdateUserRank($editor->getDecoratedObject()))(); } } @@ -385,6 +344,8 @@ public function updateUserRank() * Updates user online markings. * * @return void + * + * @deprecated 6.3 use the `UpdateUserOnlineMarking` command instead. */ public function updateUserOnlineMarking() { @@ -392,111 +353,8 @@ public function updateUserOnlineMarking() $this->readObjects(); } - $fixUserGroupIDs = $userToGroup = $removeFromGroupIDs = []; - $newGroupIDs = []; - foreach ($this->getObjects() as $user) { - $groupIDs = $user->getGroupIDs(); - if (!\in_array(UserGroup::EVERYONE, $groupIDs)) { - $fixUserGroupIDs[$user->userID] = [UserGroup::EVERYONE]; - $groupIDs[] = UserGroup::EVERYONE; - } - if ($user->pendingActivation()) { - if (!\in_array(UserGroup::GUESTS, $groupIDs)) { - if (!isset($fixUserGroupIDs[$user->userID])) { - $fixUserGroupIDs[$user->userID] = []; - } - $fixUserGroupIDs[$user->userID][] = UserGroup::GUESTS; - $groupIDs[] = UserGroup::GUESTS; - } - - if (\in_array(UserGroup::USERS, $groupIDs)) { - if (!isset($removeFromGroupIDs[$user->userID])) { - $removeFromGroupIDs[$user->userID] = []; - } - - $removeFromGroupIDs[$user->userID][] = UserGroup::USERS; - } - } else { - if (!\in_array(UserGroup::USERS, $groupIDs)) { - if (!isset($fixUserGroupIDs[$user->userID])) { - $fixUserGroupIDs[$user->userID] = []; - } - $fixUserGroupIDs[$user->userID][] = UserGroup::USERS; - $groupIDs[] = UserGroup::USERS; - } - - if (\in_array(UserGroup::GUESTS, $groupIDs)) { - if (!isset($removeFromGroupIDs[$user->userID])) { - $removeFromGroupIDs[$user->userID] = []; - } - - $removeFromGroupIDs[$user->userID][] = UserGroup::GUESTS; - } - } - $newGroupIDs[$user->userID] = $groupIDs; - - $conditionBuilder = new PreparedStatementConditionBuilder(); - $conditionBuilder->add('groupID IN (?)', [$groupIDs]); - - $sql = "SELECT groupID - FROM wcf1_user_group - " . $conditionBuilder . " - ORDER BY priority DESC"; - $statement = WCF::getDB()->prepare($sql, 1); - $statement->execute($conditionBuilder->getParameters()); - $row = $statement->fetchArray(); - if ($row['groupID'] != $user->userOnlineGroupID) { - $userToGroup[$user->userID] = $row['groupID']; - } - } - - // add users to missing default user groups - if (!empty($fixUserGroupIDs)) { - $sql = "INSERT INTO wcf1_user_to_group - (userID, groupID) - VALUES (?, ?)"; - $statement = WCF::getDB()->prepare($sql); - - WCF::getDB()->beginTransaction(); - foreach ($fixUserGroupIDs as $userID => $groupIDs) { - foreach ($groupIDs as $groupID) { - $statement->execute([$userID, $groupID]); - } - - UserStorageHandler::getInstance()->update($userID, 'groupIDs', \serialize($newGroupIDs[$userID])); - } - WCF::getDB()->commitTransaction(); - } - - if ($removeFromGroupIDs !== []) { - $sql = "DELETE FROM wcf1_user_to_group - WHERE userID = ? - AND groupID = ?"; - $statement = WCF::getDB()->prepare($sql); - - WCF::getDB()->beginTransaction(); - foreach ($removeFromGroupIDs as $userID => $groupIDs) { - foreach ($groupIDs as $groupID) { - $statement->execute([$userID, $groupID]); - } - } - WCF::getDB()->commitTransaction(); - } - - if (!empty($userToGroup)) { - $sql = "UPDATE wcf1_user - SET userOnlineGroupID = ? - WHERE userID = ?"; - $statement = WCF::getDB()->prepare($sql); - - WCF::getDB()->beginTransaction(); - foreach ($userToGroup as $userID => $groupID) { - $statement->execute([ - $groupID, - $userID, - ]); - } - WCF::getDB()->commitTransaction(); + foreach ($this->getObjects() as $editor) { + (new UpdateUserOnlineMarking($editor->getDecoratedObject()))(); } } @@ -504,6 +362,8 @@ public function updateUserOnlineMarking() * Updates the special trophies. * * @return void + * + * @deprecated 6.3 use the `UpdateUserSpecialTrophies` command instead. */ public function updateSpecialTrophies() { @@ -511,33 +371,8 @@ public function updateSpecialTrophies() $this->readObjects(); } - $sql = "DELETE FROM wcf1_user_special_trophy - WHERE userID = ?"; - $deleteStatement = WCF::getDB()->prepare($sql); - - $sql = "INSERT INTO wcf1_user_special_trophy - (userID, trophyID) - VALUES (?, ?)"; - $insertStatement = WCF::getDB()->prepare($sql); - foreach ($this->getObjects() as $user) { - WCF::getDB()->beginTransaction(); - - // delete all user special trophies for the user - $deleteStatement->execute([$user->userID]); - - if (!empty($this->parameters['trophyIDs'])) { - foreach ($this->parameters['trophyIDs'] as $trophyID) { - $insertStatement->execute([ - $user->userID, - $trophyID, - ]); - } - } - - WCF::getDB()->commitTransaction(); - - UserStorageHandler::getInstance()->reset([$user->userID], 'specialTrophies'); + (new UpdateUserSpecialTrophies($user->getDecoratedObject(), $this->parameters['trophyIDs'] ?? []))(); } } diff --git a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php index 8556ba7d8a8..94aa6b4e154 100644 --- a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php @@ -2,10 +2,10 @@ namespace wcf\data\user\trophy; +use wcf\command\user\UpdateUserSpecialTrophies; use wcf\data\AbstractDatabaseObjectAction; use wcf\data\user\UserAction; use wcf\data\user\UserProfile; -use wcf\data\user\UserProfileAction; use wcf\system\cache\runtime\UserProfileRuntimeCache; use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\IllegalLinkException; @@ -71,16 +71,12 @@ public function create() } if (!$hasTrophy) { - $userProfileAction = new UserProfileAction( - [$userTrophy->getUserProfile()->getDecoratedObject()], - 'updateSpecialTrophies', - [ - 'trophyIDs' => \array_unique(\array_merge(\array_map(static function ($trophy) { - return $trophy->trophyID; - }, $userTrophy->getUserProfile()->getSpecialTrophies()), [$userTrophy->trophyID])), - ] - ); - $userProfileAction->executeAction(); + (new UpdateUserSpecialTrophies( + $userTrophy->getUserProfile()->getDecoratedObject(), + \array_unique(\array_merge(\array_map(static function ($trophy) { + return $trophy->trophyID; + }, $userTrophy->getUserProfile()->getSpecialTrophies()), [$userTrophy->trophyID])) + ))(); } } } diff --git a/wcfsetup/install/files/lib/event/user/UserOnlineMarkingUpdated.class.php b/wcfsetup/install/files/lib/event/user/UserOnlineMarkingUpdated.class.php new file mode 100644 index 00000000000..b49c38e0ca4 --- /dev/null +++ b/wcfsetup/install/files/lib/event/user/UserOnlineMarkingUpdated.class.php @@ -0,0 +1,22 @@ + + * @since 6.3 + */ +final class UserOnlineMarkingUpdated implements IPsr14Event +{ + public function __construct( + public readonly User $user, + public readonly ?int $newOnlineGroupID + ) {} +} diff --git a/wcfsetup/install/files/lib/event/user/UserRankUpdated.class.php b/wcfsetup/install/files/lib/event/user/UserRankUpdated.class.php new file mode 100644 index 00000000000..e68168f534a --- /dev/null +++ b/wcfsetup/install/files/lib/event/user/UserRankUpdated.class.php @@ -0,0 +1,22 @@ + + * @since 6.3 + */ +final class UserRankUpdated implements IPsr14Event +{ + public function __construct( + public readonly User $user, + public readonly ?int $newRankID, + ) {} +} diff --git a/wcfsetup/install/files/lib/event/user/UserSpecialTrophiesUpdated.class.php b/wcfsetup/install/files/lib/event/user/UserSpecialTrophiesUpdated.class.php new file mode 100644 index 00000000000..084715310c9 --- /dev/null +++ b/wcfsetup/install/files/lib/event/user/UserSpecialTrophiesUpdated.class.php @@ -0,0 +1,23 @@ + + * @since 6.3 + */ +final class UserSpecialTrophiesUpdated implements IPsr14Event +{ + public function __construct( + public readonly User $user, + /** @var int[] */ + public readonly array $trophyIDs + ) {} +} diff --git a/wcfsetup/install/files/lib/system/user/activity/point/UserActivityPointHandler.class.php b/wcfsetup/install/files/lib/system/user/activity/point/UserActivityPointHandler.class.php index b720ba3d688..c18610f4969 100644 --- a/wcfsetup/install/files/lib/system/user/activity/point/UserActivityPointHandler.class.php +++ b/wcfsetup/install/files/lib/system/user/activity/point/UserActivityPointHandler.class.php @@ -2,9 +2,10 @@ namespace wcf\system\user\activity\point; +use wcf\command\user\UpdateUserRank; use wcf\data\object\type\ObjectType; use wcf\data\object\type\ObjectTypeCache; -use wcf\data\user\UserProfileAction; +use wcf\data\user\UserList; use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\InvalidObjectTypeException; use wcf\system\exception\SystemException; @@ -289,7 +290,13 @@ public function getObjectTypeByName($objectType) */ protected function updateUserRanks(array $userIDs) { - $action = new UserProfileAction($userIDs, 'updateUserRank'); - $action->executeAction(); + // Do not use the `UserRuntimeCache` to get up-to-date values. + $userList = new UserList(); + $userList->setObjectIDs($userIDs); + $userList->readObjects(); + + foreach ($userList->getObjects() as $user) { + (new UpdateUserRank($user))(); + } } } diff --git a/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php b/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php index 912134028ea..df581fe1667 100644 --- a/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php +++ b/wcfsetup/install/files/lib/system/worker/UserRebuildDataWorker.class.php @@ -2,6 +2,7 @@ namespace wcf\system\worker; +use wcf\command\user\UpdateUserOnlineMarking; use wcf\data\file\FileEditor; use wcf\data\reaction\type\ReactionTypeCache; use wcf\data\user\avatar\UserAvatarEditor; @@ -11,7 +12,6 @@ use wcf\data\user\UserEditor; use wcf\data\user\UserList; use wcf\data\user\UserProfile; -use wcf\data\user\UserProfileAction; use wcf\system\bbcode\BBCodeHandler; use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\SystemException; @@ -70,10 +70,8 @@ public function execute() $userIDs[] = $user->userID; } - // update user ranks - if (!empty($users)) { - $action = new UserProfileAction($users, 'updateUserOnlineMarking'); - $action->executeAction(); + foreach ($users as $user) { + (new UpdateUserOnlineMarking($user->getDecoratedObject()))(); } $this->updateUserOnlineStatus($users);