Add bulk reverting frontend
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 22 Jul 2014 23:48:46 +0000 (01:48 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 22 Jul 2014 23:52:30 +0000 (01:52 +0200)
com.woltlab.wcf/clipboardAction.xml
com.woltlab.wcf/userGroupOption.xml
wcfsetup/install/files/acp/templates/userContentRevertChanges.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/acp/form/UserContentRevertChangesForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/user/UserContentAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/clipboard/action/UserContentClipboardAction.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index f8970230842580b406061500b6a7d6587bc71d90..57ccaa70bcc4d3135ba6e74c84cbeebccb5c9eeb 100644 (file)
                                <page><![CDATA[wcf\acp\page\UserListPage]]></page>
                        </pages>
                </action>
+               
+               <action name="revertContentChanges">
+                       <actionclassname><![CDATA[wcf\system\clipboard\action\UserContentClipboardAction]]></actionclassname>
+                       <showorder>9</showorder>
+                       <pages>
+                               <page><![CDATA[wcf\acp\page\UserListPage]]></page>
+                       </pages>
+               </action>
        </import>
 </data>
index 1141a04be6b4185cda14d2a052f2d27469e834c3..944c3525a4baeec139685ed65ca23cb7a836f674 100644 (file)
@@ -695,6 +695,14 @@ png]]></defaultvalue>
                        </option>
                        <!-- /user.profileComment -->
                        
+                       <option name="admin.content.canBulkRevertContentChanges">
+                               <categoryname>admin.content</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>0</defaultvalue>
+                               <admindefaultvalue>1</admindefaultvalue>
+                               <usersonly>1</usersonly>
+                       </option>
+                       
                        <option name="admin.content.label.canManageLabel">
                                <categoryname>admin.content.label</categoryname>
                                <optiontype>boolean</optiontype>
diff --git a/wcfsetup/install/files/acp/templates/userContentRevertChanges.tpl b/wcfsetup/install/files/acp/templates/userContentRevertChanges.tpl
new file mode 100644 (file)
index 0000000..5a6cfa6
--- /dev/null
@@ -0,0 +1,62 @@
+{include file='header' pageTitle='wcf.acp.user.revertChanges'}
+
+<header class="boxHeadline">
+       <h1>{lang}wcf.acp.user.revertChanges{/lang}</h1>
+</header>
+
+{include file='formError'}
+
+<div class="contentNavigation">
+       {hascontent}
+               <nav>
+                       <ul>
+                               {content}
+                                       {event name='contentNavigationButtons'}
+                               {/content}
+                       </ul>
+               </nav>
+       {/hascontent}
+</div>
+
+<form method="post" action="{link controller='UserContentRevertChanges'}{/link}">
+       <div class="container containerPadding marginTop">
+               <fieldset>
+                       <legend>{lang}wcf.acp.user.revertChanges.markedUsers{/lang}</legend>
+                       
+                       <div>
+                               {implode from=$users item='user'}<a href="{link controller='UserEdit' id=$user->userID}{/link}">{$user}</a>{/implode}
+                       </div>
+                       
+                       {event name='markedUserFields'}
+               </fieldset>
+               
+               <fieldset>
+                       <legend>{lang}wcf.acp.user.revertChanges.timeframe{/lang}</legend>
+                       
+                       <dl{if $errorField == 'timeframe'} class="formError"{/if}>
+                               <dt><label for="timeframe">{lang}wcf.acp.user.revertChanges.timeframe{/lang}</label></dt>
+                               <dd>
+                                       <input name="timeframe" type="number" min="0" value="{$timeframe}" />
+                                       
+                                       {if $errorField == 'timeframe'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}{lang}wcf.global.form.error.empty{/lang}{/if}
+                                               </small>
+                                       {/if}
+                                       <small>{lang}wcf.acp.user.revertChanges.timeframe.description{/lang}</small>
+                               <dd>
+                       </dl>
+                       
+                       {event name='mergeFields'}
+               </fieldset>
+               
+               {event name='fieldsets'}
+       </div>
+       
+       <div class="formSubmit">
+               <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
+               {@SECURITY_TOKEN_INPUT_TAG}
+       </div>
+</form>
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/lib/acp/form/UserContentRevertChangesForm.class.php b/wcfsetup/install/files/lib/acp/form/UserContentRevertChangesForm.class.php
new file mode 100644 (file)
index 0000000..1415ad1
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\form\AbstractForm;
+use wcf\system\clipboard\ClipboardHandler;
+use wcf\system\edit\EditHistoryManager;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+
+/**
+ * Shows the user content revert changes form.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2014 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage acp.form
+ * @category   Community Framework
+ */
+class UserContentRevertChangesForm extends AbstractForm {
+       /**
+        * @see \wcf\page\AbstractPage::$neededPermissions
+        */
+       public $neededPermissions = array('admin.content.canBulkRevertContentChanges');
+       
+       /**
+        * @see \wcf\page\AbstractPage::$activeMenuItem
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.user.management';
+       
+       /**
+        * ids of the relevant users
+        * @var array<integer>
+        */
+       public $userIDs = array();
+       
+       /**
+        * relevant users
+        * @var array<\wcf\data\user\User>
+        */
+       public $users = array();
+       
+       /**
+        * timeframe to consider
+        * @var integer
+        */
+       public $timeframe = 7;
+       
+       /**
+        * id of the user clipboard item object type
+        * @var integer
+        */
+       protected $objectTypeID = null;
+       
+       /**
+        * @see \wcf\page\IPage::readParameters()
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               // get object type id
+               $this->objectTypeID = ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.user');
+               // get user
+               $this->users = ClipboardHandler::getInstance()->getMarkedItems($this->objectTypeID);
+               if (empty($this->users)) {
+                       throw new IllegalLinkException();
+               }
+               $this->userIDs = array_keys($this->users);
+       }
+       
+       /**
+        * @see \wcf\form\IForm::readFormParameters()
+        */
+       public function readFormParameters() {
+               parent::readFormParameters();
+               
+               if (isset($_POST['timeframe'])) $this->timeframe = intval($_POST['timeframe']);
+       }
+       
+       /**
+        * @see \wcf\form\IForm::validate()
+        */
+       public function validate() {
+               parent::validate();
+               
+               if ($this->timeframe < 1) {
+                       throw new UserInputException('timeframe');
+               }
+       }
+       
+       /**
+        * @see \wcf\form\IForm::save()
+        */
+       public function save() {
+               parent::save();
+               
+               EditHistoryManager::getInstance()->bulkRevert($this->userIDs, $this->timeframe * 86400);
+               
+               // reset clipboard
+               ClipboardHandler::getInstance()->removeItems($this->objectTypeID);
+               $this->saved();
+               
+               // show success message
+               WCF::getTPL()->assign('message', 'wcf.global.success');
+               WCF::getTPL()->display('success');
+               exit;
+       }
+       
+       /**
+        * @see \wcf\page\IPage::assignVariables()
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign(array(
+                       'users' => $this->users,
+                       'userIDs' => $this->userIDs,
+                       'timeframe' => $this->timeframe
+               ));
+       }
+}
diff --git a/wcfsetup/install/files/lib/data/user/UserContentAction.class.php b/wcfsetup/install/files/lib/data/user/UserContentAction.class.php
new file mode 100644 (file)
index 0000000..83d121c
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+namespace wcf\data\user;
+use wcf\system\edit\EditHistoryManager;
+use wcf\system\WCF;
+
+/**
+ * Executes actions on user generated content.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2014 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.user
+ * @category   Community Framework
+ */
+class UserContentAction extends UserAction {
+       /**
+        * Checks permissions to bulk revert.
+        */
+       public function validateBulkRevert() {
+               WCF::getSession()->checkPermissions('admin.content.canBulkRevertContentChanges');
+       }
+       
+       /**
+        * Bulk reverts changes made to history saving objects.
+        */
+       public function bulkRevert() {
+               $this->readInteger('timeframe', true);
+               if (!$this->parameters['timeframe']) {
+                       $this->parameters['timeframe'] = 86400 * 7;
+               }
+               
+               EditHistoryManager::getInstance()->bulkRevert($this->objectIDs, $this->parameters['timeframe']);
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/clipboard/action/UserContentClipboardAction.class.php b/wcfsetup/install/files/lib/system/clipboard/action/UserContentClipboardAction.class.php
new file mode 100644 (file)
index 0000000..e43337b
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+namespace wcf\system\clipboard\action;
+use wcf\data\clipboard\action\ClipboardAction;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+
+/**
+ * Prepares clipboard editor items for edit history entries.
+ * 
+ * @author     Tim Duesterhus
+ * @copyright  2001-2014 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.clipboard.action
+ * @category   Community Framework
+ */
+class UserContentClipboardAction extends AbstractClipboardAction {
+       /**
+        * @see \wcf\system\clipboard\action\AbstractClipboardAction::$supportedActions
+        */
+       protected $supportedActions = array('revertContentChanges');
+       
+       /**
+        * @see \wcf\system\clipboard\action\IClipboardAction::execute()
+        */
+       public function execute(array $objects, ClipboardAction $action) {
+               $item = parent::execute($objects, $action);
+               
+               if ($item === null) {
+                       return null;
+               }
+               
+               // handle actions
+               switch ($action->actionName) {
+                       case 'revertContentChanges':
+                               $item->setURL(LinkHandler::getInstance()->getLink('UserContentRevertChanges'));
+                       break;
+               }
+               
+               return $item;
+       }
+       
+       /**
+        * @see \wcf\system\clipboard\action\IClipboardAction::getClassName()
+        */
+       public function getClassName() {
+               return 'wcf\data\user\UserContentAction';
+       }
+       
+       /**
+        * @see \wcf\system\clipboard\action\IClipboardAction::getTypeName()
+        */
+       public function getTypeName() {
+               return 'com.woltlab.wcf.user';
+       }
+       
+       /**
+        * Returns the ids of the users which can be enabled.
+        * 
+        * @return      array<integer>
+        */
+       protected function validateRevertChanges() {
+               // check permissions
+               if (!WCF::getSession()->getPermission('admin.content.canBulkRevertContentChanges')) {
+                       return array();
+               }
+               
+               $userIDs = array();
+               foreach ($this->objects as $user) {
+                       $userIDs[] = $user->userID;
+               }
+               
+               return $userIDs;
+       }
+}
index d0cec65f59711c00e0dbf73b149577c2bc18fe1f..117262b889aabe056983ea59db57815c09bc9ace 100644 (file)
                <item name="wcf.acp.group.option.admin.template.canManageTemplate"><![CDATA[Kann Templates verwalten]]></item>
                <item name="wcf.acp.group.option.admin.style.canManageStyle"><![CDATA[Kann Stile verwalten]]></item>
                <item name="wcf.acp.group.option.category.admin.content"><![CDATA[Inhalte]]></item>
+               <item name="wcf.acp.group.option.admin.content.canBulkRevertContentChanges"><![CDATA[Kann Änderungen der letzten Tage zurücksetzen]]></item>
                <item name="wcf.acp.group.option.category.admin.community"><![CDATA[Community]]></item>
                <item name="wcf.acp.group.option.category.mod.general"><![CDATA[Allgemeine Rechte]]></item>
                <item name="wcf.acp.group.option.category.admin.user.option"><![CDATA[Benutzerprofilfelder]]></item>
@@ -1479,6 +1480,10 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.user.merge.destination"><![CDATA[Ziel]]></item>
                <item name="wcf.acp.user.merge.destination.description"><![CDATA[Die ausgewählten Benutzer werden in dieses Benutzerkonto zusammengefügt.]]></item>
                <item name="wcf.acp.user.merge.markedUsers"><![CDATA[Folgende Benutzer zusammenfügen]]></item>
+               <item name="wcf.acp.user.revertChanges"><![CDATA[Änderungen an Inhalten zurücksetzen]]></item>
+               <item name="wcf.acp.user.revertChanges.timeframe"><![CDATA[Zeitraum]]></item>
+               <item name="wcf.acp.user.revertChanges.timeframe.description"><![CDATA[Zeitraum in dem Änderungen des Benutzers zurückgesetzt werden sollen. Inhalte werden auf die neuste Version, welche entweder älter als der angebene Zeitraum ist oder welche von einem anderen Nutzer stammt, zurückgesetzt. [Zeitraum in Tagen]]]></item>
+               <item name="wcf.acp.user.revertChanges.markedUsers"><![CDATA[Änderungen folgender Nutzer zurücksetzen]]></item>
                <item name="wcf.acp.user.bulkProcessing"><![CDATA[Benutzer-Massenbearbeitung]]></item>
                <item name="wcf.acp.user.bulkProcessing.action"><![CDATA[Aktion]]></item>
                <item name="wcf.acp.user.bulkProcessing.conditions"><![CDATA[Bedingungen]]></item>
@@ -1754,6 +1759,7 @@ Fehler sind beispielsweise:
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[Wollen Sie wirklich {if $count == 1}einem{else}{#$count}{/if} Benutzer ein neues Kennwort zusenden?]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{if $count == 1}Ein{else}{#$count}{/if} Benutzer markiert]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.merge"><![CDATA[Zusammenfügen]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.revertContentChanges"><![CDATA[Änderungen an Inhalten zurücksetzen]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.enable"><![CDATA[Aktivieren]]></item>
        </category>
        
index 3bc33251e821dfa04c3f8ef42fd45949ed4f3a1e..a8d5dfbe73bd941847a94ea75ea4fbce65ef308d 100644 (file)
@@ -329,6 +329,7 @@ Examples for medium ID detection:
                <item name="wcf.acp.group.option.admin.template.canManageTemplate"><![CDATA[Can manage templates]]></item>
                <item name="wcf.acp.group.option.admin.style.canManageStyle"><![CDATA[Can manage styles]]></item>
                <item name="wcf.acp.group.option.category.admin.content"><![CDATA[Content]]></item>
+               <item name="wcf.acp.group.option.admin.content.canBulkRevertContentChanges"><![CDATA[Can bulk revert content changes]]></item>
                <item name="wcf.acp.group.option.category.admin.community"><![CDATA[Community]]></item>
                <item name="wcf.acp.group.option.category.mod.general"><![CDATA[General]]></item>
                <item name="wcf.acp.group.option.category.admin.user.option"><![CDATA[User Profile Fields]]></item>
@@ -1447,6 +1448,10 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
                <item name="wcf.acp.user.merge.destination"><![CDATA[Destination]]></item>
                <item name="wcf.acp.user.merge.destination.description"><![CDATA[The selected users will be merged into this user account.]]></item>
                <item name="wcf.acp.user.merge.markedUsers"><![CDATA[Merge the following users]]></item>
+               <item name="wcf.acp.user.revertChanges"><![CDATA[Revert Changes To Contents]]></item>
+               <item name="wcf.acp.user.revertChanges.timeframe"><![CDATA[Timeframe]]></item>
+               <item name="wcf.acp.user.revertChanges.timeframe.description"><![CDATA[Changes made in this timeframe will be reverted to the newest version that is either older than the given timeframe or made by an unrelated user [time in days]]]></item>
+               <item name="wcf.acp.user.revertChanges.markedUsers"><![CDATA[Revert changes by the following users]]></item>
                <item name="wcf.acp.user.bulkProcessing"><![CDATA[Bulk Processing]]></item>
                <item name="wcf.acp.user.bulkProcessing.action"><![CDATA[Actions]]></item>
                <item name="wcf.acp.user.bulkProcessing.conditions"><![CDATA[Conditions]]></item>
@@ -1721,6 +1726,7 @@ Errors are:
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.sendNewPassword.confirmMessage"><![CDATA[Do you really want to send a new password to {#$count} user{if $count != 1}s{/if}?]]></item>
                <item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{#$count} User{if $count != 1}s{/if} marked]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.merge"><![CDATA[Merge]]></item>
+               <item name="wcf.clipboard.item.com.woltlab.wcf.user.revertContentChanges"><![CDATA[Revert Changes To Contents]]></item>
                <item name="wcf.clipboard.item.com.woltlab.wcf.user.enable"><![CDATA[Approve]]></item>
        </category>