Added automatic removal of orphaned moderation queues
authorAlexander Ebert <ebert@woltlab.com>
Mon, 23 Sep 2013 22:15:48 +0000 (00:15 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 23 Sep 2013 22:15:48 +0000 (00:15 +0200)
wcfsetup/install/files/lib/data/moderation/queue/ModerationQueueAction.class.php
wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueHandler.class.php
wcfsetup/install/files/lib/system/moderation/queue/IModerationQueueHandler.class.php
wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueManager.class.php
wcfsetup/install/files/lib/system/moderation/queue/report/CommentCommentModerationQueueReportHandler.class.php
wcfsetup/install/files/lib/system/moderation/queue/report/CommentResponseModerationQueueReportHandler.class.php

index c2596554c9c8f05a9c9f7d4c33285636c7d24752..9c3252b726a362a93c12d5b50cce50d13ac4a130 100644 (file)
@@ -97,9 +97,16 @@ class ModerationQueueAction extends AbstractDatabaseObjectAction {
                        'queues' => $queueList
                ));
                
+               // check if user storage is outdated
                $totalCount = ModerationQueueManager::getInstance()->getOutstandingModerationCount();
                if (count($queueList) < $totalCount) {
                        UserStorageHandler::getInstance()->reset(array(WCF::getUser()->userID), 'outstandingModerationCount');
+                       
+                       // check for orphaned queues
+                       $queueCount = ModerationQueueManager::getInstance()->getOutstandingModerationCount();
+                       if (count($queueList) < $queueCount) {
+                               ModerationQueueManager::getInstance()->identifyOrphans();
+                       }
                }
                
                return array(
index 39ce6a984cd8181896b9e3c89b55e88ba2f46a86..a501a7193f11d995f34314792e8dd20cd80a8d7d 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\system\moderation\queue;
 use wcf\data\moderation\queue\ModerationQueueAction;
+use wcf\data\DatabaseObject;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\SystemException;
 use wcf\system\WCF;
@@ -16,6 +17,12 @@ use wcf\system\WCF;
  * @category   Community Framework
  */
 abstract class AbstractModerationQueueHandler implements IModerationQueueHandler {
+       /**
+        * database object class name
+        * @var string
+        */
+       protected $className = '';
+       
        /**
         * definition name
         * @var string
@@ -28,6 +35,32 @@ abstract class AbstractModerationQueueHandler implements IModerationQueueHandler
         */
        protected $objectType = '';
        
+       /**
+        * @see wcf\system\moderation\queue\IModerationQueueHandler::identifyOrphans()
+        */
+       public function identifyOrphans(array $queues) {
+               if (empty($this->className) || !class_exists($this->className) || !($this->className instanceof DatabaseObject)) {
+                       throw new SystemException("DatabaseObject class name '" . $this->className . "' is missing or invalid");
+               }
+               
+               $indexName = call_user_func(array($this->className, 'getDatabaseTableIndexName'));
+               $tableName = call_user_func(array($this->className, 'getDatabaseTableName'));
+               
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add($indexName . " IN (?)", array(array_keys($queues)));
+               
+               $sql = "SELECT  " . $indexName . "
+                       FROM    " . $tableName . "
+                       ".$conditions;
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute($conditions->getParameters());
+               while ($row = $statement->fetchArray()) {
+                       unset($queues[$row[$indexName]]);
+               }
+               
+               return array_values($queues);
+       }
+       
        /**
         * @see wcf\system\moderation\queue\IModerationQueueHandler::removeQueues()
         */
index 2b6b4e7a82b05822a26a8754ebf068d358bb85f3..71fb83f39b4cb157f32f71375c21433fe79622c5 100644 (file)
@@ -28,6 +28,14 @@ interface IModerationQueueHandler {
         */
        public function getContainerID($objectID);
        
+       /**
+        * Validates object ids and returns orphaned queue ids.
+        * 
+        * @param       array<integer>          $queues
+        * @return      array<integer>
+        */
+       public function identifyOrphans(array $queues);
+       
        /**
         * Returns true if given object id is valid.
         * 
index d61dd5020e4fdc087b5da5c5a4fe2836dc1b51f4..f3c888109266b8887c32a8d51695924ce6fd3537 100644 (file)
@@ -289,6 +289,44 @@ class ModerationQueueManager extends SingletonFactory {
                WCF::getDB()->commitTransaction();
        }
        
+       /**
+        * Identifies and removes orphaned queues.
+        */
+       public function identifyOrphans() {
+               $sql = "SELECT          moderation_queue.queueID, moderation_queue.objectTypeID, moderation_queue.objectID
+                       FROM            wcf".WCF_N."_moderation_queue_to_user moderation_queue_to_user
+                       LEFT JOIN       wcf".WCF_N."_moderation_queue moderation_queue
+                       ON              (moderation_queue.queueID = moderation_queue_to_user.queueID)
+                       WHERE           moderation_queue_to_user.userID = ?
+                                       AND moderation_queue_to_user.isAffected = ?
+                                       AND moderation_queue.status <> ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute(array(
+                       WCF::getUser()->userID,
+                       1,
+                       ModerationQueue::STATUS_DONE
+               ));
+               
+               $queues = array();
+               while ($row = $statement->fetchArray()) {
+                       $objectTypeID = $row['objectTypeID'];
+                       if (!isset($queues[$objectTypeID])) {
+                               $queues[$objectTypeID] = array();
+                       }
+                       
+                       $queues[$objectTypeID][$row['queueID']] = $row['objectID'];
+               }
+               
+               if (!empty($queues)) {
+                       $queueIDs = array();
+                       foreach ($queues as $objectTypeID => $objectQueues) {
+                               $queueID = array_merge($queueIDs, $this->getProcessor($this->definitions[$this->objectTypes[$objectTypeID]->definitionID], null, $objectTypeID)->identifyOrphans());
+                       }
+                       
+                       $this->removeOrphans($queueIDs);
+               }
+       }
+       
        /**
         * Removes a list of orphaned queue ids.
         * 
index c1a61b68beb4063cdb9ecbb4917461732036af32..04f243dc62ec2bf155e391d903bd2c15c35b98d4 100644 (file)
@@ -23,6 +23,11 @@ use wcf\system\WCF;
  * @category   Community Framework
  */
 class CommentCommentModerationQueueReportHandler extends AbstractModerationQueueHandler implements IModerationQueueReportHandler {
+       /**
+        * @see wcf\system\moderation\queue\AbstractModerationQueueHandler::$className
+        */
+       protected $className = 'wcf\data\comment\Comment';
+       
        /**
         * @see wcf\system\moderation\queue\AbstractModerationQueueHandler::$definitionName
         */
index 81e6d624c5c3fa44e8b3842ebd965919ac6b8a0d..9450617ede6bc61ceeee2ab5154fe3fcbf55d7d0 100644 (file)
@@ -23,6 +23,11 @@ use wcf\system\WCF;
  * @category   Community Framework
  */
 class CommentResponseModerationQueueReportHandler extends CommentCommentModerationQueueReportHandler {
+       /**
+        * @see wcf\system\moderation\queue\AbstractModerationQueueHandler::$className
+        */
+       protected $className = 'wcf\data\comment\response\CommentResponse';
+       
        /**
         * @see wcf\system\moderation\queue\AbstractModerationQueueHandler::$objectType
         */