Commit | Line | Data |
---|---|---|
9544b6b4 | 1 | <?php |
fea86294 | 2 | |
9544b6b4 | 3 | namespace wcf\data\conversation\message; |
fea86294 TD |
4 | |
5 | use wcf\data\AbstractDatabaseObjectAction; | |
9544b6b4 | 6 | use wcf\data\conversation\Conversation; |
3b34d39f | 7 | use wcf\data\conversation\ConversationAction; |
9544b6b4 | 8 | use wcf\data\conversation\ConversationEditor; |
52971287 | 9 | use wcf\data\DatabaseObject; |
e77f4283 | 10 | use wcf\data\IAttachmentMessageQuickReplyAction; |
4a2ee5bb | 11 | use wcf\data\IMessageInlineEditorAction; |
5fa9d104 | 12 | use wcf\data\IMessageQuoteAction; |
fea86294 | 13 | use wcf\data\smiley\SmileyCache; |
5d7f0df0 | 14 | use wcf\system\attachment\AttachmentHandler; |
a21c8732 | 15 | use wcf\system\bbcode\BBCodeHandler; |
7d84f6d1 | 16 | use wcf\system\conversation\ConversationHandler; |
a5f33d57 | 17 | use wcf\system\event\EventHandler; |
7d84f6d1 | 18 | use wcf\system\exception\NamedUserException; |
5e52978f AE |
19 | use wcf\system\exception\PermissionDeniedException; |
20 | use wcf\system\exception\UserInputException; | |
7d84f6d1 | 21 | use wcf\system\flood\FloodControl; |
5ff95003 | 22 | use wcf\system\html\input\HtmlInputProcessor; |
f872b5b6 | 23 | use wcf\system\html\upcast\HtmlUpcastProcessor; |
d8671029 | 24 | use wcf\system\message\censorship\Censorship; |
a0c1a541 | 25 | use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; |
5e52978f | 26 | use wcf\system\message\QuickReplyManager; |
fea86294 | 27 | use wcf\system\message\quote\MessageQuoteManager; |
3b37e024 | 28 | use wcf\system\moderation\queue\ModerationQueueManager; |
80a0761e | 29 | use wcf\system\search\SearchIndexManager; |
b5ffaf76 AE |
30 | use wcf\system\user\notification\object\ConversationMessageUserNotificationObject; |
31 | use wcf\system\user\notification\UserNotificationHandler; | |
df8f8628 | 32 | use wcf\system\user\storage\UserStorageHandler; |
9544b6b4 | 33 | use wcf\system\WCF; |
5e00d333 | 34 | use wcf\util\StringUtil; |
6d65a25b | 35 | use wcf\util\UserUtil; |
9544b6b4 MW |
36 | |
37 | /** | |
3b37e024 | 38 | * Executes conversation message-related actions. |
fea86294 TD |
39 | * |
40 | * @author Marcel Werk | |
41 | * @copyright 2001-2019 WoltLab GmbH | |
42 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
fea86294 TD |
43 | * |
44 | * @method ConversationMessageEditor[] getObjects() | |
45 | * @method ConversationMessageEditor getSingleObject() | |
9544b6b4 | 46 | */ |
fea86294 TD |
47 | class ConversationMessageAction extends AbstractDatabaseObjectAction implements |
48 | IAttachmentMessageQuickReplyAction, | |
49 | IMessageInlineEditorAction, | |
50 | IMessageQuoteAction | |
51 | { | |
52 | /** | |
53 | * @inheritDoc | |
54 | */ | |
55 | protected $className = ConversationMessageEditor::class; | |
56 | ||
57 | /** | |
58 | * conversation object | |
59 | * @var Conversation | |
60 | */ | |
61 | public $conversation; | |
62 | ||
63 | /** | |
64 | * @var HtmlInputProcessor | |
65 | */ | |
66 | public $htmlInputProcessor; | |
67 | ||
68 | /** | |
69 | * conversation message object | |
70 | * @var ConversationMessage | |
71 | */ | |
72 | public $message; | |
73 | ||
74 | /** | |
75 | * @inheritDoc | |
76 | * @return ConversationMessage | |
77 | */ | |
78 | public function create() | |
79 | { | |
80 | if (!isset($this->parameters['data']['enableHtml'])) { | |
81 | $this->parameters['data']['enableHtml'] = 1; | |
82 | } | |
83 | ||
84 | // count attachments | |
85 | if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { | |
86 | $this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']); | |
87 | } | |
88 | ||
89 | if (LOG_IP_ADDRESS) { | |
90 | // add ip address | |
91 | if (!isset($this->parameters['data']['ipAddress'])) { | |
6d65a25b | 92 | $this->parameters['data']['ipAddress'] = UserUtil::getIpAddress(); |
fea86294 TD |
93 | } |
94 | } else { | |
95 | // do not track ip address | |
96 | if (isset($this->parameters['data']['ipAddress'])) { | |
97 | unset($this->parameters['data']['ipAddress']); | |
98 | } | |
99 | } | |
100 | ||
101 | if (!empty($this->parameters['htmlInputProcessor'])) { | |
102 | /** @noinspection PhpUndefinedMethodInspection */ | |
103 | $this->parameters['data']['message'] = $this->parameters['htmlInputProcessor']->getHtml(); | |
104 | } | |
105 | ||
106 | // create message | |
107 | /** @var ConversationMessage $message */ | |
108 | $message = parent::create(); | |
109 | $messageEditor = new ConversationMessageEditor($message); | |
110 | ||
111 | // get conversation | |
112 | $conversation = ($this->parameters['conversation'] ?? new Conversation($message->conversationID)); | |
113 | $conversationEditor = new ConversationEditor($conversation); | |
114 | ||
115 | if (empty($this->parameters['isFirstPost'])) { | |
116 | // update last message | |
117 | $conversationEditor->addMessage($message); | |
118 | ||
119 | // fire notification event | |
120 | if (!$conversation->isDraft) { | |
121 | // don't notify message author | |
122 | $notificationRecipients = \array_diff($conversation->getParticipantIDs(true), [$message->userID]); | |
123 | if (!empty($notificationRecipients)) { | |
124 | UserNotificationHandler::getInstance()->fireEvent( | |
125 | 'conversationMessage', | |
126 | 'com.woltlab.wcf.conversation.message.notification', | |
127 | new ConversationMessageUserNotificationObject($message), | |
128 | $notificationRecipients | |
129 | ); | |
130 | } | |
131 | } | |
132 | ||
133 | $userConversation = Conversation::getUserConversation($conversation->conversationID, $message->userID); | |
134 | if ($userConversation !== null && $userConversation->isInvisible) { | |
135 | // make invisible participant visible | |
8fbd8b01 MS |
136 | $sql = "UPDATE wcf" . WCF_N . "_conversation_to_user |
137 | SET isInvisible = 0 | |
138 | WHERE participantID = ? | |
139 | AND conversationID = ?"; | |
fea86294 TD |
140 | $statement = WCF::getDB()->prepareStatement($sql); |
141 | $statement->execute([$message->userID, $conversation->conversationID]); | |
142 | ||
143 | $conversationEditor->updateParticipantSummary(); | |
144 | $conversationEditor->updateParticipantCount(); | |
145 | } | |
146 | ||
147 | // reset visibility if it was hidden but not left | |
8fbd8b01 MS |
148 | $sql = "UPDATE wcf" . WCF_N . "_conversation_to_user |
149 | SET hideConversation = ? | |
150 | WHERE conversationID = ? | |
151 | AND hideConversation = ?"; | |
fea86294 TD |
152 | $statement = WCF::getDB()->prepareStatement($sql); |
153 | $statement->execute([ | |
154 | Conversation::STATE_DEFAULT, | |
155 | $conversation->conversationID, | |
156 | Conversation::STATE_HIDDEN, | |
157 | ]); | |
158 | } | |
159 | ||
160 | // reset storage | |
161 | UserStorageHandler::getInstance()->reset($conversation->getParticipantIDs(), 'unreadConversationCount'); | |
162 | ||
163 | // update search index | |
164 | SearchIndexManager::getInstance()->set( | |
165 | 'com.woltlab.wcf.conversation.message', | |
166 | $message->messageID, | |
167 | $message->message, | |
168 | !empty($this->parameters['isFirstPost']) ? $conversation->subject : '', | |
169 | $message->time, | |
170 | $message->userID, | |
171 | $message->username | |
172 | ); | |
173 | ||
174 | // update attachments | |
175 | if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { | |
176 | /** @noinspection PhpUndefinedMethodInspection */ | |
177 | $this->parameters['attachmentHandler']->updateObjectID($message->messageID); | |
178 | } | |
179 | ||
180 | // save embedded objects | |
181 | if (!empty($this->parameters['htmlInputProcessor'])) { | |
182 | /** @noinspection PhpUndefinedMethodInspection */ | |
183 | $this->parameters['htmlInputProcessor']->setObjectID($message->messageID); | |
184 | ||
185 | if (MessageEmbeddedObjectManager::getInstance()->registerObjects($this->parameters['htmlInputProcessor'])) { | |
186 | $messageEditor->update(['hasEmbeddedObjects' => 1]); | |
187 | } | |
188 | } | |
189 | ||
190 | // clear quotes | |
191 | if (isset($this->parameters['removeQuoteIDs']) && !empty($this->parameters['removeQuoteIDs'])) { | |
192 | MessageQuoteManager::getInstance()->markQuotesForRemoval($this->parameters['removeQuoteIDs']); | |
193 | } | |
194 | MessageQuoteManager::getInstance()->removeMarkedQuotes(); | |
195 | ||
196 | // return new message | |
197 | return $message; | |
198 | } | |
199 | ||
200 | /** | |
201 | * @inheritDoc | |
202 | */ | |
203 | public function update() | |
204 | { | |
205 | // count attachments | |
206 | if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { | |
207 | $this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']); | |
208 | } | |
209 | ||
210 | if (!empty($this->parameters['htmlInputProcessor'])) { | |
211 | /** @noinspection PhpUndefinedMethodInspection */ | |
212 | $this->parameters['data']['message'] = $this->parameters['htmlInputProcessor']->getHtml(); | |
213 | } | |
214 | ||
215 | parent::update(); | |
216 | ||
217 | // update search index / embedded objects | |
218 | if (isset($this->parameters['data']) && isset($this->parameters['data']['message'])) { | |
219 | foreach ($this->getObjects() as $message) { | |
220 | $conversation = $message->getConversation(); | |
221 | SearchIndexManager::getInstance()->set( | |
222 | 'com.woltlab.wcf.conversation.message', | |
223 | $message->messageID, | |
224 | $this->parameters['data']['message'], | |
225 | $conversation->firstMessageID == $message->messageID ? $conversation->subject : '', | |
226 | $message->time, | |
227 | $message->userID, | |
228 | $message->username | |
229 | ); | |
230 | ||
231 | if (!empty($this->parameters['htmlInputProcessor'])) { | |
232 | /** @noinspection PhpUndefinedMethodInspection */ | |
233 | $this->parameters['htmlInputProcessor']->setObjectID($message->messageID); | |
234 | ||
235 | if ($message->hasEmbeddedObjects != MessageEmbeddedObjectManager::getInstance()->registerObjects($this->parameters['htmlInputProcessor'])) { | |
236 | $message->update(['hasEmbeddedObjects' => $message->hasEmbeddedObjects ? 0 : 1]); | |
237 | } | |
238 | } | |
239 | } | |
240 | } | |
241 | } | |
242 | ||
243 | /** | |
244 | * @inheritDoc | |
245 | */ | |
246 | public function delete() | |
247 | { | |
248 | $count = parent::delete(); | |
249 | ||
250 | $attachmentMessageIDs = $conversationIDs = []; | |
251 | foreach ($this->getObjects() as $message) { | |
252 | if (!\in_array($message->conversationID, $conversationIDs)) { | |
253 | $conversationIDs[] = $message->conversationID; | |
254 | } | |
255 | ||
256 | if ($message->attachments) { | |
257 | $attachmentMessageIDs[] = $message->messageID; | |
258 | } | |
259 | } | |
260 | ||
261 | // rebuild conversations | |
262 | if (!empty($conversationIDs)) { | |
263 | $conversationAction = new ConversationAction($conversationIDs, 'rebuild'); | |
264 | $conversationAction->executeAction(); | |
265 | } | |
266 | ||
267 | if (!empty($this->objectIDs)) { | |
268 | // delete notifications | |
269 | UserNotificationHandler::getInstance() | |
270 | ->removeNotifications('com.woltlab.wcf.conversation.message.notification', $this->objectIDs); | |
271 | ||
272 | // update search index | |
273 | SearchIndexManager::getInstance()->delete('com.woltlab.wcf.conversation.message', $this->objectIDs); | |
274 | ||
275 | // update embedded objects | |
276 | MessageEmbeddedObjectManager::getInstance() | |
277 | ->removeObjects('com.woltlab.wcf.conversation.message', $this->objectIDs); | |
278 | ||
279 | // remove moderation queues | |
280 | ModerationQueueManager::getInstance() | |
281 | ->removeQueues('com.woltlab.wcf.conversation.message', $this->objectIDs); | |
282 | } | |
283 | ||
284 | // remove attachments | |
285 | if (!empty($attachmentMessageIDs)) { | |
286 | AttachmentHandler::removeAttachments('com.woltlab.wcf.conversation.message', $attachmentMessageIDs); | |
287 | } | |
288 | ||
289 | return $count; | |
290 | } | |
291 | ||
292 | /** | |
293 | * @inheritDoc | |
294 | */ | |
295 | public function validateQuickReply() | |
296 | { | |
7d84f6d1 TD |
297 | try { |
298 | ConversationHandler::getInstance()->enforceFloodControl(true); | |
299 | } catch (NamedUserException $e) { | |
300 | throw new UserInputException('message', $e->getMessage()); | |
301 | } | |
302 | ||
fea86294 TD |
303 | QuickReplyManager::getInstance()->setDisallowedBBCodes(\explode( |
304 | ',', | |
305 | WCF::getSession()->getPermission('user.message.disallowedBBCodes') | |
306 | )); | |
307 | QuickReplyManager::getInstance()->validateParameters($this, $this->parameters, Conversation::class); | |
308 | } | |
309 | ||
310 | /** | |
311 | * @inheritDoc | |
312 | */ | |
313 | public function quickReply() | |
314 | { | |
7d84f6d1 | 315 | $returnValues = QuickReplyManager::getInstance()->createMessage( |
fea86294 TD |
316 | $this, |
317 | $this->parameters, | |
318 | ConversationAction::class, | |
319 | CONVERSATION_LIST_DEFAULT_SORT_ORDER, | |
320 | 'conversationMessageList' | |
321 | ); | |
7d84f6d1 | 322 | |
a5f33d57 MW |
323 | EventHandler::getInstance()->fireAction($this, 'afterQuickReply', $returnValues); |
324 | ||
7d84f6d1 TD |
325 | FloodControl::getInstance()->registerContent('com.woltlab.wcf.conversation.message'); |
326 | ||
327 | return $returnValues; | |
fea86294 TD |
328 | } |
329 | ||
fea86294 TD |
330 | /** |
331 | * @inheritDoc | |
332 | */ | |
333 | public function validateBeginEdit() | |
334 | { | |
335 | $this->readInteger('containerID'); | |
336 | $this->readInteger('objectID'); | |
337 | ||
338 | $this->conversation = new Conversation($this->parameters['containerID']); | |
339 | if (!$this->conversation->conversationID) { | |
340 | throw new UserInputException('containerID'); | |
341 | } | |
342 | ||
343 | if ($this->conversation->isClosed || !Conversation::isParticipant([$this->conversation->conversationID])) { | |
344 | throw new PermissionDeniedException(); | |
345 | } | |
346 | ||
347 | $this->message = new ConversationMessage($this->parameters['objectID']); | |
348 | if (!$this->message->messageID) { | |
349 | throw new UserInputException('objectID'); | |
350 | } | |
351 | ||
352 | if (!$this->message->canEdit()) { | |
353 | throw new PermissionDeniedException(); | |
354 | } | |
355 | ||
356 | BBCodeHandler::getInstance()->setDisallowedBBCodes(\explode( | |
357 | ',', | |
358 | WCF::getSession()->getPermission('user.message.disallowedBBCodes') | |
359 | )); | |
360 | } | |
361 | ||
362 | /** | |
363 | * @inheritDoc | |
364 | */ | |
365 | public function beginEdit() | |
366 | { | |
f872b5b6 C |
367 | $upcastProcessor = new HtmlUpcastProcessor(); |
368 | $upcastProcessor->process( | |
369 | $this->message->message, | |
370 | 'com.woltlab.wcf.conversation.message', | |
371 | $this->message->messageID | |
372 | ); | |
fea86294 TD |
373 | WCF::getTPL()->assign([ |
374 | 'defaultSmilies' => SmileyCache::getInstance()->getCategorySmilies(), | |
375 | 'message' => $this->message, | |
d77364a2 | 376 | 'text' => $upcastProcessor->getHtml(), |
fea86294 TD |
377 | 'permissionCanUseSmilies' => 'user.message.canUseSmilies', |
378 | 'wysiwygSelector' => 'messageEditor' . $this->message->messageID, | |
379 | ]); | |
380 | ||
381 | $tmpHash = StringUtil::getRandomID(); | |
382 | $attachmentHandler = new AttachmentHandler( | |
383 | 'com.woltlab.wcf.conversation.message', | |
384 | $this->message->messageID, | |
385 | $tmpHash | |
386 | ); | |
387 | $attachmentList = $attachmentHandler->getAttachmentList(); | |
388 | ||
389 | WCF::getTPL()->assign([ | |
390 | 'attachmentHandler' => $attachmentHandler, | |
391 | 'attachmentList' => $attachmentList->getObjects(), | |
392 | 'attachmentObjectID' => $this->message->messageID, | |
393 | 'attachmentObjectType' => 'com.woltlab.wcf.conversation.message', | |
394 | 'attachmentParentObjectID' => 0, | |
395 | 'tmpHash' => $tmpHash, | |
396 | ]); | |
397 | ||
398 | return [ | |
399 | 'actionName' => 'beginEdit', | |
400 | 'template' => WCF::getTPL()->fetch('conversationMessageInlineEditor'), | |
401 | ]; | |
402 | } | |
403 | ||
404 | /** | |
405 | * @inheritDoc | |
406 | */ | |
407 | public function validateSave() | |
408 | { | |
409 | $this->readString('message', true, 'data'); | |
410 | ||
411 | if (empty($this->parameters['data']['message'])) { | |
412 | throw new UserInputException( | |
413 | 'message', | |
414 | WCF::getLanguage()->getDynamicVariable('wcf.global.form.error.empty') | |
415 | ); | |
416 | } | |
417 | ||
418 | $this->validateBeginEdit(); | |
419 | ||
420 | $this->validateMessage( | |
421 | $this->conversation, | |
422 | $this->getHtmlInputProcessor($this->parameters['data']['message'], $this->message->messageID) | |
423 | ); | |
424 | } | |
425 | ||
426 | /** | |
427 | * @inheritDoc | |
428 | */ | |
429 | public function save() | |
430 | { | |
431 | $data = []; | |
432 | ||
433 | if (!$this->message->getConversation()->isDraft) { | |
434 | $data['lastEditTime'] = TIME_NOW; | |
435 | $data['editCount'] = $this->message->editCount + 1; | |
436 | } | |
437 | // execute update action | |
438 | $action = new self([$this->message], 'update', [ | |
439 | 'data' => $data, | |
440 | 'htmlInputProcessor' => $this->getHtmlInputProcessor(), | |
441 | ]); | |
442 | $action->executeAction(); | |
443 | ||
444 | // load new message | |
445 | $this->message = new ConversationMessage($this->message->messageID); | |
446 | $this->message->getAttachments(); | |
447 | ||
448 | $attachmentList = $this->message->getAttachments(true); | |
449 | $count = 0; | |
450 | if ($attachmentList !== null) { | |
451 | // set permissions | |
452 | $attachmentList->setPermissions([ | |
453 | 'canDownload' => true, | |
454 | 'canViewPreview' => true, | |
455 | ]); | |
456 | ||
457 | $count = \count($attachmentList); | |
458 | } | |
459 | ||
460 | // update count to reflect number of attachments after edit | |
461 | if ($count != $this->message->attachments) { | |
462 | $messageEditor = new ConversationMessageEditor($this->message); | |
463 | $messageEditor->update(['attachments' => $count]); | |
464 | } | |
465 | ||
466 | // load embedded objects | |
467 | MessageEmbeddedObjectManager::getInstance() | |
468 | ->loadObjects('com.woltlab.wcf.conversation.message', [$this->message->messageID]); | |
469 | ||
470 | $data = [ | |
471 | 'actionName' => 'save', | |
472 | 'message' => $this->message->getFormattedMessage(), | |
473 | ]; | |
474 | ||
475 | WCF::getTPL()->assign([ | |
476 | 'attachmentList' => $attachmentList, | |
477 | 'objectID' => $this->message->messageID, | |
478 | ]); | |
479 | $data['attachmentList'] = WCF::getTPL()->fetch('attachments'); | |
480 | ||
481 | return $data; | |
482 | } | |
483 | ||
484 | /** | |
485 | * @inheritDoc | |
486 | */ | |
3888d79b | 487 | public function validateContainer(DatabaseObject $container) |
fea86294 | 488 | { |
3888d79b | 489 | /** @var Conversation $container */ |
fea86294 | 490 | |
3888d79b | 491 | if (!$container->conversationID) { |
fea86294 TD |
492 | throw new UserInputException('objectID'); |
493 | } | |
3888d79b | 494 | if ($container->isClosed) { |
fea86294 TD |
495 | throw new PermissionDeniedException(); |
496 | } | |
3888d79b | 497 | $container->loadUserParticipation(); |
5267cbe2 | 498 | if (!$container->canReply()) { |
fea86294 TD |
499 | throw new PermissionDeniedException(); |
500 | } | |
501 | } | |
502 | ||
503 | /** | |
504 | * @inheritDoc | |
505 | */ | |
506 | public function validateMessage(DatabaseObject $container, HtmlInputProcessor $htmlInputProcessor) | |
507 | { | |
508 | $message = $htmlInputProcessor->getTextContent(); | |
509 | if (\mb_strlen($message) > WCF::getSession()->getPermission('user.conversation.maxLength')) { | |
510 | throw new UserInputException( | |
511 | 'message', | |
512 | WCF::getLanguage()->getDynamicVariable( | |
513 | 'wcf.message.error.tooLong', | |
514 | ['maxTextLength' => WCF::getSession()->getPermission('user.conversation.maxLength')] | |
515 | ) | |
516 | ); | |
517 | } | |
518 | ||
519 | // search for disallowed bbcodes | |
520 | $disallowedBBCodes = $htmlInputProcessor->validate(); | |
521 | if (!empty($disallowedBBCodes)) { | |
522 | throw new UserInputException( | |
523 | 'text', | |
524 | WCF::getLanguage()->getDynamicVariable( | |
525 | 'wcf.message.error.disallowedBBCodes', | |
526 | ['disallowedBBCodes' => $disallowedBBCodes] | |
527 | ) | |
528 | ); | |
529 | } | |
530 | ||
9da2ca0e TD |
531 | $censoredWords = Censorship::getInstance()->test($message); |
532 | if ($censoredWords) { | |
533 | throw new UserInputException( | |
534 | 'message', | |
535 | WCF::getLanguage()->getDynamicVariable( | |
536 | 'wcf.message.error.censoredWordsFound', | |
537 | ['censoredWords' => $censoredWords] | |
538 | ) | |
539 | ); | |
fea86294 TD |
540 | } |
541 | } | |
542 | ||
543 | /** | |
544 | * @inheritDoc | |
545 | */ | |
3888d79b | 546 | public function getMessageList(DatabaseObject $container, $lastMessageTime) |
fea86294 | 547 | { |
3888d79b | 548 | /** @var Conversation $container */ |
fea86294 TD |
549 | |
550 | $messageList = new ViewableConversationMessageList(); | |
3888d79b | 551 | $messageList->setConversation($container); |
fea86294 | 552 | $messageList->getConditionBuilder() |
3888d79b | 553 | ->add("conversation_message.conversationID = ?", [$container->conversationID]); |
fea86294 TD |
554 | $messageList->getConditionBuilder() |
555 | ->add("conversation_message.time > ?", [$lastMessageTime]); | |
556 | $messageList->sqlOrderBy = "conversation_message.time " . CONVERSATION_LIST_DEFAULT_SORT_ORDER; | |
557 | $messageList->readObjects(); | |
558 | ||
559 | return $messageList; | |
560 | } | |
561 | ||
562 | /** | |
563 | * @inheritDoc | |
564 | */ | |
3888d79b | 565 | public function getPageNo(DatabaseObject $container) |
fea86294 | 566 | { |
3888d79b | 567 | /** @var Conversation $container */ |
fea86294 | 568 | |
8fbd8b01 MS |
569 | $sql = "SELECT COUNT(*) AS count |
570 | FROM wcf" . WCF_N . "_conversation_message | |
571 | WHERE conversationID = ?"; | |
fea86294 | 572 | $statement = WCF::getDB()->prepareStatement($sql); |
3888d79b | 573 | $statement->execute([$container->conversationID]); |
fea86294 TD |
574 | $count = $statement->fetchArray(); |
575 | ||
576 | return [\intval(\ceil($count['count'] / CONVERSATION_MESSAGES_PER_PAGE)), $count['count']]; | |
577 | } | |
578 | ||
579 | /** | |
580 | * @inheritDoc | |
581 | */ | |
3888d79b | 582 | public function getRedirectUrl(DatabaseObject $container, DatabaseObject $message) |
fea86294 TD |
583 | { |
584 | /** @var ConversationMessage $message */ | |
585 | return $message->getLink(); | |
586 | } | |
587 | ||
588 | /** | |
589 | * @inheritDoc | |
590 | */ | |
591 | public function validateSaveFullQuote() | |
592 | { | |
593 | $this->message = $this->getSingleObject(); | |
594 | ||
595 | if (!Conversation::isParticipant([$this->message->conversationID])) { | |
596 | throw new PermissionDeniedException(); | |
597 | } | |
598 | } | |
599 | ||
600 | /** | |
601 | * @inheritDoc | |
602 | */ | |
603 | public function saveFullQuote() | |
604 | { | |
605 | $quoteID = MessageQuoteManager::getInstance()->addQuote( | |
606 | 'com.woltlab.wcf.conversation.message', | |
607 | $this->message->conversationID, | |
608 | $this->message->messageID, | |
609 | $this->message->getExcerpt(), | |
610 | $this->message->getMessage() | |
611 | ); | |
612 | ||
613 | if ($quoteID === false) { | |
614 | $removeQuoteID = MessageQuoteManager::getInstance()->getQuoteID( | |
615 | 'com.woltlab.wcf.conversation.message', | |
616 | $this->message->messageID, | |
617 | $this->message->getExcerpt(), | |
618 | $this->message->getMessage() | |
619 | ); | |
620 | MessageQuoteManager::getInstance()->removeQuote($removeQuoteID); | |
621 | } | |
622 | ||
623 | $returnValues = [ | |
624 | 'count' => MessageQuoteManager::getInstance()->countQuotes(), | |
625 | 'fullQuoteMessageIDs' => MessageQuoteManager::getInstance()->getFullQuoteObjectIDs( | |
626 | ['com.woltlab.wcf.conversation.message'] | |
627 | ), | |
628 | ]; | |
629 | ||
630 | if ($quoteID) { | |
631 | $returnValues['renderedQuote'] = MessageQuoteManager::getInstance()->getQuoteComponents($quoteID); | |
632 | } | |
633 | ||
634 | return $returnValues; | |
635 | } | |
636 | ||
637 | /** | |
638 | * @inheritDoc | |
639 | */ | |
640 | public function validateSaveQuote() | |
641 | { | |
642 | $this->readString('message'); | |
643 | $this->readBoolean('renderQuote', true); | |
644 | $this->message = $this->getSingleObject(); | |
645 | ||
646 | if (!Conversation::isParticipant([$this->message->conversationID])) { | |
647 | throw new PermissionDeniedException(); | |
648 | } | |
649 | } | |
650 | ||
651 | /** | |
652 | * @inheritDoc | |
653 | */ | |
654 | public function saveQuote() | |
655 | { | |
656 | $quoteID = MessageQuoteManager::getInstance()->addQuote( | |
657 | 'com.woltlab.wcf.conversation.message', | |
658 | $this->message->conversationID, | |
659 | $this->message->messageID, | |
660 | $this->parameters['message'], | |
661 | false | |
662 | ); | |
663 | ||
664 | $returnValues = [ | |
665 | 'count' => MessageQuoteManager::getInstance()->countQuotes(), | |
666 | 'fullQuoteMessageIDs' => MessageQuoteManager::getInstance()->getFullQuoteObjectIDs( | |
667 | ['com.woltlab.wcf.conversation.message'] | |
668 | ), | |
669 | ]; | |
670 | ||
671 | if ($this->parameters['renderQuote']) { | |
672 | $returnValues['renderedQuote'] = MessageQuoteManager::getInstance()->getQuoteComponents($quoteID); | |
673 | } | |
674 | ||
675 | return $returnValues; | |
676 | } | |
677 | ||
678 | /** | |
679 | * @inheritDoc | |
680 | */ | |
681 | public function validateGetRenderedQuotes() | |
682 | { | |
683 | $this->readInteger('parentObjectID'); | |
684 | ||
685 | $this->conversation = new Conversation($this->parameters['parentObjectID']); | |
686 | if (!$this->conversation->conversationID) { | |
687 | throw new UserInputException('parentObjectID'); | |
688 | } | |
689 | } | |
690 | ||
691 | /** | |
692 | * @inheritDoc | |
693 | */ | |
694 | public function getRenderedQuotes() | |
695 | { | |
696 | $quotes = MessageQuoteManager::getInstance() | |
697 | ->getQuotesByParentObjectID('com.woltlab.wcf.conversation.message', $this->conversation->conversationID); | |
698 | ||
699 | return [ | |
700 | 'template' => \implode("\n\n", $quotes), | |
701 | ]; | |
702 | } | |
703 | ||
704 | /** | |
705 | * @inheritDoc | |
706 | */ | |
3888d79b | 707 | public function getAttachmentHandler(DatabaseObject $container) |
fea86294 TD |
708 | { |
709 | return new AttachmentHandler('com.woltlab.wcf.conversation.message', 0, $this->parameters['tmpHash']); | |
710 | } | |
711 | ||
712 | /** | |
713 | * @inheritDoc | |
714 | */ | |
715 | public function getHtmlInputProcessor($message = null, $objectID = 0) | |
716 | { | |
717 | if ($message === null) { | |
718 | return $this->htmlInputProcessor; | |
719 | } | |
720 | ||
721 | $this->htmlInputProcessor = new HtmlInputProcessor(); | |
722 | $this->htmlInputProcessor->process($message, 'com.woltlab.wcf.conversation.message', $objectID); | |
723 | ||
724 | return $this->htmlInputProcessor; | |
725 | } | |
9544b6b4 | 726 | } |