2 namespace wcf\data\comment
;
3 use wcf\data\comment\response\CommentResponse
;
4 use wcf\data\comment\response\CommentResponseAction
;
5 use wcf\data\comment\response\CommentResponseEditor
;
6 use wcf\data\comment\response\CommentResponseList
;
7 use wcf\data\comment\response\StructuredCommentResponse
;
8 use wcf\data\
object\type\ObjectTypeCache
;
9 use wcf\data\user\UserProfile
;
10 use wcf\data\AbstractDatabaseObjectAction
;
11 use wcf\system\comment\CommentHandler
;
12 use wcf\system\exception\PermissionDeniedException
;
13 use wcf\system\exception\UserInputException
;
14 use wcf\system\like\LikeHandler
;
15 use wcf\system\user\activity\event\UserActivityEventHandler
;
16 use wcf\system\user\notification\
object\CommentResponseUserNotificationObject
;
17 use wcf\system\user\notification\
object\CommentUserNotificationObject
;
18 use wcf\system\user\notification\UserNotificationHandler
;
20 use wcf\util\MessageUtil
;
23 * Executes comment-related actions.
25 * @author Alexander Ebert
26 * @copyright 2001-2014 WoltLab GmbH
27 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
28 * @package com.woltlab.wcf
29 * @subpackage data.comment
30 * @category Community Framework
32 class CommentAction
extends AbstractDatabaseObjectAction
{
34 * @see \wcf\data\AbstractDatabaseObjectAction::$allowGuestAccess
36 protected $allowGuestAccess = array('loadComments');
39 * @see \wcf\data\AbstractDatabaseObjectAction::$className
41 protected $className = 'wcf\data\comment\CommentEditor';
45 * @var \wcf\data\comment\Comment
47 protected $comment = null;
51 * @var \wcf\system\comment\manager\ICommentManager
53 protected $commentProcessor = null;
57 * @var \wcf\data\comment\response\CommentResponse
59 protected $response = null;
62 * @see \wcf\data\AbstractDatabaseObjectAction::delete()
64 public function delete() {
65 if (empty($this->objects
)) {
70 $processors = array();
71 $groupCommentIDs = $commentIDs = array();
72 foreach ($this->objects
as $comment) {
73 if (!isset($processors[$comment->objectTypeID
])) {
74 $objectType = ObjectTypeCache
::getInstance()->getObjectType($comment->objectTypeID
);
75 $processors[$comment->objectTypeID
] = $objectType->getProcessor();
77 $groupCommentIDs[$comment->objectTypeID
] = array();
80 $processors[$comment->objectTypeID
]->updateCounter($comment->objectID
, -1 * ($comment->responses +
1));
81 $groupCommentIDs[$comment->objectTypeID
][] = $comment->commentID
;
82 $commentIDs[] = $comment->commentID
;
85 if (!empty($groupCommentIDs)) {
86 $likeObjectIDs = array();
87 foreach ($groupCommentIDs as $objectTypeID => $objectIDs) {
88 // remove activity events
89 $objectType = ObjectTypeCache
::getInstance()->getObjectType($objectTypeID);
90 if (UserActivityEventHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.recentActivityEvent')) {
91 UserActivityEventHandler
::getInstance()->removeEvents($objectType->objectType
.'.recentActivityEvent', $objectIDs);
94 $likeObjectIDs = array_merge($likeObjectIDs, $objectIDs);
96 // delete notifications
97 $objectType = ObjectTypeCache
::getInstance()->getObjectType($comment->objectTypeID
);
98 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.notification')) {
99 UserNotificationHandler
::getInstance()->deleteNotifications('comment', $objectType->objectType
.'.notification', array(), $objectIDs);
104 LikeHandler
::getInstance()->removeLikes('com.woltlab.wcf.comment', $likeObjectIDs);
108 if (!empty($commentIDs)) {
109 $commentResponseList = new CommentResponseList();
110 $commentResponseList->getConditionBuilder()->add('comment_response.commentID IN (?)', array($commentIDs));
111 $commentResponseList->readObjectIDs();
112 if (count($commentResponseList->getObjectIDs())) {
113 $action = new CommentResponseAction($commentResponseList->getObjectIDs(), 'delete', array(
114 'ignoreCounters' => true
116 $action->executeAction();
120 return parent
::delete();
124 * Validates parameters to load comments.
126 public function validateLoadComments() {
127 $this->readInteger('lastCommentTime', false, 'data');
128 $this->readInteger('objectID', false, 'data');
130 $objectType = $this->validateObjectType();
131 $this->commentProcessor
= $objectType->getProcessor();
132 if (!$this->commentProcessor
->isAccessible($this->parameters
['data']['objectID'])) {
133 throw new PermissionDeniedException();
138 * Returns parsed comments.
142 public function loadComments() {
143 $commentList = CommentHandler
::getInstance()->getCommentList($this->commentProcessor
, $this->parameters
['data']['objectTypeID'], $this->parameters
['data']['objectID'], false);
144 $commentList->getConditionBuilder()->add("comment.time < ?", array($this->parameters
['data']['lastCommentTime']));
145 $commentList->readObjects();
147 WCF
::getTPL()->assign(array(
148 'commentList' => $commentList,
149 'likeData' => (MODULE_LIKE ?
$commentList->getLikeData() : array())
153 'lastCommentTime' => $commentList->getMinCommentTime(),
154 'template' => WCF
::getTPL()->fetch('commentList')
159 * Validates parameters to add a comment.
161 public function validateAddComment() {
162 CommentHandler
::enforceFloodControl();
164 $this->readInteger('objectID', false, 'data');
165 $this->validateMessage();
166 $objectType = $this->validateObjectType();
168 // validate object id and permissions
169 $this->commentProcessor
= $objectType->getProcessor();
170 if (!$this->commentProcessor
->canAdd($this->parameters
['data']['objectID'])) {
171 throw new PermissionDeniedException();
180 public function addComment() {
182 $comment = CommentEditor
::create(array(
183 'objectTypeID' => $this->parameters
['data']['objectTypeID'],
184 'objectID' => $this->parameters
['data']['objectID'],
186 'userID' => WCF
::getUser()->userID
,
187 'username' => WCF
::getUser()->username
,
188 'message' => $this->parameters
['data']['message'],
190 'responseIDs' => serialize(array())
194 $this->commentProcessor
->updateCounter($this->parameters
['data']['objectID'], 1);
196 // fire activity event
197 $objectType = ObjectTypeCache
::getInstance()->getObjectType($this->parameters
['data']['objectTypeID']);
198 if (UserActivityEventHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.recentActivityEvent')) {
199 UserActivityEventHandler
::getInstance()->fireEvent($objectType->objectType
.'.recentActivityEvent', $comment->commentID
);
202 // fire notification event
203 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.notification')) {
204 $notificationObjectType = UserNotificationHandler
::getInstance()->getObjectTypeProcessor($objectType->objectType
.'.notification');
205 $userID = $notificationObjectType->getOwnerID($comment->commentID
);
206 if ($userID != WCF
::getUser()->userID
) {
207 $notificationObject = new CommentUserNotificationObject($comment);
209 UserNotificationHandler
::getInstance()->fireEvent('comment', $objectType->objectType
.'.notification', $notificationObject, array($userID));
214 'template' => $this->renderComment($comment)
219 * Validates parameters to add a response.
221 public function validateAddResponse() {
222 CommentHandler
::enforceFloodControl();
224 $this->readInteger('objectID', false, 'data');
225 $this->validateMessage();
227 // validate comment id
228 $this->validateCommentID();
230 // validate object type id
231 $objectType = $this->validateObjectType();
233 // validate object id and permissions
234 $this->commentProcessor
= $objectType->getProcessor();
235 if (!$this->commentProcessor
->canAdd($this->parameters
['data']['objectID'])) {
236 throw new PermissionDeniedException();
245 public function addResponse() {
247 $response = CommentResponseEditor
::create(array(
248 'commentID' => $this->comment
->commentID
,
250 'userID' => WCF
::getUser()->userID
,
251 'username' => WCF
::getUser()->username
,
252 'message' => $this->parameters
['data']['message']
255 // update response data
256 $responseIDs = $this->comment
->getResponseIDs();
257 if (count($responseIDs) < 3) {
258 $responseIDs[] = $response->responseID
;
260 $responses = $this->comment
->responses +
1;
263 $commentEditor = new CommentEditor($this->comment
);
264 $commentEditor->update(array(
265 'responseIDs' => serialize($responseIDs),
266 'responses' => $responses
270 $this->commentProcessor
->updateCounter($this->parameters
['data']['objectID'], 1);
272 // fire activity event
273 $objectType = ObjectTypeCache
::getInstance()->getObjectType($this->comment
->objectTypeID
);
274 if (UserActivityEventHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.response.recentActivityEvent')) {
275 UserActivityEventHandler
::getInstance()->fireEvent($objectType->objectType
.'.response.recentActivityEvent', $response->responseID
);
278 // fire notification event
279 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.response.notification')) {
280 $notificationObject = new CommentResponseUserNotificationObject($response);
281 if ($this->comment
->userID
!= WCF
::getUser()->userID
) {
282 UserNotificationHandler
::getInstance()->fireEvent('commentResponse', $objectType->objectType
.'.response.notification', $notificationObject, array($this->comment
->userID
));
285 // notify the container owner
286 if (UserNotificationHandler
::getInstance()->getObjectTypeID($objectType->objectType
.'.notification')) {
287 $notificationObjectType = UserNotificationHandler
::getInstance()->getObjectTypeProcessor($objectType->objectType
.'.notification');
288 $userID = $notificationObjectType->getOwnerID($this->comment
->commentID
);
290 if ($userID != $this->comment
->userID
&& $userID != WCF
::getUser()->userID
) {
291 UserNotificationHandler
::getInstance()->fireEvent('commentResponseOwner', $objectType->objectType
.'.response.notification', $notificationObject, array($userID));
297 'commentID' => $this->comment
->commentID
,
298 'template' => $this->renderResponse($response),
299 'responses' => $responses
304 * Validates parameters to edit a comment or a response.
306 public function validatePrepareEdit() {
307 // validate comment id or response id
309 $this->validateCommentID();
311 catch (UserInputException
$e) {
313 $this->validateResponseID();
315 catch (UserInputException
$e) {
316 throw new UserInputException('objectIDs');
320 // validate object type id
321 $objectType = $this->validateObjectType();
323 // validate object id and permissions
324 $this->commentProcessor
= $objectType->getProcessor();
325 if ($this->comment
!== null) {
326 if (!$this->commentProcessor
->canEditComment($this->comment
)) {
327 throw new PermissionDeniedException();
331 if (!$this->commentProcessor
->canEditResponse($this->response
)) {
332 throw new PermissionDeniedException();
338 * Prepares editing of a comment or a response.
342 public function prepareEdit() {
344 if ($this->comment
!== null) {
345 $message = $this->comment
->message
;
348 $message = $this->response
->message
;
351 $returnValues = array(
352 'action' => 'prepare',
353 'message' => $message
355 if ($this->comment
!== null) {
356 $returnValues['commentID'] = $this->comment
->commentID
;
359 $returnValues['responseID'] = $this->response
->responseID
;
362 return $returnValues;
366 * @see \wcf\data\comment\CommentAction::validatePrepareEdit()
368 public function validateEdit() {
369 $this->validatePrepareEdit();
371 $this->validateMessage();
375 * Edits a comment or response.
379 public function edit() {
380 $returnValues = array(
384 if ($this->response
=== null) {
385 $editor = new CommentEditor($this->comment
);
386 $editor->update(array(
387 'message' => $this->parameters
['data']['message']
389 $comment = new Comment($this->comment
->commentID
);
390 $returnValues['commentID'] = $this->comment
->commentID
;
391 $returnValues['message'] = $comment->getFormattedMessage();
394 $editor = new CommentResponseEditor($this->response
);
395 $editor->update(array(
396 'message' => $this->parameters
['data']['message']
398 $response = new CommentResponse($this->response
->responseID
);
399 $returnValues['responseID'] = $this->response
->responseID
;
400 $returnValues['message'] = $response->getFormattedMessage();
403 return $returnValues;
407 * Validates parameters to remove a comment or response.
409 public function validateRemove() {
410 // validate comment id or response id
412 $this->validateCommentID();
414 catch (UserInputException
$e) {
416 $this->validateResponseID();
418 catch (UserInputException
$e) {
419 throw new UserInputException('objectIDs');
423 // validate object type id
424 $objectType = $this->validateObjectType();
426 // validate object id and permissions
427 $this->commentProcessor
= $objectType->getProcessor();
428 if ($this->comment
!== null) {
429 if (!$this->commentProcessor
->canDeleteComment($this->comment
)) {
430 throw new PermissionDeniedException();
434 if (!$this->commentProcessor
->canDeleteResponse($this->response
)) {
435 throw new PermissionDeniedException();
441 * Removes a comment or response.
445 public function remove() {
446 if ($this->comment
!== null) {
447 $objectAction = new CommentAction(array($this->comment
), 'delete');
448 $objectAction->executeAction();
451 'commentID' => $this->comment
->commentID
455 $objectAction = new CommentResponseAction(array($this->response
), 'delete');
456 $objectAction->executeAction();
459 'responseID' => $this->response
->responseID
467 * @param \wcf\data\comment\Comment $comment
470 protected function renderComment(Comment
$comment) {
471 $comment = new StructuredComment($comment);
472 $comment->setIsDeletable($this->commentProcessor
->canDeleteComment($comment->getDecoratedObject()));
473 $comment->setIsEditable($this->commentProcessor
->canEditComment($comment->getDecoratedObject()));
476 $userProfile = UserProfile
::getUserProfile($comment->userID
);
477 $comment->setUserProfile($userProfile);
479 WCF
::getTPL()->assign(array(
480 'commentList' => array($comment)
482 return WCF
::getTPL()->fetch('commentList');
486 * Renders a response.
488 * @param \wcf\data\comment\response\CommentResponse $response
491 protected function renderResponse(CommentResponse
$response) {
492 $response = new StructuredCommentResponse($response);
493 $response->setIsDeletable($this->commentProcessor
->canDeleteResponse($response->getDecoratedObject()));
494 $response->setIsEditable($this->commentProcessor
->canEditResponse($response->getDecoratedObject()));
497 $userProfile = UserProfile
::getUserProfile($response->userID
);
498 $response->setUserProfile($userProfile);
501 WCF
::getTPL()->assign(array(
502 'responseList' => array($response)
504 return WCF
::getTPL()->fetch('commentResponseList');
508 * Validates message parameter.
510 protected function validateMessage() {
511 $this->readString('message', false, 'data');
512 $this->parameters
['data']['message'] = MessageUtil
::stripCrap($this->parameters
['data']['message']);
514 if (empty($this->parameters
['data']['message'])) {
515 throw new UserInputException('message');
520 * Validates object type id parameter.
522 * @return \wcf\data\object\type\ObjectType
524 protected function validateObjectType() {
525 $this->readInteger('objectTypeID', false, 'data');
527 $objectType = ObjectTypeCache
::getInstance()->getObjectType($this->parameters
['data']['objectTypeID']);
528 if ($objectType === null) {
529 throw new UserInputException('objectTypeID');
536 * Validates comment id parameter.
538 protected function validateCommentID() {
539 $this->readInteger('commentID', false, 'data');
541 $this->comment
= new Comment($this->parameters
['data']['commentID']);
542 if ($this->comment
=== null ||
!$this->comment
->commentID
) {
543 throw new UserInputException('commentID');
548 * Validates response id parameter.
550 protected function validateResponseID() {
551 if (isset($this->parameters
['data']['responseID'])) {
552 $this->response
= new CommentResponse($this->parameters
['data']['responseID']);
554 if ($this->response
=== null ||
!$this->response
->responseID
) {
555 throw new UserInputException('responseID');
560 * Returns the comment object.
562 * @return \wcf\data\comment\Comment
564 public function getComment() {
565 return $this->comment
;
569 * Returns the comment response object.
571 * @return \wcf\data\comment\response\CommentResponse
573 public function getResponse() {
574 return $this->response
;
578 * Returns the comment manager.
580 * @return \wcf\system\comment\manager\ICommentManager
582 public function getCommentManager() {
583 return $this->commentProcessor
;