From afb4e9a350a4ac2106d7c2d25f572c097f76d57e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Joshua=20R=C3=BCsweg?= Date: Sun, 11 Nov 2018 14:48:56 +0100 Subject: [PATCH] Add ContentRemoveWorker See #2716 --- com.woltlab.wcf/objectTypeDefinition.xml | 5 + .../install/files/acp/templates/userList.tpl | 5 +- .../WoltLabSuite/Core/Acp/Ui/User/Editor.js | 26 ++- ...tractDatabaseUserContentProvider.class.php | 79 +++++++++ .../provider/IUserContentProvider.class.php | 30 ++++ .../worker/UserContentRemoveWorker.class.php | 154 ++++++++++++++++++ wcfsetup/install/lang/de.xml | 2 + wcfsetup/install/lang/en.xml | 2 + 8 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/user/content/provider/AbstractDatabaseUserContentProvider.class.php create mode 100644 wcfsetup/install/files/lib/system/user/content/provider/IUserContentProvider.class.php create mode 100644 wcfsetup/install/files/lib/system/worker/UserContentRemoveWorker.class.php diff --git a/com.woltlab.wcf/objectTypeDefinition.xml b/com.woltlab.wcf/objectTypeDefinition.xml index 9aa044d7e1..d0f8fcfd8d 100644 --- a/com.woltlab.wcf/objectTypeDefinition.xml +++ b/com.woltlab.wcf/objectTypeDefinition.xml @@ -242,6 +242,11 @@ com.woltlab.wcf.article.discussionProvider wcf\system\article\discussion\IArticleDiscussionProvider + + + com.woltlab.wcf.content.userContentProvider + wcf\system\user\content\provider\IUserContentProvider + diff --git a/wcfsetup/install/files/acp/templates/userList.tpl b/wcfsetup/install/files/acp/templates/userList.tpl index 951db8110d..33827fcc3e 100644 --- a/wcfsetup/install/files/acp/templates/userList.tpl +++ b/wcfsetup/install/files/acp/templates/userList.tpl @@ -30,7 +30,9 @@ 'wcf.acp.user.ban.expires.description': '{lang}wcf.acp.user.ban.expires.description{/lang}', 'wcf.acp.user.ban.neverExpires': '{lang}wcf.acp.user.ban.neverExpires{/lang}', 'wcf.acp.user.sendNewPassword.workerTitle': '{lang}wcf.acp.user.sendNewPassword.workerTitle{/lang}', - 'wcf.acp.worker.abort.confirmMessage': '{lang}wcf.acp.worker.abort.confirmMessage{/lang}' + 'wcf.acp.worker.abort.confirmMessage': '{lang}wcf.acp.worker.abort.confirmMessage{/lang}', + 'wcf.acp.user.content.removeContent': '{lang}wcf.acp.user.content.removeContent{/lang}', + 'wcf.acp.user.content.removeContent.confirmMessage': '{lang}wcf.acp.user.content.removeContent.confirmMessage{/lang}', }); WCF.ACP.User.BanHandler.init(); @@ -130,6 +132,7 @@ {if $user->deletable}
  • {lang}wcf.global.button.delete{/lang}
  • +
  • {lang}wcf.acp.user.content.removeContent{/lang}
  • {/if} {if $user->editable} diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/User/Editor.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/User/Editor.js index 6eee1991f4..c3229058a1 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/User/Editor.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/User/Editor.js @@ -7,7 +7,7 @@ * @module WoltLabSuite/Core/Acp/Ui/User/Editor * @since 3.1 */ -define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/SimpleDropdown'], function(Ajax, Core, EventHandler, Language, UiSimpleDropdown) { +define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/SimpleDropdown', 'WoltLabSuite/Core/Acp/Ui/Worker', 'Ui/Confirmation'], function(Ajax, Core, EventHandler, Language, UiSimpleDropdown, Worker, Confirmation) { "use strict"; /** @@ -68,6 +68,30 @@ define(['Ajax', 'Core', 'EventHandler', 'Language', 'Ui/SimpleDropdown'], functi }); }); } + + var deleteContent = elBySel('.jsDeleteContent', dropdownMenu); + if (deleteContent !== null) { + deleteContent.addEventListener(WCF_CLICK_EVENT, function (event) { + event.preventDefault(); + + Confirmation.show({ + confirm: function () { + new Worker({ + // dialog + dialogId: 'deleteContentWorker', + dialogTitle: Language.get('wcf.acp.user.content.removeContent'), + + // ajax + className: '\\wcf\\system\\worker\\UserContentRemoveWorker', + parameters: { + userID: userId + } + }); + }, + message: Language.get('wcf.acp.user.content.removeContent.confirmMessage') + }); + }); + } }, /** diff --git a/wcfsetup/install/files/lib/system/user/content/provider/AbstractDatabaseUserContentProvider.class.php b/wcfsetup/install/files/lib/system/user/content/provider/AbstractDatabaseUserContentProvider.class.php new file mode 100644 index 0000000000..5a9023af65 --- /dev/null +++ b/wcfsetup/install/files/lib/system/user/content/provider/AbstractDatabaseUserContentProvider.class.php @@ -0,0 +1,79 @@ + + * @package WoltLabSuite\Core\System\User\Content\Provider + * @since 3.2 + */ +abstract class AbstractDatabaseUserContentProvider implements IUserContentProvider { + /** + * Returns the database object class for the object. + * + * @return string + */ + abstract public static function getDatabaseObjectClass(); + + /** + * Returns the database object list class for the object. + * + * @return string + */ + public static function getDatabaseObjectListClass() { + return static::getDatabaseObjectClass() . 'List'; + } + + /** + * Returns the database object action class for the object. + * + * @return string + */ + public static function getDatabaseObjectActionClass() { + return static::getDatabaseObjectClass() . 'Action'; + } + + /** + * @inheritDoc + */ + public function getContentListForUser(User $user) { + if ($user->userID == 0) { + throw new \RuntimeException('Removing content for guests is not allowed.'); + } + + $className = static::getDatabaseObjectListClass(); + + if (!is_subclass_of($className, DatabaseObjectList::class)) { + throw new ImplementationException($className, DatabaseObjectList::class); + } + + /** @var DatabaseObjectList $databaseObjectList */ + $databaseObjectList = new $className; + $tableAlias = call_user_func([static::getDatabaseObjectClass(), 'getDatabaseTableAlias']); + $databaseObjectList->getConditionBuilder()->add($tableAlias . '.userID = ?', [$user->userID]); + + return $databaseObjectList; + } + + /** + * @inheritDoc + */ + public function deleteContent(array $objectIDs) { + $className = self::getDatabaseObjectActionClass(); + + if (!is_subclass_of($className, AbstractDatabaseObjectAction::class)) { + throw new ImplementationException($className, AbstractDatabaseObjectAction::class); + } + + /** @var AbstractDatabaseObjectAction $objectAction */ + $objectAction = new $className($objectIDs, 'delete'); + $objectAction->executeAction(); + } +} diff --git a/wcfsetup/install/files/lib/system/user/content/provider/IUserContentProvider.class.php b/wcfsetup/install/files/lib/system/user/content/provider/IUserContentProvider.class.php new file mode 100644 index 0000000000..1d9fdad3cf --- /dev/null +++ b/wcfsetup/install/files/lib/system/user/content/provider/IUserContentProvider.class.php @@ -0,0 +1,30 @@ + + * @package WoltLabSuite\Core\System\User\Content\Provider + * @since 3.2 + */ +interface IUserContentProvider { + /** + * Returns a DatabaseObjectList with all user content objects. + * + * @param User $user + * @return DatabaseObjectList + */ + public function getContentListForUser(User $user); + + /** + * Delete the content for the given object ids. + * + * @param int[] $objectIDs + */ + public function deleteContent(array $objectIDs); +} diff --git a/wcfsetup/install/files/lib/system/worker/UserContentRemoveWorker.class.php b/wcfsetup/install/files/lib/system/worker/UserContentRemoveWorker.class.php new file mode 100644 index 0000000000..0c83e7ac0f --- /dev/null +++ b/wcfsetup/install/files/lib/system/worker/UserContentRemoveWorker.class.php @@ -0,0 +1,154 @@ + + * @package WoltLabSuite\Core\System\Worker + * @since 3.2 + */ +class UserContentRemoveWorker extends AbstractWorker implements IWorker { + /** + * variable name for the session to store the data + */ + const USER_CONTENT_REMOVE_WORKER_SESSION_NAME = 'userContentRemoveWorkerData'; + + /** + * @inheritDoc + */ + protected $limit = 10; + + /** + * user + * @var User + */ + protected $user = null; + + /** + * data + * @var mixed + */ + protected $data = null; + + /** + * @inheritDoc + */ + public function validate() { + if (!isset($this->parameters['userID'])) { + throw new \InvalidArgumentException("userID missing"); + } + + $this->user = new User($this->parameters['userID']); + + if (!$this->user->canEdit()) { + throw new PermissionDeniedException(); + } + + if ($this->loopCount === 0) { + $this->generateData(); + } + else { + $data = WCF::getSession()->getVar(self::USER_CONTENT_REMOVE_WORKER_SESSION_NAME); + + if (!is_array($data) || !isset($data[$this->user->userID])) { + throw new \RuntimeException('`data` variable in session is invalid or missing.'); + } + + $this->data = $data[$this->user->userID]; + } + } + + /** + * Generate the data variable. + */ + private function generateData() { + $this->data = [ + 'provider' => [], + 'count' => 0 + ]; + + $contentProviders = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.content.userContentProvider'); + + foreach ($contentProviders as $contentProvider) { + /** @var IUserContentProvider $processor */ + $processor = $contentProvider->getProcessor(); + $contentList = $processor->getContentListForUser($this->user); + $count = $contentList->countObjects(); + + if ($count) { + $this->data['provider'][$contentProvider->objectTypeID] = [ + 'processor' => $processor, + 'count' => $count + ]; + + $this->data['count'] += ceil($count / $this->limit) * $this->limit; + } + } + } + + /** + * @inheritDoc + */ + protected function countObjects() { + $this->count = $this->data['count']; + } + + /** + * @inheritDoc + */ + public function execute() { + if (empty($this->data['provider'])) { + return; + } + + $values = array_keys($this->data['provider']); + $providerID = array_pop($values); + $provider = $this->data['provider'][$providerID]; + /** @var IUserContentProvider $processor */ + $processor = $provider['processor']; + + $objectList = $processor->getContentListForUser($this->user); + $objectList->sqlLimit = $this->limit; + $objectList->readObjectIDs(); + $processor->deleteContent($objectList->objectIDs); + + $this->data['provider'][$providerID]['count'] -= $this->limit; + + if ($this->data['provider'][$providerID]['count'] <= 0) { + unset($this->data['provider'][$providerID]); + } + } + + /** + * @inheritDoc + */ + public function finalize() { + parent::finalize(); + + $dataArray = WCF::getSession()->getVar(self::USER_CONTENT_REMOVE_WORKER_SESSION_NAME); + + if (!is_array($dataArray)) { + $dataArray = []; + } + + $dataArray[$this->user->userID] = $this->data; + + WCF::getSession()->register(self::USER_CONTENT_REMOVE_WORKER_SESSION_NAME, $dataArray); + } + + /** + * @inheritDoc + */ + public function getProceedURL() { + return LinkHandler::getInstance()->getLink('UserList'); + } +} diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml index cdc512c602..5f5f5dd7cc 100644 --- a/wcfsetup/install/lang/de.xml +++ b/wcfsetup/install/lang/de.xml @@ -2461,6 +2461,8 @@ Benutzerkontos nun in vollem Umfang nutzen.]]> + + diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml index 185a26f4e3..ad9a500586 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -2809,6 +2809,8 @@ full extend.]]> + + -- 2.20.1