From: Tim Düsterhus Date: Tue, 22 Jul 2014 20:13:10 +0000 (+0200) Subject: Add bulkRevert() to EditHistoryManager X-Git-Tag: 2.1.0_Alpha_1~546 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=f86d7ff735ac0c1bb4dfe004fbb64ee25ce15068;p=GitHub%2FWoltLab%2FWCF.git Add bulkRevert() to EditHistoryManager --- diff --git a/wcfsetup/install/files/lib/system/cronjob/DailyCleanUpCronjob.class.php b/wcfsetup/install/files/lib/system/cronjob/DailyCleanUpCronjob.class.php index 2c6dbfc57b..7cf64836a7 100644 --- a/wcfsetup/install/files/lib/system/cronjob/DailyCleanUpCronjob.class.php +++ b/wcfsetup/install/files/lib/system/cronjob/DailyCleanUpCronjob.class.php @@ -128,7 +128,7 @@ class DailyCleanUpCronjob extends AbstractCronjob { // clean up expired edit history entries if (EDIT_HISTORY_EXPIRATION) { $sql = "DELETE FROM wcf".WCF_N."_edit_history_entry - WHERE insertionTime < ?"; + WHERE obsoletedAt < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array( (TIME_NOW - 86400 * EDIT_HISTORY_EXPIRATION) diff --git a/wcfsetup/install/files/lib/system/edit/EditHistoryManager.class.php b/wcfsetup/install/files/lib/system/edit/EditHistoryManager.class.php index b08d4a4cba..cbfb8a2926 100644 --- a/wcfsetup/install/files/lib/system/edit/EditHistoryManager.class.php +++ b/wcfsetup/install/files/lib/system/edit/EditHistoryManager.class.php @@ -1,5 +1,6 @@ prepareStatement($sql); - $statement->execute(array($this->getObjectTypeID($objectType), $objectID, $message, $time, TIME_NOW, $userID, $username, $editReason)); + $statement->execute(array($this->getObjectTypeID($objectType), $objectID, $message, $time, TIME_NOW, $userID, $username, $editReason, $obsoletedByUserID)); } /** @@ -83,4 +85,61 @@ class EditHistoryManager extends SingletonFactory { } WCF::getDB()->commitTransaction(); } + + /** + * Performs mass reverting of edits by the given users in the given timeframe. + * + * @param array $userIDs + * @param integer $timeframe + */ + public function bulkRevert(array $userIDs, $timeframe = 86400) { + if (empty($userIDs)) return; + + // 1: Select the newest edit history item for each object ("newestEntries") + // 2: Check whether the edit was made by the offending users ("vandalizedEntries") + // 3: Fetch the newest version that is either: + // a) older than $timeframe days + // b) by a non offending user + $userIDPlaceholders = '?'.str_repeat(',?', count($userIDs) - 1); + $sql = "SELECT MAX(entryID) + FROM wcf".WCF_N."_edit_history_entry revertTo + INNER JOIN( + SELECT vandalizedEntries.objectID, + vandalizedEntries.objectTypeID + FROM wcf".WCF_N."_edit_history_entry vandalizedEntries + INNER JOIN ( + SELECT MAX(newestEntries.entryID) AS entryID + FROM wcf".WCF_N."_edit_history_entry newestEntries + WHERE newestEntries.obsoletedAt > ? + GROUP BY newestEntries.objectTypeID, newestEntries.objectID + ) newestEntries2 + WHERE newestEntries2.entryID = vandalizedEntries.entryID + AND vandalizedEntries.obsoletedByUserID IN (".$userIDPlaceholders.") + ) AS vandalizedEntries2 + WHERE revertTo.objectID = vandalizedEntries2.objectID + AND revertTo.objectTypeID = vandalizedEntries2.objectTypeID + AND ( revertTo.obsoletedAt <= ? + OR revertTo.userID NOT IN(".$userIDPlaceholders.")) + GROUP BY revertTo.objectTypeID, revertTo.objectID"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute(array_merge( + array(TIME_NOW - $timeframe), + $userIDs, + array(TIME_NOW - $timeframe), + $userIDs + )); + + $entryIDs = array(); + while ($entryID = $statement->fetchColumn()) { + $entryIDs[] = $entryID; + } + if (empty($entryIDs)) return; + + $list = new EditHistoryEntryList(); + $list->getConditionBuilder()->add('entryID IN(?)', array($entryIDs)); + $list->readObjects(); + foreach ($list as $entry) { + $entry->getObject()->revertVersion($entry); + } + } } diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index b836a43d77..9e1bfc47ff 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -358,11 +358,13 @@ CREATE TABLE wcf1_edit_history_entry ( userID INT(10), username VARCHAR(255) NOT NULL DEFAULT '', time INT(10) NOT NULL DEFAULT 0, -- time the version was created, displayed to the user - insertionTime INT(10) NOT NULL DEFAULT 0, -- time the version was inserted into the edit history, used for clean up + obsoletedAt INT(10) NOT NULL DEFAULT 0, -- time the version was inserted into the edit history, used for clean up + obsoletedByUserID INT(10), message MEDIUMTEXT, editReason TEXT, - KEY (objectTypeID, objectID) + KEY (objectTypeID, objectID), + KEY (obsoletedAt, obsoletedByUserID) ); DROP TABLE IF EXISTS wcf1_event_listener; @@ -1482,6 +1484,7 @@ ALTER TABLE wcf1_cronjob_log ADD FOREIGN KEY (cronjobID) REFERENCES wcf1_cronjob ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE; ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL; +ALTER TABLE wcf1_edit_history_entry ADD FOREIGN KEY (obsoletedByUserID) REFERENCES wcf1_user (userID) ON DELETE SET NULL; ALTER TABLE wcf1_event_listener ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;