Using html upcast
[GitHub/WoltLab/com.woltlab.wcf.conversation.git] / files / lib / data / conversation / message / ConversationMessageAction.class.php
CommitLineData
9544b6b4 1<?php
fea86294 2
9544b6b4 3namespace wcf\data\conversation\message;
fea86294
TD
4
5use wcf\data\AbstractDatabaseObjectAction;
9544b6b4 6use wcf\data\conversation\Conversation;
3b34d39f 7use wcf\data\conversation\ConversationAction;
9544b6b4 8use wcf\data\conversation\ConversationEditor;
52971287 9use wcf\data\DatabaseObject;
e77f4283 10use wcf\data\IAttachmentMessageQuickReplyAction;
4a2ee5bb 11use wcf\data\IMessageInlineEditorAction;
5fa9d104 12use wcf\data\IMessageQuoteAction;
fea86294 13use wcf\data\smiley\SmileyCache;
5d7f0df0 14use wcf\system\attachment\AttachmentHandler;
a21c8732 15use wcf\system\bbcode\BBCodeHandler;
7d84f6d1 16use wcf\system\conversation\ConversationHandler;
a5f33d57 17use wcf\system\event\EventHandler;
7d84f6d1 18use wcf\system\exception\NamedUserException;
5e52978f
AE
19use wcf\system\exception\PermissionDeniedException;
20use wcf\system\exception\UserInputException;
7d84f6d1 21use wcf\system\flood\FloodControl;
5ff95003 22use wcf\system\html\input\HtmlInputProcessor;
f872b5b6 23use wcf\system\html\upcast\HtmlUpcastProcessor;
d8671029 24use wcf\system\message\censorship\Censorship;
a0c1a541 25use wcf\system\message\embedded\object\MessageEmbeddedObjectManager;
5e52978f 26use wcf\system\message\QuickReplyManager;
fea86294 27use wcf\system\message\quote\MessageQuoteManager;
3b37e024 28use wcf\system\moderation\queue\ModerationQueueManager;
80a0761e 29use wcf\system\search\SearchIndexManager;
b5ffaf76
AE
30use wcf\system\user\notification\object\ConversationMessageUserNotificationObject;
31use wcf\system\user\notification\UserNotificationHandler;
df8f8628 32use wcf\system\user\storage\UserStorageHandler;
9544b6b4 33use wcf\system\WCF;
5e00d333 34use wcf\util\StringUtil;
6d65a25b 35use 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
47class 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,
f872b5b6 376 'messageText' => $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}