<page>wcf\acp\page\ArticleListPage</page>
</pages>
</action>
+ <action name="assignUserByClipboard">
+ <actionclassname>wcf\system\clipboard\action\ModerationQueueClipboardAction</actionclassname>
+ <showorder>1</showorder>
+ <pages>
+ <page>wcf\page\ModerationListPage</page>
+ </pages>
+ </action>
+ <action name="enableContent">
+ <actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
+ <showorder>2</showorder>
+ <pages>
+ <page>wcf\page\ModerationListPage</page>
+ </pages>
+ </action>
+ <action name="removeActivationContent">
+ <actionclassname>wcf\system\clipboard\action\ModerationQueueActivationClipboardAction</actionclassname>
+ <showorder>3</showorder>
+ <pages>
+ <page>wcf\page\ModerationListPage</page>
+ </pages>
+ </action>
+ <action name="removeReport">
+ <actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
+ <showorder>4</showorder>
+ <pages>
+ <page>wcf\page\ModerationListPage</page>
+ </pages>
+ </action>
+ <action name="removeReportContent">
+ <actionclassname>wcf\system\clipboard\action\ModerationQueueReportClipboardAction</actionclassname>
+ <showorder>5</showorder>
+ <pages>
+ <page>wcf\page\ModerationListPage</page>
+ </pages>
+ </action>
</import>
</data>
<definitionname>com.woltlab.wcf.clipboardItem</definitionname>
<listclassname>wcf\data\article\ArticleList</listclassname>
</type>
+ <type>
+ <name>com.woltlab.wcf.moderation.queue</name>
+ <definitionname>com.woltlab.wcf.clipboardItem</definitionname>
+ <listclassname>wcf\data\moderation\queue\ViewableModerationQueueList</listclassname>
+ </type>
<!-- /clipboard items -->
<!-- articles -->
<type>
{/hascontent}
{if $objects|count}
- <div class="section tabularBox messageGroupList moderationList moderationQueueEntryList">
+ <div class="section tabularBox messageGroupList moderationList moderationQueueEntryList jsClipboardContainer" data-type="com.woltlab.wcf.moderation.queue">
<ol class="tabularList">
<li class="tabularListRow tabularListRowHead">
<ol class="tabularListColumns">
+ <li class="columnMark jsOnly"><label><input type="checkbox" class="jsClipboardMarkAll"></label></li>
+
<li class="columnSort">
<ul class="inlineList">
<li>
<li>
<div class="dropdown">
<span class="dropdownToggle">{lang}wcf.moderation.{$sortField}{/lang}</span>
-
+
<ul class="dropdownMenu">
{foreach from=$validSortFields item=_sortField}
<li{if $_sortField === $sortField} class="active"{/if}><a href="{link controller='ModerationList'}definitionID={@$definitionID}&assignedUserID={@$assignedUserID}&status={@$status}&pageNo={@$pageNo}&sortField={$_sortField}&sortOrder={if $sortField == $_sortField && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.moderation.{$_sortField}{/lang}</a></li>
{foreach from=$objects item=entry}
<li class="tabularListRow">
- <ol class="tabularListColumns messageGroup moderationQueueEntry{if $entry->isNew()} new{/if}" data-queue-id="{@$entry->queueID}">
+ <ol class="tabularListColumns messageGroup moderationQueueEntry jsClipboardObject{if $entry->isNew()} new{/if}" data-queue-id="{@$entry->queueID}">
+ <li class="columnMark jsOnly">
+ <label><input type="checkbox" class="jsClipboardItem" data-object-id="{@$entry->getObjectID()}"></label>
+ </li>
<li class="columnIcon columnAvatar">
<div>
<p{if $entry->isNew()} title="{lang}wcf.moderation.markAsRead.doubleClick{/lang}"{/if}>{@$entry->getUserProfile()->getAvatar()->getImageTag(48)}</p>
</div>
<script data-relocate="true">
- $(function() {
+ require([
+ 'Language',
+ 'WoltLabSuite/Core/Controller/Clipboard',
+ 'WoltLabSuite/Core/Ui/Moderation/Clipboard/AssignUser'
+ ], (
+ Language,
+ ControllerClipboard,
+ UiModerationClipboardAssignUser
+ ) => {
+ Language.addObject({
+ 'wcf.moderation.assignedUser': '{jslang}wcf.moderation.assignedUser{/jslang}',
+ 'wcf.moderation.assignedUser.change': '{jslang}wcf.moderation.assignedUser.change{/jslang}',
+ 'wcf.moderation.assignedUser.error.notAffected': '{jslang}wcf.moderation.assignedUser.error.notAffected{/jslang}',
+ 'wcf.moderation.assignedUser.nobody': '{jslang}wcf.moderation.assignedUser.nobody{/jslang}',
+ 'wcf.user.username.error.notFound': '{jslang __literal=true}wcf.user.username.error.notFound{/jslang}',
+ });
+
+ ControllerClipboard.setup({
+ hasMarkedItems: {if $hasMarkedItems}true{else}false{/if},
+ pageClassName: 'wcf\\page\\ModerationListPage',
+ });
+
+ UiModerationClipboardAssignUser.setup();
+
new WCF.Moderation.Queue.MarkAsRead();
new WCF.Moderation.Queue.MarkAllAsRead();
});
--- /dev/null
+<div class="section">
+ <dl>
+ <dt>
+ <label for="message">{lang}wcf.moderation.report.removeContent.reason{/lang}</label>
+ </dt>
+ <dd>
+ <textarea name="message" cols="40" rows="3"></textarea>
+ </dd>
+ </dl>
+</div>
--- /dev/null
+<div class="section">
+ <dl>
+ <dt></dt>
+ <dd>
+ <label>
+ <input type="checkbox" name="markAsJustified" id="markAsJustified" value="1">
+ {lang}wcf.moderation.report.removeReport.markAsJustified{/lang}
+ </label>
+ </dd>
+ </dl>
+</div>
--- /dev/null
+/**
+ * Handles the dialog to select the user when assigning a user to multiple moderation queue entries
+ * via clipboard.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Ui/Moderation/Clipboard/AssignUser
+ */
+
+import * as EventHandler from "../../../Event/Handler";
+import { AjaxResponse, ClipboardActionData } from "../../../Controller/Clipboard/Data";
+import * as UiNotification from "../../Notification";
+import User from "../../../User";
+import * as StringUtil from "../../../StringUtil";
+import * as Language from "../../../Language";
+import UiUserSearchInput from "../../User/Search/Input";
+import * as DomTraverse from "../../../Dom/Traverse";
+import * as Ajax from "../../../Ajax";
+import { AjaxCallbackObject, AjaxCallbackSetup, ResponseData } from "../../../Ajax/Data";
+import DomUtil from "../../../Dom/Util";
+import { DialogCallbackObject, DialogCallbackSetup } from "../../Dialog/Data";
+import UiDialog from "../../Dialog";
+
+interface EventData {
+ data: ClipboardActionData;
+ listItem: HTMLLIElement;
+ responseData: AjaxResponse;
+}
+
+class UiModerationClipboardAssignUser implements AjaxCallbackObject, DialogCallbackObject {
+ /**
+ * ids of the moderation queue entries currently being handled
+ */
+ protected queueIds: number[] = [];
+
+ public _ajaxFailure(data: ResponseData): boolean {
+ if (data.returnValues?.fieldName === "assignedUsername") {
+ let errorMessage = "";
+
+ const dialog = UiDialog.getDialog(this)!.content;
+ const assignedUsername = dialog.querySelector("input[name=assignedUsername]") as HTMLInputElement;
+
+ const errorType: string = data.returnValues.errorType;
+ switch (errorType) {
+ case "empty":
+ errorMessage = Language.get("wcf.global.form.error.empty");
+ break;
+
+ case "notAffected":
+ errorMessage = Language.get("wcf.moderation.assignedUser.error.notAffected");
+ break;
+
+ default:
+ errorMessage = Language.get(`wcf.user.username.error.${errorType}`, {
+ username: assignedUsername.value,
+ });
+ break;
+ }
+
+ DomUtil.innerError(assignedUsername, errorMessage);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public _ajaxSetup(): ReturnType<AjaxCallbackSetup> {
+ return {
+ data: {
+ actionName: "assignUserByClipboard",
+ className: "wcf\\data\\moderation\\queue\\ModerationQueueAction",
+ },
+ };
+ }
+
+ public _ajaxSuccess(): void {
+ UiDialog.close(this);
+
+ UiNotification.show(undefined, () => window.location.reload());
+ }
+
+ public _dialogSetup(): ReturnType<DialogCallbackSetup> {
+ const submitCallback = () => this.submitDialog();
+
+ return {
+ id: "moderationQueueClipboardAssignUser",
+ options: {
+ onSetup(content: HTMLElement): void {
+ const username = content.querySelector("input[name=assignedUsername]") as HTMLInputElement;
+ new UiUserSearchInput(username, {});
+
+ username.addEventListener("click", (event) => {
+ const assignedUserId = DomTraverse.prevBySel(
+ event.currentTarget as HTMLElement,
+ "input[name=assignedUserID]",
+ ) as HTMLInputElement;
+ assignedUserId.click();
+ });
+
+ content.querySelector("button[data-type=submit]")!.addEventListener("click", submitCallback);
+ },
+ onShow(content: HTMLElement): void {
+ // Reset dialog to initial state.
+ const assignedUsername = content.querySelector("input[name=assignedUsername]") as HTMLInputElement;
+ content
+ .querySelectorAll("input[name=assignedUserID]")
+ .forEach((el: HTMLInputElement) => (el.checked = el.defaultChecked));
+
+ assignedUsername.value = "";
+
+ DomUtil.innerError(assignedUsername, "");
+ },
+ title: Language.get("wcf.moderation.assignedUser.change"),
+ },
+ source: `
+<div class="section">
+ <dl>
+ <dt>${Language.get("wcf.moderation.assignedUser")}</dt>
+ <dd>
+ <ul>
+ <li>
+ <label>
+ <input type="radio" name="assignedUserID" value="${User.userId}" checked>
+ ${StringUtil.escapeHTML(User.username)}
+ </label>
+ </li>
+ <li>
+ <label>
+ <input type="radio" name="assignedUserID" value="0">
+ ${Language.get("wcf.moderation.assignedUser.nobody")}
+ </label>
+ </li>
+ <li>
+ <input type="radio" name="assignedUserID" value="-1">
+ <input type="text" name="assignedUsername" value="">
+ </li>
+ </ul>
+ </dd>
+ </dl>
+</div>
+<div class="formSubmit">
+ <button class="buttonPrimary" data-type="submit">${Language.get("wcf.global.button.save")}</button>
+</div>`,
+ };
+ }
+
+ public showDialog(queueIds: number[]): void {
+ this.queueIds = queueIds;
+
+ UiDialog.open(this);
+ }
+
+ public submitDialog(): void {
+ const dialog = UiDialog.getDialog(this)!.content;
+ const assignedUserId = dialog.querySelector("input[name=assignedUserID]:checked") as HTMLInputElement;
+ const assignedUsername = dialog.querySelector("input[name=assignedUsername]") as HTMLInputElement;
+
+ Ajax.api(this, {
+ objectIDs: this.queueIds,
+ parameters: {
+ assignedUserID: assignedUserId.value,
+ assignedUsername: assignedUsername.value,
+ },
+ });
+ }
+}
+
+let isSetUp = false;
+
+export function setup(): void {
+ if (isSetUp) {
+ return;
+ }
+
+ const handler = new UiModerationClipboardAssignUser();
+
+ EventHandler.add("com.woltlab.wcf.clipboard", "com.woltlab.wcf.moderation.queue", (data: EventData) => {
+ if (
+ data.data.actionName === "com.woltlab.wcf.moderation.queue.assignUserByClipboard" &&
+ data.responseData === null
+ ) {
+ handler.showDialog(data.data.parameters.objectIDs);
+ }
+ });
+
+ isSetUp = true;
+}
--- /dev/null
+/**
+ * Handles the dialog to select the user when assigning a user to multiple moderation queue entries
+ * via clipboard.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Ui/Moderation/Clipboard/AssignUser
+ */
+define(["require", "exports", "tslib", "../../../Event/Handler", "../../Notification", "../../../User", "../../../StringUtil", "../../../Language", "../../User/Search/Input", "../../../Dom/Traverse", "../../../Ajax", "../../../Dom/Util", "../../Dialog"], function (require, exports, tslib_1, EventHandler, UiNotification, User_1, StringUtil, Language, Input_1, DomTraverse, Ajax, Util_1, Dialog_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.setup = void 0;
+ EventHandler = tslib_1.__importStar(EventHandler);
+ UiNotification = tslib_1.__importStar(UiNotification);
+ User_1 = tslib_1.__importDefault(User_1);
+ StringUtil = tslib_1.__importStar(StringUtil);
+ Language = tslib_1.__importStar(Language);
+ Input_1 = tslib_1.__importDefault(Input_1);
+ DomTraverse = tslib_1.__importStar(DomTraverse);
+ Ajax = tslib_1.__importStar(Ajax);
+ Util_1 = tslib_1.__importDefault(Util_1);
+ Dialog_1 = tslib_1.__importDefault(Dialog_1);
+ class UiModerationClipboardAssignUser {
+ constructor() {
+ /**
+ * ids of the moderation queue entries currently being handled
+ */
+ this.queueIds = [];
+ }
+ _ajaxFailure(data) {
+ var _a;
+ if (((_a = data.returnValues) === null || _a === void 0 ? void 0 : _a.fieldName) === "assignedUsername") {
+ let errorMessage = "";
+ const dialog = Dialog_1.default.getDialog(this).content;
+ const assignedUsername = dialog.querySelector("input[name=assignedUsername]");
+ const errorType = data.returnValues.errorType;
+ switch (errorType) {
+ case "empty":
+ errorMessage = Language.get("wcf.global.form.error.empty");
+ break;
+ case "notAffected":
+ errorMessage = Language.get("wcf.moderation.assignedUser.error.notAffected");
+ break;
+ default:
+ errorMessage = Language.get(`wcf.user.username.error.${errorType}`, {
+ username: assignedUsername.value,
+ });
+ break;
+ }
+ Util_1.default.innerError(assignedUsername, errorMessage);
+ return false;
+ }
+ return true;
+ }
+ _ajaxSetup() {
+ return {
+ data: {
+ actionName: "assignUserByClipboard",
+ className: "wcf\\data\\moderation\\queue\\ModerationQueueAction",
+ },
+ };
+ }
+ _ajaxSuccess() {
+ Dialog_1.default.close(this);
+ UiNotification.show(undefined, () => window.location.reload());
+ }
+ _dialogSetup() {
+ const submitCallback = () => this.submitDialog();
+ return {
+ id: "moderationQueueClipboardAssignUser",
+ options: {
+ onSetup(content) {
+ const username = content.querySelector("input[name=assignedUsername]");
+ new Input_1.default(username, {});
+ username.addEventListener("click", (event) => {
+ const assignedUserId = DomTraverse.prevBySel(event.currentTarget, "input[name=assignedUserID]");
+ assignedUserId.click();
+ });
+ content.querySelector("button[data-type=submit]").addEventListener("click", submitCallback);
+ },
+ onShow(content) {
+ // Reset dialog to initial state.
+ const assignedUsername = content.querySelector("input[name=assignedUsername]");
+ content
+ .querySelectorAll("input[name=assignedUserID]")
+ .forEach((el) => (el.checked = el.defaultChecked));
+ assignedUsername.value = "";
+ Util_1.default.innerError(assignedUsername, "");
+ },
+ title: Language.get("wcf.moderation.assignedUser.change"),
+ },
+ source: `
+<div class="section">
+ <dl>
+ <dt>${Language.get("wcf.moderation.assignedUser")}</dt>
+ <dd>
+ <ul>
+ <li>
+ <label>
+ <input type="radio" name="assignedUserID" value="${User_1.default.userId}" checked>
+ ${StringUtil.escapeHTML(User_1.default.username)}
+ </label>
+ </li>
+ <li>
+ <label>
+ <input type="radio" name="assignedUserID" value="0">
+ ${Language.get("wcf.moderation.assignedUser.nobody")}
+ </label>
+ </li>
+ <li>
+ <input type="radio" name="assignedUserID" value="-1">
+ <input type="text" name="assignedUsername" value="">
+ </li>
+ </ul>
+ </dd>
+ </dl>
+</div>
+<div class="formSubmit">
+ <button class="buttonPrimary" data-type="submit">${Language.get("wcf.global.button.save")}</button>
+</div>`,
+ };
+ }
+ showDialog(queueIds) {
+ this.queueIds = queueIds;
+ Dialog_1.default.open(this);
+ }
+ submitDialog() {
+ const dialog = Dialog_1.default.getDialog(this).content;
+ const assignedUserId = dialog.querySelector("input[name=assignedUserID]:checked");
+ const assignedUsername = dialog.querySelector("input[name=assignedUsername]");
+ Ajax.api(this, {
+ objectIDs: this.queueIds,
+ parameters: {
+ assignedUserID: assignedUserId.value,
+ assignedUsername: assignedUsername.value,
+ },
+ });
+ }
+ }
+ let isSetUp = false;
+ function setup() {
+ if (isSetUp) {
+ return;
+ }
+ const handler = new UiModerationClipboardAssignUser();
+ EventHandler.add("com.woltlab.wcf.clipboard", "com.woltlab.wcf.moderation.queue", (data) => {
+ if (data.data.actionName === "com.woltlab.wcf.moderation.queue.assignUserByClipboard" &&
+ data.responseData === null) {
+ handler.showDialog(data.data.parameters.objectIDs);
+ }
+ });
+ isSetUp = true;
+ }
+ exports.setup = setup;
+});
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\object\type\ObjectTypeCache;
use wcf\data\user\User;
+use wcf\system\clipboard\ClipboardHandler;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\PermissionDeniedException;
use wcf\system\exception\UserInputException;
+use wcf\system\moderation\queue\IModerationQueueHandler;
use wcf\system\moderation\queue\ModerationQueueManager;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\visitTracker\VisitTracker;
{
// does nothing
}
+
+ /**
+ * Validates the `assignUserByClipboard` action.
+ *
+ * @since 5.4
+ */
+ public function validateAssignUserByClipboard(): void
+ {
+ if (empty($this->objects)) {
+ $this->readObjects();
+
+ if (empty($this->objects)) {
+ throw new UserInputException('objectIDs');
+ }
+ }
+
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ if (!$moderationQueueEditor->canEdit()) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ $this->readInteger('assignedUserID', false);
+
+ if ($this->parameters['assignedUserID'] < -1) {
+ throw new UserInputException('assignedUserID');
+ } elseif ($this->parameters['assignedUserID'] == -1) {
+ $this->readString('assignedUsername', false);
+
+ $this->user = User::getUserByUsername($this->parameters['assignedUsername']);
+ if (!$this->user->userID) {
+ throw new UserInputException('assignedUsername', 'notFound');
+ }
+
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ /** @var IModerationQueueHandler $processor */
+ $processor = ObjectTypeCache::getInstance()->getObjectType(
+ $moderationQueueEditor->objectTypeID
+ )->getProcessor();
+
+ $isAffected = $processor->isAffectedUser(
+ $moderationQueueEditor->getDecoratedObject(),
+ $this->user->userID
+ );
+ if (!$isAffected) {
+ throw new UserInputException('assignedUsername', 'notAffected');
+ }
+ }
+
+ $this->parameters['assignedUserID'] = $this->user->userID;
+ $this->parameters['assignedUsername'] = '';
+ } elseif ($this->parameters['assignedUserID'] == WCF::getUser()->userID) {
+ $this->user = WCF::getUser();
+ }
+ }
+
+ /**
+ * Assigns a user to multiple moderation queue entries via clipboard.
+ *
+ * @since 5.4
+ */
+ public function assignUserByClipboard(): void
+ {
+ WCF::getDB()->beginTransaction();
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ $data = [
+ 'assignedUserID' => $this->user ? $this->user->userID : null,
+ ];
+ if ($this->user) {
+ if ($moderationQueueEditor->status == ModerationQueue::STATUS_OUTSTANDING) {
+ $data['status'] = ModerationQueue::STATUS_PROCESSING;
+ }
+ } else {
+ if ($moderationQueueEditor->status == ModerationQueue::STATUS_PROCESSING) {
+ $data['status'] = ModerationQueue::STATUS_OUTSTANDING;
+ }
+ }
+
+ $moderationQueueEditor->update($data);
+ }
+ WCF::getDB()->commitTransaction();
+
+ $this->unmarkItems();
+ }
+
+ /**
+ * Unmarks the moderation queue entries with the given ids or all currently handled entries if
+ * no argument is given.
+ *
+ * @param int[] $queueIDs
+ * @since 5.4
+ */
+ protected function unmarkItems(array $queueIDs = []): void
+ {
+ if (empty($queueIDs)) {
+ $queueIDs = $this->objectIDs;
+ }
+
+ if (!empty($queueIDs)) {
+ ClipboardHandler::getInstance()->unmark(
+ $queueIDs,
+ ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.moderation.queue')
+ );
+ }
+ }
}
namespace wcf\data\moderation\queue;
use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\UserInputException;
use wcf\system\moderation\queue\ModerationQueueActivationManager;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
/**
* Executes actions for reports.
*/
public function validateEnableContent()
{
- $this->queue = $this->getSingleObject();
- if (!$this->queue->canEdit()) {
- throw new PermissionDeniedException();
+ if (empty($this->objects)) {
+ $this->readObjects();
+
+ if (empty($this->objects)) {
+ throw new UserInputException('objectIDs');
+ }
+ }
+
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ if (!$moderationQueueEditor->canEdit()) {
+ throw new PermissionDeniedException();
+ }
}
}
*/
public function enableContent()
{
- // enable content
- ModerationQueueActivationManager::getInstance()->enableContent($this->queue->getDecoratedObject());
+ WCF::getDB()->beginTransaction();
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ ModerationQueueActivationManager::getInstance()->enableContent(
+ $moderationQueueEditor->getDecoratedObject()
+ );
- $this->queue->markAsConfirmed();
+ $moderationQueueEditor->markAsConfirmed();
+ }
+ WCF::getDB()->commitTransaction();
+
+ $this->unmarkItems();
}
/**
);
$this->queue->markAsRejected();
+
+ $this->unmarkItems();
+ }
+
+ /**
+ * Validates the `removeActivationContent` action.
+ *
+ * @since 5.4
+ */
+ public function validateRemoveActivationContent(): void
+ {
+ if (empty($this->objects)) {
+ $this->readObjects();
+
+ if (empty($this->objects)) {
+ throw new UserInputException('objectIDs');
+ }
+ }
+
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ if (
+ !$moderationQueueEditor->canEdit()
+ || !ModerationQueueActivationManager::getInstance()->canRemoveContent($moderationQueueEditor->getDecoratedObject())
+ ) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ $this->parameters['message'] = StringUtil::trim($this->parameters['message'] ?? '');
+ }
+
+ /**
+ * Deletes disabled content via clipboard.
+ *
+ * @since 5.4
+ */
+ public function removeActivationContent(): void
+ {
+ WCF::getDB()->beginTransaction();
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ ModerationQueueActivationManager::getInstance()->removeContent(
+ $moderationQueueEditor->getDecoratedObject(),
+ $this->parameters['message']
+ );
+
+ $moderationQueueEditor->markAsConfirmed();
+ }
+ WCF::getDB()->commitTransaction();
+
+ $this->unmarkItems();
}
}
);
$this->queue->markAsConfirmed();
+
+ $this->unmarkItems();
}
/**
*/
public function validateRemoveReport()
{
- $this->queue = $this->getSingleObject();
- if (!$this->queue->canEdit()) {
- throw new PermissionDeniedException();
+ if (empty($this->objects)) {
+ $this->readObjects();
+
+ if (empty($this->objects)) {
+ throw new UserInputException('objectIDs');
+ }
}
- $this->readBoolean('markAsJustified', true);
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ if (!$moderationQueueEditor->canEdit()) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ if (isset($this->parameters['data']['markAsJustified'])) {
+ $this->readBoolean('markAsJustified', true, 'data');
+
+ // Clipboard passes `markAsJustified` in the `data` array.
+ $this->parameters['markAsJustified'] = $this->parameters['data']['markAsJustified'];
+ } else {
+ $this->readBoolean('markAsJustified', true);
+ }
}
/**
*/
public function removeReport()
{
- $this->queue->markAsRejected(($this->parameters['markAsJustified'] ?? false));
+ WCF::getDB()->beginTransaction();
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ $moderationQueueEditor->markAsRejected($this->parameters['markAsJustified'] ?? false);
+ }
+ WCF::getDB()->commitTransaction();
+
+ $this->unmarkItems();
}
/**
'additionalData' => \serialize($additionalData),
]);
}
+
+ /**
+ * Validates the `removeReportContent` action.
+ *
+ * @since 5.4
+ */
+ public function validateRemoveReportContent(): void
+ {
+ if (empty($this->objects)) {
+ $this->readObjects();
+
+ if (empty($this->objects)) {
+ throw new UserInputException('objectIDs');
+ }
+ }
+
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ if (
+ !$moderationQueueEditor->canEdit()
+ || !ModerationQueueReportManager::getInstance()->canRemoveContent($moderationQueueEditor->getDecoratedObject())
+ ) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ $this->parameters['message'] = StringUtil::trim($this->parameters['message'] ?? '');
+ }
+
+ /**
+ * Deletes reported content via clipboard.
+ *
+ * @since 5.4
+ */
+ public function removeReportContent(): void
+ {
+ WCF::getDB()->beginTransaction();
+ foreach ($this->getObjects() as $moderationQueueEditor) {
+ ModerationQueueReportManager::getInstance()->removeContent(
+ $moderationQueueEditor->getDecoratedObject(),
+ $this->parameters['message']
+ );
+
+ $moderationQueueEditor->markAsConfirmed();
+ }
+ WCF::getDB()->commitTransaction();
+
+ $this->unmarkItems();
+ }
}
use wcf\data\moderation\queue\ModerationQueue;
use wcf\data\moderation\queue\ViewableModerationQueueList;
+use wcf\system\clipboard\ClipboardHandler;
use wcf\system\exception\IllegalLinkException;
use wcf\system\moderation\queue\ModerationQueueManager;
use wcf\system\request\LinkHandler;
'status' => $this->status,
'validSortFields' => $this->validSortFields,
'hasActiveFilter' => $this->hasActiveFilter,
+ 'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(
+ ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.moderation.queue')
+ ),
]);
}
}
--- /dev/null
+<?php
+
+namespace wcf\system\clipboard\action;
+
+use wcf\data\clipboard\action\ClipboardAction;
+use wcf\data\moderation\queue\ModerationQueueActivationAction;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\moderation\queue\report\IModerationQueueReportHandler;
+use wcf\system\WCF;
+
+/**
+ * Clipboard action implementation for activation moderation queue entries.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Clipboard\Action
+ * @since 5.4
+ */
+class ModerationQueueActivationClipboardAction extends AbstractClipboardAction
+{
+ /**
+ * @inheritDoc
+ */
+ protected $actionClassActions = [
+ 'enableContent',
+ 'removeActivationContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ protected $reloadPageOnSuccess = [
+ 'enableContent',
+ 'removeActivationContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ protected $supportedActions = [
+ 'enableContent',
+ 'removeActivationContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ public function execute(array $objects, ClipboardAction $action)
+ {
+ $item = parent::execute($objects, $action);
+
+ if ($item === null) {
+ return;
+ }
+
+ switch ($action->actionName) {
+ case 'enableContent':
+ $item->addInternalData(
+ 'confirmMessage',
+ WCF::getLanguage()->getDynamicVariable(
+ 'wcf.moderation.activation.enableContent.confirmMessage',
+ [
+ 'moderationQueueCount' => $item->getCount(),
+ ]
+ )
+ );
+ break;
+
+ case 'removeActivationContent':
+ $item->addInternalData(
+ 'confirmMessage',
+ WCF::getLanguage()->getDynamicVariable(
+ 'wcf.moderation.activation.removeContent.confirmMessage',
+ [
+ 'moderationQueueCount' => $item->getCount(),
+ ]
+ )
+ );
+ break;
+ }
+
+ return $item;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getClassName()
+ {
+ return ModerationQueueActivationAction::class;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTypeName()
+ {
+ return 'com.woltlab.wcf.moderation.queue';
+ }
+
+ /**
+ * Returns the ids of the ids of the marked moderation queue entries that are activation
+ * moderation queue entries whose content the active user can delete.
+ *
+ * @return int[]
+ */
+ public function validateRemoveActivationContent(): array
+ {
+ return \array_values(\array_filter(\array_map(static function (ViewableModerationQueue $queue) {
+ $objectType = ObjectTypeCache::getInstance()->getObjectType($queue->objectTypeID);
+ /** @var IModerationQueueReportHandler $processor */
+ $processor = $objectType->getProcessor();
+ $definition = $objectType->getDefinition();
+ if (
+ $definition->definitionName === 'com.woltlab.wcf.moderation.activation'
+ && $queue->canEdit()
+ && $processor->canRemoveContent($queue->getDecoratedObject())
+ && !$queue->isDone()
+ ) {
+ return $queue->queueID;
+ }
+ }, $this->objects)));
+ }
+
+ /**
+ * Returns the ids of the ids of the marked moderation queue entries that are activation
+ * moderation queue entries whose content the active user can enable.
+ *
+ * @return int[]
+ */
+ public function validateEnableContent(): array
+ {
+ return \array_values(\array_filter(\array_map(static function (ViewableModerationQueue $queue) {
+ $definition = ObjectTypeCache::getInstance()->getObjectType($queue->objectTypeID)->getDefinition();
+ if (
+ $definition->definitionName === 'com.woltlab.wcf.moderation.activation'
+ && $queue->canEdit()
+ && !$queue->isDone()
+ ) {
+ return $queue->queueID;
+ }
+ }, $this->objects)));
+ }
+}
--- /dev/null
+<?php
+
+namespace wcf\system\clipboard\action;
+
+use wcf\data\moderation\queue\ModerationQueueAction;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+
+/**
+ * Clipboard action implementation for moderation queue entries.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Clipboard\Action
+ * @since 5.4
+ */
+class ModerationQueueClipboardAction extends AbstractClipboardAction
+{
+ /**
+ * @inheritDoc
+ */
+ protected $supportedActions = [
+ 'assignUserByClipboard',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ public function getClassName()
+ {
+ return ModerationQueueAction::class;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTypeName()
+ {
+ return 'com.woltlab.wcf.moderation.queue';
+ }
+
+ /**
+ * Returns the ids of the ids of the marked moderation queue entries for which the active user
+ * can assign users.
+ *
+ * @return int[]
+ */
+ public function validateAssignUserByClipboard(): array
+ {
+ return \array_values(\array_filter(\array_map(static function (ViewableModerationQueue $queue) {
+ if ($queue->canEdit()) {
+ return $queue->queueID;
+ }
+ }, $this->objects)));
+ }
+}
--- /dev/null
+<?php
+
+namespace wcf\system\clipboard\action;
+
+use wcf\data\clipboard\action\ClipboardAction;
+use wcf\data\moderation\queue\ModerationQueueReportAction;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\moderation\queue\report\IModerationQueueReportHandler;
+use wcf\system\WCF;
+
+/**
+ * Clipboard action implementation for report moderation queue entries.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2021 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Clipboard\Action
+ * @since 5.4
+ */
+class ModerationQueueReportClipboardAction extends AbstractClipboardAction
+{
+ /**
+ * @inheritDoc
+ */
+ protected $actionClassActions = [
+ 'removeReport',
+ 'removeReportContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ protected $reloadPageOnSuccess = [
+ 'removeReport',
+ 'removeReportContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ protected $supportedActions = [
+ 'removeReport',
+ 'removeReportContent',
+ ];
+
+ /**
+ * @inheritDoc
+ */
+ public function execute(array $objects, ClipboardAction $action)
+ {
+ $item = parent::execute($objects, $action);
+
+ if ($item === null) {
+ return;
+ }
+
+ switch ($action->actionName) {
+ case 'removeReportContent':
+ $item->addInternalData(
+ 'confirmMessage',
+ WCF::getLanguage()->getDynamicVariable(
+ 'wcf.moderation.report.removeContent.confirmMessage',
+ [
+ 'moderationQueueCount' => $item->getCount(),
+ ]
+ )
+ );
+ $item->addInternalData(
+ 'template',
+ WCF::getTPL()->fetch('moderationReportRemoveContent')
+ );
+ break;
+
+ case 'removeReport':
+ $item->addInternalData(
+ 'confirmMessage',
+ WCF::getLanguage()->getDynamicVariable(
+ 'wcf.moderation.report.removeReport.confirmMessage',
+ [
+ 'moderationQueueCount' => $item->getCount(),
+ ]
+ )
+ );
+ $item->addInternalData(
+ 'template',
+ WCF::getTPL()->fetch('moderationReportRemoveReport')
+ );
+ break;
+ }
+
+ return $item;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getClassName()
+ {
+ return ModerationQueueReportAction::class;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTypeName()
+ {
+ return 'com.woltlab.wcf.moderation.queue';
+ }
+
+ /**
+ * Returns the ids of the ids of the marked moderation queue entries that are report
+ * moderation queue entries whose content the active user can delete.
+ *
+ * @return int[]
+ */
+ public function validateRemoveReportContent(): array
+ {
+ return \array_values(\array_filter(\array_map(static function (ViewableModerationQueue $queue) {
+ $objectType = ObjectTypeCache::getInstance()->getObjectType($queue->objectTypeID);
+ /** @var IModerationQueueReportHandler $processor */
+ $processor = $objectType->getProcessor();
+ $definition = $objectType->getDefinition();
+ if (
+ $definition->definitionName === 'com.woltlab.wcf.moderation.report'
+ && $queue->canEdit()
+ && $processor->canRemoveContent($queue->getDecoratedObject())
+ && !$queue->isDone()
+ ) {
+ return $queue->queueID;
+ }
+ }, $this->objects)));
+ }
+
+ /**
+ * Returns the ids of the ids of the marked moderation queue entries that are report
+ * moderation queue entries the active user can close.
+ *
+ * @return int[]
+ */
+ public function validateRemoveReport(): array
+ {
+ return \array_values(\array_filter(\array_map(static function (ViewableModerationQueue $queue) {
+ $definition = ObjectTypeCache::getInstance()->getObjectType($queue->objectTypeID)->getDefinition();
+ if (
+ $definition->definitionName === 'com.woltlab.wcf.moderation.report'
+ && $queue->canEdit()
+ && !$queue->isDone()
+ ) {
+ return $queue->queueID;
+ }
+ }, $this->objects)));
+ }
+}
<item name="wcf.clipboard.item.com.woltlab.wcf.user.confirmEmail"><![CDATA[E-Mail-Adresse bestätigen ({#$count})]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.unconfirmEmail"><![CDATA[Bestätigung der E-Mail-Adresse widerrufen ({#$count})]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.deleteUserContent"><![CDATA[Inhalte der Benutzer löschen ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.assignUserByClipboard"><![CDATA[Zugewiesenen Benutzer ändern ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.enableContent"><![CDATA[Inhalt freischalten ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeActivationContent"><![CDATA[Freizuschaltenden Inhalt löschen ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeReport"><![CDATA[Meldung schließen ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeReportContent"><![CDATA[Gemeldeten Inhalt löschen ({#$count})]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.article.marked"><![CDATA[{if $count == 1}Ein{else}{#$count}{/if} Artikel]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.media.marked"><![CDATA[{if $count == 1}Eine Datei{else}{#$count} Dateien{/if}]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.tag.marked"><![CDATA[{if $count == 1}Ein Tag{else}{#$count} Tags{/if}]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{if $count == 1}Ein{else}{#$count}{/if} Benutzer]]></item>
+ <item name="wcf.clipboard.label.com.woltlab.wcf.moderation.queue.marked"><![CDATA[{plural value=$count 1='Ein Moderationseintrag' other='# Moderationseinträge'}]]></item>
</category>
<category name="wcf.comment">
<item name="wcf.comment.add"><![CDATA[Kommentar schreiben …]]></item>
<item name="wcf.moderation.activation.details"><![CDATA[Informationen]]></item>
<item name="wcf.moderation.activation.content"><![CDATA[Freizuschaltender Inhalt]]></item>
<item name="wcf.moderation.activation.enableContent"><![CDATA[Inhalt freischalten]]></item>
- <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diesen Inhalt wirklich freischalten?]]></item>
+ <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if !$moderationQueueCount|isset || $moderationQueueCount == 1}diesen Inhalt{else}diese Inhalte{/if} wirklich freischalten?]]></item>
<item name="wcf.moderation.activation.notification.comment.title"><![CDATA[Neuer Kommentar (Freischaltung)]]></item>
<item name="wcf.moderation.activation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Freischaltung)]]></item>
<item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}Ein Gast{/if} hat einen Kommentar zum freizuschaltenden Inhalt <strong>{$moderationQueue}</strong> verfasst.]]></item>
<item name="wcf.moderation.activation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von {@$commentAuthor} zum freizuschaltenden Inhalt {@$moderationQueue->getTitle()} [URL:{@$moderationQueue->getLink()}] verfasst{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
<item name="wcf.moderation.activation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} {if $count == 1 && $guestTimesTriggered < 2 && (!$event->getAuthor()->userID || $guestTimesTriggered == 0)}hat eine Antwort{else}haben Antworten{/if} zum Kommentar von <strong>{$commentAuthor} zum freizuschaltenden Inhalt <a href="{$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst:</p>]]></item>
<item name="wcf.moderation.activation.removeContent"><![CDATA[Inhalt löschen]]></item>
- <item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diesen Inhalt wirklich löschen?]]></item>
+ <item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if !$moderationQueueCount|isset || $moderationQueueCount == 1}diesen Inhalt{else}diese Inhalte{/if} wirklich löschen?]]></item>
</category>
<category name="wcf.moderation.report">
<item name="wcf.moderation.report"><![CDATA[Meldung]]></item>
<item name="wcf.moderation.report.reason"><![CDATA[Grund der Meldung]]></item>
<item name="wcf.moderation.report.reason.description"><![CDATA[Diese Funktion ist ausschließlich zu verwenden bei: Spam, Werbung und anderen problematischen (rassistischen, gewaltverherrlichenden, aggressiven, beleidigenden oder sexistischen) Inhalten.]]></item>
<item name="wcf.moderation.report.removeContent"><![CDATA[Inhalt löschen]]></item>
- <item name="wcf.moderation.report.removeContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den gemeldeten Inhalt wirklich löschen?]]></item>
+ <item name="wcf.moderation.report.removeContent.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if !$moderationQueueCount|isset || $moderationQueueCount == 1}den gemeldeten Inhalt{else}die gemeldeten Inhalte{/if} wirklich löschen?]]></item>
<item name="wcf.moderation.report.removeContent.reason"><![CDATA[Begründung (optional)]]></item>
<item name="wcf.moderation.report.removeReport"><![CDATA[Meldung schließen]]></item>
- <item name="wcf.moderation.report.removeReport.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diese Meldung wirklich schließen?]]></item>
+ <item name="wcf.moderation.report.removeReport.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} diese Meldung{if $moderationQueueCount|isset && $moderationQueueCount > 1}en{/if} wirklich schließen?]]></item>
<item name="wcf.moderation.report.removeReport.markAsJustified"><![CDATA[Meldung zusätzlich als „Berechtigt“ markieren]]></item>
<item name="wcf.moderation.report.reportContent"><![CDATA[Inhalt melden]]></item>
<item name="wcf.moderation.report.reportedBy"><![CDATA[Gemeldet von]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.confirmEmail"><![CDATA[Confirm Email Address ({#$count})]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.unconfirmEmail"><![CDATA[Unconfirm Email Address ({#$count})]]></item>
<item name="wcf.clipboard.item.com.woltlab.wcf.user.deleteUserContent"><![CDATA[Delete User Contents ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.assignUserByClipboard"><![CDATA[Change Assigned User ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.enableContent"><![CDATA[Approve Content ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeActivationContent"><![CDATA[Delete Pending Content ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeReport"><![CDATA[Close Report ({#$count})]]></item>
+ <item name="wcf.clipboard.item.com.woltlab.wcf.moderation.queue.removeReportContent"><![CDATA[Delete Repored Content ({#$count})]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.article.marked"><![CDATA[{if $count == 1}One Article{else}{#$count} Articles{/if}]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.media.marked"><![CDATA[{if $count == 1}One File{else}{#$count} Files{/if}]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.tag.marked"><![CDATA[{if $count == 1}One Tag{else}{#$count} Tags{/if}]]></item>
<item name="wcf.clipboard.label.com.woltlab.wcf.user.marked"><![CDATA[{if $count == 1}One User{else}{#$count} Users{/if}]]></item>
+ <item name="wcf.clipboard.label.com.woltlab.wcf.moderation.queue.marked"><![CDATA[{plural value=$count 1='One Moderation Item' other='# Moderation Items'}]]></item>
</category>
<category name="wcf.comment">
<item name="wcf.comment.add"><![CDATA[Write a comment …]]></item>
<item name="wcf.moderation.activation.details"><![CDATA[Information]]></item>
<item name="wcf.moderation.activation.content"><![CDATA[Content awaiting approval]]></item>
<item name="wcf.moderation.activation.enableContent"><![CDATA[Approve]]></item>
- <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[Do you really want to approve this content?]]></item>
+ <item name="wcf.moderation.activation.enableContent.confirmMessage"><![CDATA[Do you really want to approve {if !$moderationQueueCount|isset || $moderationQueueCount == 1}this content{else}these contents{/if}?]]></item>
<item name="wcf.moderation.activation.notification.comment.title"><![CDATA[New comment (Approval)]]></item>
<item name="wcf.moderation.activation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Approval)]]></item>
<item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if $author->userID}<strong>{$author}</strong>{else}A guest{/if} commented on <strong>{$moderationQueue}</strong> waiting for approval.]]></item>
<item name="wcf.moderation.activation.notification.commentResponse.mail.plaintext"><![CDATA[{@$authorList} replied to {@$commentAuthor}’s comment on {@$moderationQueue->getTitle()} [URL:{@$moderationQueue->getLink()}] waiting for approval{if $count == 1 && !$guestTimesTriggered}:{else}.{/if}]]></item>
<item name="wcf.moderation.activation.notification.commentResponse.mail.html"><![CDATA[<p>{@$authorList} replied to <strong>{$commentAuthor}</strong>’s comment on <a href="{$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval:</p>]]></item>
<item name="wcf.moderation.activation.removeContent"><![CDATA[Delete Content]]></item>
- <item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[Do you really want to delete this content?]]></item>
+ <item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[Do you really want to delete {if !$moderationQueueCount|isset || $moderationQueueCount == 1}this content{else}these contents{/if}?]]></item>
</category>
<category name="wcf.moderation.report">
<item name="wcf.moderation.report"><![CDATA[Report]]></item>
<item name="wcf.moderation.report.reason"><![CDATA[Reason]]></item>
<item name="wcf.moderation.report.reason.description"><![CDATA[This function is reserved for: spam, advertisement and other questionable (racism, glorification of violence, offending, or sexist) content.]]></item>
<item name="wcf.moderation.report.removeContent"><![CDATA[Delete Content]]></item>
- <item name="wcf.moderation.report.removeContent.confirmMessage"><![CDATA[Do you really want to delete the reported content?]]></item>
+ <item name="wcf.moderation.report.removeContent.confirmMessage"><![CDATA[Do you really want to delete the reported content{if $moderationQueueCount|isset && $moderationQueueCount > 1}s{/if}?]]></item>
<item name="wcf.moderation.report.removeContent.reason"><![CDATA[Reason (optional)]]></item>
<item name="wcf.moderation.report.removeReport"><![CDATA[Close Report]]></item>
- <item name="wcf.moderation.report.removeReport.confirmMessage"><![CDATA[Do you really want to close this report?]]></item>
+ <item name="wcf.moderation.report.removeReport.confirmMessage"><![CDATA[Do you really want to close {if !$moderationQueueCount|isset || $moderationQueueCount == 1}this report{else}these reports{/if}?]]></item>
<item name="wcf.moderation.report.removeReport.markAsJustified"><![CDATA[Also mark report as “Justified”]]></item>
<item name="wcf.moderation.report.reportContent"><![CDATA[Report Content]]></item>
<item name="wcf.moderation.report.reportedBy"><![CDATA[Reported by]]></item>