From 85c6884c252c68f03af9f378b088e7553b9d7520 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 3 Aug 2025 18:36:46 +0200 Subject: [PATCH 1/4] Reintroduce the quote handler --- .../ConversationMessageQuoteHandler.class.php | 36 +++++++++++++++++++ objectType.xml | 1 + templates/conversation.tpl | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php 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..af2ccaf3 --- /dev/null +++ b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php @@ -0,0 +1,36 @@ + + */ +final class ConversationMessageQuoteHandler extends AbstractMessageQuoteHandler +{ + #[\Override] + public function getMessage(int $objectID): ?IMessage + { + $message = new ConversationMessage($objectID); + if (!$message->messageID) { + return null; + } + + if (!Conversation::isParticipant([$message->conversationID])) { + 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); From 81f2663332c574683508e7d4ea73bb515349a519 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 3 Aug 2025 23:54:45 +0200 Subject: [PATCH 2/4] Add a `canRead()` method for conversation messages This is now in line with the other implementations that also offload the logic to a separate `canRead()` method. This is also quite cheap to implement with the new collections, I like them a lot! :) --- .../message/ConversationMessage.class.php | 22 +++++++++++++++++++ .../ConversationMessageQuoteHandler.class.php | 3 +-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php index bfb720ea..0f84c679 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->getCollection()->getConversation($this); + if ($conversation === null) { + return false; + } + + $participant = $conversation->getParticipant(); + if ($participant === null) { + return false; + } + + if ($participant->joinedAt > $this->time || $participant->leftAt < $this->time) { + return false; + } + + return true; + } } diff --git a/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php index af2ccaf3..7aacfe95 100644 --- a/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php +++ b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php @@ -2,7 +2,6 @@ namespace wcf\system\message\quote; -use wcf\data\conversation\Conversation; use wcf\data\conversation\message\ConversationMessage; use wcf\data\IMessage; @@ -23,7 +22,7 @@ public function getMessage(int $objectID): ?IMessage return null; } - if (!Conversation::isParticipant([$message->conversationID])) { + if ($message->canRead()) { return null; } From 0134a4f294b5d80e5abe4d2dbb753cffdeb3fd77 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 4 Aug 2025 00:14:37 +0200 Subject: [PATCH 3/4] Simplify the code a bit --- .../lib/data/conversation/message/ConversationMessage.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php index 0f84c679..569f9bd4 100644 --- a/files/lib/data/conversation/message/ConversationMessage.class.php +++ b/files/lib/data/conversation/message/ConversationMessage.class.php @@ -231,7 +231,7 @@ public function getUserProfile(): UserProfile */ public function canRead(): bool { - $conversation = $this->getCollection()->getConversation($this); + $conversation = $this->getConversation(); if ($conversation === null) { return false; } From 66d9dcd94c535dcc184e0413469aa33911a64f04 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 4 Aug 2025 12:37:42 +0200 Subject: [PATCH 4/4] Add helper methods to simplify working with leftAt/joinedAt This avoids having to explicitly deal with the magic `0` value. --- .../message/ConversationMessage.class.php | 2 +- .../ConversationParticipant.class.php | 26 +++++++++++++++++++ .../ConversationMessageQuoteHandler.class.php | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/files/lib/data/conversation/message/ConversationMessage.class.php b/files/lib/data/conversation/message/ConversationMessage.class.php index 569f9bd4..f75683c9 100644 --- a/files/lib/data/conversation/message/ConversationMessage.class.php +++ b/files/lib/data/conversation/message/ConversationMessage.class.php @@ -241,7 +241,7 @@ public function canRead(): bool return false; } - if ($participant->joinedAt > $this->time || $participant->leftAt < $this->time) { + if ($participant->hasJoinedAfter($this->time) || $participant->hasLeftBefore($this->time)) { return false; } 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 index 7aacfe95..718af831 100644 --- a/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php +++ b/files/lib/system/message/quote/ConversationMessageQuoteHandler.class.php @@ -22,7 +22,7 @@ public function getMessage(int $objectID): ?IMessage return null; } - if ($message->canRead()) { + if (!$message->canRead()) { return null; }