Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions files/lib/command/conversation/RebuildConversation.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace wcf\command\conversation;

use wcf\data\conversation\Conversation;
use wcf\data\conversation\ConversationEditor;
use wcf\system\WCF;

/**
* Rebuilds the conversation data.
*
* @author Olaf Braun
* @copyright 2001-2025 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.3
*/
final class RebuildConversation
{
public function __construct(
private readonly Conversation $conversation
) {}

public function __invoke(): void
{
['messages' => $messages, 'attachments' => $attachments] = $this->getConversationStats($this->conversation->conversationID);

$editor = new ConversationEditor($this->conversation);
if ($messages === 0) {
$editor->delete();

return;
}

$editor->update([
'attachments' => $attachments,
'replies' => $messages - 1,
]);

$editor->updateFirstMessage();
$editor->updateLastMessage();
}

/**
* @return array{attachments: int, messages: int}
*/
private function getConversationStats(int $conversationID): array
{
$sql = "SELECT COUNT(messageID) AS messages,
COALESCE(SUM(attachments), 0) AS attachments
FROM wcf1_conversation_message
WHERE conversationID = ?";
$statement = WCF::getDB()->prepare($sql);
$statement->execute([$conversationID]);
$row = $statement->fetchArray();

return [
'messages' => $row['messages'],
'attachments' => $row['attachments'],
];
}
}
38 changes: 5 additions & 33 deletions files/lib/data/conversation/ConversationAction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace wcf\data\conversation;

use wcf\command\conversation\MarkAllConversationsAsRead;
use wcf\command\conversation\RebuildConversation;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\conversation\message\ConversationMessageAction;
use wcf\data\conversation\message\ConversationMessageList;
Expand Down Expand Up @@ -563,46 +564,17 @@ public function getConversations(): array
* Rebuilds the conversation data of the relevant conversations.
*
* @return void
*
* @deprecated 6.3 Use the `RebuildConversation` command instead.
*/
public function rebuild()
{
if (empty($this->objects)) {
$this->readObjects();
}

// collect number of messages for each conversation
$conditionBuilder = new PreparedStatementConditionBuilder();
$conditionBuilder->add('conversation_message.conversationID IN (?)', [$this->objectIDs]);
$sql = "SELECT conversationID, COUNT(messageID) AS messages, SUM(attachments) AS attachments
FROM wcf1_conversation_message conversation_message
" . $conditionBuilder . "
GROUP BY conversationID";
$statement = WCF::getDB()->prepare($sql);
$statement->execute($conditionBuilder->getParameters());

$objectIDs = [];
while ($row = $statement->fetchArray()) {
if (!$row['messages']) {
continue;
}
$objectIDs[] = $row['conversationID'];

$conversationEditor = new ConversationEditor(new Conversation(null, [
'conversationID' => $row['conversationID'],
]));
$conversationEditor->update([
'attachments' => $row['attachments'],
'replies' => $row['messages'] - 1,
]);
$conversationEditor->updateFirstMessage();
$conversationEditor->updateLastMessage();
}

// delete conversations without messages
$deleteConversationIDs = \array_diff($this->objectIDs, $objectIDs);
if (!empty($deleteConversationIDs)) {
$conversationAction = new self($deleteConversationIDs, 'delete');
$conversationAction->executeAction();
foreach ($this->objects as $editor) {
(new RebuildConversation($editor->getDecoratedObject()))();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace wcf\data\conversation\message;

use wcf\command\conversation\RebuildConversation;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\conversation\Conversation;
use wcf\data\conversation\ConversationAction;
Expand Down Expand Up @@ -242,21 +243,19 @@ public function delete()
{
$count = parent::delete();

$attachmentMessageIDs = $conversationIDs = [];
$attachmentMessageIDs = $conversations = [];
foreach ($this->getObjects() as $message) {
if (!\in_array($message->conversationID, $conversationIDs)) {
$conversationIDs[] = $message->conversationID;
if (!\array_key_exists($message->conversationID, $conversations)) {
$conversations[$message->conversationID] = $message->getConversation();
}

if ($message->attachments) {
$attachmentMessageIDs[] = $message->messageID;
}
}

// rebuild conversations
if (!empty($conversationIDs)) {
$conversationAction = new ConversationAction($conversationIDs, 'rebuild');
$conversationAction->executeAction();
foreach ($conversations as $conversation) {
(new RebuildConversation($conversation))();
}

if (!empty($this->objectIDs)) {
Expand Down