From: Matthias Schmidt Date: Sun, 23 Jun 2019 13:28:08 +0000 (+0200) Subject: Support creating multiple moderation queue entries at once X-Git-Tag: 5.2.0_Alpha_3~26^2~5 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=b0df4ce46720baf431c833537915af21bf015130;p=GitHub%2FWoltLab%2FWCF.git Support creating multiple moderation queue entries at once --- diff --git a/wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueManager.class.php b/wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueManager.class.php index fe2aaa673c..370c45fda7 100644 --- a/wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueManager.class.php +++ b/wcfsetup/install/files/lib/system/moderation/queue/AbstractModerationQueueManager.class.php @@ -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. * diff --git a/wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueActivationManager.class.php b/wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueActivationManager.class.php index eedc997825..fbab3271b8 100644 --- a/wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueActivationManager.class.php +++ b/wcfsetup/install/files/lib/system/moderation/queue/ModerationQueueActivationManager.class.php @@ -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. *