Moderation queue integration for comments/responses
authorAlexander Ebert <ebert@woltlab.com>
Thu, 9 Mar 2017 22:24:11 +0000 (23:24 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 9 Mar 2017 22:24:17 +0000 (23:24 +0100)
See #2219

wcfsetup/install/files/lib/data/comment/CommentAction.class.php
wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentCommentModerationQueueHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentResponseModerationQueueHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/moderation/queue/activation/CommentCommentModerationQueueActivationHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/moderation/queue/activation/CommentResponseModerationQueueActivationHandler.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/moderation/queue/report/CommentCommentModerationQueueReportHandler.class.php
wcfsetup/install/files/lib/system/moderation/queue/report/CommentResponseModerationQueueReportHandler.class.php

index ec1035590635ce91c18cee03699c51dcc4c8a7d1..e3766aca5d2a21420352183aa7c7e229a53e68c1 100644 (file)
@@ -18,6 +18,7 @@ use wcf\system\exception\SystemException;
 use wcf\system\exception\UserInputException;
 use wcf\system\html\input\HtmlInputProcessor;
 use wcf\system\like\LikeHandler;
+use wcf\system\moderation\queue\ModerationQueueActivationManager;
 use wcf\system\user\activity\event\UserActivityEventHandler;
 use wcf\system\user\notification\object\type\ICommentUserNotificationObjectType;
 use wcf\system\user\notification\object\type\IMultiRecipientCommentUserNotificationObjectType;
@@ -317,6 +318,10 @@ class CommentAction extends AbstractDatabaseObjectAction implements IMessageInli
                        ]);
                        $action->executeAction();
                }
+               else {
+                       // mark comment for moderated content
+                       ModerationQueueActivationManager::getInstance()->addModeratedContent('com.woltlab.wcf.comment.comment', $this->createdComment->commentID);
+               }
                
                if (!$this->createdComment->userID) {
                        // save user name is session
@@ -470,6 +475,10 @@ class CommentAction extends AbstractDatabaseObjectAction implements IMessageInli
                        ]);
                        $action->executeAction();
                }
+               else {
+                       // mark response for moderated content
+                       ModerationQueueActivationManager::getInstance()->addModeratedContent('com.woltlab.wcf.comment.response', $this->createdResponse->responseID);
+               }
                
                if (!$this->createdResponse->userID) {
                        // save user name is session
@@ -609,9 +618,12 @@ class CommentAction extends AbstractDatabaseObjectAction implements IMessageInli
        }
        
        public function enable() {
+               if ($this->comment === null) $this->comment = reset($this->objects);
+               
                if ($this->comment->isDisabled) {
                        $action = new CommentAction([$this->comment], 'triggerPublication', [
-                               'commentProcessor' => $this->commentProcessor
+                               'commentProcessor' => $this->commentProcessor,
+                               'objectTypeID' => $this->comment->objectTypeID
                        ]);
                        $action->executeAction();
                }
@@ -636,6 +648,9 @@ class CommentAction extends AbstractDatabaseObjectAction implements IMessageInli
        }
        
        public function enableResponse() {
+               if ($this->comment === null) $this->comment = reset($this->objects);
+               if ($this->response === null) $this->response = reset($this->parameters['responses']);
+               
                if ($this->response->isDisabled) {
                        $action = new CommentAction([], 'triggerPublicationResponse', [
                                'commentProcessor' => $this->commentProcessor,
diff --git a/wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentCommentModerationQueueHandler.class.php b/wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentCommentModerationQueueHandler.class.php
new file mode 100644 (file)
index 0000000..3493dfb
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+namespace wcf\system\moderation\queue;
+use wcf\data\comment\Comment;
+use wcf\data\comment\CommentAction;
+use wcf\data\comment\ViewableComment;
+use wcf\data\moderation\queue\ModerationQueue;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\cache\runtime\CommentRuntimeCache;
+use wcf\system\comment\manager\ICommentManager;
+use wcf\system\WCF;
+
+/**
+ * An abstract implementation of IModerationQueueHandler for comments.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Moderation\Queue
+ */
+class AbstractCommentCommentModerationQueueHandler extends AbstractModerationQueueHandler {
+       /**
+        * @inheritDoc
+        */
+       protected $className = Comment::class;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $objectType = 'com.woltlab.wcf.comment.comment';
+       
+       /**
+        * list of comment managers
+        * @var ICommentManager[]
+        */
+       protected static $commentManagers = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignQueues(array $queues) {
+               $assignments = [];
+               
+               // read comments
+               $commentIDs = [];
+               foreach ($queues as $queue) {
+                       $commentIDs[] = $queue->objectID;
+               }
+               
+               $comments = CommentRuntimeCache::getInstance()->getObjects($commentIDs);
+               
+               $orphanedQueueIDs = [];
+               foreach ($queues as $queue) {
+                       $assignUser = false;
+                       
+                       if ($comments[$queue->objectID] === null) {
+                               $orphanedQueueIDs[] = $queue->queueID;
+                               continue;
+                       }
+                       
+                       $comment = $comments[$queue->objectID];
+                       if ($this->getCommentManager($comment)->canModerate($comment->objectTypeID, $comment->objectID)) {
+                               $assignUser = true;
+                       }
+                       
+                       $assignments[$queue->queueID] = $assignUser;
+               }
+               
+               ModerationQueueManager::getInstance()->removeOrphans($orphanedQueueIDs);
+               ModerationQueueManager::getInstance()->setAssignment($assignments);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getContainerID($objectID) {
+               return 0;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isValid($objectID) {
+               if ($this->getComment($objectID) === null) {
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * Returns a comment object by comment id or null if comment id is invalid.
+        * 
+        * @param       integer         $objectID
+        * @return      Comment|null
+        */
+       protected function getComment($objectID) {
+               return CommentRuntimeCache::getInstance()->getObject($objectID);
+       }
+       
+       /**
+        * Returns a comment manager for given comment.
+        * 
+        * @param       Comment $comment
+        * @return      ICommentManager
+        */
+       protected function getCommentManager(Comment $comment) {
+               if (!isset(self::$commentManagers[$comment->objectTypeID])) {
+                       self::$commentManagers[$comment->objectTypeID] = ObjectTypeCache::getInstance()->getObjectType($comment->objectTypeID)->getProcessor();
+               }
+               
+               return self::$commentManagers[$comment->objectTypeID];
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function populate(array $queues) {
+               $objectIDs = [];
+               foreach ($queues as $object) {
+                       $objectIDs[] = $object->objectID;
+               }
+               
+               // fetch comments
+               $comments = CommentRuntimeCache::getInstance()->getObjects($objectIDs);
+               foreach ($queues as $object) {
+                       if ($comments[$object->objectID] !== null) {
+                               $object->setAffectedObject($comments[$object->objectID]);
+                       }
+                       else {
+                               $object->setIsOrphaned();
+                       }
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function removeContent(ModerationQueue $queue, $message) {
+               if ($this->isValid($queue->objectID)) {
+                       $commentAction = new CommentAction([$this->getComment($queue->objectID)], 'delete');
+                       $commentAction->executeAction();
+               }
+       }
+       
+       /**
+        * Returns the parsed template for the target comment.
+        * 
+        * @param       ViewableModerationQueue         $queue
+        * @return      string
+        */
+       protected function getRelatedContent(ViewableModerationQueue $queue) {
+               WCF::getTPL()->assign([
+                       'message' => ViewableComment::getComment($queue->objectID)
+               ]);
+               
+               return WCF::getTPL()->fetch('moderationComment');
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentResponseModerationQueueHandler.class.php b/wcfsetup/install/files/lib/system/moderation/queue/AbstractCommentResponseModerationQueueHandler.class.php
new file mode 100644 (file)
index 0000000..2f3aa31
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+namespace wcf\system\moderation\queue;
+use wcf\data\comment\response\CommentResponse;
+use wcf\data\comment\response\CommentResponseAction;
+use wcf\data\comment\response\ViewableCommentResponse;
+use wcf\data\comment\Comment;
+use wcf\data\moderation\queue\ModerationQueue;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\system\cache\runtime\CommentResponseRuntimeCache;
+use wcf\system\cache\runtime\CommentRuntimeCache;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\WCF;
+
+/**
+ * An implementation of IModerationQueueHandler for comment responses.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Moderation\Queue
+ */
+class AbstractCommentResponseModerationQueueHandler extends AbstractCommentCommentModerationQueueHandler {
+       /**
+        * @inheritDoc
+        */
+       protected $className = CommentResponse::class;
+       
+       /**
+        * @inheritDoc
+        */
+       protected $objectType = 'com.woltlab.wcf.comment.response';
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignQueues(array $queues) {
+               $assignments = [];
+               
+               // read comments and responses
+               $responseIDs = [];
+               foreach ($queues as $queue) {
+                       $responseIDs[] = $queue->objectID;
+               }
+               
+               $conditions = new PreparedStatementConditionBuilder();
+               $conditions->add("comment_response.responseID IN (?)", [$responseIDs]);
+               
+               $sql = "SELECT          comment_response.responseID, comment.commentID, comment.objectTypeID, comment.objectID
+                       FROM            wcf".WCF_N."_comment_response comment_response
+                       LEFT JOIN       wcf".WCF_N."_comment comment
+                       ON              (comment.commentID = comment_response.commentID)
+                       ".$conditions;
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute($conditions->getParameters());
+               $comments = $responses = [];
+               while ($row = $statement->fetchArray()) {
+                       $comments[$row['commentID']] = new Comment(null, $row);
+                       $responses[$row['responseID']] = new CommentResponse(null, $row);
+               }
+               
+               $orphanedQueueIDs = [];
+               foreach ($queues as $queue) {
+                       $assignUser = false;
+                       
+                       if (!isset($responses[$queue->objectID]) || !isset($comments[$responses[$queue->objectID]->commentID])) {
+                               $orphanedQueueIDs[] = $queue->queueID;
+                               continue;
+                       }
+                       
+                       $comment = $comments[$responses[$queue->objectID]->commentID];
+                       if ($this->getCommentManager($comment)->canModerate($comment->objectTypeID, $comment->objectID)) {
+                               $assignUser = true;
+                       }
+                       
+                       $assignments[$queue->queueID] = $assignUser;
+               }
+               
+               ModerationQueueManager::getInstance()->removeOrphans($orphanedQueueIDs);
+               ModerationQueueManager::getInstance()->setAssignment($assignments);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getRelatedContent(ViewableModerationQueue $queue) {
+               WCF::getTPL()->assign([
+                       'message' => ViewableCommentResponse::getResponse($queue->objectID)
+               ]);
+               
+               return WCF::getTPL()->fetch('moderationComment');
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function isValid($objectID) {
+               if ($this->getResponse($objectID) === null) {
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * Returns a comment response object by response id or null if response id is invalid.
+        *
+        * @param       integer         $objectID
+        * @return      CommentResponse|null
+        */
+       protected function getResponse($objectID) {
+               return CommentResponseRuntimeCache::getInstance()->getObject($objectID);
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function populate(array $queues) {
+               $objectIDs = [];
+               foreach ($queues as $object) {
+                       $objectIDs[] = $object->objectID;
+               }
+               
+               $responses = CommentResponseRuntimeCache::getInstance()->getObjects($objectIDs);
+               
+               $commentIDs = [];
+               foreach ($responses as $response) {
+                       if ($response !== null) {
+                               $commentIDs[] = $response->commentID;
+                       }
+               }
+               
+               $comments = [];
+               if (!empty($commentIDs)) {
+                       $comments = CommentRuntimeCache::getInstance()->getObjects($commentIDs);
+               }
+               
+               foreach ($queues as $object) {
+                       if ($responses[$object->objectID] !== null) {
+                               $response = $responses[$object->objectID];
+                               $response->setComment($comments[$response->commentID]);
+                               
+                               $object->setAffectedObject($response);
+                       }
+                       else {
+                               $object->setIsOrphaned();
+                       }
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function removeContent(ModerationQueue $queue, $message) {
+               if ($this->isValid($queue->objectID)) {
+                       $responseAction = new CommentResponseAction([$this->getResponse($queue->objectID)], 'delete');
+                       $responseAction->executeAction();
+               }
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/moderation/queue/activation/CommentCommentModerationQueueActivationHandler.class.php b/wcfsetup/install/files/lib/system/moderation/queue/activation/CommentCommentModerationQueueActivationHandler.class.php
new file mode 100644 (file)
index 0000000..e9238cb
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+namespace wcf\system\moderation\queue\activation;
+use wcf\data\comment\CommentAction;
+use wcf\data\moderation\queue\ModerationQueue;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\system\moderation\queue\AbstractCommentCommentModerationQueueHandler;
+
+/**
+ * An implementation of IModerationQueueActivationHandler for comments.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Moderation\Queue
+ */
+class CommentCommentModerationQueueActivationHandler extends AbstractCommentCommentModerationQueueHandler implements IModerationQueueActivationHandler {
+       /**
+        * @inheritDoc
+        */
+       protected $definitionName = 'com.woltlab.wcf.moderation.activation';
+       
+       /**
+        * @inheritDoc
+        */
+       public function enableContent(ModerationQueue $queue) {
+               if ($this->isValid($queue->objectID) && $this->getComment($queue->objectID)->isDisabled) {
+                       $commentAction = new CommentAction([$this->getComment($queue->objectID)], 'enable');
+                       $commentAction->executeAction();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getDisabledContent(ViewableModerationQueue $queue) {
+               return $this->getRelatedContent($queue);
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/moderation/queue/activation/CommentResponseModerationQueueActivationHandler.class.php b/wcfsetup/install/files/lib/system/moderation/queue/activation/CommentResponseModerationQueueActivationHandler.class.php
new file mode 100644 (file)
index 0000000..6997e13
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+namespace wcf\system\moderation\queue\activation;
+use wcf\data\comment\CommentAction;
+use wcf\data\moderation\queue\ModerationQueue;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\system\moderation\queue\AbstractCommentResponseModerationQueueHandler;
+
+/**
+ * An implementation of IModerationQueueReportHandler for comment responses.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core\System\Moderation\Queue
+ */
+class CommentResponseModerationQueueActivationHandler extends AbstractCommentResponseModerationQueueHandler implements IModerationQueueActivationHandler {
+       /**
+        * @inheritDoc
+        */
+       public function enableContent(ModerationQueue $queue) {
+               if ($this->isValid($queue->objectID) && $this->getResponse($queue->objectID)->isDisabled) {
+                       $response = $this->getResponse($queue->objectID);
+                       
+                       $commentAction = new CommentAction([$this->getComment($response->commentID)], 'enableResponse', [
+                               'responses' => [$response]
+                       ]);
+                       $commentAction->executeAction();
+               }
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function getDisabledContent(ViewableModerationQueue $queue) {
+               return $this->getRelatedContent($queue);
+       }
+}
index b9d72d2305b0628a9195607de563b858bb5c29c6..0cb42edf33ae123dc7ac46bf1d7286b14a0a914b 100644 (file)
@@ -1,16 +1,7 @@
 <?php
 namespace wcf\system\moderation\queue\report;
-use wcf\data\comment\Comment;
-use wcf\data\comment\CommentAction;
-use wcf\data\comment\ViewableComment;
-use wcf\data\moderation\queue\ModerationQueue;
 use wcf\data\moderation\queue\ViewableModerationQueue;
-use wcf\data\object\type\ObjectTypeCache;
-use wcf\system\cache\runtime\CommentRuntimeCache;
-use wcf\system\comment\manager\ICommentManager;
-use wcf\system\moderation\queue\AbstractModerationQueueHandler;
-use wcf\system\moderation\queue\ModerationQueueManager;
-use wcf\system\WCF;
+use wcf\system\moderation\queue\AbstractCommentCommentModerationQueueHandler;
 
 /**
  * An implementation of IModerationQueueReportHandler for comments.
@@ -20,63 +11,12 @@ use wcf\system\WCF;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Moderation\Queue
  */
-class CommentCommentModerationQueueReportHandler extends AbstractModerationQueueHandler implements IModerationQueueReportHandler {
-       /**
-        * @inheritDoc
-        */
-       protected $className = Comment::class;
-       
+class CommentCommentModerationQueueReportHandler extends AbstractCommentCommentModerationQueueHandler implements IModerationQueueReportHandler {
        /**
         * @inheritDoc
         */
        protected $definitionName = 'com.woltlab.wcf.moderation.report';
        
-       /**
-        * @inheritDoc
-        */
-       protected $objectType = 'com.woltlab.wcf.comment.comment';
-       
-       /**
-        * list of comment managers
-        * @var ICommentManager[]
-        */
-       protected static $commentManagers = [];
-       
-       /**
-        * @inheritDoc
-        */
-       public function assignQueues(array $queues) {
-               $assignments = [];
-               
-               // read comments
-               $commentIDs = [];
-               foreach ($queues as $queue) {
-                       $commentIDs[] = $queue->objectID;
-               }
-               
-               $comments = CommentRuntimeCache::getInstance()->getObjects($commentIDs);
-               
-               $orphanedQueueIDs = [];
-               foreach ($queues as $queue) {
-                       $assignUser = false;
-                       
-                       if ($comments[$queue->objectID] === null) {
-                               $orphanedQueueIDs[] = $queue->queueID;
-                               continue;
-                       }
-                       
-                       $comment = $comments[$queue->objectID];
-                       if ($this->getCommentManager($comment)->canModerate($comment->objectTypeID, $comment->objectID)) {
-                               $assignUser = true;
-                       }
-                       
-                       $assignments[$queue->queueID] = $assignUser;
-               }
-               
-               ModerationQueueManager::getInstance()->removeOrphans($orphanedQueueIDs);
-               ModerationQueueManager::getInstance()->setAssignment($assignments);
-       }
-       
        /**
         * @inheritDoc
         */
@@ -93,22 +33,11 @@ class CommentCommentModerationQueueReportHandler extends AbstractModerationQueue
                return true;
        }
        
-       /**
-        * @inheritDoc
-        */
-       public function getContainerID($objectID) {
-               return 0;
-       }
-       
        /**
         * @inheritDoc
         */
        public function getReportedContent(ViewableModerationQueue $queue) {
-               WCF::getTPL()->assign([
-                       'message' => ViewableComment::getComment($queue->objectID)
-               ]);
-               
-               return WCF::getTPL()->fetch('moderationComment');
+               return $this->getRelatedContent($queue);
        }
        
        /**
@@ -117,70 +46,4 @@ class CommentCommentModerationQueueReportHandler extends AbstractModerationQueue
        public function getReportedObject($objectID) {
                return $this->getComment($objectID);
        }
-       
-       /**
-        * @inheritDoc
-        */
-       public function isValid($objectID) {
-               if ($this->getComment($objectID) === null) {
-                       return false;
-               }
-               
-               return true;
-       }
-       
-       /**
-        * Returns a comment object by comment id or null if comment id is invalid.
-        * 
-        * @param       integer         $objectID
-        * @return      Comment|null
-        */
-       protected function getComment($objectID) {
-               return CommentRuntimeCache::getInstance()->getObject($objectID);
-       }
-       
-       /**
-        * Returns a comment manager for given comment.
-        * 
-        * @param       Comment $comment
-        * @return      ICommentManager
-        */
-       protected function getCommentManager(Comment $comment) {
-               if (!isset(self::$commentManagers[$comment->objectTypeID])) {
-                       self::$commentManagers[$comment->objectTypeID] = ObjectTypeCache::getInstance()->getObjectType($comment->objectTypeID)->getProcessor();
-               }
-               
-               return self::$commentManagers[$comment->objectTypeID];
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function populate(array $queues) {
-               $objectIDs = [];
-               foreach ($queues as $object) {
-                       $objectIDs[] = $object->objectID;
-               }
-               
-               // fetch comments
-               $comments = CommentRuntimeCache::getInstance()->getObjects($objectIDs);
-               foreach ($queues as $object) {
-                       if ($comments[$object->objectID] !== null) {
-                               $object->setAffectedObject($comments[$object->objectID]);
-                       }
-                       else {
-                               $object->setIsOrphaned();
-                       }
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function removeContent(ModerationQueue $queue, $message) {
-               if ($this->isValid($queue->objectID)) {
-                       $commentAction = new CommentAction([$this->getComment($queue->objectID)], 'delete');
-                       $commentAction->executeAction();
-               }
-       }
 }
index 861cebd97d192fb252805f8a65f24e925d0b211e..c3ac88b4d2c28198195f47fe84cb979f729de499 100644 (file)
@@ -1,16 +1,7 @@
 <?php
 namespace wcf\system\moderation\queue\report;
-use wcf\data\comment\response\CommentResponse;
-use wcf\data\comment\response\CommentResponseAction;
-use wcf\data\comment\response\ViewableCommentResponse;
-use wcf\data\comment\Comment;
-use wcf\data\moderation\queue\ModerationQueue;
 use wcf\data\moderation\queue\ViewableModerationQueue;
-use wcf\system\cache\runtime\CommentResponseRuntimeCache;
-use wcf\system\cache\runtime\CommentRuntimeCache;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\moderation\queue\ModerationQueueManager;
-use wcf\system\WCF;
+use wcf\system\moderation\queue\AbstractCommentResponseModerationQueueHandler;
 
 /**
  * An implementation of IModerationQueueReportHandler for comment responses.
@@ -20,66 +11,7 @@ use wcf\system\WCF;
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    WoltLabSuite\Core\System\Moderation\Queue
  */
-class CommentResponseModerationQueueReportHandler extends CommentCommentModerationQueueReportHandler {
-       /**
-        * @inheritDoc
-        */
-       protected $className = CommentResponse::class;
-       
-       /**
-        * @inheritDoc
-        */
-       protected $objectType = 'com.woltlab.wcf.comment.response';
-       
-       /**
-        * @inheritDoc
-        */
-       public function assignQueues(array $queues) {
-               $assignments = [];
-               
-               // read comments and responses
-               $responseIDs = [];
-               foreach ($queues as $queue) {
-                       $responseIDs[] = $queue->objectID;
-               }
-               
-               $conditions = new PreparedStatementConditionBuilder();
-               $conditions->add("comment_response.responseID IN (?)", [$responseIDs]);
-               
-               $sql = "SELECT          comment_response.responseID, comment.commentID, comment.objectTypeID, comment.objectID
-                       FROM            wcf".WCF_N."_comment_response comment_response
-                       LEFT JOIN       wcf".WCF_N."_comment comment
-                       ON              (comment.commentID = comment_response.commentID)
-                       ".$conditions;
-               $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute($conditions->getParameters());
-               $comments = $responses = [];
-               while ($row = $statement->fetchArray()) {
-                       $comments[$row['commentID']] = new Comment(null, $row);
-                       $responses[$row['responseID']] = new CommentResponse(null, $row);
-               }
-               
-               $orphanedQueueIDs = [];
-               foreach ($queues as $queue) {
-                       $assignUser = false;
-                       
-                       if (!isset($responses[$queue->objectID]) || !isset($comments[$responses[$queue->objectID]->commentID])) {
-                               $orphanedQueueIDs[] = $queue->queueID;
-                               continue;
-                       }
-                       
-                       $comment = $comments[$responses[$queue->objectID]->commentID];
-                       if ($this->getCommentManager($comment)->canModerate($comment->objectTypeID, $comment->objectID)) {
-                               $assignUser = true;
-                       }
-                       
-                       $assignments[$queue->queueID] = $assignUser;
-               }
-               
-               ModerationQueueManager::getInstance()->removeOrphans($orphanedQueueIDs);
-               ModerationQueueManager::getInstance()->setAssignment($assignments);
-       }
-       
+class CommentResponseModerationQueueReportHandler extends AbstractCommentResponseModerationQueueHandler implements IModerationQueueReportHandler {
        /**
         * @inheritDoc
         */
@@ -97,22 +29,11 @@ class CommentResponseModerationQueueReportHandler extends CommentCommentModerati
                return true;
        }
        
-       /**
-        * @inheritDoc
-        */
-       public function getContainerID($objectID) {
-               return 0;
-       }
-       
        /**
         * @inheritDoc
         */
        public function getReportedContent(ViewableModerationQueue $queue) {
-               WCF::getTPL()->assign([
-                       'message' => ViewableCommentResponse::getResponse($queue->objectID)
-               ]);
-               
-               return WCF::getTPL()->fetch('moderationComment');
+               return $this->getRelatedContent($queue);
        }
        
        /**
@@ -121,71 +42,4 @@ class CommentResponseModerationQueueReportHandler extends CommentCommentModerati
        public function getReportedObject($objectID) {
                return $this->getResponse($objectID);
        }
-       
-       /**
-        * @inheritDoc
-        */
-       public function isValid($objectID) {
-               if ($this->getResponse($objectID) === null) {
-                       return false;
-               }
-               
-               return true;
-       }
-       
-       /**
-        * Returns a comment response object by response id or null if response id is invalid.
-        * 
-        * @param       integer         $objectID
-        * @return      CommentResponse|null
-        */
-       protected function getResponse($objectID) {
-               return CommentResponseRuntimeCache::getInstance()->getObject($objectID);
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function populate(array $queues) {
-               $objectIDs = [];
-               foreach ($queues as $object) {
-                       $objectIDs[] = $object->objectID;
-               }
-               
-               $responses = CommentResponseRuntimeCache::getInstance()->getObjects($objectIDs);
-               
-               $commentIDs = [];
-               foreach ($responses as $response) {
-                       if ($response !== null) {
-                               $commentIDs[] = $response->commentID;
-                       }
-               }
-               
-               $comments = [];
-               if (!empty($commentIDs)) {
-                       $comments = CommentRuntimeCache::getInstance()->getObjects($commentIDs);
-               }
-               
-               foreach ($queues as $object) {
-                       if ($responses[$object->objectID] !== null) {
-                               $response = $responses[$object->objectID];
-                               $response->setComment($comments[$response->commentID]);
-                               
-                               $object->setAffectedObject($response);
-                       }
-                       else {
-                               $object->setIsOrphaned();
-                       }
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function removeContent(ModerationQueue $queue, $message) {
-               if ($this->isValid($queue->objectID)) {
-                       $responseAction = new CommentResponseAction([$this->getResponse($queue->objectID)], 'delete');
-                       $responseAction->executeAction();
-               }
-       }
 }