From a0c1a5415d73f7e3aae5b93a009d0dd477edbcc4 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Thu, 3 Jul 2014 14:18:34 +0200 Subject: [PATCH] Implemented message embedded object system --- .../conversation/ConversationAction.class.php | 4 +- .../message/ConversationMessage.class.php | 13 ++- .../ConversationMessageAction.class.php | 21 ++++- ...rchResultConversationMessageList.class.php | 2 +- ...dViewableConversationMessageList.class.php | 25 ++++++ .../ViewableConversationMessageList.class.php | 87 +++++++++++++++++-- .../form/ConversationMessageAddForm.class.php | 1 + .../ConversationMessageEditForm.class.php | 1 + files/lib/page/ConversationPage.class.php | 1 + ...ationMessageAttachmentObjectType.class.php | 60 +++++++++++++ install.sql | 1 + objectType.xml | 5 ++ 12 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php diff --git a/files/lib/data/conversation/ConversationAction.class.php b/files/lib/data/conversation/ConversationAction.class.php index 2d5cc75..5eee010 100644 --- a/files/lib/data/conversation/ConversationAction.class.php +++ b/files/lib/data/conversation/ConversationAction.class.php @@ -3,7 +3,7 @@ namespace wcf\data\conversation; use wcf\data\conversation\label\ConversationLabel; use wcf\data\conversation\message\ConversationMessageAction; use wcf\data\conversation\message\ConversationMessageList; -use wcf\data\conversation\message\ViewableConversationMessageList; +use wcf\data\conversation\message\SimplifiedViewableConversationMessageList; use wcf\data\package\PackageCache; use wcf\data\AbstractDatabaseObjectAction; use wcf\data\IClipboardAction; @@ -387,7 +387,7 @@ class ConversationAction extends AbstractDatabaseObjectAction implements IClipbo * @return array */ public function getMessagePreview() { - $messageList = new ViewableConversationMessageList(); + $messageList = new SimplifiedViewableConversationMessageList(); $messageList->getConditionBuilder()->add("conversation_message.messageID = ?", array($this->conversation->firstMessageID)); $messageList->readObjects(); diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php index dc09d58..aa61c06 100644 --- a/files/lib/data/conversation/message/ConversationMessage.class.php +++ b/files/lib/data/conversation/message/ConversationMessage.class.php @@ -4,8 +4,8 @@ use wcf\data\attachment\GroupedAttachmentList; use wcf\data\conversation\Conversation; use wcf\data\DatabaseObject; use wcf\data\IMessage; -use wcf\system\bbcode\AttachmentBBCode; use wcf\system\bbcode\MessageParser; +use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; use wcf\system\request\LinkHandler; use wcf\system\WCF; use wcf\util\StringUtil; @@ -41,9 +41,9 @@ class ConversationMessage extends DatabaseObject implements IMessage { * @see \wcf\data\IMessage::getFormattedMessage() */ public function getFormattedMessage() { - // assign embedded attachments - AttachmentBBCode::setObjectID($this->messageID); - + // assign embedded objects + MessageEmbeddedObjectManager::getInstance()->setActiveMessage('com.woltlab.wcf.conversation.message', $this->messageID); + // parse and return message MessageParser::getInstance()->setOutputType('text/html'); return MessageParser::getInstance()->parse($this->message, $this->enableSmilies, $this->enableHtml, $this->enableBBCodes); @@ -74,9 +74,6 @@ class ConversationMessage extends DatabaseObject implements IMessage { 'canViewPreview' => true )); - // set embedded attachments - AttachmentBBCode::setAttachmentList($attachmentList); - return $attachmentList; } @@ -112,7 +109,7 @@ class ConversationMessage extends DatabaseObject implements IMessage { */ public function getConversation() { if ($this->conversation === null) { - $this->conversation = new Conversation($this->conversationID); + $this->conversation = Conversation::getUserConversation($this->conversationID, WCF::getUser()->userID); } return $this->conversation; diff --git a/files/lib/data/conversation/message/ConversationMessageAction.class.php b/files/lib/data/conversation/message/ConversationMessageAction.class.php index a13a51f..6f2d3ac 100644 --- a/files/lib/data/conversation/message/ConversationMessageAction.class.php +++ b/files/lib/data/conversation/message/ConversationMessageAction.class.php @@ -16,6 +16,7 @@ use wcf\system\bbcode\PreParser; use wcf\system\exception\PermissionDeniedException; use wcf\system\exception\UserInputException; use wcf\system\message\censorship\Censorship; +use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; use wcf\system\message\quote\MessageQuoteManager; use wcf\system\message\QuickReplyManager; use wcf\system\moderation\queue\ModerationQueueManager; @@ -79,6 +80,7 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements // create message $message = parent::create(); + $messageEditor = new ConversationMessageEditor($message); // get conversation $conversation = (isset($this->parameters['converation']) ? $this->parameters['converation'] : new Conversation($message->conversationID)); @@ -129,6 +131,13 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements // update search index SearchIndexManager::getInstance()->add('com.woltlab.wcf.conversation.message', $message->messageID, $message->message, (!empty($this->parameters['isFirstPost']) ? $conversation->subject : ''), $message->time, $message->userID, $message->username); + // save embedded objects + if (MessageEmbeddedObjectManager::getInstance()->registerObjects('com.woltlab.wcf.conversation.message', $message->messageID, $message->message)) { + $messageEditor->update(array( + 'hasEmbeddedObjects' => 1 + )); + } + // update attachments if (isset($this->parameters['attachmentHandler']) && $this->parameters['attachmentHandler'] !== null) { $this->parameters['attachmentHandler']->updateObjectID($message->messageID); @@ -155,10 +164,16 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements parent::update(); - // update search index + // update search index / embedded objects foreach ($this->objects as $message) { $conversation = $message->getConversation(); SearchIndexManager::getInstance()->update('com.woltlab.wcf.conversation.message', $message->messageID, $message->message, ($conversation->firstMessageID == $message->messageID ? $conversation->subject : ''), $message->time, $message->userID, $message->username); + + if ($message->hasEmbeddedObjects != MessageEmbeddedObjectManager::getInstance()->registerObjects('com.woltlab.wcf.conversation.message', $message->messageID, $message->message)) { + $message->update(array( + 'hasEmbeddedObjects' => ($message->hasEmbeddedObjects ? 0 : 1) + )); + } } } @@ -192,6 +207,9 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements // update search index SearchIndexManager::getInstance()->delete('com.woltlab.wcf.conversation.message', $this->objectIDs); + // update embedded objects + MessageEmbeddedObjectManager::getInstance()->removeObjects('com.woltlab.wcf.conversation.message', $this->objectIDs); + // remove moderation queues ModerationQueueManager::getInstance()->removeQueues('com.woltlab.wcf.conversation.message', $this->objectIDs); } @@ -399,6 +417,7 @@ class ConversationMessageAction extends AbstractDatabaseObjectAction implements */ public function getMessageList(DatabaseObject $conversation, $lastMessageTime) { $messageList = new ViewableConversationMessageList(); + $messageList->setConversation($conversation); $messageList->getConditionBuilder()->add("conversation_message.conversationID = ?", array($conversation->conversationID)); $messageList->getConditionBuilder()->add("conversation_message.time > ?", array($lastMessageTime)); $messageList->sqlOrderBy = "conversation_message.time ".CONVERSATION_LIST_DEFAULT_SORT_ORDER; diff --git a/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php b/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php index 6614546..66069cd 100644 --- a/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php +++ b/files/lib/data/conversation/message/SearchResultConversationMessageList.class.php @@ -11,7 +11,7 @@ namespace wcf\data\conversation\message; * @subpackage data.conversation.message * @category Community Framework */ -class SearchResultConversationMessageList extends ViewableConversationMessageList { +class SearchResultConversationMessageList extends SimplifiedViewableConversationMessageList { /** * @see \wcf\data\DatabaseObjectList::$decoratorClassName */ diff --git a/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php b/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php new file mode 100644 index 0000000..795c718 --- /dev/null +++ b/files/lib/data/conversation/message/SimplifiedViewableConversationMessageList.class.php @@ -0,0 +1,25 @@ + + * @package com.woltlab.wcf.conversation + * @subpackage data.conversation.message + * @category Community Framework + */ +class SimplifiedViewableConversationMessageList extends ViewableConversationMessageList { + /** + * @see \wcf\data\conversation\message\ViewableConversationMessageList::$attachmentLoading + */ + protected $attachmentLoading = false; + + /** + * @see \wcf\data\conversation\message\ViewableConversationMessageList::$embeddedObjectLoading + */ + protected $embeddedObjectLoading = false; +} diff --git a/files/lib/data/conversation/message/ViewableConversationMessageList.class.php b/files/lib/data/conversation/message/ViewableConversationMessageList.class.php index ff7f6f9..a797cc2 100644 --- a/files/lib/data/conversation/message/ViewableConversationMessageList.class.php +++ b/files/lib/data/conversation/message/ViewableConversationMessageList.class.php @@ -1,7 +1,9 @@ + */ + public $embeddedObjectMessageIDs = array(); + /** * attachment list * @var \wcf\data\attachment\GroupedAttachmentList @@ -42,6 +50,24 @@ class ViewableConversationMessageList extends ConversationMessageList { */ protected $maxPostTime = 0; + /** + * enables/disables the loading of attachments + * @var boolean + */ + protected $attachmentLoading = true; + + /** + * enables/disables the loading of embedded objects + * @var boolean + */ + protected $embeddedObjectLoading = true; + + /** + * conversation object + * @var \wcf\data\conversation\Conversation + */ + protected $conversation = null; + /** * Creates a new ViewableConversationMessageList object. */ @@ -68,17 +94,42 @@ class ViewableConversationMessageList extends ConversationMessageList { parent::readObjects(); - foreach ($this->objects as &$message) { + foreach ($this->objects as $message) { if ($message->time > $this->maxPostTime) { $this->maxPostTime = $message->time; } + if ($this->conversation !== null) { + $message->setConversation($this->conversation); + } if ($message->attachments) { $this->attachmentObjectIDs[] = $message->messageID; } + + if ($message->hasEmbeddedObjects) { + $this->embeddedObjectMessageIDs[] = $message->messageID; + } } - $this->readAttachments(); + if ($this->embeddedObjectLoading) { + $this->readEmbeddedObjects(); + } + if ($this->attachmentLoading) { + $this->readAttachments(); + } + } + + /** + * Reads the embedded objects of the messages in the list. + */ + public function readEmbeddedObjects() { + if (!empty($this->embeddedObjectMessageIDs)) { + // add message objects to attachment object cache to save SQL queries + ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'com.woltlab.wcf.conversation.message')->getProcessor()->setCachedObjects($this->objects); + + // load embedded objects + MessageEmbeddedObjectManager::getInstance()->loadObjects('com.woltlab.wcf.conversation.message', $this->embeddedObjectMessageIDs); + } } /** @@ -89,9 +140,6 @@ class ViewableConversationMessageList extends ConversationMessageList { $this->attachmentList = new GroupedAttachmentList('com.woltlab.wcf.conversation.message'); $this->attachmentList->getConditionBuilder()->add('attachment.objectID IN (?)', array($this->attachmentObjectIDs)); $this->attachmentList->readObjects(); - - // set embedded attachments - AttachmentBBCode::setAttachmentList($this->attachmentList); } } @@ -112,4 +160,31 @@ class ViewableConversationMessageList extends ConversationMessageList { public function getAttachmentList() { return $this->attachmentList; } + + /** + * Enables/disables the loading of attachments. + * + * @param boolean $enable + */ + public function enableAttachmentLoading($enable = true) { + $this->attachmentLoading = $enable; + } + + /** + * Enables/disables the loading of embedded objects. + * + * @param boolean $enable + */ + public function enableEmbeddedObjectLoading($enable = true) { + $this->embeddedObjectLoading = $enable; + } + + /** + * Sets active conversation. + * + * @param \wcf\data\conversation\Conversation $conversation + */ + public function setConversation(Conversation $conversation) { + $this->conversation = $conversation; + } } diff --git a/files/lib/form/ConversationMessageAddForm.class.php b/files/lib/form/ConversationMessageAddForm.class.php index fd96ccd..3f5c6cf 100644 --- a/files/lib/form/ConversationMessageAddForm.class.php +++ b/files/lib/form/ConversationMessageAddForm.class.php @@ -149,6 +149,7 @@ class ConversationMessageAddForm extends MessageForm { // get message list $this->messageList = new ViewableConversationMessageList(); + $this->messageList->setConversation($this->conversation); $this->messageList->sqlLimit = CONVERSATION_REPLY_SHOW_MESSAGES_MAX; $this->messageList->sqlOrderBy = 'conversation_message.time DESC'; $this->messageList->getConditionBuilder()->add('conversation_message.conversationID = ?', array($this->conversation->conversationID)); diff --git a/files/lib/form/ConversationMessageEditForm.class.php b/files/lib/form/ConversationMessageEditForm.class.php index 0bd3338..287758c 100644 --- a/files/lib/form/ConversationMessageEditForm.class.php +++ b/files/lib/form/ConversationMessageEditForm.class.php @@ -216,6 +216,7 @@ class ConversationMessageEditForm extends ConversationAddForm { // get message list $this->messageList = new ViewableConversationMessageList(); + $this->messageList->setConversation($this->conversation); $this->messageList->sqlLimit = CONVERSATION_REPLY_SHOW_MESSAGES_MAX; $this->messageList->sqlOrderBy = 'conversation_message.time DESC'; $this->messageList->getConditionBuilder()->add('conversation_message.conversationID = ?', array($this->message->conversationID)); diff --git a/files/lib/page/ConversationPage.class.php b/files/lib/page/ConversationPage.class.php index 8c01a50..9156ded 100644 --- a/files/lib/page/ConversationPage.class.php +++ b/files/lib/page/ConversationPage.class.php @@ -144,6 +144,7 @@ class ConversationPage extends MultipleLinkPage { parent::initObjectList(); $this->objectList->getConditionBuilder()->add('conversation_message.conversationID = ?', array($this->conversation->conversationID)); + $this->objectList->setConversation($this->conversation); // handle jump to if ($this->action == 'lastPost') $this->goToLastPost(); diff --git a/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php b/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php index 83887c7..daf51fb 100644 --- a/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php +++ b/files/lib/system/attachment/ConversationMessageAttachmentObjectType.class.php @@ -1,6 +1,7 @@ setObjectIDs($objectIDs); + $messageList->readObjects(); + $conversationIDs = array(); + foreach ($messageList as $message) { + $conversationIDs[] = $message->conversationID; + } + if (!empty($conversationIDs)) { + $conversations = Conversation::getUserConversations($conversationIDs, WCF::getUser()->userID); + foreach ($messageList as $message) { + if (isset($conversations[$message->conversationID])) $message->setConversation($conversations[$message->conversationID]); + } + } + $this->cachedObjects = $messageList->getObjects(); + } + + /** + * @see \wcf\system\attachment\IAttachmentObjectType::setPermissions() + */ + public function setPermissions(array $attachments) { + $postIDs = array(); + foreach ($attachments as $attachment) { + // set default permissions + $attachment->setPermissions(array( + 'canDownload' => false, + 'canViewPreview' => false + )); + + if ($this->getObject($attachment->objectID) === null) { + $messageIDs[] = $attachment->objectID; + } + } + + if (!empty($messageIDs)) { + $this->cacheObjects($messageIDs); + } + + foreach ($attachments as $attachment) { + if (($message = $this->getObject($attachment->objectID)) !== null) { + if (!$message->getConversation()->canRead()) continue; + + $attachment->setPermissions(array( + 'canDownload' => true, + 'canViewPreview' => true + )); + } + else if ($attachment->tmpHash != '' && $attachment->userID == WCF::getUser()->userID) { + $attachment->setPermissions(array( + 'canDownload' => true, + 'canViewPreview' => true + )); + } + } + } } diff --git a/install.sql b/install.sql index 519881d..dcf2b0f 100644 --- a/install.sql +++ b/install.sql @@ -50,6 +50,7 @@ CREATE TABLE wcf1_conversation_message ( ipAddress VARCHAR(39) NOT NULL DEFAULT '', lastEditTime INT(10) NOT NULL DEFAULT 0, editCount MEDIUMINT(7) NOT NULL DEFAULT 0, + hasEmbeddedObjects TINYINT(1) NOT NULL DEFAULT 0, KEY (conversationID, userID), KEY (ipAddress) diff --git a/objectType.xml b/objectType.xml index 4742dfd..d3b5c50 100644 --- a/objectType.xml +++ b/objectType.xml @@ -14,6 +14,11 @@ 1 + + com.woltlab.wcf.conversation.message + com.woltlab.wcf.message + + com.woltlab.wcf.conversation.conversation com.woltlab.wcf.clipboardItem -- 2.20.1