Skip to content
Open
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
21 changes: 18 additions & 3 deletions Sources/PersonalMessage/Received.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,21 @@ public function save(): void
$this->in_inbox = true;
}

// A row here is one member's copy of one PM, and (id_pm, id_member) is
// the primary key. Naming only the PM makes this statement try to hand
// every recipient's copy to the same member, so anything that saves a
// PM with more than one recipient - marking it read, labelling it,
// deleting it - is a duplicate key error rather than a save.
Db::$db->query(
'UPDATE {db_prefix}pm_recipients
SET
id_member = {int:member},
bcc = {int:bcc},
is_read = {int:is_read},
is_new = {int:is_new},
deleted = {int:deleted},
in_inbox = {int:in_inbox}
WHERE id_pm = {int:id}',
WHERE id_pm = {int:id}
AND id_member = {int:member}',
[
'id' => (int) $this->id,
'member' => (int) $this->member,
Expand All @@ -259,12 +264,22 @@ public function save(): void

$labels = array_diff($this->labels, [-1]);

// Labels belong to a member too, so only clear the ones this member
// owns. Every other recipient has their own labels on the same PM, and
// with the update above fixed this line is finally reached for a PM
// that has some.
Db::$db->query(
'DELETE FROM {db_prefix}pm_labeled_messages
WHERE id_pm = {int:current_pm}' . (empty($labels) ? '' : '
WHERE id_pm = {int:current_pm}
AND id_label IN (
SELECT id_label
FROM {db_prefix}pm_labels
WHERE id_member = {int:member}
)' . (empty($labels) ? '' : '
AND id_label NOT IN ({array_int:labels})'),
[
'current_pm' => $this->id,
'member' => (int) $this->member,
'labels' => $labels,
],
);
Expand Down