diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php index bfb720ea..f75683c9 100644 --- a/files/lib/data/conversation/message/ConversationMessage.class.php +++ b/files/lib/data/conversation/message/ConversationMessage.class.php @@ -225,4 +225,26 @@ public function getUserProfile(): UserProfile { return $this->getCollection()->getUserProfile($this); } + + /** + * Checks if the current user can read this particular message. + */ + public function canRead(): bool + { + $conversation = $this->getConversation(); + if ($conversation === null) { + return false; + } + + $participant = $conversation->getParticipant(); + if ($participant === null) { + return false; + } + + if ($participant->hasJoinedAfter($this->time) || $participant->hasLeftBefore($this->time)) { + return false; + } + + return true; + } } diff --git a/files/lib/data/conversation/participant/ConversationParticipant.class.php b/files/lib/data/conversation/participant/ConversationParticipant.class.php index b531f67a..ec288e2d 100644 --- a/files/lib/data/conversation/participant/ConversationParticipant.class.php +++ b/files/lib/data/conversation/participant/ConversationParticipant.class.php @@ -37,6 +37,32 @@ class ConversationParticipant extends DatabaseObject */ protected static $databaseTableIndexName = 'conversationParticipantID'; + /** + * Returns true if the user has joined the conversation after the provided + * timestamp. + */ + public function hasJoinedAfter(int $timestamp): bool + { + if ($this->joinedAt === 0) { + return false; + } + + return $this->joinedAt > $timestamp; + } + + /** + * Returns true if the user has left the conversation before the provided + * timestamp. + */ + public function hasLeftBefore(int $timestamp): bool + { + if ($this->leftAt === 0) { + return false; + } + + return $this->leftAt < $timestamp; + } + public static function getParticipant(int $conversationID, int $userID): ?static { $sql = "SELECT * FROM wcf1_conversation_to_user WHERE conversationID = ? AND userID = ?"; diff --git a/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php new file mode 100644 index 00000000..718af831 --- /dev/null +++ b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php @@ -0,0 +1,35 @@ + + */ +final class ConversationMessageQuoteHandler extends AbstractMessageQuoteHandler +{ + #[\Override] + public function getMessage(int $objectID): ?IMessage + { + $message = new ConversationMessage($objectID); + if (!$message->messageID) { + return null; + } + + if (!$message->canRead()) { + return null; + } + + if ($message->hasEmbeddedObjects) { + $message->getCollection()->loadEmbeddedObjects(); + } + + return $message; + } +} diff --git a/objectType.xml b/objectType.xml index 60e28252..23b9ea24 100644 --- a/objectType.xml +++ b/objectType.xml @@ -32,6 +32,7 @@ com.woltlab.wcf.conversation.message com.woltlab.wcf.message.quote + wcf\system\message\quote\ConversationMessageQuoteHandler com.woltlab.wcf.conversation.message diff --git a/templates/conversation.tpl b/templates/conversation.tpl index 490b3e11..e18b8334 100644 --- a/templates/conversation.tpl +++ b/templates/conversation.tpl @@ -84,7 +84,7 @@ ], ({ UiConversationMessageInlineEditor }, { registerContainer }, { getParticipantList }) => { new UiConversationMessageInlineEditor({$conversation->conversationID}); - registerContainer(".message", ".messageBody", "wcf\\data\\conversation\\message\\ConversationMessage", "com.woltlab.wcf.conversation.message"); + registerContainer(".message", ".messageBody", "com.woltlab.wcf.conversation.message"); const contextMenu = document.getElementById('{unsafe:$interactionContextMenu->getContainerID()|encodeJS}') console.log(contextMenu);