From: Joshua Rüsweg Date: Mon, 31 Jul 2017 14:31:38 +0000 (+0200) Subject: Improve trophyPoints counting X-Git-Tag: 3.1.0_Alpha_1~138 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=9e1fe4070ab1413d6c64aa61f1eb1cd89e0cc0b8;p=GitHub%2FWoltLab%2FWCF.git Improve trophyPoints counting See #2315 --- diff --git a/wcfsetup/install/files/lib/acp/form/TrophyEditForm.class.php b/wcfsetup/install/files/lib/acp/form/TrophyEditForm.class.php index fd8f0bece7..72c1d082a4 100644 --- a/wcfsetup/install/files/lib/acp/form/TrophyEditForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/TrophyEditForm.class.php @@ -2,11 +2,14 @@ namespace wcf\acp\form; use wcf\data\trophy\Trophy; use wcf\data\trophy\TrophyAction; +use wcf\data\user\UserAction; use wcf\system\condition\ConditionHandler; +use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\exception\IllegalLinkException; use wcf\system\exception\UserInputException; use wcf\system\language\I18nHandler; use wcf\system\trophy\condition\TrophyConditionHandler; +use wcf\system\user\storage\UserStorageHandler; use wcf\system\WCF; /** @@ -194,6 +197,22 @@ class TrophyEditForm extends TrophyAddForm { UserStorageHandler::getInstance()->resetAll('specialTrophies'); } + // update trophy points + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('trophyID = ?', [$this->trophyID]); + $sql = "SELECT COUNT(*) as count, userID FROM wcf".WCF_N."_user_trophy ".$conditionBuilder." GROUP BY userID"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + while ($row = $statement->fetchArray()) { + $userAction = new UserAction([$row['userID']], 'update', [ + 'counters' => [ + 'trophyPoints' => $row['count'] * ($this->isDisabled) ? -1 : 1 + ] + ]); + $userAction->executeAction(); + } + $this->saved(); // show success message diff --git a/wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php b/wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php index 104a4aab61..240876b81c 100644 --- a/wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php +++ b/wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php @@ -1,8 +1,12 @@ sqlJoins)) $userTrophyList->sqlJoins .= ' '; + $userTrophyList->sqlJoins .= 'LEFT JOIN wcf'.WCF_N.'_trophy trophy ON user_trophy.trophyID = trophy.trophyID'; + $userTrophyList->sqlJoins .= ' LEFT JOIN wcf'.WCF_N.'_category category ON trophy.categoryID = category.categoryID'; + + $userTrophyList->getConditionBuilder()->add('trophy.isDisabled = ?', [0]); + $userTrophyList->getConditionBuilder()->add('category.isDisabled = ?', [0]); + $userTrophyList->getConditionBuilder()->add('user_trophy.trophyID IN (?)', [$this->getObjectIDs()]); + $userTrophyList->readObjects(); + + $userTrophyAction = new UserTrophyAction($userTrophyList->getObjects(), 'delete'); + $userTrophyAction->executeAction(); + $returnValues = parent::delete(); UserStorageHandler::getInstance()->resetAll('specialTrophies'); @@ -77,14 +95,60 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction * @inheritDoc */ public function toggle() { - $sql = "DELETE FROM wcf". WCF_N ."_user_special_trophy WHERE trophyID = ?"; - $deleteStatement = WCF::getDB()->prepareStatement($sql); + $enabledTrophyIDs = []; + $disabledTrophyIDs = []; foreach ($this->getObjects() as $trophy) { $trophy->update(['isDisabled' => $trophy->isDisabled ? 0 : 1]); if (!$trophy->isDisabled) { - $deleteStatement->execute([$trophy->trophyID]); + + $disabledTrophyIDs[] = $trophy->trophyID; + } + else { + $enabledTrophyIDs[] = $trophy->trophyID; + } + } + + if (!empty($disabledTrophyIDs)) { + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('trophyID IN (?)', [$disabledTrophyIDs]); + $sql = "DELETE FROM wcf". WCF_N ."_user_special_trophy ".$conditionBuilder; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + // update trophy points + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('trophyID IN (?)', [$disabledTrophyIDs]); + $sql = "SELECT COUNT(*) as count, userID FROM wcf".WCF_N."_user_trophy ".$conditionBuilder." GROUP BY userID"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + while ($row = $statement->fetchArray()) { + $userAction = new UserAction([$row['userID']], 'update', [ + 'counters' => [ + 'trophyPoints' => $row['count'] * -1 + ] + ]); + $userAction->executeAction(); + } + } + + if (!empty($enabledTrophyIDs)) { + // update trophy points + $conditionBuilder = new PreparedStatementConditionBuilder(); + $conditionBuilder->add('trophyID IN (?)', [$enabledTrophyIDs]); + $sql = "SELECT COUNT(*) as count, userID FROM wcf".WCF_N."_user_trophy ".$conditionBuilder." GROUP BY userID"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + while ($row = $statement->fetchArray()) { + $userAction = new UserAction([$row['userID']], 'update', [ + 'counters' => [ + 'trophyPoints' => $row['count'] + ] + ]); + $userAction->executeAction(); } } 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 caf7bb46ab..38c5730086 100644 --- a/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php +++ b/wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php @@ -41,11 +41,14 @@ class UserTrophyAction extends AbstractDatabaseObjectAction { public function create() { $returnValues = parent::create(); - (new UserAction([$returnValues->userID], 'update', [ - 'counters' => [ - 'trophyPoints' => 1 - ] - ]))->executeAction(); + if (!$returnValues->getTrophy()->isDisabled()) { + $userAction = new UserAction([$returnValues->userID], 'update', [ + 'counters' => [ + 'trophyPoints' => 1 + ] + ]); + $userAction->executeAction(); + } UserActivityEventHandler::getInstance()->fireEvent('com.woltlab.wcf.userTrophy.recentActivityEvent.trophyReceived', $returnValues->getObjectID(), null, $returnValues->userID); @@ -82,38 +85,43 @@ class UserTrophyAction extends AbstractDatabaseObjectAction { $returnValues = parent::delete(); - // update user special trophies trophies - $userTrophies = UserTrophyList::getUserTrophies($userIDs); - - foreach ($userTrophies as $userID => $trophies) { - $userTrophyIDs = []; - foreach ($trophies as $trophy) { - $userTrophyIDs[] = $trophy->trophyID; - } + if (!empty($this->objects)) { + // update user special trophies trophies + $userTrophies = UserTrophyList::getUserTrophies($userIDs); - $conditionBuilder = new PreparedStatementConditionBuilder(); - $conditionBuilder->add('trophyID NOT IN (?)', [array_unique($userTrophyIDs)]); - $conditionBuilder->add('userID = ?', [$userID]); + foreach ($userTrophies as $userID => $trophies) { + $userTrophyIDs = []; + foreach ($trophies as $trophy) { + $userTrophyIDs[] = $trophy->trophyID; + } + + $conditionBuilder = new PreparedStatementConditionBuilder(); + if (!empty($userTrophyIDs)) $conditionBuilder->add('trophyID NOT IN (?)', [array_unique($userTrophyIDs)]); + $conditionBuilder->add('userID = ?', [$userID]); + + $sql = "DELETE FROM wcf". WCF_N ."_user_special_trophy ". $conditionBuilder; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($conditionBuilder->getParameters()); + + UserStorageHandler::getInstance()->reset([$userID], 'specialTrophies'); + } - $sql = "DELETE FROM wcf". WCF_N ."_user_special_trophy ". $conditionBuilder; - $statement = WCF::getDB()->prepareStatement($sql); - $statement->execute($conditionBuilder->getParameters()); + $updateUserTrophies = []; + foreach ($this->getObjects() as $object) { + if (!$object->getTrophy()->isDisabled()) { + if (!isset($updateUserTrophies[$object->userID])) $updateUserTrophies[$object->userID] = 0; + $updateUserTrophies[$object->userID]--; + } + } - UserStorageHandler::getInstance()->reset([$userID], 'specialTrophies'); - } - - /** @var $object UserTrophyEditor */ - foreach ($this->getObjects() as $object) { - if (!isset($updateUserTrophies[$object->userID])) $updateUserTrophies[$object->userID] = 0; - $updateUserTrophies[$object->userID]--; - } - - foreach ($updateUserTrophies as $userID => $count) { - (new UserAction([$userID], 'update', [ - 'counters' => [ - 'trophyPoints' => $count - ] - ]))->executeAction(); + foreach ($updateUserTrophies as $userID => $count) { + $userAction = new UserAction([$returnValues->userID], 'update', [ + 'counters' => [ + 'trophyPoints' => $count + ] + ]); + $userAction->executeAction(); + } } return $returnValues; diff --git a/wcfsetup/install/files/lib/system/category/TrophyCategoryType.class.php b/wcfsetup/install/files/lib/system/category/TrophyCategoryType.class.php index 6946941610..0258ba796c 100644 --- a/wcfsetup/install/files/lib/system/category/TrophyCategoryType.class.php +++ b/wcfsetup/install/files/lib/system/category/TrophyCategoryType.class.php @@ -1,5 +1,8 @@ getPermission('admin.trophy.canManageTrophy'); } + + /** + * @inheritDoc + */ + public function beforeDeletion(CategoryEditor $categoryEditor) { + // update user trophyPoints + $userTrophyList = new UserTrophyList(); + if (!empty($userTrophyList->sqlJoins)) $userTrophyList->sqlJoins .= ' '; + $userTrophyList->sqlJoins .= 'LEFT JOIN wcf'.WCF_N.'_trophy trophy ON user_trophy.trophyID = trophy.trophyID'; + $userTrophyList->sqlJoins .= ' LEFT JOIN wcf'.WCF_N.'_category category ON trophy.categoryID = category.categoryID'; + + $userTrophyList->getConditionBuilder()->add('trophy.isDisabled = ?', [0]); + $userTrophyList->getConditionBuilder()->add('category.isDisabled = ?', [0]); + $userTrophyList->getConditionBuilder()->add('category.categoryID = ?', [$categoryEditor->categoryID]); + $userTrophyList->readObjects(); + + $userTrophyAction = new UserTrophyAction($userTrophyList->getObjects(), 'delete'); + $userTrophyAction->executeAction(); + } }