Skip to content

Commit 718e141

Browse files
committed
Implement a command to rebuild the conversation stats
1 parent 78ee9c8 commit 718e141

File tree

3 files changed

+72
-40
lines changed

3 files changed

+72
-40
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace wcf\command\conversation;
4+
5+
use wcf\data\conversation\Conversation;
6+
use wcf\data\conversation\ConversationEditor;
7+
use wcf\system\WCF;
8+
9+
/**
10+
* Rebuilds the conversation data.
11+
*
12+
* @author Olaf Braun
13+
* @copyright 2001-2025 WoltLab GmbH
14+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15+
* @since 6.3
16+
*/
17+
final class RebuildConversation
18+
{
19+
public function __construct(
20+
private readonly Conversation $conversation
21+
) {}
22+
23+
public function __invoke(): void
24+
{
25+
['messages' => $messages, 'attachments' => $attachments] = $this->getConversationStats($this->conversation->conversationID);
26+
27+
$editor = new ConversationEditor($this->conversation);
28+
if ($messages === 0) {
29+
$editor->delete();
30+
31+
return;
32+
}
33+
34+
$editor->update([
35+
'attachments' => $attachments,
36+
'replies' => $messages - 1,
37+
]);
38+
39+
$editor->updateFirstMessage();
40+
$editor->updateLastMessage();
41+
}
42+
43+
/**
44+
* @return array{attachments: int, messages: int}
45+
*/
46+
private function getConversationStats(int $conversationID): array
47+
{
48+
$sql = "SELECT COUNT(messageID) AS messages,
49+
COALESCE(SUM(attachments), 0) AS attachments
50+
FROM wcf1_conversation_message
51+
WHERE conversationID = ?";
52+
$statement = WCF::getDB()->prepare($sql);
53+
$statement->execute([$conversationID]);
54+
$row = $statement->fetchArray();
55+
56+
return [
57+
'messages' => $row['messages'],
58+
'attachments' => $row['attachments'],
59+
];
60+
}
61+
}

files/lib/data/conversation/ConversationAction.class.php

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace wcf\data\conversation;
44

55
use wcf\command\conversation\MarkAllConversationsAsRead;
6+
use wcf\command\conversation\RebuildConversation;
67
use wcf\data\AbstractDatabaseObjectAction;
78
use wcf\data\conversation\message\ConversationMessageAction;
89
use wcf\data\conversation\message\ConversationMessageList;
@@ -563,46 +564,17 @@ public function getConversations(): array
563564
* Rebuilds the conversation data of the relevant conversations.
564565
*
565566
* @return void
567+
*
568+
* @deprecated 6.3 Use the `RebuildConversation` command instead.
566569
*/
567570
public function rebuild()
568571
{
569572
if (empty($this->objects)) {
570573
$this->readObjects();
571574
}
572575

573-
// collect number of messages for each conversation
574-
$conditionBuilder = new PreparedStatementConditionBuilder();
575-
$conditionBuilder->add('conversation_message.conversationID IN (?)', [$this->objectIDs]);
576-
$sql = "SELECT conversationID, COUNT(messageID) AS messages, SUM(attachments) AS attachments
577-
FROM wcf1_conversation_message conversation_message
578-
" . $conditionBuilder . "
579-
GROUP BY conversationID";
580-
$statement = WCF::getDB()->prepare($sql);
581-
$statement->execute($conditionBuilder->getParameters());
582-
583-
$objectIDs = [];
584-
while ($row = $statement->fetchArray()) {
585-
if (!$row['messages']) {
586-
continue;
587-
}
588-
$objectIDs[] = $row['conversationID'];
589-
590-
$conversationEditor = new ConversationEditor(new Conversation(null, [
591-
'conversationID' => $row['conversationID'],
592-
]));
593-
$conversationEditor->update([
594-
'attachments' => $row['attachments'],
595-
'replies' => $row['messages'] - 1,
596-
]);
597-
$conversationEditor->updateFirstMessage();
598-
$conversationEditor->updateLastMessage();
599-
}
600-
601-
// delete conversations without messages
602-
$deleteConversationIDs = \array_diff($this->objectIDs, $objectIDs);
603-
if (!empty($deleteConversationIDs)) {
604-
$conversationAction = new self($deleteConversationIDs, 'delete');
605-
$conversationAction->executeAction();
576+
foreach ($this->objects as $editor) {
577+
(new RebuildConversation($editor->getDecoratedObject()))();
606578
}
607579
}
608580
}

files/lib/data/conversation/message/ConversationMessageAction.class.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace wcf\data\conversation\message;
44

5+
use wcf\command\conversation\RebuildConversation;
56
use wcf\data\AbstractDatabaseObjectAction;
67
use wcf\data\conversation\Conversation;
78
use wcf\data\conversation\ConversationAction;
@@ -242,21 +243,19 @@ public function delete()
242243
{
243244
$count = parent::delete();
244245

245-
$attachmentMessageIDs = $conversationIDs = [];
246+
$attachmentMessageIDs = $conversations = [];
246247
foreach ($this->getObjects() as $message) {
247-
if (!\in_array($message->conversationID, $conversationIDs)) {
248-
$conversationIDs[] = $message->conversationID;
248+
if (!\array_key_exists($message->conversationID, $conversations)) {
249+
$conversations[$message->conversationID] = $message->getConversation();
249250
}
250251

251252
if ($message->attachments) {
252253
$attachmentMessageIDs[] = $message->messageID;
253254
}
254255
}
255256

256-
// rebuild conversations
257-
if (!empty($conversationIDs)) {
258-
$conversationAction = new ConversationAction($conversationIDs, 'rebuild');
259-
$conversationAction->executeAction();
257+
foreach ($conversations as $conversation) {
258+
(new RebuildConversation($conversation))();
260259
}
261260

262261
if (!empty($this->objectIDs)) {

0 commit comments

Comments
 (0)