Improve trophyPoints counting
authorJoshua Rüsweg <josh@bastelstu.be>
Mon, 31 Jul 2017 14:31:38 +0000 (16:31 +0200)
committerJoshua Rüsweg <josh@bastelstu.be>
Mon, 31 Jul 2017 14:31:38 +0000 (16:31 +0200)
See #2315

wcfsetup/install/files/lib/acp/form/TrophyEditForm.class.php
wcfsetup/install/files/lib/data/trophy/TrophyAction.class.php
wcfsetup/install/files/lib/data/user/trophy/UserTrophyAction.class.php
wcfsetup/install/files/lib/system/category/TrophyCategoryType.class.php

index fd8f0bece7b8af340154c700a6bf6f541ed3da9b..72c1d082a4266d1f3661cce33b7a3b245ef49c2d 100644 (file)
@@ -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
index 104a4aab614ba29f4661ce5ceaa5043710eb87bc..240876b81ccde7f87c37beee41d00eed6cb9cff6 100644 (file)
@@ -1,8 +1,12 @@
 <?php
 namespace wcf\data\trophy;
+use wcf\data\user\trophy\UserTrophyAction;
+use wcf\data\user\trophy\UserTrophyList;
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\data\IToggleAction;
 use wcf\data\IUploadAction;
+use wcf\data\user\UserAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
 use wcf\system\image\ImageHandler;
@@ -51,6 +55,20 @@ class TrophyAction extends AbstractDatabaseObjectAction implements IToggleAction
         * @inheritDoc
         */
        public function delete() {
+               // update trophy points 
+               $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('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();
                        }
                }
                
index caf7bb46abc560b302ad6dc4f106c66b40e6b20d..38c5730086859f23a247de294ee50ea2b6136c8e 100644 (file)
@@ -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;
index 69469416101bb48c30378e54f99a2b364fcde262..0258ba796c08ad5ce90285901e61e570b57e8e1f 100644 (file)
@@ -1,5 +1,8 @@
 <?php
 namespace wcf\system\category;
+use wcf\data\category\CategoryEditor;
+use wcf\data\user\trophy\UserTrophyAction;
+use wcf\data\user\trophy\UserTrophyList;
 use wcf\system\WCF;
 
 /**
@@ -45,4 +48,23 @@ class TrophyCategoryType extends AbstractCategoryType {
        public function canEditCategory() {
                return WCF::getSession()->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(); 
+       }
 }