Support creating multiple moderation queue entries at once
authorMatthias Schmidt <gravatronics@live.com>
Sun, 23 Jun 2019 13:28:08 +0000 (15:28 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 23 Jun 2019 13:28:08 +0000 (15:28 +0200)
wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueManager.class.php
wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueActivationManager.class.php

index fe2aaa673ca56e03dce8ba4add1d8d68532ba7b8..370c45fda7b62e4800dbb510745cc04b4e74a931 100644 (file)
@@ -3,6 +3,7 @@ namespace wcf\system\moderation\queue;
 use wcf\data\moderation\queue\ModerationQueue;
 use wcf\data\moderation\queue\ModerationQueueAction;
 use wcf\data\moderation\queue\ModerationQueueList;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 
@@ -119,6 +120,112 @@ abstract class AbstractModerationQueueManager extends SingletonFactory implement
                ModerationQueueManager::getInstance()->resetModerationCount();
        }
        
+       /**
+        * Adds multiple entries to moderation queue at once.
+        *
+        * In contrast to `addModeratedContent()`, this method expects the container ids to be
+        * passed as a parameter. If no container id is given for a specific object id, `0` is
+        * used as container id.
+        *
+        * This method is intended for bulk processing.
+        * 
+        * @param       integer         $objectTypeID
+        * @param       integer[]       $objectIDs
+        * @param       integer[]       $containerIDs           format: `objectID => containerID`
+        * @param       array           $additionalData
+        */
+       protected function addEntries($objectTypeID, array $objectIDs, array $containerIDs, array $additionalData = []) {
+               $conditionBuilder = new PreparedStatementConditionBuilder();
+               $conditionBuilder->add('objectTypeID = ?', [$objectTypeID]);
+               $conditionBuilder->add('objectID IN (?)', [$objectIDs]);
+               
+               $sql = "SELECT  queueID, objectID
+                       FROM    wcf".WCF_N."_moderation_queue
+                       " . $conditionBuilder;
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute($conditionBuilder->getParameters());
+               $existingQueueIDs = $statement->fetchMap('objectID', 'queueID');
+               
+               // create new moderation queue entries for new objects
+               $newObjectIDs = array_diff($objectIDs, array_keys($existingQueueIDs));
+               
+               $itemsPerLoop = 1000;
+               $batchCount = ceil(count($newObjectIDs) / $itemsPerLoop);
+               $userID = WCF::getUser()->userID ?: null;
+               $serializedData = serialize($additionalData);
+               
+               WCF::getDB()->beginTransaction();
+               for ($i = 0; $i < $batchCount; $i++) {
+                       $batchObjectIDs = array_slice($newObjectIDs, $i * $itemsPerLoop, $itemsPerLoop);
+                       
+                       $parameters = [];
+                       foreach ($batchObjectIDs as $objectID) {
+                               $parameters = array_merge($parameters, [
+                                       $objectTypeID,
+                                       $objectID,
+                                       $containerIDs[$objectID] ?? 0,
+                                       $userID,
+                                       TIME_NOW,
+                                       TIME_NOW,
+                                       $serializedData
+                               ]);
+                       }
+                       
+                       $sql = "INSERT INTO     wcf" . WCF_N . "_moderation_queue
+                                               (objectTypeID, objectID, containerID, userID, time, lastChangeTime, additionalData)
+                               VALUES          (?, ?, ?, ?, ?, ?, ?)" . str_repeat(', (?, ?, ?, ?, ?, ?, ?)', count($batchObjectIDs) - 1);
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute($parameters);
+               }
+               WCF::getDB()->commitTransaction();
+               
+               // update existing moderation queue entries
+               
+               // group queue ids by container id
+               $groupedQueueIDs = [];
+               foreach ($existingQueueIDs as $objectID => $queueID) {
+                       $containerID = $containerIDs[$objectID] ?? 0;
+                       
+                       if (!isset($groupedQueueIDs[$containerID])) {
+                               $groupedQueueIDs[$containerID] = [];
+                       }
+                       $groupedQueueIDs[$containerID][] = $queueID;
+               }
+               
+               WCF::getDB()->beginTransaction();
+               foreach ($groupedQueueIDs as $containerID => $queueIDs) {
+                       $batchCount = ceil(count($queueIDs) / $itemsPerLoop);
+                       
+                       for ($i = 0; $i < $batchCount; $i++) {
+                               $batchQueueIDs = array_slice($queueIDs, $i * $itemsPerLoop, $itemsPerLoop);
+                               
+                               $sql = "UPDATE  wcf" . WCF_N . "_moderation_queue
+                                       SET     status = ?,
+                                               containerID = ?,
+                                               userID = ?,
+                                               time = ?,
+                                               lastChangeTime = ?,
+                                               additionalData = ?
+                                       WHERE   queueID IN (?" . str_repeat(', ?', count($batchQueueIDs) - 1) . ")";
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               $statement->execute(array_merge(
+                                       [
+                                               ModerationQueue::STATUS_OUTSTANDING,
+                                               $containerID,
+                                               $userID,
+                                               TIME_NOW,
+                                               TIME_NOW,
+                                               $serializedData
+                                       ],
+                                       $batchQueueIDs
+                               ));
+                       }
+               }
+               WCF::getDB()->commitTransaction();
+               
+               ModerationQueueManager::getInstance()->resetModerationCount();
+       }
+       
        /**
         * Marks a list of moderation queue entries as done.
         * 
index eedc997825c4b8f898932ae40be974d54847f2ca..fbab3271b8c63815d4fe3cfc707e497b217d9a92 100644 (file)
@@ -66,6 +66,34 @@ class ModerationQueueActivationManager extends AbstractModerationQueueManager {
                );
        }
        
+       /**
+        * Adds multiple entries for moderated content at once.
+        * 
+        * In contrast to `addModeratedContent()`, this method expects the container ids to be
+        * passed as a parameter. If no container id is given for a specific object id, `0` is
+        * used as container id.
+        * 
+        * This method is intended for bulk processing.
+        * 
+        * @param       string          $objectType
+        * @param       integer[]       $objectID
+        * @poram       integer[]       $containerIDs           format: `objectID => containerID`
+        * @param       array           $additionalData
+        * @throws      InvalidObjectTypeException
+        */
+       public function addModeratedContents($objectType, array $objectIDs, array $containerIDs, array $additionalData = []) {
+               if (!$this->isValid($objectType)) {
+                       throw new InvalidObjectTypeException($objectType, 'com.woltlab.wcf.moderation.activation');
+               }
+               
+               $this->addEntries(
+                       $this->getObjectTypeID($objectType),
+                       $objectIDs,
+                       $containerIDs,
+                       $additionalData
+               );
+       } 
+       
        /**
         * Marks entries from moderation queue as done.
         *