diff options
author | Anna Larch <anna@nextcloud.com> | 2021-03-04 19:31:21 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2021-03-22 20:06:02 +0300 |
commit | 83a58623b116cd3f8c79f751a3df5963b3392692 (patch) | |
tree | 8f9660e75ea8748057e752c4f1573e3c618b5b85 /lib/Service | |
parent | f27fb61c0fe15ef6a278a40d7774cde4b7c748b8 (diff) |
Add tagging to messages
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'lib/Service')
-rw-r--r-- | lib/Service/MailManager.php | 113 | ||||
-rw-r--r-- | lib/Service/Search/Flag.php | 4 | ||||
-rw-r--r-- | lib/Service/SetupService.php | 16 | ||||
-rw-r--r-- | lib/Service/Sync/ImapToDbSynchronizer.php | 14 |
4 files changed, 114 insertions, 33 deletions
diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php index d37278477..782946e6a 100644 --- a/lib/Service/MailManager.php +++ b/lib/Service/MailManager.php @@ -23,34 +23,36 @@ declare(strict_types=1); namespace OCA\Mail\Service; -use Horde_Imap_Client; -use Horde_Imap_Client_Exception; -use Horde_Imap_Client_Exception_NoSupportExtension; -use Horde_Imap_Client_Socket; +use OCA\Mail\Db\Tag; +use OCA\Mail\Folder; use OCA\Mail\Account; -use OCA\Mail\Contracts\IMailManager; +use Horde_Imap_Client; +use function array_map; use OCA\Mail\Db\Mailbox; -use OCA\Mail\Db\MailboxMapper; use OCA\Mail\Db\Message; -use OCA\Mail\Db\MessageMapper as DbMessageMapper; -use OCA\Mail\Events\BeforeMessageDeletedEvent; +use function array_values; +use OCA\Mail\Db\TagMapper; +use Psr\Log\LoggerInterface; +use Horde_Imap_Client_Socket; +use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\IMAP\FolderStats; +use OCA\Mail\IMAP\MailboxSync; +use OCA\Mail\IMAP\FolderMapper; +use OCA\Mail\Model\IMAPMessage; +use Horde_Imap_Client_Exception; +use OCA\Mail\Contracts\IMailManager; +use OCA\Mail\IMAP\IMAPClientFactory; +use OCA\Mail\Exception\ClientException; use OCA\Mail\Events\MessageDeletedEvent; use OCA\Mail\Events\MessageFlaggedEvent; -use OCA\Mail\Exception\ClientException; use OCA\Mail\Exception\ServiceException; +use OCP\EventDispatcher\IEventDispatcher; +use OCA\Mail\Events\BeforeMessageDeletedEvent; +use OCP\AppFramework\Db\DoesNotExistException; +use OCA\Mail\Db\MessageMapper as DbMessageMapper; +use Horde_Imap_Client_Exception_NoSupportExtension; use OCA\Mail\Exception\TrashMailboxNotSetException; -use OCA\Mail\Folder; -use OCA\Mail\IMAP\FolderMapper; -use OCA\Mail\IMAP\FolderStats; -use OCA\Mail\IMAP\IMAPClientFactory; -use OCA\Mail\IMAP\MailboxSync; use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper; -use OCA\Mail\Model\IMAPMessage; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\EventDispatcher\IEventDispatcher; -use Psr\Log\LoggerInterface; -use function array_map; -use function array_values; class MailManager implements IMailManager { @@ -86,8 +88,12 @@ class MailManager implements IMailManager { /** @var DbMessageMapper */ private $dbMessageMapper; + /** @var TagMapper */ + private $tagMapper; + /** @var IEventDispatcher */ private $eventDispatcher; + /** * @var LoggerInterface */ @@ -100,7 +106,8 @@ class MailManager implements IMailManager { ImapMessageMapper $messageMapper, DbMessageMapper $dbMessageMapper, IEventDispatcher $eventDispatcher, - LoggerInterface $logger) { + LoggerInterface $logger, + TagMapper $tagMapper) { $this->imapClientFactory = $imapClientFactory; $this->mailboxMapper = $mailboxMapper; $this->mailboxSync = $mailboxSync; @@ -109,6 +116,7 @@ class MailManager implements IMailManager { $this->dbMessageMapper = $dbMessageMapper; $this->eventDispatcher = $eventDispatcher; $this->logger = $logger; + $this->tagMapper = $tagMapper; } public function getMailbox(string $uid, int $id): Mailbox { @@ -393,7 +401,7 @@ class MailManager implements IMailManager { if (empty($imapFlag) === true) { continue; } - if ($value === true) { + if ($value) { $this->imapMessageMapper->addFlag($client, $mb, $uid, $imapFlag); } else { $this->imapMessageMapper->removeFlag($client, $mb, $uid, $imapFlag); @@ -420,6 +428,50 @@ class MailManager implements IMailManager { } /** + * Tag (flag) a message on IMAP + * + * @param Account $account + * @param string $mailbox + * @param integer $uid + * @param Tag $tag + * @param boolean $value + * @return void + * + * @uses + * + * @link https://github.com/nextcloud/mail/issues/25 + */ + public function tagMessage(Account $account, string $mailbox, Message $message, Tag $tag, bool $value): void { + $client = $this->imapClientFactory->getClient($account); + try { + $mb = $this->mailboxMapper->find($account, $mailbox); + } catch (DoesNotExistException $e) { + throw new ClientException("Mailbox $mailbox does not exist", 0, $e); + } + if ($this->isPermflagsEnabled($account, $mailbox) === true) { + try { + if ($value) { + // imap keywords and flags work the same way + $this->imapMessageMapper->addFlag($client, $mb, $message->getUid(), $tag->getImapLabel()); + } else { + $this->imapMessageMapper->removeFlag($client, $mb, $message->getUid(), $tag->getImapLabel()); + } + } catch (Horde_Imap_Client_Exception $e) { + throw new ServiceException( + "Could not set message keyword on IMAP: " . $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + } + if ($value) { + $this->tagMapper->tagMessage($tag, $message->getMessageId(), $account->getUserId()); + } else { + $this->tagMapper->untagMessage($tag, $message->getMessageId()); + } + } + + /** * @param Account $account * * @return Quota|null @@ -518,6 +570,21 @@ class MailManager implements IMailManager { } /** + * @param string $imapLabel + * @param string $userId + * @return Tag + * @throws DoesNotExistException + */ + public function getTagByImapLabel(string $imapLabel, string $userId): Tag { + try { + return $this->tagMapper->getTagByImapLabel($imapLabel, $userId); + } catch (DoesNotExistException $e) { + throw new ClientException('Unknow Tag', (int)$e->getCode(), $e); + } + } + + + /** * Filter out IMAP flags that aren't supported by the client server * * @param Horde_Imap_Client_Socket $client @@ -534,7 +601,7 @@ class MailManager implements IMailManager { // Only allow flag setting if IMAP supports Permaflags // @TODO check if there are length & char limits on permflags if ($this->isPermflagsEnabled($account, $mailbox) === true) { - return ["$" . $flag]; + return [$flag]; } return []; } diff --git a/lib/Service/Search/Flag.php b/lib/Service/Search/Flag.php index 79294813a..491a63aca 100644 --- a/lib/Service/Search/Flag.php +++ b/lib/Service/Search/Flag.php @@ -26,6 +26,7 @@ declare(strict_types=1); namespace OCA\Mail\Service\Search; use Horde_Imap_Client; +use OCA\Mail\Db\Tag; /** * @psalm-immutable @@ -34,7 +35,8 @@ class Flag { public const ANSWERED = Horde_Imap_Client::FLAG_ANSWERED; public const SEEN = Horde_Imap_Client::FLAG_SEEN; public const FLAGGED = Horde_Imap_Client::FLAG_FLAGGED; - public const IMPORTANT = '\\important'; + /** @deprecated */ + public const IMPORTANT = Tag::LABEL_IMPORTANT; public const DELETED = Horde_Imap_Client::FLAG_DELETED; /** @var string */ diff --git a/lib/Service/SetupService.php b/lib/Service/SetupService.php index ffd6146ac..78b423425 100644 --- a/lib/Service/SetupService.php +++ b/lib/Service/SetupService.php @@ -31,6 +31,7 @@ use Horde_Mail_Exception; use Horde_Mail_Transport_Smtphorde; use OCA\Mail\Account; use OCA\Mail\Db\MailAccount; +use OCA\Mail\Db\TagMapper; use OCA\Mail\Exception\CouldNotConnectException; use OCA\Mail\Exception\ServiceException; use OCA\Mail\IMAP\IMAPClientFactory; @@ -56,21 +57,26 @@ class SetupService { /** @var IMAPClientFactory */ private $imapClientFactory; - /** var LoggerInterface */ + /** @var LoggerInterface */ private $logger; + /** @var TagMapper */ + private $tagMapper; + public function __construct(AutoConfig $autoConfig, AccountService $accountService, ICrypto $crypto, SmtpClientFactory $smtpClientFactory, IMAPClientFactory $imapClientFactory, - LoggerInterface $logger) { + LoggerInterface $logger, + TagMapper $tagMapper) { $this->autoConfig = $autoConfig; $this->accountService = $accountService; $this->crypto = $crypto; $this->smtpClientFactory = $smtpClientFactory; $this->imapClientFactory = $imapClientFactory; $this->logger = $logger; + $this->tagMapper = $tagMapper; } /** @@ -78,6 +84,8 @@ class SetupService { * @param string $emailAddress * @param string $password * @return Account|null + * + * @link https://github.com/nextcloud/mail/issues/25 */ public function createNewAutoConfiguredAccount($accountName, $emailAddress, $password) { $this->logger->info('setting up auto detected account'); @@ -88,6 +96,8 @@ class SetupService { $this->accountService->save($mailAccount); + $this->tagMapper->createDefaultTags($mailAccount); + return new Account($mailAccount); } @@ -139,6 +149,8 @@ class SetupService { $this->accountService->save($newAccount); $this->logger->debug("account created " . $newAccount->getId()); + $this->tagMapper->createDefaultTags($newAccount); + return $account; } diff --git a/lib/Service/Sync/ImapToDbSynchronizer.php b/lib/Service/Sync/ImapToDbSynchronizer.php index 3132aad06..2adba1ee2 100644 --- a/lib/Service/Sync/ImapToDbSynchronizer.php +++ b/lib/Service/Sync/ImapToDbSynchronizer.php @@ -292,8 +292,8 @@ class ImapToDbSynchronizer { } foreach (array_chunk($imapMessages['messages'], 500) as $chunk) { - $this->dbMapper->insertBulk(...array_map(function (IMAPMessage $imapMessage) use ($mailbox) { - return $imapMessage->toDbMessage($mailbox->getId()); + $this->dbMapper->insertBulk($account, ...array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) { + return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount()); }, $chunk)); } $perf->step('persist messages in database'); @@ -349,8 +349,8 @@ class ImapToDbSynchronizer { $perf->step('get new messages via Horde'); foreach (array_chunk($response->getNewMessages(), 500) as $chunk) { - $dbMessages = array_map(function (IMAPMessage $imapMessage) use ($mailbox) { - return $imapMessage->toDbMessage($mailbox->getId()); + $dbMessages = array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) { + return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount()); }, $chunk); $this->dispatcher->dispatch( @@ -359,7 +359,7 @@ class ImapToDbSynchronizer { ); $perf->step('classified a chunk of new messages'); - $this->dbMapper->insertBulk(...$dbMessages); + $this->dbMapper->insertBulk($account, ...$dbMessages); } $perf->step('persist new messages'); @@ -378,8 +378,8 @@ class ImapToDbSynchronizer { $perf->step('get changed messages via Horde'); foreach (array_chunk($response->getChangedMessages(), 500) as $chunk) { - $this->dbMapper->updateBulk(...array_map(function (IMAPMessage $imapMessage) use ($mailbox) { - return $imapMessage->toDbMessage($mailbox->getId()); + $this->dbMapper->updateBulk($account, ...array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) { + return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount()); }, $chunk)); } $perf->step('persist changed messages'); |