* `wcf\system\event\listener\AbstractUserActionRenameListener` added.
* `wcf\system\event\listener\AbstractUserMergeListener` added.
* Notice texts support `{$username}` and `{$email}` placeholders.
+* Notifications for comments in moderation.
#### New Traits
<definitionname>com.woltlab.wcf.comment.commentableContent</definitionname>
<classname><![CDATA[wcf\system\comment\manager\ModerationQueueCommentManager]]></classname>
</type>
+ <type>
+ <name>com.woltlab.wcf.moderation.queue.notification</name>
+ <definitionname>com.woltlab.wcf.notification.objectType</definitionname>
+ <classname><![CDATA[wcf\system\user\notification\object\type\ModerationQueueCommentUserNotificationObjectType]]></classname>
+ <category>com.woltlab.wcf.moderation</category>
+ </type>
+ <type>
+ <name>com.woltlab.wcf.moderation.queue.response.notification</name>
+ <definitionname>com.woltlab.wcf.notification.objectType</definitionname>
+ <classname><![CDATA[wcf\system\user\notification\object\type\ModerationQueueCommentResponseUserNotificationObjectType]]></classname>
+ <category>com.woltlab.wcf.moderation</category>
+ </type>
<!-- /comments -->
<!-- moderation -->
<preset>1</preset>
<options>module_like</options>
</event>
+
+ <event>
+ <name>comment</name>
+ <objecttype>com.woltlab.wcf.moderation.queue.notification</objecttype>
+ <classname><![CDATA[wcf\system\user\notification\event\ModerationQueueCommentUserNotificationEvent]]></classname>
+ <preset>1</preset>
+ <permissions>mod.general.canUseModeration</permissions>
+ </event>
+ <event>
+ <name>commentResponse</name>
+ <objecttype>com.woltlab.wcf.moderation.queue.response.notification</objecttype>
+ <classname><![CDATA[wcf\system\user\notification\event\ModerationQueueCommentResponseUserNotificationEvent]]></classname>
+ <preset>1</preset>
+ <permissions>mod.general.canUseModeration</permissions>
+ </event>
</import>
</data>
use wcf\data\comment\response\CommentResponseEditor;
use wcf\data\comment\response\CommentResponseList;
use wcf\data\comment\response\StructuredCommentResponse;
+use wcf\data\object\type\ObjectType;
use wcf\data\object\type\ObjectTypeCache;
-use wcf\data\user\UserProfile;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\system\captcha\CaptchaHandler;
use wcf\system\comment\CommentHandler;
+use wcf\system\comment\manager\ICommentManager;
use wcf\system\exception\PermissionDeniedException;
use wcf\system\exception\SystemException;
use wcf\system\exception\UserInputException;
use wcf\system\user\activity\event\UserActivityEventHandler;
use wcf\system\user\notification\object\CommentResponseUserNotificationObject;
use wcf\system\user\notification\object\CommentUserNotificationObject;
+use wcf\system\user\notification\object\type\IMultiRecipientCommentUserNotificationObjectType;
use wcf\system\user\notification\UserNotificationHandler;
use wcf\system\WCF;
use wcf\util\MessageUtil;
/**
* @see \wcf\data\AbstractDatabaseObjectAction::$allowGuestAccess
*/
- protected $allowGuestAccess = array('addComment', 'addResponse', 'loadComments', 'getGuestDialog');
+ protected $allowGuestAccess = ['addComment', 'addResponse', 'loadComments', 'getGuestDialog'];
/**
* captcha object type used for comments
- * @var \wcf\data\object\type\ObjectType
+ * @var ObjectType
*/
public $captchaObjectType = null;
/**
- * @see \wcf\data\AbstractDatabaseObjectAction::$className
+ * @inheritDoc
*/
- protected $className = 'wcf\data\comment\CommentEditor';
+ protected $className = CommentEditor::class;
/**
* comment object
- * @var \wcf\data\comment\Comment
+ * @var Comment
*/
protected $comment = null;
/**
* comment processor
- * @var \wcf\system\comment\manager\ICommentManager
+ * @var ICommentManager
*/
protected $commentProcessor = null;
/**
* response object
- * @var \wcf\data\comment\response\CommentResponse
+ * @var CommentResponse
*/
protected $response = null;
/**
* comment object created by addComment()
- * @var \wcf\data\comment\Comment
+ * @var Comment
*/
public $createdComment = null;
/**
* response object created by addResponse()
- * @var \wcf\data\comment\response\CommentResponse
+ * @var CommentResponse
*/
public $createdResponse = null;
* errors occuring durch the validation of addComment or addResponse
* @var array
*/
- public $validationErrors = array();
+ public $validationErrors = [];
/**
- * @see \wcf\data\AbstractDatabaseObjectAction::delete()
+ * @inheritDoc
*/
public function delete() {
if (empty($this->objects)) {
}
// update counters
- $processors = array();
- $groupCommentIDs = $commentIDs = array();
+ $processors = [];
+ $groupCommentIDs = $commentIDs = [];
foreach ($this->objects as $comment) {
if (!isset($processors[$comment->objectTypeID])) {
$objectType = ObjectTypeCache::getInstance()->getObjectType($comment->objectTypeID);
$processors[$comment->objectTypeID] = $objectType->getProcessor();
- $groupCommentIDs[$comment->objectTypeID] = array();
+ $groupCommentIDs[$comment->objectTypeID] = [];
}
$processors[$comment->objectTypeID]->updateCounter($comment->objectID, -1 * ($comment->responses + 1));
}
if (!empty($groupCommentIDs)) {
- $likeObjectIDs = array();
- $notificationObjectTypes = array();
+ $likeObjectIDs = [];
+ $notificationObjectTypes = [];
foreach ($groupCommentIDs as $objectTypeID => $objectIDs) {
// remove activity events
$objectType = ObjectTypeCache::getInstance()->getObjectType($objectTypeID);
// delete responses
if (!empty($commentIDs)) {
$commentResponseList = new CommentResponseList();
- $commentResponseList->getConditionBuilder()->add('comment_response.commentID IN (?)', array($commentIDs));
+ $commentResponseList->getConditionBuilder()->add('comment_response.commentID IN (?)', [$commentIDs]);
$commentResponseList->readObjectIDs();
if (count($commentResponseList->getObjectIDs())) {
- $action = new CommentResponseAction($commentResponseList->getObjectIDs(), 'delete', array(
+ $action = new CommentResponseAction($commentResponseList->getObjectIDs(), 'delete', [
'ignoreCounters' => true
- ));
+ ]);
$action->executeAction();
}
}
*/
public function loadComments() {
$commentList = CommentHandler::getInstance()->getCommentList($this->commentProcessor, $this->parameters['data']['objectTypeID'], $this->parameters['data']['objectID'], false);
- $commentList->getConditionBuilder()->add("comment.time < ?", array($this->parameters['data']['lastCommentTime']));
+ $commentList->getConditionBuilder()->add("comment.time < ?", [$this->parameters['data']['lastCommentTime']]);
$commentList->readObjects();
- WCF::getTPL()->assign(array(
+ WCF::getTPL()->assign([
'commentList' => $commentList,
- 'likeData' => (MODULE_LIKE ? $commentList->getLikeData() : array())
- ));
+ 'likeData' => (MODULE_LIKE ? $commentList->getLikeData() : [])
+ ]);
- return array(
+ return [
'lastCommentTime' => $commentList->getMinCommentTime(),
'template' => WCF::getTPL()->fetch('commentList')
- );
+ ];
}
/**
/**
* Adds a comment.
*
- * @return array
+ * @return string[]
*/
public function addComment() {
if (!empty($this->validationErrors)) {
WCF::getTPL()->assign('errorType', $this->validationErrors);
$guestDialog = $this->getGuestDialog();
- return array(
+ return [
'useCaptcha' => $guestDialog['useCaptcha'],
'guestDialog' => $guestDialog['template']
- );
+ ];
}
// create comment
- $this->createdComment = CommentEditor::create(array(
+ $this->createdComment = CommentEditor::create([
'objectTypeID' => $this->parameters['data']['objectTypeID'],
'objectID' => $this->parameters['data']['objectID'],
'time' => TIME_NOW,
'username' => WCF::getUser()->userID ? WCF::getUser()->username : $this->parameters['data']['username'],
'message' => $this->parameters['data']['message'],
'responses' => 0,
- 'responseIDs' => serialize(array())
- ));
+ 'responseIDs' => serialize([])
+ ]);
// update counter
$this->commentProcessor->updateCounter($this->parameters['data']['objectID'], 1);
// fire notification event
if (UserNotificationHandler::getInstance()->getObjectTypeID($objectType->objectType.'.notification')) {
+ $notificationObject = new CommentUserNotificationObject($this->createdComment);
$notificationObjectType = UserNotificationHandler::getInstance()->getObjectTypeProcessor($objectType->objectType.'.notification');
- $userID = $notificationObjectType->getOwnerID($this->createdComment->commentID);
- if ($userID != WCF::getUser()->userID) {
- $notificationObject = new CommentUserNotificationObject($this->createdComment);
+
+ if ($notificationObjectType instanceof IMultiRecipientCommentUserNotificationObjectType) {
+ $recipientIDs = $notificationObjectType->getRecipientIDs($this->createdComment);
+
+ // make sure that the active user gets no notification
+ $recipientIDs = array_diff($recipientIDs, [WCF::getUser()->userID]);
- UserNotificationHandler::getInstance()->fireEvent('comment', $objectType->objectType.'.notification', $notificationObject, array($userID), array(
- 'objectUserID' => $userID
- ));
+ if (!empty($recipientIDs)) {
+ UserNotificationHandler::getInstance()->fireEvent('comment', $objectType->objectType . '.notification', $notificationObject, $recipientIDs);
+ }
+ }
+ else {
+ $userID = $notificationObjectType->getOwnerID($this->createdComment->commentID);
+ if ($userID != WCF::getUser()->userID) {
+ UserNotificationHandler::getInstance()->fireEvent('comment', $objectType->objectType . '.notification', $notificationObject, [$userID], [
+ 'objectUserID' => $userID
+ ]);
+ }
}
}
}
}
- return array(
+ return [
'template' => $this->renderComment($this->createdComment)
- );
+ ];
}
/**
WCF::getTPL()->assign('errorType', $this->validationErrors);
$guestDialog = $this->getGuestDialog();
- return array(
+ return [
'useCaptcha' => $guestDialog['useCaptcha'],
'guestDialog' => $guestDialog['template']
- );
+ ];
}
// create response
- $this->createdResponse = CommentResponseEditor::create(array(
+ $this->createdResponse = CommentResponseEditor::create([
'commentID' => $this->comment->commentID,
'time' => TIME_NOW,
'userID' => WCF::getUser()->userID ?: null,
'username' => WCF::getUser()->userID ? WCF::getUser()->username : $this->parameters['data']['username'],
'message' => $this->parameters['data']['message']
- ));
+ ]);
// update response data
$responseIDs = $this->comment->getResponseIDs();
// update comment
$commentEditor = new CommentEditor($this->comment);
- $commentEditor->update(array(
+ $commentEditor->update([
'responseIDs' => serialize($responseIDs),
'responses' => $responses
- ));
+ ]);
// update counter
$this->commentProcessor->updateCounter($this->parameters['data']['objectID'], 1);
// fire notification event
if (UserNotificationHandler::getInstance()->getObjectTypeID($objectType->objectType.'.response.notification')) {
$notificationObjectType = UserNotificationHandler::getInstance()->getObjectTypeProcessor($objectType->objectType.'.notification');
- $userID = $notificationObjectType->getOwnerID($this->comment->commentID);
-
$notificationObject = new CommentResponseUserNotificationObject($this->createdResponse);
- if ($this->comment->userID != WCF::getUser()->userID) {
- UserNotificationHandler::getInstance()->fireEvent('commentResponse', $objectType->objectType.'.response.notification', $notificationObject, array($this->comment->userID), array(
- 'commentID' => $this->comment->commentID,
- 'objectID' => $this->comment->objectID,
- 'objectUserID' => $userID,
- 'userID' => $this->comment->userID
- ));
- }
- // notify the container owner
- if (UserNotificationHandler::getInstance()->getObjectTypeID($objectType->objectType.'.notification')) {
- if ($userID != $this->comment->userID && $userID != WCF::getUser()->userID) {
- UserNotificationHandler::getInstance()->fireEvent('commentResponseOwner', $objectType->objectType.'.response.notification', $notificationObject, array($userID), array(
+ if ($notificationObjectType instanceof IMultiRecipientCommentUserNotificationObjectType) {
+ $recipientIDs = $notificationObjectType->getRecipientIDs($this->comment);
+
+ // make sure that the active user gets no notification
+ $recipientIDs = array_diff($recipientIDs, [WCF::getUser()->userID]);
+
+ if (!empty($recipientIDs)) {
+ UserNotificationHandler::getInstance()->fireEvent('commentResponse', $objectType->objectType.'.response.notification', $notificationObject, $recipientIDs, [
+ 'commentID' => $this->comment->commentID,
+ 'objectID' => $this->comment->objectID,
+ 'userID' => $this->comment->userID
+ ]);
+ }
+ }
+ else {
+ $userID = $notificationObjectType->getOwnerID($this->comment->commentID);
+
+ if ($this->comment->userID != WCF::getUser()->userID) {
+ UserNotificationHandler::getInstance()->fireEvent('commentResponse', $objectType->objectType.'.response.notification', $notificationObject, [$this->comment->userID], [
'commentID' => $this->comment->commentID,
'objectID' => $this->comment->objectID,
'objectUserID' => $userID,
'userID' => $this->comment->userID
- ));
+ ]);
+ }
+
+ // notify the container owner
+ if (UserNotificationHandler::getInstance()->getObjectTypeID($objectType->objectType.'.notification')) {
+ if ($userID != $this->comment->userID && $userID != WCF::getUser()->userID) {
+ UserNotificationHandler::getInstance()->fireEvent('commentResponseOwner', $objectType->objectType . '.response.notification', $notificationObject, [$userID], [
+ 'commentID' => $this->comment->commentID,
+ 'objectID' => $this->comment->objectID,
+ 'objectUserID' => $userID,
+ 'userID' => $this->comment->userID
+ ]);
+ }
}
}
}
}
}
- return array(
+ return [
'commentID' => $this->comment->commentID,
'template' => $this->renderResponse($this->createdResponse),
'responses' => $responses
- );
+ ];
}
/**
$message = $this->response->message;
}
- $returnValues = array(
+ $returnValues = [
'action' => 'prepare',
'message' => $message
- );
+ ];
if ($this->comment !== null) {
$returnValues['commentID'] = $this->comment->commentID;
}
}
/**
- * @see \wcf\data\comment\CommentAction::validatePrepareEdit()
+ * @inheritDoc
*/
public function validateEdit() {
$this->validatePrepareEdit();
* @return array
*/
public function edit() {
- $returnValues = array(
- 'action' => 'saved',
- );
+ $returnValues = ['action' => 'saved'];
if ($this->response === null) {
$editor = new CommentEditor($this->comment);
- $editor->update(array(
+ $editor->update([
'message' => $this->parameters['data']['message']
- ));
+ ]);
$comment = new Comment($this->comment->commentID);
$returnValues['commentID'] = $this->comment->commentID;
$returnValues['message'] = $comment->getFormattedMessage();
}
else {
$editor = new CommentResponseEditor($this->response);
- $editor->update(array(
+ $editor->update([
'message' => $this->parameters['data']['message']
- ));
+ ]);
$response = new CommentResponse($this->response->responseID);
$returnValues['responseID'] = $this->response->responseID;
$returnValues['message'] = $response->getFormattedMessage();
/**
* Removes a comment or response.
*
- * @return array
+ * @return integer[]
*/
public function remove() {
if ($this->comment !== null) {
- $objectAction = new CommentAction(array($this->comment), 'delete');
+ $objectAction = new CommentAction([$this->comment], 'delete');
$objectAction->executeAction();
- return array(
- 'commentID' => $this->comment->commentID
- );
+ return ['commentID' => $this->comment->commentID];
}
else {
- $objectAction = new CommentResponseAction(array($this->response), 'delete');
+ $objectAction = new CommentResponseAction([$this->response], 'delete');
$objectAction->executeAction();
- return array(
- 'responseID' => $this->response->responseID
- );
+ return ['responseID' => $this->response->responseID];
}
}
}
}
- return array(
+ return [
'useCaptcha' => $captchaObjectType !== null,
- 'template' => WCF::getTPL()->fetch('commentAddGuestDialog', 'wcf', array(
+ 'template' => WCF::getTPL()->fetch('commentAddGuestDialog', 'wcf', [
'ajaxCaptcha' => true,
'captchaID' => 'commentAdd',
'captchaObjectType' => $captchaObjectType,
'username' => WCF::getSession()->getVar('username')
- ))
- );
+ ])
+ ];
}
/**
* Renders a comment.
*
- * @param \wcf\data\comment\Comment $comment
+ * @param Comment $comment
* @return string
*/
protected function renderComment(Comment $comment) {
$comment->setIsDeletable($this->commentProcessor->canDeleteComment($comment->getDecoratedObject()));
$comment->setIsEditable($this->commentProcessor->canEditComment($comment->getDecoratedObject()));
- WCF::getTPL()->assign(array(
- 'commentList' => array($comment),
+ WCF::getTPL()->assign([
+ 'commentList' => [$comment],
'commentManager' => $this->commentProcessor
- ));
+ ]);
return WCF::getTPL()->fetch('commentList');
}
/**
* Renders a response.
*
- * @param \wcf\data\comment\response\CommentResponse $response
+ * @param CommentResponse $response
* @return string
*/
protected function renderResponse(CommentResponse $response) {
$response->setIsEditable($this->commentProcessor->canEditResponse($response->getDecoratedObject()));
// render response
- WCF::getTPL()->assign(array(
- 'responseList' => array($response),
+ WCF::getTPL()->assign([
+ 'responseList' => [$response],
'commentManager' => $this->commentProcessor
- ));
+ ]);
return WCF::getTPL()->fetch('commentResponseList');
}
/**
* Validates object type id parameter.
*
- * @return \wcf\data\object\type\ObjectType
+ * @return ObjectType
*/
protected function validateObjectType() {
$this->readInteger('objectTypeID', false, 'data');
$this->captchaObjectType->getProcessor()->validate();
}
catch (UserInputException $e) {
- $this->validationErrors = array_merge($this->validationErrors,
- array(
- $e->getField() => $e->getType()
- )
- );
+ $this->validationErrors = array_merge($this->validationErrors, [$e->getField() => $e->getType()]);
}
}
/**
* Returns the comment object.
*
- * @return \wcf\data\comment\Comment
+ * @return Comment
*/
public function getComment() {
return $this->comment;
/**
* Returns the comment response object.
*
- * @return \wcf\data\comment\response\CommentResponse
+ * @return CommentResponse
*/
public function getResponse() {
return $this->response;
/**
* Returns the comment manager.
*
- * @return \wcf\system\comment\manager\ICommentManager
+ * @return ICommentManager
*/
public function getCommentManager() {
return $this->commentProcessor;
<?php
namespace wcf\data\moderation\queue;
+use wcf\data\ILinkableObject;
use wcf\data\object\type\ObjectTypeCache;
use wcf\data\user\User;
use wcf\data\user\UserProfile;
use wcf\data\user\UserProfileCache;
use wcf\data\DatabaseObjectDecorator;
+use wcf\data\ITitledObject;
use wcf\data\IUserContent;
use wcf\system\bbcode\SimpleMessageParser;
use wcf\system\moderation\queue\ModerationQueueManager;
* @subpackage data.moderation.queue
* @category Community Framework
*/
-class ViewableModerationQueue extends DatabaseObjectDecorator {
+class ViewableModerationQueue extends DatabaseObjectDecorator implements ILinkableObject, ITitledObject {
/**
- * @see \wcf\data\DatabaseObject::$baseClass
+ * @inheritDoc
*/
- protected static $baseClass = 'wcf\data\moderation\queue\ModerationQueue';
+ protected static $baseClass = ModerationQueue::class;
/**
* affected object
- * @var \wcf\data\IUserContent
+ * @var IUserContent
*/
protected $affectedObject = null;
/**
* user profile object
- * @var \wcf\data\user\UserProfile
+ * @var UserProfile
*/
protected $userProfile = null;
/**
* Sets link for viewing/editing.
*
- * @param \wcf\data\IUserContent $object
+ * @param IUserContent $object
*/
public function setAffectedObject(IUserContent $object) {
$this->affectedObject = $object;
}
/**
- * Returns the link for viewing/editing this object.
- *
- * @return string
+ * @inheritDoc
*/
public function getLink() {
return ModerationQueueManager::getInstance()->getLink($this->objectTypeID, $this->queueID);
}
/**
- * Returns the title for this entry.
- *
- * @return string
+ * @inheritDoc
*/
public function getTitle() {
return ($this->affectedObject === null ? '' : $this->affectedObject->getTitle());
/**
* Returns affected object.
*
- * @return \wcf\data\IUserContent
+ * @return IUserContent
*/
public function getAffectedObject() {
return $this->affectedObject;
/**
* Sets associated user profile object.
*
- * @param \wcf\data\user\UserProfile $userProfile
+ * @param UserProfile $userProfile
*/
public function setUserProfile(UserProfile $userProfile) {
if ($this->affectedObject !== null && ($userProfile->userID == $this->affectedObject->getUserID())) {
/**
* Returns associated user profile object.
*
- * @return \wcf\data\user\UserProfile
+ * @return UserProfile
*/
public function getUserProfile() {
if ($this->affectedObject !== null && $this->userProfile === null) {
$this->userProfile = UserProfileCache::getInstance()->getUserProfile($this->affectedObject->getUserID());
}
else {
- $this->userProfile = new UserProfile(new User(null, array()));
+ $this->userProfile = new UserProfile(new User(null, []));
}
}
* Returns a viewable moderation queue entry.
*
* @param integer $queueID
- * @return \wcf\data\moderation\queue\ViewableModerationQueue
+ * @return ViewableModerationQueue
*/
public static function getViewableModerationQueue($queueID) {
$queueList = new ViewableModerationQueueList();
- $queueList->getConditionBuilder()->add("moderation_queue.queueID = ?", array($queueID));
+ $queueList->getConditionBuilder()->add("moderation_queue.queueID = ?", [$queueID]);
$queueList->sqlLimit = 1;
$queueList->readObjects();
$queues = $queueList->getObjects();
use wcf\data\user\UserProfile;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
+use wcf\system\moderation\queue\activation\IModerationQueueActivationHandler;
+use wcf\system\moderation\queue\report\IModerationQueueReportHandler;
use wcf\system\WCF;
/**
* Default implementation for moderation queue handlers.
*
* @author Alexander Ebert
- * @copyright 2001-2015 WoltLab GmbH
+ * @copyright 2001-2016 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage system.moderation.queue
protected $requiredPermission = 'mod.general.canUseModeration';
/**
- * @see \wcf\system\moderation\queue\IModerationQueueHandler::identifyOrphans()
+ * @inheritDoc
*/
public function identifyOrphans(array $queues) {
if (empty($this->className) || !class_exists($this->className) || !is_subclass_of($this->className, 'wcf\data\DatabaseObject')) {
}
/**
- * @see \wcf\system\moderation\queue\IModerationQueueHandler::removeQueues()
+ * @inheritDoc
*/
public function removeQueues(array $objectIDs) {
$objectTypeID = ModerationQueueManager::getInstance()->getObjectTypeID($this->definitionName, $this->objectType);
}
/**
- * @see \wcf\system\moderation\queue\IModerationQueueHandler::canRemoveContent()
+ * @inheritDoc
*/
public function canRemoveContent(ModerationQueue $queue) {
return true;
}
/**
- * @see \wcf\system\moderation\queue\IModerationQueueHandler::isAffectedUser()
+ * @inheritDoc
*/
public function isAffectedUser(ModerationQueue $queue, $userID) {
$user = new UserProfile(new User($userID));
return $user->getPermission($this->requiredPermission);
}
+
+ /**
+ * @inheritDoc
+ * @since 2.2
+ */
+ public function getCommentNotificationLanguageItemPrefix() {
+ // this implementation exists to provide backwards compatibility;
+ // as there are no abstract implementations of the two interfaces,
+ // this is the best approach
+ if ($this instanceof IModerationQueueActivationHandler) {
+ return 'wcf.moderation.activation.notification';
+ }
+ else if ($this instanceof IModerationQueueReportHandler) {
+ return 'wcf.moderation.activation.notification';
+ }
+
+ return 'wcf.moderation.notification';
+ }
}
<?php
namespace wcf\system\moderation\queue;
use wcf\data\moderation\queue\ModerationQueue;
+use wcf\data\moderation\queue\ViewableModerationQueue;
/**
* Default interface for moderation queue handlers.
/**
* Creates queue assignments for matching object ids.
*
- * @param array<\wcf\data\moderation\queue\ModerationQueue> $queues
+ * @param ModerationQueue[] $queues
*/
public function assignQueues(array $queues);
/**
* Validates object ids and returns orphaned queue ids.
*
- * @param array<integer> $queues
- * @return array<integer>
+ * @param integer[] $queues
+ * @return integer[]
*/
public function identifyOrphans(array $queues);
/**
* Populates object properties for viewing.
*
- * @param array<\wcf\data\moderation\queue\ViewableModerationQueue> $queues
+ * @param ViewableModerationQueue[] $queues
*/
public function populate(array $queues);
* Removes affected content. It is up to the processing class to either
* soft-delete the content or remove it permanently.
*
- * @param \wcf\data\moderation\queue\ModerationQueue $queue
- * @param string $message
+ * @param ModerationQueue $queue
+ * @param string $message
*/
public function removeContent(ModerationQueue $queue, $message);
* Removes queses from database, should only be called if the referenced
* object is permanently deleted.
*
- * @param array<integer> $objectIDs
+ * @param integer[] $objectIDs
*/
public function removeQueues(array $objectIDs);
/**
* Returns true, if given user is affected by given queue entry.
*
- * @param \wcf\data\moderation\queue\ModerationQueue $queue
- * @param integer $userID
+ * @param ModerationQueue $queue
+ * @param integer $userID
* @return boolean
*/
public function isAffectedUser(ModerationQueue $queue, $userID);
+
+ /**
+ * Returns the prefix of language items for notifications for comments
+ * and comment reponses on moderation queues of this type.
+ *
+ * @return string
+ * @since 2.2
+ */
+ public function getCommentNotificationLanguageItemPrefix();
}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\event;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\system\comment\CommentDataHandler;
+use wcf\system\moderation\queue\report\IModerationQueueReportHandler;
+use wcf\system\WCF;
+
+/**
+ * User notification event for moderation queue commments.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.event
+ * @category Community Framework
+ * @since 2.2
+ */
+class ModerationQueueCommentResponseUserNotificationEvent extends AbstractSharedUserNotificationEvent {
+ /**
+ * language item prefix for the notification texts
+ * @var string
+ */
+ protected $languageItemPrefix = null;
+
+ /**
+ * moderation queue object the notifications (indirectly) belong to
+ * @var ViewableModerationQueue
+ */
+ protected $moderationQueue = null;
+
+ /**
+ * true if the moderation queue is already loaded
+ * @var boolean
+ */
+ protected $moderationQueueLoaded = false;
+
+ /**
+ * @inheritDoc
+ */
+ protected $stackable = true;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkAccess() {
+ if (!WCF::getSession()->getPermission('mod.general.canUseModeration') || $this->getModerationQueue() === null) {
+ return false;
+ }
+
+ return $this->getModerationQueue()->canEdit();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getEmailMessage($notificationType = 'instant') {
+ $authors = $this->getAuthors();
+ if (count($authors) > 1) {
+ if (isset($authors[0])) {
+ unset($authors[0]);
+ }
+ $count = count($authors);
+
+ return $this->getLanguage()->getDynamicVariable($this->getLanguageItemPrefix().'.commentResponse.mail.stacked', [
+ 'author' => $this->author,
+ 'authors' => array_values($authors),
+ 'count' => $count,
+ 'notificationType' => $notificationType,
+ 'others' => $count - 1,
+ 'moderationQueue' => $this->getModerationQueue(),
+ 'response' => $this->userNotificationObject
+ ]);
+ }
+
+ $comment = CommentDataHandler::getInstance()->getComment($this->userNotificationObject->commentID);
+ if ($comment->userID) {
+ $commentAuthor = CommentDataHandler::getInstance()->getUser($comment->userID);
+ }
+ else {
+ $commentAuthor = new User(null, [
+ 'username' => $comment->username
+ ]);
+ }
+
+ return $this->getLanguage()->getDynamicVariable($this->getLanguageItemPrefix().'.commentResponse.mail', [
+ 'author' => $this->author,
+ 'commentAuthor' => $commentAuthor,
+ 'moderationQueue' => $this->getModerationQueue(),
+ 'notificationType' => $notificationType,
+ 'response' => $this->userNotificationObject
+ ]);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getEventHash() {
+ return sha1($this->eventID . '-' . $this->getModerationQueue()->queueID);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getLink() {
+ return $this->getModerationQueue()->getLink() . '#comments';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getMessage() {
+ $authors = $this->getAuthors();
+ if (count($authors) > 1) {
+ if (isset($authors[0])) {
+ unset($authors[0]);
+ }
+ $count = count($authors);
+
+ return $this->getLanguage()->getDynamicVariable($this->getLanguageItemPrefix().'.commentResponse.message.stacked', [
+ 'authors' => array_values($authors),
+ 'count' => $count,
+ 'others' => $count - 1,
+ 'moderationQueue' => $this->getModerationQueue()
+ ]);
+ }
+
+ $comment = CommentDataHandler::getInstance()->getComment($this->userNotificationObject->commentID);
+ if ($comment->userID) {
+ $commentAuthor = CommentDataHandler::getInstance()->getUser($comment->userID);
+ }
+ else {
+ $commentAuthor = new User(null, [
+ 'username' => $comment->username
+ ]);
+ }
+
+ return $this->getLanguage()->getDynamicVariable($this->getLanguageItemPrefix().'.commentResponse.message', [
+ 'author' => $this->author,
+ 'commentAuthor' => $commentAuthor,
+ 'moderationQueue' => $this->getModerationQueue()
+ ]);
+ }
+
+ /**
+ * Returns the moderation queue object the responded to comment belongs to.
+ * Returns null if the active user has no access to the moderation queue.
+ *
+ * @return ViewableModerationQueue
+ */
+ public function getModerationQueue() {
+ if (!$this->moderationQueueLoaded) {
+ $comment = CommentDataHandler::getInstance()->getComment($this->userNotificationObject->commentID);
+
+ $this->moderationQueue = ViewableModerationQueue::getViewableModerationQueue($comment->objectID);
+ $this->moderationQueueLoaded = true;
+ }
+
+ return $this->moderationQueue;
+ }
+
+ /**
+ * Returns the language item prefix for the notification texts.
+ *
+ * @return string
+ */
+ public function getLanguageItemPrefix() {
+ if ($this->languageItemPrefix === null) {
+ /** @var IModerationQueueReportHandler $moderationHandler */
+ $moderationHandler = ObjectTypeCache::getInstance()->getObjectType($this->getModerationQueue()->objectTypeID)->getProcessor();
+ $this->languageItemPrefix = $moderationHandler->getCommentNotificationLanguageItemPrefix();
+ }
+
+ return $this->languageItemPrefix;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTitle() {
+ $count = count($this->getAuthors());
+ if ($count > 1) {
+ return $this->getLanguage()->getDynamicVariable($this->getLanguageItemPrefix().'.commentResponse.title.stacked', [
+ 'count' => $count,
+ 'timesTriggered' => $this->notification->timesTriggered
+ ]);
+ }
+
+ return $this->getLanguage()->get($this->getLanguageItemPrefix().'.commentResponse.title');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function prepare() {
+ CommentDataHandler::getInstance()->cacheCommentID($this->userNotificationObject->commentID);
+ CommentDataHandler::getInstance()->cacheUserID($this->additionalData['userID']);
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\event;
+use wcf\data\moderation\queue\ViewableModerationQueue;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\data\user\notification\UserNotification;
+use wcf\data\user\UserProfile;
+use wcf\system\moderation\queue\IModerationQueueHandler;
+use wcf\system\user\notification\object\IUserNotificationObject;
+use wcf\system\WCF;
+
+/**
+ * User notification event for moderation queue commments.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.event
+ * @category Community Framework
+ * @since 2.2
+ */
+class ModerationQueueCommentUserNotificationEvent extends AbstractUserNotificationEvent {
+ /**
+ * language item prefix for the notification texts
+ * @var string
+ */
+ protected $languageItemPrefix = '';
+
+ /**
+ * moderation queue object the notifications (indirectly) belong to
+ * @var ViewableModerationQueue
+ */
+ protected $moderationQueue = null;
+
+ /**
+ * @inheritDoc
+ */
+ protected $stackable = true;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkAccess() {
+ if ($this->moderationQueue === null || !WCF::getSession()->getPermission('mod.general.canUseModeration')) {
+ return false;
+ }
+
+ return $this->moderationQueue->canEdit();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getEmailMessage($notificationType = 'instant') {
+ $authors = $this->getAuthors();
+ if (count($authors) > 1) {
+ if (isset($authors[0])) {
+ unset($authors[0]);
+ }
+ $count = count($authors);
+
+ return $this->getLanguage()->getDynamicVariable($this->languageItemPrefix.'.comment.mail.stacked', [
+ 'author' => $this->author,
+ 'authors' => array_values($authors),
+ 'count' => $count,
+ 'others' => $count - 1,
+ 'moderationQueue' => $this->moderationQueue,
+ 'notificationType' => $notificationType
+ ]);
+ }
+
+ return $this->getLanguage()->getDynamicVariable($this->languageItemPrefix.'.comment.mail', [
+ 'comment' => $this->userNotificationObject,
+ 'author' => $this->author,
+ 'moderationQueue' => $this->moderationQueue,
+ 'notificationType' => $notificationType
+ ]);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getEventHash() {
+ return sha1($this->eventID . '-' . $this->moderationQueue->queueID);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getLink() {
+ return $this->moderationQueue->getLink() . '#comments';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getMessage() {
+ $authors = $this->getAuthors();
+ if (count($authors) > 1) {
+ if (isset($authors[0])) {
+ unset($authors[0]);
+ }
+ $count = count($authors);
+
+ return $this->getLanguage()->getDynamicVariable($this->languageItemPrefix.'.comment.message.stacked', [
+ 'author' => $this->author,
+ 'authors' => array_values($authors),
+ 'count' => $count,
+ 'others' => $count - 1,
+ 'moderationQueue' => $this->moderationQueue
+ ]);
+ }
+
+ return $this->getLanguage()->getDynamicVariable($this->languageItemPrefix.'.comment.message', [
+ 'author' => $this->author,
+ 'moderationQueue' => $this->moderationQueue
+ ]);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTitle() {
+ $count = count($this->getAuthors());
+ if ($count > 1) {
+ return $this->getLanguage()->getDynamicVariable($this->languageItemPrefix.'.comment.title.stacked', [
+ 'count' => $count,
+ 'timesTriggered' => $this->notification->timesTriggered
+ ]);
+ }
+
+ return $this->getLanguage()->get($this->languageItemPrefix.'.comment.title');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function setObject(UserNotification $notification, IUserNotificationObject $object, UserProfile $author, array $additionalData = []) {
+ parent::setObject($notification, $object, $author, $additionalData);
+
+ // if the active user has no access, $this->moderationQueue is null
+ $this->moderationQueue = ViewableModerationQueue::getViewableModerationQueue($this->userNotificationObject->objectID);
+
+ if ($this->moderationQueue) {
+ /** @var IModerationQueueHandler $moderationHandler */
+ $moderationHandler = ObjectTypeCache::getInstance()->getObjectType($this->moderationQueue->objectTypeID)->getProcessor();
+ $this->languageItemPrefix = $moderationHandler->getCommentNotificationLanguageItemPrefix();
+ }
+ }
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object\type;
+use wcf\data\comment\Comment;
+
+/**
+ * Default interface for comment user notification object types with notifications
+ * being sent to multiple recipients.
+ *
+ * This interface can also be implemented by user notification object types for
+ * comment responses. In this case, there is no distinction between commentResponse
+ * and commentResponseOwner event and only a commentResponse event is fired.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.object.type
+ * @category Community Framework
+ * @since 2.2
+ */
+interface IMultiRecipientCommentUserNotificationObjectType {
+ /**
+ * Returns the user ids of the notification recipients. If an empty array
+ * is returned, no notifications should be sent.
+ *
+ * @param integer $comment
+ * @return integer[]
+ */
+ public function getRecipientIDs(Comment $comment);
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object\type;
+use wcf\data\comment\response\CommentResponse;
+use wcf\data\comment\response\CommentResponseList;
+use wcf\system\user\notification\object\CommentResponseUserNotificationObject;
+
+/**
+ * User notification object type implementation for moderation queue comment responses.
+ *
+ * @author Mathias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.object.type
+ * @category Community Framework
+ * @since 2.2
+ */
+class ModerationQueueCommentResponseUserNotificationObjectType extends AbstractUserNotificationObjectType implements IMultiRecipientCommentUserNotificationObjectType {
+ use TMultiRecipientModerationQueueCommentUserNotificationObjectType;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $decoratorClassName = CommentResponseUserNotificationObject::class;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $objectClassName = CommentResponse::class;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $objectListClassName = CommentResponseList::class;
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object\type;
+use wcf\data\comment\Comment;
+use wcf\data\comment\CommentList;
+use wcf\system\user\notification\object\CommentUserNotificationObject;
+
+/**
+ * User notification object type implementation for moderation queue comments.
+ *
+ * @author Mathias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.object.type
+ * @category Community Framework
+ * @since 2.2
+ */
+class ModerationQueueCommentUserNotificationObjectType extends AbstractUserNotificationObjectType implements IMultiRecipientCommentUserNotificationObjectType {
+ use TMultiRecipientModerationQueueCommentUserNotificationObjectType;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $decoratorClassName = CommentUserNotificationObject::class;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $objectClassName = Comment::class;
+
+ /**
+ * @inheritDoc
+ */
+ protected static $objectListClassName = CommentList::class;
+}
--- /dev/null
+<?php
+namespace wcf\system\user\notification\object\type;
+use wcf\data\comment\Comment;
+use wcf\data\user\UserProfile;
+use wcf\data\user\UserProfileCache;
+use wcf\system\comment\CommentHandler;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\user\storage\UserStorageHandler;
+use wcf\system\WCF;
+
+/**
+ * Implements IMultiRecipientCommentUserNotificationObjectType::getRecipientIDs()
+ * for moderation queue comment user notification object types.
+ *
+ * @author Mathias Schmidt
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.user.notification.object.type
+ * @category Community Framework
+ * @since 2.2
+ */
+trait TMultiRecipientModerationQueueCommentUserNotificationObjectType {
+ /**
+ * @see IMultiRecipientCommentUserNotificationObjectType::getRecipientIDs()
+ */
+ public function getRecipientIDs(Comment $comment) {
+ $objectTypeID = CommentHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.moderation.queue');
+ if ($comment->objectTypeID != $objectTypeID) {
+ return [];
+ }
+
+ $recipientIDs = [];
+
+ // 1. fetch assigned user
+ // 2. fetch users who commented on the moderation queue entry
+ // 3. fetch users who responded to a comment on the moderation queue entry
+ $sql = "(
+ SELECT assignedUserID
+ FROM wcf".WCF_N."_moderation_queue
+ WHERE queueID = ?
+ AND assignedUserID IS NOT NULL
+ )
+ UNION
+ (
+ SELECT DISTINCT userID
+ FROM wcf".WCF_N."_comment
+ WHERE objectID = ?
+ AND objectTypeID = ?
+ )
+ UNION
+ (
+ SELECT DISTINCT comment_response.userID
+ FROM wcf".WCF_N."_comment_response comment_response
+ LEFT JOIN wcf".WCF_N."_comment comment
+ ON (comment.commentID = comment_response.commentID)
+ WHERE comment.objectID = ?
+ AND comment.objectTypeID = ?
+ )";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute([
+ $comment->objectID,
+ $comment->objectID,
+ $objectTypeID,
+ $comment->objectID,
+ $objectTypeID
+ ]);
+ while ($userID = $statement->fetchColumn()) {
+ $recipientIDs[] = $userID;
+ }
+
+ // make sure that all users can (still) access the moderation queue entry
+ if (!empty($recipientIDs)) {
+ $conditionBuilder = new PreparedStatementConditionBuilder();
+ $conditionBuilder->add('userID IN (?)', [$recipientIDs]);
+ $conditionBuilder->add('queueID = ?', [$comment->objectID]);
+ $conditionBuilder->add('isAffected = ?', [1]);
+ $sql = "SELECT userID
+ FROM wcf".WCF_N."_moderation_queue_to_user
+ ".$conditionBuilder;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditionBuilder->getParameters());
+
+ $recipientIDs = [];
+ while ($userID = $statement->fetchColumn()) {
+ $recipientIDs[] = $userID;
+ }
+
+ // make sure that all users (still) have permission to access moderation
+ if (!$recipientIDs) {
+ UserStorageHandler::getInstance()->loadStorage($recipientIDs);
+ $userProfiles = UserProfileCache::getInstance()->getUserProfiles($recipientIDs);
+ $recipientIDs = array_keys(array_filter($userProfiles, function(UserProfile $userProfile) {
+ return $userProfile->getPermission('mod.general.canUseModeration');
+ }));
+ }
+ }
+
+ return $recipientIDs;
+ }
+}
<item name="wcf.moderation.markAllAsRead.confirmMessage"><![CDATA[Wollen Sie wirklich alle Einträge als gelesen markieren?]]></item>
<item name="wcf.moderation.moderation"><![CDATA[Moderation]]></item>
<item name="wcf.moderation.noMoreItems"><![CDATA[Keine weiteren Einträge]]></item>
+ <item name="wcf.moderation.notification.comment.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat einen Kommentar zum Moderationseintrag "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} und {#$others} weitere Benutzer{/if} haben Kommentare zum Moderationseintrag "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zum Moderationseintrag <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zum Moderationseintrag <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.notification.comment.title"><![CDATA[Neuer Kommentar (Moderation)]]></item>
+ <item name="wcf.moderation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Moderation)]]></item>
+ <item name="wcf.moderation.notification.commentResponse.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat eine Antwort zum Kommentar von "{@$commentAuthor->username}" zum Moderationseintrag "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zum Moderationseintrag "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zum Moderationseintrag <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zum Moderationseintrag <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.notification.commentResponse.title"><![CDATA[Neue Antwort (Moderation)]]></item>
+ <item name="wcf.moderation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Moderation)]]></item>
<item name="wcf.moderation.status"><![CDATA[Status]]></item>
<item name="wcf.moderation.status.outstanding"><![CDATA[Ausstehend]]></item>
<item name="wcf.moderation.status.processing"><![CDATA[In Bearbeitung]]></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[Wollen Sie diesen Inhalt wirklich freischalten?]]></item>
+ <item name="wcf.moderation.activation.notification.comment.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat einen Kommentar zum freizuschaltenden Inhalt "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3}und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} {#$others} weitere Benutzer {/if} haben Kommentare zum freizuschaltenden Inhalt "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></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.commentResponse.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat eine Antwort zum Kommentar von "{@$commentAuthor->username}" zum freizuschaltenden Inhalt "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zum freizuschaltenden Inhalt "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zum freizuschaltenden Inhalt <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.title"><![CDATA[Neue Antwort (Freischaltung)]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (Freischaltung)]]></item>
<item name="wcf.moderation.activation.removeContent"><![CDATA[Inhalt löschen]]></item>
<item name="wcf.moderation.activation.removeContent.confirmMessage"><![CDATA[Wollen Sie diesen Inhalt wirklich löschen?]]></item>
</category>
<item name="wcf.moderation.report"><![CDATA[Meldung]]></item>
<item name="wcf.moderation.report.alreadyReported"><![CDATA[Dieser Inhalt wurde bereits gemeldet.]]></item>
<item name="wcf.moderation.report.details"><![CDATA[Informationen]]></item>
+ <item name="wcf.moderation.report.notification.comment.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat einen Kommentar zur Meldung "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} und {#$others} weitere Benutzer{/if} haben Kommentare zur Meldung "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar zur Meldung <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Kommentare zur Meldung <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.report.notification.comment.title"><![CDATA[Neuer Kommentar (Meldung)]]></item>
+ <item name="wcf.moderation.report.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Meldung)]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.mail"><![CDATA[{if !$author->userID}ein Gast{else}{@$author->username}{/if} hat eine Antwort zum Kommentar von "{@$commentAuthor->username}" zur Meldung "{$moderationQueue->getTitle()}" verfasst:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zur Meldung "{$moderationQueue->getTitle()}" verfasst:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat eine Antwort zum Kommentar von {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} zur Meldung <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3}und {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weitere Benutzer{/if} haben Antworten zu Kommentare zur Meldung <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> verfasst.]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.title"><![CDATA[Neue Antwort (Meldung)]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} neue Antworten (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[Gemeldeten Inhalt löschen]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.notification.commentResponseOwner"><![CDATA[Neue Antwort auf einen Kommentar an Ihrer Pinnwand]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.like.notification.like"><![CDATA[Jemandem gefällt Ihr Kommentar]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.like.notification.like"><![CDATA[Jemandem gefällt Ihre Antwort auf einen Kommentar]]></item>
+
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation"><![CDATA[Moderation]]></item>
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation.queue.notification.comment"><![CDATA[Neuer Kommentar in der Moderation]]></item>
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation.queue.response.notification.commentResponse"><![CDATA[Neue Antwort auf einen Kommentar in der Moderation]]></item>
</category>
<category name="wcf.user.profile">
<item name="wcf.moderation.markAllAsRead.confirmMessage"><![CDATA[Do you really want to mark all entries as read?]]></item>
<item name="wcf.moderation.moderation"><![CDATA[Moderation]]></item>
<item name="wcf.moderation.noMoreItems"><![CDATA[No more items]]></item>
+ <item name="wcf.moderation.notification.comment.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a comment on the moderation entry "{$moderationQueue->getTitle()}":
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote comments on the moderation entry "{$moderationQueue->getTitle()}":
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on the moderation entry <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on the moderation entry <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.notification.comment.title"><![CDATA[New comment (Moderation)]]></item>
+ <item name="wcf.moderation.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Moderation)]]></item>
+ <item name="wcf.moderation.notification.commentResponse.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a reply to {@$commentAuthor->username}’s comment on the moderation entry "{$moderationQueue->getTitle()}":
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote replies to comments on the moderation entry "{$moderationQueue->getTitle()}":
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on the moderation entry <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote replies to comments on the moderation entry <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.notification.commentResponse.title"><![CDATA[New reply (Moderation)]]></item>
+ <item name="wcf.moderation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Moderation)]]></item>
<item name="wcf.moderation.status"><![CDATA[Status]]></item>
<item name="wcf.moderation.status.outstanding"><![CDATA[Pending]]></item>
<item name="wcf.moderation.status.processing"><![CDATA[In Progress]]></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.notification.comment.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a comment on "{$moderationQueue->getTitle()}" waiting for approval:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote comments on "{$moderationQueue->getTitle()}" waiting for approval:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
+ <item name="wcf.moderation.activation.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></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.commentResponse.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a reply to {@$commentAuthor->username}’s comment on "{$moderationQueue->getTitle()}" waiting for approval:
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote replies to comments on "{$moderationQueue->getTitle()}" waiting for approval:
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote replies to comments on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.title"><![CDATA[New reply (Approval)]]></item>
+ <item name="wcf.moderation.activation.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (Approval)]]></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>
</category>
<item name="wcf.moderation.report"><![CDATA[Report]]></item>
<item name="wcf.moderation.report.alreadyReported"><![CDATA[This content has already been reported.]]></item>
<item name="wcf.moderation.report.details"><![CDATA[Information]]></item>
+ <item name="wcf.moderation.report.notification.comment.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a comment on the report "{$moderationQueue->getTitle()}":
+{if $notificationType == 'instant'}
+---------------------------------
+{@$comment->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.comment.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote comments on the report "{$moderationQueue->getTitle()}":
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a> waiting for approval.]]></item>
+ <item name="wcf.moderation.report.notification.comment.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} other users{/if} wrote comments on the report <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.report.notification.comment.title"><![CDATA[New comment (Report)]]></item>
+ <item name="wcf.moderation.report.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Report)]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.mail"><![CDATA[{if !$author->userID}a guest{else}{@$author->username}{/if} wrote a reply to {@$commentAuthor->username}’s comment on the report "{$moderationQueue->getTitle()}":
+{if $notificationType == 'instant'}
+---------------------------------
+{@$response->message}
+---------------------------------
+{/if}{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{/if}{else}{@$authors[0]->username} and {#$others} other users{/if} wrote replies to comments on the report "{$moderationQueue->getTitle()}":
+{$moderationQueue->getLink()}#comments]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a reply to a comment by {if $commentAuthor->userID}<a href="{link controller='User' object=$commentAuthor}{/link}" class="userLink" data-user-id="{@$commentAuthor->userID}">{$commentAuthor->username}</a>{else}{$commentAuthor->username}{/if} on the report <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count != 1}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{/if}{else}{@$authors[0]->getAnchorTag()}{if $guestTimesTriggered},{else} and{/if} {#$others} other users{/if} wrote replies to comments on the report <a href="{@$moderationQueue->getLink()}">{$moderationQueue->getTitle()}</a>.]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.title"><![CDATA[New reply (Report)]]></item>
+ <item name="wcf.moderation.report.notification.commentResponse.title.stacked"><![CDATA[{#$timesTriggered} new replies (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 Reported Content]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.notification.commentResponseOwner"><![CDATA[New reply to a comment on your wall]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.like.notification.like"><![CDATA[Your comment was liked]]></item>
<item name="wcf.user.notification.com.woltlab.wcf.user.profileComment.response.like.notification.like"><![CDATA[Reply to your comment was liked]]></item>
+
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation"><![CDATA[Moderation]]></item>
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation.queue.notification.comment"><![CDATA[New comment in moderation]]></item>
+ <item name="wcf.user.notification.com.woltlab.wcf.moderation.queue.response.notification.commentResponse"><![CDATA[New reply to a comment in moderation]]></item>
</category>
<category name="wcf.user.profile">