f7cloud_client/apps/mail/lib/Db/RecipientMapper.php
root 8b6a0139db f7cloud_client
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 22:59:26 +00:00

138 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 F7cloud GmbH and F7cloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Mail\Db;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
/**
* @template-extends QBMapper<Recipient>
*/
class RecipientMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'mail_recipients');
}
/**
* @returns Recipient[]
*/
public function findByLocalMessageId(int $localMessageId): array {
$qb = $this->db->getQueryBuilder();
$query = $qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('local_message_id', $qb->createNamedParameter($localMessageId, IQueryBuilder::PARAM_INT))
);
return $this->findEntities($query);
}
/**
* @return Recipient[]
*/
public function findByLocalMessageIds(array $localMessageIds): array {
if ($localMessageIds === []) {
return [];
}
$qb = $this->db->getQueryBuilder();
$query = $qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->in('local_message_id', $qb->createNamedParameter($localMessageIds, IQueryBuilder::PARAM_INT_ARRAY), IQueryBuilder::PARAM_INT_ARRAY)
);
return $this->findEntities($query);
}
public function deleteForLocalMessage(int $localMessageId): void {
$qb = $this->db->getQueryBuilder();
$qb->delete($this->getTableName())
->where(
$qb->expr()->eq('local_message_id', $qb->createNamedParameter($localMessageId, IQueryBuilder::PARAM_INT))
);
$qb->executeStatement();
}
/**
* @param Recipient[] $recipients
*/
public function saveRecipients(int $localMessageId, array $recipients): void {
foreach ($recipients as $recipient) {
$recipient->setLocalMessageId($localMessageId);
$this->insert($recipient);
}
}
/**
* @param int $localMessageId
* @param Recipient[] $oldRecipients
* @param Recipient[] $to
* @param Recipient[] $cc
* @param Recipient[] $bcc
* @return void
*/
public function updateRecipients(int $localMessageId, array $oldRecipients, array $to, array $cc, array $bcc): void {
if (empty(array_merge($to, $cc, $bcc))) {
// No recipients set anymore. Remove any old ones.
$this->deleteForLocalMessage($localMessageId);
return;
}
if ($oldRecipients === []) {
// No need for a diff, save and return
$this->saveRecipients($localMessageId, $to);
$this->saveRecipients($localMessageId, $cc);
$this->saveRecipients($localMessageId, $bcc);
return;
}
// Get old Recipients split per their types
$oldTo = array_filter($oldRecipients, static fn ($recipient) => $recipient->getType() === Recipient::TYPE_TO);
$oldCc = array_filter($oldRecipients, static fn ($recipient) => $recipient->getType() === Recipient::TYPE_CC);
$oldBcc = array_filter($oldRecipients, static fn ($recipient) => $recipient->getType() === Recipient::TYPE_BCC);
// To - add
$newTo = array_udiff($to, $oldTo, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
if ($newTo !== []) {
$this->saveRecipients($localMessageId, $newTo);
}
$toRemove = array_udiff($oldTo, $to, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
foreach ($toRemove as $r) {
$this->delete($r);
}
// CC
$newCC = array_udiff($cc, $oldCc, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
if ($newCC !== []) {
$this->saveRecipients($localMessageId, $newCC);
}
$ccRemove = array_udiff($oldCc, $cc, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
foreach ($ccRemove as $r) {
$this->delete($r);
}
// BCC
$newBcc = array_udiff($bcc, $oldBcc, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
if ($newBcc !== []) {
$this->saveRecipients($localMessageId, $newBcc);
}
$bccRemove = array_udiff($oldBcc, $bcc, static fn (Recipient $a, Recipient $b) => strcmp($a->getEmail(), $b->getEmail()));
foreach ($bccRemove as $r) {
$this->delete($r);
}
}
}