Skip to content

Commit ea44dd1

Browse files
committed
Use endpoints to leave the conversation and render the dialog
1 parent 998df9b commit ea44dd1

File tree

14 files changed

+441
-136
lines changed

14 files changed

+441
-136
lines changed

files/js/WCF.Conversation.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,7 @@ WCF.Conversation.InlineEditor = WCF.InlineEditor.extend({
506506

507507
case 'leave':
508508
require(["WoltLabSuite/Core/Conversation/Component/Leave"], ({ openDialog }) => {
509-
openDialog(
510-
elData(elById(elementID), "conversation-leave-form-link"),
511-
this._environment,
512-
);
509+
openDialog(elData(elById(elementID), "conversation-id"), this._environment);
513510
});
514511
break;
515512

files/js/WoltLabSuite/Core/Api/Conversations/GetConversationLeaveDialog.js

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

files/js/WoltLabSuite/Core/Api/Conversations/LeaveConversation.js

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

files/js/WoltLabSuite/Core/Conversation/Component/Leave.js

Lines changed: 29 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

files/lib/bootstrap/com.woltlab.wcf.conversation.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ static function (\wcf\event\user\profile\UserProfileHeaderInteractionOptionColle
4040
\wcf\event\endpoint\ControllerCollecting::class,
4141
static function (\wcf\event\endpoint\ControllerCollecting $event) {
4242
$event->register(new \wcf\system\endpoint\controller\core\conversations\GetConversationPopover());
43+
$event->register(new \wcf\system\endpoint\controller\core\conversations\LeaveConversation());
44+
$event->register(new \wcf\system\endpoint\controller\core\conversations\GetConversationLeaveDialog());
4345
}
4446
);
4547
};

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

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use wcf\data\user\group\UserGroup;
1212
use wcf\page\ConversationPage;
1313
use wcf\system\clipboard\ClipboardHandler;
14+
use wcf\system\conversation\command\Leave;
1415
use wcf\system\conversation\ConversationHandler;
1516
use wcf\system\database\util\PreparedStatementConditionBuilder;
1617
use wcf\system\event\EventHandler;
@@ -554,51 +555,6 @@ public function open()
554555
return $this->getConversationData();
555556
}
556557

557-
/**
558-
* Validates conversations for leave form.
559-
*
560-
* @throws PermissionDeniedException
561-
* @throws UserInputException
562-
*/
563-
public function validateGetLeaveForm()
564-
{
565-
if (empty($this->objectIDs)) {
566-
throw new UserInputException('objectIDs');
567-
}
568-
569-
// validate participation
570-
if (!Conversation::isParticipant($this->objectIDs)) {
571-
throw new PermissionDeniedException();
572-
}
573-
}
574-
575-
/**
576-
* Returns dialog form to leave conversations.
577-
*
578-
* @return array
579-
*/
580-
public function getLeaveForm()
581-
{
582-
// get hidden state from first conversation (all others have the same state)
583-
$sql = "SELECT hideConversation
584-
FROM wcf1_conversation_to_user
585-
WHERE conversationID = ?
586-
AND participantID = ?";
587-
$statement = WCF::getDB()->prepare($sql);
588-
$statement->execute([
589-
\current($this->objectIDs),
590-
WCF::getUser()->userID,
591-
]);
592-
$row = $statement->fetchArray();
593-
594-
WCF::getTPL()->assign('hideConversation', ($row !== false ? $row['hideConversation'] : 0));
595-
596-
return [
597-
'actionName' => 'getLeaveForm',
598-
'template' => WCF::getTPL()->fetch('conversationLeave'),
599-
];
600-
}
601-
602558
/**
603559
* Validates parameters to hide conversations.
604560
*
@@ -635,68 +591,7 @@ public function validateHideConversation()
635591
*/
636592
public function hideConversation()
637593
{
638-
$sql = "UPDATE wcf1_conversation_to_user
639-
SET hideConversation = ?
640-
WHERE conversationID = ?
641-
AND participantID = ?";
642-
$statement = WCF::getDB()->prepare($sql);
643-
644-
WCF::getDB()->beginTransaction();
645-
foreach ($this->objectIDs as $conversationID) {
646-
$statement->execute([
647-
$this->parameters['hideConversation'],
648-
$conversationID,
649-
WCF::getUser()->userID,
650-
]);
651-
}
652-
WCF::getDB()->commitTransaction();
653-
654-
// reset user's conversation counters if user leaves conversation
655-
// permanently
656-
if ($this->parameters['hideConversation'] == Conversation::STATE_LEFT) {
657-
UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'conversationCount');
658-
UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadConversationCount');
659-
}
660-
661-
// add modification log entry
662-
if ($this->parameters['hideConversation'] == Conversation::STATE_LEFT) {
663-
if (empty($this->objects)) {
664-
$this->readObjects();
665-
}
666-
667-
foreach ($this->getObjects() as $conversation) {
668-
ConversationModificationLogHandler::getInstance()->leave($conversation->getDecoratedObject());
669-
}
670-
}
671-
672-
// unmark items
673-
$this->unmarkItems();
674-
675-
if ($this->parameters['hideConversation'] == Conversation::STATE_LEFT) {
676-
// update participants count and participant summary
677-
ConversationEditor::updateParticipantCounts($this->objectIDs);
678-
ConversationEditor::updateParticipantSummaries($this->objectIDs);
679-
680-
// delete conversation if all users have left it
681-
$conditionBuilder = new PreparedStatementConditionBuilder();
682-
$conditionBuilder->add('conversation.conversationID IN (?)', [$this->objectIDs]);
683-
$conditionBuilder->add('conversation_to_user.conversationID IS NULL');
684-
$sql = "SELECT DISTINCT conversation.conversationID
685-
FROM wcf1_conversation conversation
686-
LEFT JOIN wcf1_conversation_to_user conversation_to_user
687-
ON conversation_to_user.conversationID = conversation.conversationID
688-
AND conversation_to_user.hideConversation <> " . Conversation::STATE_LEFT . "
689-
AND conversation_to_user.participantID IS NOT NULL
690-
" . $conditionBuilder;
691-
$statement = WCF::getDB()->prepare($sql);
692-
$statement->execute($conditionBuilder->getParameters());
693-
$conversationIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
694-
695-
if (!empty($conversationIDs)) {
696-
$action = new self($conversationIDs, 'delete');
697-
$action->executeAction();
698-
}
699-
}
594+
(new Leave($this->objectIDs, $this->parameters['hideConversation']))();
700595

701596
return [
702597
'actionName' => 'hideConversation',
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace wcf\system\conversation\command;
4+
5+
use wcf\data\conversation\Conversation;
6+
use wcf\data\conversation\ConversationAction;
7+
use wcf\data\conversation\ConversationEditor;
8+
use wcf\system\database\util\PreparedStatementConditionBuilder;
9+
use wcf\system\WCF;
10+
11+
/**
12+
* Command for deleting conversation if all users have left it
13+
*
14+
* @author Olaf Braun
15+
* @copyright 2001-2025 WoltLab GmbH
16+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
17+
* @since 6.2
18+
*/
19+
final class DeleteEmptyConversations
20+
{
21+
public function __construct(
22+
public readonly array $conversationIDs,
23+
) {
24+
}
25+
26+
public function __invoke()
27+
{
28+
// update participants count and participant summary
29+
ConversationEditor::updateParticipantCounts($this->conversationIDs);
30+
ConversationEditor::updateParticipantSummaries($this->conversationIDs);
31+
32+
$conditionBuilder = new PreparedStatementConditionBuilder();
33+
$conditionBuilder->add('conversation.conversationID IN (?)', [$this->conversationIDs]);
34+
$conditionBuilder->add('conversation_to_user.conversationID IS NULL');
35+
$sql = "SELECT DISTINCT conversation.conversationID
36+
FROM wcf1_conversation conversation
37+
LEFT JOIN wcf1_conversation_to_user conversation_to_user
38+
ON conversation_to_user.conversationID = conversation.conversationID
39+
AND conversation_to_user.hideConversation <> " . Conversation::STATE_LEFT . "
40+
AND conversation_to_user.participantID IS NOT NULL
41+
" . $conditionBuilder;
42+
$statement = WCF::getDB()->prepare($sql);
43+
$statement->execute($conditionBuilder->getParameters());
44+
$conversationIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
45+
46+
if (!empty($conversationIDs)) {
47+
$action = new ConversationAction($conversationIDs, 'delete');
48+
$action->executeAction();
49+
}
50+
}
51+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace wcf\system\conversation\command;
4+
5+
use wcf\data\conversation\Conversation;
6+
use wcf\data\conversation\ConversationList;
7+
use wcf\system\clipboard\ClipboardHandler;
8+
use wcf\system\log\modification\ConversationModificationLogHandler;
9+
use wcf\system\user\storage\UserStorageHandler;
10+
use wcf\system\WCF;
11+
12+
/**
13+
* Command for leaving a conversation.
14+
*
15+
* @author Olaf Braun
16+
* @copyright 2001-2025 WoltLab GmbH
17+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
18+
* @since 6.2
19+
*/
20+
final class Leave
21+
{
22+
public function __construct(
23+
public readonly array $conversationIDs,
24+
public readonly int $hideConversation
25+
) {
26+
if (
27+
!\in_array(
28+
$this->hideConversation,
29+
[Conversation::STATE_DEFAULT, Conversation::STATE_HIDDEN, Conversation::STATE_LEFT]
30+
)
31+
) {
32+
throw new \InvalidArgumentException('Invalid hideConversation value');
33+
}
34+
}
35+
36+
public function __invoke()
37+
{
38+
$sql = "UPDATE wcf1_conversation_to_user
39+
SET hideConversation = ?
40+
WHERE conversationID = ?
41+
AND participantID = ?";
42+
$statement = WCF::getDB()->prepare($sql);
43+
44+
WCF::getDB()->beginTransaction();
45+
foreach ($this->conversationIDs as $conversationID) {
46+
$statement->execute([
47+
$this->hideConversation,
48+
$conversationID,
49+
WCF::getUser()->userID,
50+
]);
51+
}
52+
WCF::getDB()->commitTransaction();
53+
54+
if ($this->hideConversation == Conversation::STATE_LEFT) {
55+
// reset user's conversation counters if user leaves conversation
56+
// permanently
57+
UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'conversationCount');
58+
UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'unreadConversationCount');
59+
60+
61+
// add modification log entry
62+
$conversationList = new ConversationList();
63+
$conversationList->setObjectIDs($this->conversationIDs);
64+
$conversationList->readObjects();
65+
66+
foreach ($conversationList as $conversation) {
67+
ConversationModificationLogHandler::getInstance()->leave($conversation);
68+
}
69+
}
70+
71+
// unmark items
72+
$this->unmarkItems();
73+
74+
(new DeleteEmptyConversations($this->conversationIDs))();
75+
}
76+
77+
private function unmarkItems(): void
78+
{
79+
ClipboardHandler::getInstance()->unmark(
80+
$this->conversationIDs,
81+
ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.conversation.conversation')
82+
);
83+
}
84+
}

0 commit comments

Comments
 (0)