Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/mail.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2019-09-04 18:05:19 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2019-09-05 14:45:50 +0300
commitd18ef16578dc34ffd67e48bc5c61654e55461ce9 (patch)
tree0fb85d03cba26c56be550b2cba5072dd6aca4e91 /lib/Listener
parenteec81c6c38259c0edc843018581a1f1bd1ab280a (diff)
Move message sending and draft saving code
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib/Listener')
-rw-r--r--lib/Listener/AddressCollectionListener.php68
-rw-r--r--lib/Listener/DeleteDraftListener.php144
-rw-r--r--lib/Listener/DraftMailboxCreatorListener.php98
-rw-r--r--lib/Listener/FlagRepliedMessageListener.php98
-rw-r--r--lib/Listener/SaveSentMessageListener.php126
-rw-r--r--lib/Listener/TrashMailboxCreatorListener.php (renamed from lib/Listener/MessageDeleteTrashCreatorListener.php)16
6 files changed, 542 insertions, 8 deletions
diff --git a/lib/Listener/AddressCollectionListener.php b/lib/Listener/AddressCollectionListener.php
new file mode 100644
index 000000000..c2ae7eee9
--- /dev/null
+++ b/lib/Listener/AddressCollectionListener.php
@@ -0,0 +1,68 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\Mail\Listener;
+
+use OCA\Mail\Events\MessageSentEvent;
+use OCA\Mail\Service\AutoCompletion\AddressCollector;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+use Throwable;
+
+class AddressCollectionListener implements IEventListener {
+
+ /** @var AddressCollector */
+ private $collector;
+
+ /** @var ILogger */
+ private $logger;
+
+ public function __construct(AddressCollector $collector,
+ ILogger $logger) {
+ $this->collector = $collector;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof MessageSentEvent)) {
+ return;
+ }
+
+ // Non-essential feature, hence we catch all possible errors
+ try {
+ $message = $event->getMessage();
+ $addresses = $message->getTo()
+ ->merge($message->getCC())
+ ->merge($message->getBCC());
+
+ $this->collector->addAddresses($addresses);
+ } catch (Throwable $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Error while collecting mail addresses',
+ 'level' => ILogger::WARN,
+ ]);
+ }
+ }
+
+}
diff --git a/lib/Listener/DeleteDraftListener.php b/lib/Listener/DeleteDraftListener.php
new file mode 100644
index 000000000..fdc8622cb
--- /dev/null
+++ b/lib/Listener/DeleteDraftListener.php
@@ -0,0 +1,144 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\Mail\Listener;
+
+use Horde_Imap_Client;
+use Horde_Imap_Client_Exception;
+use Horde_Imap_Client_Exception_NoSupportExtension;
+use OCA\Mail\Account;
+use OCA\Mail\Db\Mailbox;
+use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Events\DraftSavedEvent;
+use OCA\Mail\Events\MessageSentEvent;
+use OCA\Mail\Exception\ServiceException;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\MailboxSync;
+use OCA\Mail\IMAP\MessageMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+
+class DeleteDraftListener implements IEventListener {
+
+ /** @var IMAPClientFactory */
+ private $imapClientFactory;
+
+ /** @var MailboxMapper */
+ private $mailboxMapper;
+
+ /** @var MessageMapper */
+ private $messageMapper;
+
+ /** @var MailboxSync */
+ private $mailboxSync;
+
+ /** @var ILogger */
+ private $logger;
+
+ public function __construct(IMAPClientFactory $imapClientFactory,
+ MailboxMapper $mailboxMapper,
+ MessageMapper $messageMapper,
+ MailboxSync $mailboxSync,
+ ILogger $logger) {
+ $this->imapClientFactory = $imapClientFactory;
+ $this->mailboxMapper = $mailboxMapper;
+ $this->messageMapper = $messageMapper;
+ $this->mailboxSync = $mailboxSync;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if ($event instanceof DraftSavedEvent && $event->getDraftUid() !== null) {
+ $this->deleteDraft($event->getAccount(), $event->getDraftUid());
+ } else if ($event instanceof MessageSentEvent && $event->getDraftUid() !== null) {
+ $this->deleteDraft($event->getAccount(), $event->getDraftUid());
+ }
+ }
+
+ /**
+ * @param DraftSavedEvent $event
+ */
+ private function deleteDraft(Account $account, int $draftUid): void {
+ $client = $this->imapClientFactory->getClient($account);
+ $draftsMailbox = $this->getDraftsMailbox($account);
+
+ try {
+ $this->messageMapper->addFlag(
+ $client,
+ $draftsMailbox,
+ $draftUid,
+ Horde_Imap_Client::FLAG_DELETED
+ );
+ } catch (Horde_Imap_Client_Exception_NoSupportExtension|Horde_Imap_Client_Exception $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not flag draft as deleted'
+ ]);
+ }
+
+ try {
+ $client->expunge($draftsMailbox->getName());
+ } catch (Horde_Imap_Client_Exception $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not expunge drafts folder'
+ ]);
+ }
+ }
+
+ private function getDraftsMailbox(Account $account): Mailbox {
+ try {
+ return $this->mailboxMapper->findSpecial($account, 'drafts');
+ } catch (DoesNotExistException $e) {
+ $this->logger->debug('Creating drafts mailbox');
+ $this->createDraftsMailbox($account);
+ $this->logger->debug('Drafts mailbox created');
+ }
+
+ return $this->mailboxMapper->findSpecial($account, 'drafts');
+ }
+
+ private function createDraftsMailbox(Account $account): void {
+ $client = $this->imapClientFactory->getClient($account);
+
+ try {
+ // TODO: localize mailbox name
+ $client->createMailbox(
+ 'Drafts',
+ [
+ 'special_use' => [
+ \Horde_Imap_Client::SPECIALUSE_DRAFTS,
+ ],
+ ]
+ );
+ } catch (Horde_Imap_Client_Exception $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not create drafts mailbox',
+ ]);
+ }
+
+ // TODO: find a more elegant solution for updating the mailbox cache
+ $this->mailboxSync->sync($account, true);
+ }
+
+}
diff --git a/lib/Listener/DraftMailboxCreatorListener.php b/lib/Listener/DraftMailboxCreatorListener.php
new file mode 100644
index 000000000..fdb705f1a
--- /dev/null
+++ b/lib/Listener/DraftMailboxCreatorListener.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\Mail\Listener;
+
+use Horde_Imap_Client_Exception;
+use OCA\Mail\Account;
+use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Events\SaveDraftEvent;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\MailboxSync;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+
+class DraftMailboxCreatorListener implements IEventListener {
+
+ /** @var MailboxMapper */
+ private $mailboxMapper;
+
+ /** @var IMAPClientFactory */
+ private $imapClientFactory;
+
+ /** @var MailboxSync */
+ private $mailboxSync;
+
+ /** @var ILogger */
+ private $logger;
+
+ public function __construct(MailboxMapper $mailboxMapper,
+ IMAPClientFactory $imapClientFactory,
+ MailboxSync $mailboxSync,
+ ILogger $logger) {
+ $this->mailboxMapper = $mailboxMapper;
+ $this->imapClientFactory = $imapClientFactory;
+ $this->mailboxSync = $mailboxSync;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof SaveDraftEvent)) {
+ return;
+ }
+
+ try {
+ $this->mailboxMapper->findSpecial($event->getAccount(), 'drafts');
+ } catch (DoesNotExistException $e) {
+ $this->logger->debug('Creating drafts mailbox');
+ $this->createDraftsMailbox($event->getAccount());
+ $this->logger->debug('Drafts mailbox created');
+ }
+ }
+
+ private function createDraftsMailbox(Account $account): void {
+ $client = $this->imapClientFactory->getClient($account);
+
+ try {
+ // TODO: localize mailbox name
+ $client->createMailbox(
+ 'Drafts',
+ [
+ 'special_use' => [
+ \Horde_Imap_Client::SPECIALUSE_DRAFTS,
+ ],
+ ]
+ );
+ } catch (Horde_Imap_Client_Exception $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not create drafts mailbox',
+ ]);
+ }
+
+ // TODO: find a more elegant solution for updating the mailbox cache
+ $this->mailboxSync->sync($account, true);
+ }
+
+}
diff --git a/lib/Listener/FlagRepliedMessageListener.php b/lib/Listener/FlagRepliedMessageListener.php
new file mode 100644
index 000000000..c52795380
--- /dev/null
+++ b/lib/Listener/FlagRepliedMessageListener.php
@@ -0,0 +1,98 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\Mail\Listener;
+
+use Horde_Imap_Client;
+use Horde_Imap_Client_Exception;
+use Horde_Imap_Client_Exception_NoSupportExtension;
+use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Events\MessageSentEvent;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\MessageMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+
+class FlagRepliedMessageListener implements IEventListener {
+
+ /** @var IMAPClientFactory */
+ private $imapClientFactory;
+
+ /** @var MailboxMapper */
+ private $mailboxMapper;
+
+ /** @var MessageMapper */
+ private $messageMapper;
+
+ /** @var ILogger */
+ private $logger;
+
+ public function __construct(IMAPClientFactory $imapClientFactory,
+ MailboxMapper $mailboxMapper,
+ MessageMapper $mapper,
+ ILogger $logger) {
+
+ $this->imapClientFactory = $imapClientFactory;
+ $this->mailboxMapper = $mailboxMapper;
+ $this->messageMapper = $mapper;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof MessageSentEvent) || !$event->getRepliedMessageData()->isReply()) {
+ return;
+ }
+
+ try {
+ $mailbox = $this->mailboxMapper->find(
+ $event->getAccount(),
+ base64_decode($event->getRepliedMessageData()->getFolderId())
+ );
+ } catch (DoesNotExistException $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not flag the message in reply to',
+ 'level' => ILogger::WARN,
+ ]);
+ // Not critical -> continue
+ return;
+ }
+
+ try {
+ $client = $this->imapClientFactory->getClient($event->getAccount());
+ $this->messageMapper->addFlag(
+ $client,
+ $mailbox,
+ $event->getRepliedMessageData()->getId(),
+ Horde_Imap_Client::FLAG_ANSWERED
+ );
+ } catch (Horde_Imap_Client_Exception_NoSupportExtension|Horde_Imap_Client_Exception $e) {
+ $this->logger->logException($e, [
+ 'message' => 'Could not flag replied message',
+ 'level' => ILogger::WARN,
+ ]);
+ }
+ }
+
+}
diff --git a/lib/Listener/SaveSentMessageListener.php b/lib/Listener/SaveSentMessageListener.php
new file mode 100644
index 000000000..271dee92e
--- /dev/null
+++ b/lib/Listener/SaveSentMessageListener.php
@@ -0,0 +1,126 @@
+<?php declare(strict_types=1);
+
+/**
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\Mail\Listener;
+
+use Horde_Imap_Client_Exception;
+use OCA\Mail\Account;
+use OCA\Mail\Db\Mailbox;
+use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Events\MessageSentEvent;
+use OCA\Mail\Exception\ServiceException;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\MailboxSync;
+use OCA\Mail\IMAP\MessageMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\ILogger;
+
+class SaveSentMessageListener implements IEventListener {
+
+ /** @var MailboxMapper */
+ private $mailboxMapper;
+
+ /** @var IMAPClientFactory */
+ private $imapClientFactory;
+
+ /** @var MessageMapper */
+ private $messageMapper;
+
+ /** @var MailboxSync */
+ private $mailboxSync;
+
+ /** @var ILogger */
+ private $logger;
+
+ public function __construct(MailboxMapper $mailboxMapper,
+ IMAPClientFactory $imapClientFactory,
+ MessageMapper $messageMapper,
+ MailboxSync $mailboxSync,
+ ILogger $logger) {
+ $this->mailboxMapper = $mailboxMapper;
+ $this->imapClientFactory = $imapClientFactory;
+ $this->messageMapper = $messageMapper;
+ $this->mailboxSync = $mailboxSync;
+ $this->logger = $logger;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof MessageSentEvent)) {
+ return;
+ }
+
+ // Save the message in the sent mailbox
+ try {
+ $sentMailbox = $this->mailboxMapper->findSpecial($event->getAccount(), 'sent');
+ } catch (DoesNotExistException $e) {
+ $this->logger->debug('creating sent mailbox');
+ $sentMailbox = $this->createSentMailbox($event->getAccount());
+ $this->logger->debug('sent mailbox created');
+ }
+
+ try {
+ $this->messageMapper->save(
+ $this->imapClientFactory->getClient($event->getAccount()),
+ $sentMailbox,
+ $event->getMail()
+ );
+ } catch (Horde_Imap_Client_Exception $e) {
+ throw new ServiceException('Could not save sent message on IMAP', 0, $e);
+ }
+ }
+
+ /**
+ * @throws DoesNotExistException
+ * @throws ServiceException
+ */
+ private function createSentMailbox(Account $account): Mailbox {
+ $client = $this->imapClientFactory->getClient($account);
+
+ try {
+ // TODO: localize mailbox name
+ $client->createMailbox(
+ 'Sent',
+ [
+ 'special_use' => [
+ \Horde_Imap_Client::SPECIALUSE_SENT,
+ ],
+ ]
+ );
+ } catch (Horde_Imap_Client_Exception $e) {
+ // Let's assume this error is caused because the mailbox already exists,
+ // caused by concurrent requests or out-of-sync mailbox cache
+ $this->logger->logException($e, [
+ 'message' => 'Could not create sent mailbox',
+ 'level' => ILogger::WARN,
+ ]);
+ }
+
+ // TODO: find a more elegant solution for updating the mailbox cache
+ $this->mailboxSync->sync($account, true);
+
+ return $this->mailboxMapper->findSpecial($account, 'sent');
+ }
+
+}
diff --git a/lib/Listener/MessageDeleteTrashCreatorListener.php b/lib/Listener/TrashMailboxCreatorListener.php
index c13240458..a3a00b2b1 100644
--- a/lib/Listener/MessageDeleteTrashCreatorListener.php
+++ b/lib/Listener/TrashMailboxCreatorListener.php
@@ -34,7 +34,7 @@ use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\ILogger;
-class MessageDeleteTrashCreatorListener implements IEventListener {
+class TrashMailboxCreatorListener implements IEventListener {
/** @var MailboxMapper */
private $mailboxMapper;
@@ -66,7 +66,7 @@ class MessageDeleteTrashCreatorListener implements IEventListener {
try {
$this->mailboxMapper->findSpecial(
$event->getAccount(),
- "trash"
+ 'trash'
);
} catch (DoesNotExistException $e) {
$this->logger->debug("Creating trash mailbox");
@@ -81,21 +81,21 @@ class MessageDeleteTrashCreatorListener implements IEventListener {
try {
// TODO: localize mailbox name
$client->createMailbox(
- "Trash",
+ 'Trash',
[
- "special_use" => [
+ 'special_use' => [
\Horde_Imap_Client::SPECIALUSE_TRASH,
],
]
);
+
+ // TODO: find a more elegant solution for updating the mailbox cache
+ $this->mailboxSync->sync($account, true);
} catch (Horde_Imap_Client_Exception $e) {
$this->logger->logException($e, [
- "message" => "Could not creat trash mailbox",
+ 'message' => 'Could not creat trash mailbox',
]);
}
-
- // TODO: find a more elegant solution for updating the mailbox cache
- $this->mailboxSync->sync($account, true);
}
}