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

94 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 F7cloud GmbH and F7cloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Mail\Service;
use OCA\Mail\Account;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\Db\Mailbox;
use OCA\Mail\Db\Message;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\IMAP\IMAPClientFactory;
use OCA\Mail\Model\IMAPMessage;
use OCP\AppFramework\Db\DoesNotExistException;
use Psr\Log\LoggerInterface;
/**
* Enriches a DB message with from/to/subject from IMAP when they are missing
* (e.g. old messages synced before recipients were stored).
* Used so that "Create filter from message" always has data to prefill.
*/
class MessageEnvelopeEnricher {
public function __construct(
private IMAPClientFactory $clientFactory,
private IMailManager $mailManager,
private LoggerInterface $logger,
) {
}
/**
* If the message has empty from, to or subject, fetch envelope from IMAP
* and set on the message (in-memory only; response will include enriched data).
*/
public function enrichFromImapWhenEmpty(Account $account, Mailbox $mailbox, Message $message): void {
$needsEnvelope = $message->getFrom()->count() === 0
|| $message->getTo()->count() === 0
|| trim((string)$message->getSubject()) === '';
if (!$needsEnvelope) {
return;
}
try {
$client = $this->clientFactory->getClient($account);
try {
$imapMessage = $this->mailManager->getImapMessage(
$client,
$account,
$mailbox,
$message->getUid(),
false
);
$this->applyEnvelopeToMessage($imapMessage, $message);
} finally {
$client->logout();
}
} catch (DoesNotExistException $e) {
$this->logger->debug('Message no longer on IMAP, skip envelope enrichment', [
'id' => $message->getId(),
'uid' => $message->getUid(),
]);
} catch (ServiceException $e) {
$this->logger->warning('Could not fetch envelope for message, filter prefill may be incomplete', [
'id' => $message->getId(),
'message' => $e->getMessage(),
]);
}
}
private function applyEnvelopeToMessage(IMAPMessage $imapMessage, Message $message): void {
if ($message->getFrom()->count() === 0 && $imapMessage->getFrom()->count() > 0) {
$message->setFrom($imapMessage->getFrom());
}
if ($message->getTo()->count() === 0 && $imapMessage->getTo()->count() > 0) {
$message->setTo($imapMessage->getTo());
}
if ((trim((string)$message->getSubject()) === '') && trim($imapMessage->getSubject()) !== '') {
$message->setSubject($imapMessage->getSubject());
}
if ($message->getCc()->count() === 0 && $imapMessage->getCC()->count() > 0) {
$message->setCc($imapMessage->getCC());
}
if ($message->getBcc()->count() === 0 && $imapMessage->getBCC()->count() > 0) {
$message->setBcc($imapMessage->getBCC());
}
}
}