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
path: root/lib
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2020-08-11 22:10:49 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2020-08-24 21:21:40 +0300
commit9498ebac6eccde201526b9a6131a76c02ca5db62 (patch)
tree7256f1fc6de4dee185f5cc116e45247cf27f28cb /lib
parent430500712496242526eed2aedb5afc42d60ca1b9 (diff)
Rework the routing
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib')
-rw-r--r--lib/Attachment.php14
-rw-r--r--lib/Contracts/IMailManager.php70
-rw-r--r--lib/Contracts/IMailSearch.php14
-rw-r--r--lib/Contracts/IMailTransmission.php13
-rw-r--r--lib/Controller/AccountsController.php126
-rw-r--r--lib/Controller/AliasesController.php8
-rw-r--r--lib/Controller/MailboxesController.php (renamed from lib/Controller/FoldersController.php)97
-rwxr-xr-xlib/Controller/MessagesController.php243
-rw-r--r--lib/Controller/PageController.php56
-rw-r--r--lib/Db/MailAccount.php1
-rw-r--r--lib/Db/Mailbox.php2
-rw-r--r--lib/Db/MailboxMapper.php28
-rw-r--r--lib/Db/Message.php2
-rw-r--r--lib/Db/MessageMapper.php137
-rw-r--r--lib/Events/DraftSavedEvent.php13
-rw-r--r--lib/Events/MessageSentEvent.php13
-rw-r--r--lib/Events/SaveDraftEvent.php13
-rw-r--r--lib/IMAP/MessageMapper.php18
-rw-r--r--lib/IMAP/Sync/Response.php13
-rw-r--r--lib/IMAP/Threading/ThreadBuilder.php3
-rw-r--r--lib/Listener/DeleteDraftListener.php16
-rw-r--r--lib/Mailbox.php7
-rw-r--r--lib/Model/IMAPMessage.php17
-rw-r--r--lib/Service/AccountService.php12
-rw-r--r--lib/Service/IMailBox.php5
-rw-r--r--lib/Service/MailManager.php66
-rw-r--r--lib/Service/MailTransmission.php30
-rw-r--r--lib/Service/Search/MailSearch.php43
-rw-r--r--lib/Service/Sync/SyncService.php69
29 files changed, 731 insertions, 418 deletions
diff --git a/lib/Attachment.php b/lib/Attachment.php
index 33acaace9..1770587be 100644
--- a/lib/Attachment.php
+++ b/lib/Attachment.php
@@ -32,13 +32,13 @@ class Attachment {
/**
* @param \Horde_Imap_Client_Socket $conn
* @param \Horde_Imap_Client_Mailbox $mailBox
- * @param int $messageId
+ * @param int $messageUid
* @param string $attachmentId
*/
- public function __construct($conn, $mailBox, $messageId, $attachmentId) {
+ public function __construct($conn, $mailBox, $messageUid, $attachmentId) {
$this->conn = $conn;
$this->mailBox = $mailBox;
- $this->messageId = $messageId;
+ $this->messageUid = $messageUid;
$this->attachmentId = $attachmentId;
$this->load();
@@ -53,7 +53,7 @@ class Attachment {
* @var \Horde_Imap_Client_Mailbox
*/
private $mailBox;
- private $messageId;
+ private $messageUid;
private $attachmentId;
/**
@@ -67,13 +67,13 @@ class Attachment {
$fetch_query->mimeHeader($this->attachmentId);
// $list is an array of Horde_Imap_Client_Data_Fetch objects.
- $ids = new \Horde_Imap_Client_Ids($this->messageId);
+ $ids = new \Horde_Imap_Client_Ids($this->messageUid);
$headers = $this->conn->fetch($this->mailBox, $fetch_query, ['ids' => $ids]);
/** @var $fetch Horde_Imap_Client_Data_Fetch */
- if (!isset($headers[$this->messageId])) {
+ if (!isset($headers[$this->messageUid])) {
throw new DoesNotExistException('Unable to load the attachment.');
}
- $fetch = $headers[$this->messageId];
+ $fetch = $headers[$this->messageUid];
/** @var \Horde_Mime_Headers $mimeHeaders */
$mimeHeaders = $fetch->getMimeHeader($this->attachmentId, Horde_Imap_Client_Data_Fetch::HEADER_PARSE);
diff --git a/lib/Contracts/IMailManager.php b/lib/Contracts/IMailManager.php
index 553aea52b..212aee8a8 100644
--- a/lib/Contracts/IMailManager.php
+++ b/lib/Contracts/IMailManager.php
@@ -25,16 +25,28 @@ namespace OCA\Mail\Contracts;
use OCA\Mail\Account;
use OCA\Mail\Db\Mailbox;
+use OCA\Mail\Db\Message;
use OCA\Mail\Exception\ClientException;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\Folder;
use OCA\Mail\IMAP\FolderStats;
use OCA\Mail\Model\IMAPMessage;
use OCA\Mail\Service\Quota;
+use OCP\AppFramework\Db\DoesNotExistException;
interface IMailManager {
/**
+ * @param string $uid
+ * @param int $id
+ *
+ * @return Mailbox
+ *
+ * @throws DoesNotExistException
+ */
+ public function getMailbox(string $uid, int $id): Mailbox;
+
+ /**
* @param Account $account
*
* @return Mailbox[]
@@ -47,44 +59,63 @@ interface IMailManager {
* @param Account $account
* @param string $name
*
- * @return Folder
+ * @return Mailbox
*
* @throws ServiceException
*/
- public function createFolder(Account $account, string $name): Folder;
+ public function createMailbox(Account $account, string $name): Mailbox;
/**
* @param Account $account
- * @param string $folderId
+ * @param Mailbox $mailbox
*
* @return FolderStats
+ */
+ public function getMailboxStats(Account $account, Mailbox $mailbox): FolderStats;
+
+ /**
+ * @param Mailbox $mailbox
+ * @param $uid
*
- * @throws ServiceException
+ * @return int|null
+ */
+ public function getMessageIdForUid(Mailbox $mailbox, $uid): ?int;
+
+ /**
+ * @param string $uid
+ * @param int $id
+ *
+ * @return Mailbox
+ *
+ * @throws ClientException
*/
- public function getFolderStats(Account $account, string $folderId): FolderStats;
+ public function getMessage(string $uid, int $id): Message;
/**
* @param Account $account
* @param string $mb
- * @param int $id
+ * @param int $uid
*
* @return string
* @throws ClientException
* @throws ServiceException
*/
- public function getSource(Account $account, string $mb, int $id): string;
+ public function getSource(Account $account, string $mb, int $uid): ?string;
/**
* @param Account $account
- * @param string $mailbox
- * @param int $id
+ * @param Mailbox $mailbox
+ * @param int $uid
* @param bool $loadBody
*
* @return IMAPMessage
*
* @throws ServiceException
*/
- public function getMessage(Account $account, string $mailbox, int $id, bool $loadBody = false): IMAPMessage;
+ public function getImapMessage(Account $account,
+ Mailbox $mailbox,
+ int $uid,
+ bool $loadBody = false): IMAPMessage;
/**
* @param Account $account
@@ -97,14 +128,17 @@ interface IMailManager {
/**
* @param Account $sourceAccount
* @param string $sourceFolderId
- * @param int $messageId
+ * @param int $uid
* @param Account $destinationAccount
* @param string $destFolderId
*
* @throws ServiceException
*/
- public function moveMessage(Account $sourceAccount, string $sourceFolderId, int $messageId,
- Account $destinationAccount, string $destFolderId);
+ public function moveMessage(Account $sourceAccount,
+ string $sourceFolderId,
+ int $uid,
+ Account $destinationAccount,
+ string $destFolderId);
/**
* @param Account $account
@@ -119,11 +153,9 @@ interface IMailManager {
* Mark all messages of a folder as read
*
* @param Account $account
- * @param string $folderId
- *
- * @throws ServiceException
+ * @param Mailbox $mailbox
*/
- public function markFolderAsRead(Account $account, string $folderId): void;
+ public function markFolderAsRead(Account $account, Mailbox $mailbox): void;
/**
* @param Account $account
@@ -146,9 +178,9 @@ interface IMailManager {
/**
* @param Account $account
- * @param string $folderId
+ * @param Mailbox $mailbox
*
* @throws ServiceException
*/
- public function deleteMailbox(Account $account, string $folderId): void;
+ public function deleteMailbox(Account $account, Mailbox $mailbox): void;
}
diff --git a/lib/Contracts/IMailSearch.php b/lib/Contracts/IMailSearch.php
index 9487334b2..c751e2c53 100644
--- a/lib/Contracts/IMailSearch.php
+++ b/lib/Contracts/IMailSearch.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Mail\Contracts;
use OCA\Mail\Account;
+use OCA\Mail\Db\Mailbox;
use OCA\Mail\Db\Message;
use OCA\Mail\Exception\ClientException;
use OCA\Mail\Exception\ServiceException;
@@ -43,18 +44,25 @@ interface IMailSearch {
* @throws ClientException
* @throws ServiceException
*/
- public function findMessage(Account $account, string $mailboxName, int $uid): Message;
+ public function findMessage(Account $account,
+ Mailbox $mailbox,
+ Message $message): Message;
/**
* @param Account $account
- * @param string $mailboxName
+ * @param Mailbox $mailbox
* @param string|null $filter
* @param int|null $cursor
+ * @param int|null $limit
*
* @return Message[]
*
* @throws ClientException
* @throws ServiceException
*/
- public function findMessages(Account $account, string $mailboxName, ?string $filter, ?int $cursor, ?int $limit): array;
+ public function findMessages(Account $account,
+ Mailbox $mailbox,
+ ?string $filter,
+ ?int $cursor,
+ ?int $limit): array;
}
diff --git a/lib/Contracts/IMailTransmission.php b/lib/Contracts/IMailTransmission.php
index ff1d04138..d4e4c3c57 100644
--- a/lib/Contracts/IMailTransmission.php
+++ b/lib/Contracts/IMailTransmission.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Mail\Contracts;
use OCA\Mail\Db\Alias;
+use OCA\Mail\Db\Message;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\Model\NewMessageData;
use OCA\Mail\Model\RepliedMessageData;
@@ -33,27 +34,27 @@ interface IMailTransmission {
/**
* Send a new message or reply to an existing one
*
- * @param string $userId
* @param NewMessageData $message
- * @param RepliedMessageData $reply
+ * @param RepliedMessageData|null $reply
* @param Alias|null $alias
+ * @param Message|null $draft
*
* @throws ServiceException
*/
public function sendMessage(NewMessageData $message,
RepliedMessageData $reply = null,
Alias $alias = null,
- int $draftUID = null);
+ Message $draft = null);
/**
* Save a message draft
*
* @param NewMessageData $message
- * @param int $draftUID
+ * @param Message|null $previousDraft
*
- * @return int
+ * @return array
*
* @throws ServiceException
*/
- public function saveDraft(NewMessageData $message, int $draftUID = null): int;
+ public function saveDraft(NewMessageData $message, Message $previousDraft = null): array;
}
diff --git a/lib/Controller/AccountsController.php b/lib/Controller/AccountsController.php
index e5c8a94bb..94221eb09 100644
--- a/lib/Controller/AccountsController.php
+++ b/lib/Controller/AccountsController.php
@@ -30,8 +30,10 @@ declare(strict_types=1);
namespace OCA\Mail\Controller;
use Exception;
+use Horde_Imap_Client;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\Contracts\IMailTransmission;
+use OCA\Mail\Db\Mailbox;
use OCA\Mail\Exception\ClientException;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\Http\JsonResponse as MailJsonResponse;
@@ -41,6 +43,7 @@ use OCA\Mail\Service\AccountService;
use OCA\Mail\Service\AliasesService;
use OCA\Mail\Service\GroupsIntegration;
use OCA\Mail\Service\SetupService;
+use OCA\Mail\Service\Sync\SyncService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
@@ -77,17 +80,37 @@ class AccountsController extends Controller {
/** @var IMailManager */
private $mailManager;
+ /** @var SyncService */
+ private $syncService;
+
+ /**
+ * AccountsController constructor.
+ *
+ * @param string $appName
+ * @param IRequest $request
+ * @param AccountService $accountService
+ * @param GroupsIntegration $groupsIntegration
+ * @param $UserId
+ * @param ILogger $logger
+ * @param IL10N $l10n
+ * @param AliasesService $aliasesService
+ * @param IMailTransmission $mailTransmission
+ * @param SetupService $setup
+ * @param IMailManager $mailManager
+ * @param SyncService $syncService
+ */
public function __construct(string $appName,
- IRequest $request,
- AccountService $accountService,
- GroupsIntegration $groupsIntegration,
- $UserId,
- ILogger $logger,
- IL10N $l10n,
- AliasesService $aliasesService,
- IMailTransmission $mailTransmission,
- SetupService $setup,
- IMailManager $mailManager
+ IRequest $request,
+ AccountService $accountService,
+ GroupsIntegration $groupsIntegration,
+ $UserId,
+ ILogger $logger,
+ IL10N $l10n,
+ AliasesService $aliasesService,
+ IMailTransmission $mailTransmission,
+ SetupService $setup,
+ IMailManager $mailManager,
+ SyncService $syncService
) {
parent::__construct($appName, $request);
$this->accountService = $accountService;
@@ -99,6 +122,7 @@ class AccountsController extends Controller {
$this->mailTransmission = $mailTransmission;
$this->setup = $setup;
$this->mailManager = $mailManager;
+ $this->syncService = $syncService;
}
/**
@@ -123,13 +147,13 @@ class AccountsController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
+ * @param int $id
*
* @return JSONResponse
* @throws ClientException
*/
- public function show($accountId): JSONResponse {
- return new JSONResponse($this->accountService->find($this->currentUserId, $accountId));
+ public function show(int $id): JSONResponse {
+ return new JSONResponse($this->accountService->find($this->currentUserId, $id));
}
/**
@@ -198,7 +222,7 @@ class AccountsController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
+ * @param int $id
* @param string|null $editorMode
* @param int|null $order
* @param bool|null $showSubscribedOnly
@@ -207,11 +231,11 @@ class AccountsController extends Controller {
*
* @throws ClientException
*/
- public function patchAccount(int $accountId,
+ public function patchAccount(int $id,
string $editorMode = null,
int $order = null,
bool $showSubscribedOnly = null): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $account = $this->accountService->find($this->currentUserId, $id);
if ($account === null) {
return new JSONResponse(null, Http::STATUS_FORBIDDEN);
@@ -236,7 +260,7 @@ class AccountsController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
+ * @param int $id
* @param string|null $signature
*
* @return JSONResponse
@@ -244,8 +268,8 @@ class AccountsController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function updateSignature(int $accountId, string $signature = null): JSONResponse {
- $this->accountService->updateSignature($accountId, $this->currentUserId, $signature);
+ public function updateSignature(int $id, string $signature = null): JSONResponse {
+ $this->accountService->updateSignature($id, $this->currentUserId, $signature);
return new JSONResponse();
}
@@ -259,7 +283,7 @@ class AccountsController extends Controller {
*
* @throws ClientException
*/
- public function destroy($id): JSONResponse {
+ public function destroy(int $id): JSONResponse {
$this->accountService->delete($this->currentUserId, $id);
return new JSONResponse();
}
@@ -315,13 +339,13 @@ class AccountsController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
+ * @param int $id
* @param string $subject
* @param string $body
* @param string $to
* @param string $cc
* @param string $bcc
- * @param int|null $draftUID
+ * @param int|null $draftId
* @param string|null $folderId
* @param int|null $messageId
* @param mixed $attachments
@@ -332,19 +356,19 @@ class AccountsController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function send(int $accountId,
+ public function send(int $id,
string $subject,
string $body,
string $to,
string $cc,
string $bcc,
bool $isHtml = true,
- int $draftUID = null,
+ int $draftId = null,
string $folderId = null,
int $messageId = null,
array $attachments = [],
int $aliasId = null): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $account = $this->accountService->find($this->currentUserId, $id);
$alias = $aliasId ? $this->aliasesService->find($aliasId, $this->currentUserId) : null;
$expandedTo = $this->groupsIntegration->expand($to);
@@ -357,8 +381,16 @@ class AccountsController extends Controller {
$repliedMessageData = new RepliedMessageData($account, base64_decode($folderId), $messageId);
}
+ $draft = null;
+ if ($draftId !== null) {
+ try {
+ $draft = $this->mailManager->getMessage($this->currentUserId, $draftId);
+ } catch (ClientException $e) {
+ $this->logger->info("Draft " . $draftId . " could not be loaded: " . $e->getMessage());
+ }
+ }
try {
- $this->mailTransmission->sendMessage($messageData, $repliedMessageData, $alias, $draftUID);
+ $this->mailTransmission->sendMessage($messageData, $repliedMessageData, $alias, $draft);
return new JSONResponse();
} catch (ServiceException $ex) {
$this->logger->error('Sending mail failed: ' . $ex->getMessage());
@@ -370,7 +402,7 @@ class AccountsController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
+ * @param int $id
* @param string $subject
* @param string $body
* @param string $to
@@ -382,27 +414,43 @@ class AccountsController extends Controller {
*
* @throws ClientException
*/
- public function draft(int $accountId,
- string $subject = null,
+ public function draft(int $id,
+ string $subject,
string $body,
string $to,
string $cc,
string $bcc,
bool $isHtml = true,
- int $draftUID = null): JSONResponse {
- if ($draftUID === null) {
- $this->logger->info("Saving a new draft in account <$accountId>");
+ int $draftId = null): JSONResponse {
+ if ($draftId === null) {
+ $this->logger->info("Saving a new draft in account <$id>");
} else {
- $this->logger->info("Updating draft <$draftUID> in account <$accountId>");
+ $this->logger->info("Updating draft <$draftId> in account <$id>");
}
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $account = $this->accountService->find($this->currentUserId, $id);
+ $previousDraft = null;
+ if ($draftId !== null) {
+ try {
+ $previousDraft = $this->mailManager->getMessage($this->currentUserId, $draftId);
+ } catch (ClientException $e) {
+ $this->logger->info("Draft " . $draftId . " could not be loaded: " . $e->getMessage());
+ }
+ }
$messageData = NewMessageData::fromRequest($account, $to, $cc, $bcc, $subject, $body, [], $isHtml);
try {
- $newUID = $this->mailTransmission->saveDraft($messageData, $draftUID);
+ /** @var Mailbox $draftsMailbox */
+ [, $draftsMailbox, $newUID] = $this->mailTransmission->saveDraft($messageData, $previousDraft);
+ $this->syncService->syncMailbox(
+ $account,
+ $draftsMailbox,
+ Horde_Imap_Client::SYNC_NEWMSGS,
+ [],
+ false
+ );
return new JSONResponse([
- 'uid' => $newUID,
+ 'id' => $this->mailManager->getMessageIdForUid($draftsMailbox, $newUID)
]);
} catch (ServiceException $ex) {
$this->logger->error('Saving draft failed: ' . $ex->getMessage());
@@ -413,13 +461,13 @@ class AccountsController extends Controller {
/**
* @NoAdminRequired
*
- * @param int $accountId
+ * @param int $id
*
* @return JSONResponse
* @throws ClientException
*/
- public function getQuota(int $accountId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ public function getQuota(int $id): JSONResponse {
+ $account = $this->accountService->find($this->currentUserId, $id);
$quota = $this->mailManager->getQuota($account);
if ($quota === null) {
diff --git a/lib/Controller/AliasesController.php b/lib/Controller/AliasesController.php
index cda86bd65..ca9d61589 100644
--- a/lib/Controller/AliasesController.php
+++ b/lib/Controller/AliasesController.php
@@ -54,9 +54,10 @@ class AliasesController extends Controller {
* @TrapError
*
* @param int $accountId
+ *
* @return JSONResponse
*/
- public function index($accountId): JSONResponse {
+ public function index(int $accountId): JSONResponse {
return new JSONResponse($this->aliasService->findAll($accountId, $this->currentUser->getUID()));
}
@@ -83,7 +84,7 @@ class AliasesController extends Controller {
* @param int $id
* @return JSONResponse
*/
- public function destroy($id): JSONResponse {
+ public function destroy(int $id): JSONResponse {
return new JSONResponse($this->aliasService->delete($id, $this->currentUser->getUID()));
}
@@ -94,9 +95,10 @@ class AliasesController extends Controller {
* @param int $accountId
* @param string $alias
* @param string $aliasName
+ *
* @return JSONResponse
*/
- public function create($accountId, $alias, $aliasName): JSONResponse {
+ public function create(int $accountId, string $alias, string $aliasName): JSONResponse {
return new JSONResponse($this->aliasService->create($accountId, $alias, $aliasName), Http::STATUS_CREATED);
}
}
diff --git a/lib/Controller/FoldersController.php b/lib/Controller/MailboxesController.php
index 2527658e5..c7ad55007 100644
--- a/lib/Controller/FoldersController.php
+++ b/lib/Controller/MailboxesController.php
@@ -31,8 +31,6 @@ use OCA\Mail\Exception\IncompleteSyncException;
use OCA\Mail\Exception\MailboxNotCachedException;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\Service\Sync\SyncService;
-use function base64_decode;
-use function is_array;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\Exception\NotImplemented;
use OCA\Mail\Service\AccountService;
@@ -41,7 +39,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
-class FoldersController extends Controller {
+class MailboxesController extends Controller {
/** @var AccountService */
private $accountService;
@@ -66,7 +64,7 @@ class FoldersController extends Controller {
public function __construct(string $appName,
IRequest $request,
AccountService $accountService,
- $UserId,
+ ?string $UserId,
IMailManager $mailManager,
SyncService $syncService) {
parent::__construct($appName, $request);
@@ -94,7 +92,7 @@ class FoldersController extends Controller {
return new JSONResponse([
'id' => $accountId,
'email' => $account->getEmail(),
- 'folders' => $mailboxes,
+ 'mailboxes' => $mailboxes,
'delimiter' => reset($mailboxes)->getDelimiter(),
]);
}
@@ -103,30 +101,28 @@ class FoldersController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
- * @param string $syncToken
- * @param int[] $uids
+ * @param int $id
+ * @param int[] $ids
+ *
+ * @param bool $init
+ * @param string|null $query
*
* @return JSONResponse
* @throws ClientException
* @throws ServiceException
*/
- public function sync(int $accountId, string $folderId, array $uids = [], bool $init = false, string $query = null): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
-
- if (empty($accountId) || empty($folderId) || !is_array($uids)) {
- return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
- }
+ public function sync(int $id, array $ids = [], bool $init = false, string $query = null): JSONResponse {
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
try {
$syncResponse = $this->syncService->syncMailbox(
$account,
- base64_decode($folderId),
+ $mailbox,
Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
- array_map(function ($uid) {
- return (int) $uid;
- }, $uids),
+ array_map(function ($id) {
+ return (int) $id;
+ }, $ids),
!$init,
$query
);
@@ -143,21 +139,17 @@ class FoldersController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
+ * @param string $id
*
* @return JSONResponse
* @throws ClientException
* @throws ServiceException
*/
- public function clearCache(int $accountId, string $folderId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ public function clearCache(int $id): JSONResponse {
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
- if (empty($accountId) || empty($folderId)) {
- return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
- }
-
- $this->syncService->clearCache($account, base64_decode($folderId));
+ $this->syncService->clearCache($account, $mailbox);
return new JSONResponse(null);
}
@@ -165,43 +157,37 @@ class FoldersController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
+ * @param int $id
+ *
* @return JSONResponse
*
* @throws ClientException
*/
- public function markAllAsRead(int $accountId, string $folderId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
-
- if (empty($accountId) || empty($folderId)) {
- return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
- }
+ public function markAllAsRead(int $id): JSONResponse {
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
- $syncResponse = $this->mailManager->markFolderAsRead($account, base64_decode($folderId));
+ $this->mailManager->markFolderAsRead($account, $mailbox);
- return new JSONResponse($syncResponse);
+ return new JSONResponse(null);
}
/**
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
+ * @param int $id
*
* @return JSONResponse
*
* @throws ClientException
+ * @throws ServiceException
*/
- public function stats(int $accountId, string $folderId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
-
- if (empty($accountId) || empty($folderId)) {
- return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
- }
+ public function stats(int $id): JSONResponse {
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
- $stats = $this->mailManager->getFolderStats($account, base64_decode($folderId));
+ $stats = $this->mailManager->getMailboxStats($account, $mailbox);
return new JSONResponse($stats);
}
@@ -232,19 +218,24 @@ class FoldersController extends Controller {
public function create(int $accountId, string $name) {
$account = $this->accountService->find($this->currentUserId, $accountId);
- return new JSONResponse($this->mailManager->createFolder($account, $name));
+ return new JSONResponse($this->mailManager->createMailbox($account, $name));
}
/**
* @NoAdminRequired
* @TrapError
- * @param int $accountId
- * @param string $folderId
+ *
+ * @param int $id
+ *
+ * @return JSONResponse
+ * @throws ClientException
* @throws ServiceException
*/
- public function delete(int $accountId, string $folderId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
- $this->mailManager->deleteMailbox($account, base64_decode($folderId));
+ public function destroy(int $id): JSONResponse {
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $id);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+
+ $this->mailManager->deleteMailbox($account, $mailbox);
return new JSONResponse();
}
}
diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php
index ef6357835..df602bf94 100755
--- a/lib/Controller/MessagesController.php
+++ b/lib/Controller/MessagesController.php
@@ -39,7 +39,6 @@ use OCA\Mail\Http\AttachmentDownloadResponse;
use OCA\Mail\Http\HtmlResponse;
use OCA\Mail\Model\IMAPMessage;
use OCA\Mail\Service\AccountService;
-use OCA\Mail\Service\IMailBox;
use OCA\Mail\Service\ItineraryService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
@@ -55,7 +54,6 @@ use OCP\ILogger;
use OCP\IRequest;
use OCP\IURLGenerator;
use function array_map;
-use function base64_decode;
class MessagesController extends Controller {
@@ -131,29 +129,33 @@ class MessagesController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
+ * @param int $mailboxId
* @param int $cursor
* @param string $filter
+ * @param int|null $limit
*
* @return JSONResponse
*
* @throws ClientException
* @throws ServiceException
*/
- public function index(int $accountId, string $folderId, int $cursor = null, string $filter = null, int $limit = null): JSONResponse {
+ public function index(int $mailboxId,
+ int $cursor = null,
+ string $filter = null,
+ int $limit = null): JSONResponse {
try {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $mailboxId);
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
return new JSONResponse(null, Http::STATUS_FORBIDDEN);
}
- $this->logger->debug("loading messages of folder <$folderId>");
+ $this->logger->debug("loading messages of folder <$mailboxId>");
return new JSONResponse(
$this->mailSearch->findMessages(
$account,
- base64_decode($folderId),
+ $mailbox,
$filter === '' ? null : $filter,
$cursor,
$limit
@@ -174,20 +176,22 @@ class MessagesController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function show(int $accountId, string $folderId, int $id): JSONResponse {
+ public function show(int $id): JSONResponse {
try {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
return new JSONResponse(null, Http::STATUS_FORBIDDEN);
}
- $this->logger->debug("loading message of folder <$folderId>");
+ $this->logger->debug("loading message <$id>");
return new JSONResponse(
$this->mailSearch->findMessage(
$account,
- base64_decode($folderId),
- $id
+ $mailbox,
+ $message
)
);
}
@@ -196,40 +200,40 @@ class MessagesController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
- * @param int $messageId
+ * @param int $id
*
* @return JSONResponse
*
* @throws ClientException
* @throws ServiceException
*/
- public function getBody(int $accountId, string $folderId, int $messageId): JSONResponse {
+ public function getBody(int $id): JSONResponse {
try {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
return new JSONResponse(null, Http::STATUS_FORBIDDEN);
}
- $json = $this->mailManager->getMessage(
+ $json = $this->mailManager->getImapMessage(
$account,
- base64_decode($folderId),
- $messageId,
+ $mailbox,
+ $message->getUid(),
true
- )->getFullMessage(
- $accountId,
- base64_decode($folderId),
- $messageId
- );
+ )->getFullMessage($id);
$json['itineraries'] = $this->itineraryService->extract(
$account,
- base64_decode($folderId),
- $messageId
+ $mailbox->getName(),
+ $message->getUid()
);
- $json['attachments'] = array_map(function ($a) use ($accountId, $folderId, $messageId) {
- return $this->enrichDownloadUrl($accountId, $folderId, $messageId, $a);
+ $json['attachments'] = array_map(function ($a) use ($id) {
+ return $this->enrichDownloadUrl(
+ $id,
+ $a
+ );
}, $json['attachments']);
+ $json['databaseId'] = $message->getId();
return new JSONResponse($json);
}
@@ -239,14 +243,19 @@ class MessagesController extends Controller {
* @NoCSRFRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
+ * @param int $id
*
* @return JSONResponse
* @throws ClientException
*/
- public function getThread(int $accountId, int $id): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ public function getThread(int $id): JSONResponse {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
return new JSONResponse($this->mailManager->getThread($account, $id));
}
@@ -255,10 +264,7 @@ class MessagesController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
* @param int $id
- * @param int $destAccountId
* @param string $destFolderId
*
* @return JSONResponse
@@ -266,12 +272,24 @@ class MessagesController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function move($accountId, $folderId, $id, $destAccountId, $destFolderId): JSONResponse {
- $srcAccount = $this->accountService->find($this->currentUserId, $accountId);
- $dstAccount = $this->accountService->find($this->currentUserId,
- $destAccountId);
- $this->mailManager->moveMessage($srcAccount, base64_decode($folderId), $id,
- $dstAccount, base64_decode($destFolderId));
+ public function move(int $id, int $destFolderId): JSONResponse {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $srcMailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $dstMailbox = $this->mailManager->getMailbox($this->currentUserId, $destFolderId);
+ $srcAccount = $this->accountService->find($this->currentUserId, $srcMailbox->getAccountId());
+ $dstAccount = $this->accountService->find($this->currentUserId, $dstMailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
+
+ $this->mailManager->moveMessage(
+ $srcAccount,
+ $srcMailbox->getName(),
+ $message->getUid(),
+ $dstAccount,
+ $dstMailbox->getName()
+ );
return new JSONResponse();
}
@@ -284,17 +302,23 @@ class MessagesController extends Controller {
* @param string $folderId
* @param int $messageId
*
- * @return HtmlResponse|TemplateResponse
+ * @return JSONResponse
* @throws ServiceException
*/
- public function getSource(int $accountId, string $folderId, int $messageId): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ public function getSource(int $id): JSONResponse {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
$response = new JSONResponse([
'source' => $this->mailManager->getSource(
$account,
- base64_decode($folderId),
- $messageId
+ $mailbox->getName(),
+ $message->getUid()
)
]);
@@ -309,18 +333,18 @@ class MessagesController extends Controller {
* @NoCSRFRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
- * @param int $messageId
+ * @param int $id
*
* @return HtmlResponse|TemplateResponse
*
* @throws ClientException
*/
- public function getHtmlBody(int $accountId, string $folderId, int $messageId): Response {
+ public function getHtmlBody(int $id): Response {
try {
try {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
return new TemplateResponse(
$this->appName,
@@ -331,12 +355,14 @@ class MessagesController extends Controller {
}
$htmlResponse = new HtmlResponse(
- $this->mailManager->getMessage(
+ $this->mailManager->getImapMessage(
$account,
- base64_decode($folderId),
- $messageId,
+ $mailbox,
+ $message->getUid(),
true
- )->getHtmlBody($accountId, base64_decode($folderId), $messageId)
+ )->getHtmlBody(
+ $id
+ )
);
// Harden the default security policy
@@ -369,19 +395,25 @@ class MessagesController extends Controller {
*
* @param int $accountId
* @param string $folderId
- * @param int $messageId
+ * @param int $id
* @param int $attachmentId
*
- * @return AttachmentDownloadResponse
+ * @return Response
*
* @throws ClientException
* @throws ServiceException
*/
- public function downloadAttachment(int $accountId, string $folderId, int $messageId,
- string $attachmentId) {
- $mailBox = $this->getFolder($accountId, $folderId);
-
- $attachment = $mailBox->getAttachment($messageId, $attachmentId);
+ public function downloadAttachment(int $id,
+ string $attachmentId): Response {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
+ $folder = $account->getMailbox($mailbox->getName());
+ $attachment = $folder->getAttachment($message->getUid(), $attachmentId);
// Body party and embedded messages do not have a name
if ($attachment->getName() === null) {
@@ -404,9 +436,7 @@ class MessagesController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
- * @param int $messageId
+ * @param int $id
* @param int $attachmentId
* @param string $targetPath
*
@@ -415,14 +445,22 @@ class MessagesController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function saveAttachment(int $accountId, string $folderId, int $messageId,
- string $attachmentId, string $targetPath) {
- $mailBox = $this->getFolder($accountId, $folderId);
+ public function saveAttachment(int $id,
+ string $attachmentId,
+ string $targetPath) {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
+ $folder = $account->getMailbox($mailbox->getName());
if ($attachmentId === '0') {
// Save all attachments
/* @var $m IMAPMessage */
- $m = $mailBox->getMessage($messageId);
+ $m = $folder->getMessage($id);
$attachmentIds = array_map(function ($a) {
return $a['id'];
}, $m->attachments);
@@ -430,11 +468,11 @@ class MessagesController extends Controller {
$attachmentIds = [$attachmentId];
}
- foreach ($attachmentIds as $attachmentId) {
- $attachment = $mailBox->getAttachment($messageId, $attachmentId);
+ foreach ($attachmentIds as $aid) {
+ $attachment = $folder->getAttachment($message->getUid(), $attachmentId);
$fileName = $attachment->getName() ?? $this->l10n->t('Embedded message %s', [
- $attachmentId,
+ $aid,
]) . '.eml';
$fileParts = pathinfo($fileName);
$fileName = $fileParts['filename'];
@@ -456,9 +494,7 @@ class MessagesController extends Controller {
* @NoAdminRequired
* @TrapError
*
- * @param int $accountId
- * @param string $folderId
- * @param string $messageId
+ * @param string $id
* @param array $flags
*
* @return JSONResponse
@@ -466,12 +502,18 @@ class MessagesController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function setFlags(int $accountId, string $folderId, int $messageId, array $flags): JSONResponse {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ public function setFlags(int $id, array $flags): JSONResponse {
+ try {
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(null, Http::STATUS_FORBIDDEN);
+ }
foreach ($flags as $flag => $value) {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
- $this->mailManager->flagMessage($account, base64_decode($folderId), $messageId, $flag, $value);
+ $this->mailManager->flagMessage($account, $mailbox->getName(), $message->getUid(), $flag, $value);
}
return new JSONResponse();
}
@@ -489,49 +531,36 @@ class MessagesController extends Controller {
* @throws ClientException
* @throws ServiceException
*/
- public function destroy(int $accountId, string $folderId, int $id): JSONResponse {
- $this->logger->debug("deleting message <$id> of folder <$folderId>, account <$accountId>");
-
+ public function destroy(int $id): JSONResponse {
try {
- $account = $this->accountService->find($this->currentUserId, $accountId);
+ $message = $this->mailManager->getMessage($this->currentUserId, $id);
+ $mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
+ $account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
return new JSONResponse(null, Http::STATUS_FORBIDDEN);
}
- $this->mailManager->deleteMessage($account, base64_decode($folderId), $id);
- return new JSONResponse();
- }
+ $this->logger->debug("deleting message <$id>");
- /**
- * @param int $accountId
- * @param string $folderId
- *
- * @return IMailBox
- * @deprecated
- *
- * @throws ClientException
- * @throws ServiceException
- */
- private function getFolder(int $accountId, string $folderId): IMailBox {
- $account = $this->accountService->find($this->currentUserId, $accountId);
- return $account->getMailbox(base64_decode($folderId));
+ $this->mailManager->deleteMessage(
+ $account,
+ $mailbox->getName(),
+ $message->getUid()
+ );
+ return new JSONResponse();
}
/**
- * @param int $accountId
- * @param string $folderId
- * @param int $messageId
+ * @param int $id
* @param array $attachment
*
* @return array
*/
- private function enrichDownloadUrl(int $accountId, string $folderId, int $messageId,
+ private function enrichDownloadUrl(int $id,
array $attachment) {
$downloadUrl = $this->urlGenerator->linkToRoute('mail.messages.downloadAttachment',
[
- 'accountId' => $accountId,
- 'folderId' => $folderId,
- 'messageId' => $messageId,
+ 'id' => $id,
'attachmentId' => $attachment['id'],
]);
$downloadUrl = $this->urlGenerator->getAbsoluteURL($downloadUrl);
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
index 219bb16ff..fe9181760 100644
--- a/lib/Controller/PageController.php
+++ b/lib/Controller/PageController.php
@@ -117,13 +117,13 @@ class PageController extends Controller {
$this->currentUserId);
try {
$mailboxes = $this->mailManager->getMailboxes($mailAccount);
- $json['folders'] = $mailboxes;
+ $json['mailboxes'] = $mailboxes;
} catch (Exception $ex) {
$this->logger->logException($ex, [
- 'message' => 'Could not load account folders: ' . $ex->getMessage(),
+ 'message' => 'Could not load account mailboxes: ' . $ex->getMessage(),
'level' => ILogger::FATAL,
]);
- $json['folders'] = [];
+ $json['mailboxes'] = [];
$json['error'] = true;
}
$accountsJson[] = $json;
@@ -160,6 +160,56 @@ class PageController extends Controller {
* @NoAdminRequired
* @NoCSRFRequired
*
+ * @return TemplateResponse
+ */
+ public function setup(): TemplateResponse {
+ return $this->index();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ */
+ public function keyboardShortcuts(): TemplateResponse {
+ return $this->index();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ */
+ public function accountSettings(int $id): TemplateResponse {
+ return $this->index();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ */
+ public function mailbox(int $id): TemplateResponse {
+ return $this->index();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ */
+ public function thread(int $mailboxId, int $id): TemplateResponse {
+ return $this->index();
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
* @param string $uri
*
* @return RedirectResponse
diff --git a/lib/Db/MailAccount.php b/lib/Db/MailAccount.php
index 36fb54cdf..c63abe27c 100644
--- a/lib/Db/MailAccount.php
+++ b/lib/Db/MailAccount.php
@@ -153,6 +153,7 @@ class MailAccount extends Entity {
*/
public function toJson() {
$result = [
+ 'id' => $this->getId(),
'accountId' => $this->getId(),
'name' => $this->getName(),
'order' => $this->getOrder(),
diff --git a/lib/Db/Mailbox.php b/lib/Db/Mailbox.php
index 2a877ee64..0da25c85f 100644
--- a/lib/Db/Mailbox.php
+++ b/lib/Db/Mailbox.php
@@ -121,12 +121,14 @@ class Mailbox extends Entity implements JsonSerializable {
return [
'databaseId' => $this->getId(),
'id' => base64_encode($this->getName()),
+ 'name' => $this->getName(),
'accountId' => $this->accountId,
'displayName' => $this->getName(),
'attributes' => json_decode($this->attributes ?? '[]', true) ?? [],
'delimiter' => $this->delimiter,
'specialUse' => $specialUse,
'specialRole' => $specialUse[0] ?? 0,
+ 'mailboxes' => [],
];
}
}
diff --git a/lib/Db/MailboxMapper.php b/lib/Db/MailboxMapper.php
index d2361b927..0b2ae36ce 100644
--- a/lib/Db/MailboxMapper.php
+++ b/lib/Db/MailboxMapper.php
@@ -85,6 +85,34 @@ class MailboxMapper extends QBMapper {
}
/**
+ * @param int $id
+ * @param string $uid
+ *
+ * @return Mailbox
+ *
+ * @throws DoesNotExistException
+ * @throws ServiceException
+ */
+ public function findByUid(int $id, string $uid): Mailbox {
+ $qb = $this->db->getQueryBuilder();
+
+ $select = $qb->select('mb.*')
+ ->from($this->getTableName(), 'mb')
+ ->join('mb', 'mail_accounts', 'a', $qb->expr()->eq('mb.account_id', 'a.id', IQueryBuilder::PARAM_INT))
+ ->where(
+ $qb->expr()->eq('a.user_id', $qb->createNamedParameter($uid)),
+ $qb->expr()->eq('mb.id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT)
+ );
+
+ try {
+ return $this->findEntity($select);
+ } catch (MultipleObjectsReturnedException $e) {
+ // Not possible due to DB constraints
+ throw new ServiceException("The impossible has happened", 42, $e);
+ }
+ }
+
+ /**
* @throws DoesNotExistException
*/
public function findSpecial(Account $account, string $specialUse): Mailbox {
diff --git a/lib/Db/Message.php b/lib/Db/Message.php
index 8f028a284..95248b132 100644
--- a/lib/Db/Message.php
+++ b/lib/Db/Message.php
@@ -126,6 +126,7 @@ class Message extends Entity implements JsonSerializable {
$this->bcc = new AddressList([]);
$this->addType('uid', 'integer');
+ $this->addType('mailboxId', 'integer');
$this->addType('sentAt', 'integer');
$this->addType('flagAnswered', 'bool');
$this->addType('flagDeleted', 'bool');
@@ -252,6 +253,7 @@ class Message extends Entity implements JsonSerializable {
'to' => $this->getTo()->jsonSerialize(),
'cc' => $this->getCc()->jsonSerialize(),
'bcc' => $this->getBcc()->jsonSerialize(),
+ 'mailboxId' => $this->getMailboxId(),
];
}
}
diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php
index e6593bb8c..77d0564ed 100644
--- a/lib/Db/MessageMapper.php
+++ b/lib/Db/MessageMapper.php
@@ -31,6 +31,7 @@ use OCA\Mail\Address;
use OCA\Mail\AddressList;
use OCA\Mail\IMAP\Threading\DatabaseMessage;
use OCA\Mail\Service\Search\SearchQuery;
+use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -51,6 +52,11 @@ class MessageMapper extends QBMapper {
$this->timeFactory = $timeFactory;
}
+ /**
+ * @param IQueryBuilder $query
+ *
+ * @return int[]
+ */
private function findUids(IQueryBuilder $query): array {
$result = $query->execute();
$uids = array_map(function (array $row) {
@@ -61,6 +67,21 @@ class MessageMapper extends QBMapper {
return $uids;
}
+ /**
+ * @param IQueryBuilder $query
+ *
+ * @return int[]
+ */
+ private function findIds(IQueryBuilder $query): array {
+ $result = $query->execute();
+ $uids = array_map(function (array $row) {
+ return (int)$row['id'];
+ }, $result->fetchAll());
+ $result->closeCursor();
+
+ return $uids;
+ }
+
public function findHighestUid(Mailbox $mailbox): ?int {
$query = $this->db->getQueryBuilder();
@@ -78,12 +99,64 @@ class MessageMapper extends QBMapper {
return $max;
}
+ public function findByUserId(string $uid, int $id): Message {
+ $query = $this->db->getQueryBuilder();
+
+ $query->select('m.*')
+ ->from($this->getTableName(), 'm')
+ ->join('m', 'mail_mailboxes', 'mb', $query->expr()->eq('m.mailbox_id', 'mb.id', IQueryBuilder::PARAM_INT))
+ ->join('m', 'mail_accounts', 'a', $query->expr()->eq('mb.account_id', 'a.id', IQueryBuilder::PARAM_INT))
+ ->where(
+ $query->expr()->eq('a.user_id', $query->createNamedParameter($uid)),
+ $query->expr()->eq('m.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT)
+ );
+
+ $results = $this->findRecipients($this->findEntities($query));
+ if (empty($results)) {
+ throw new DoesNotExistException("Message $id does not exist");
+ }
+ return $results[0];
+ }
+
public function findAllUids(Mailbox $mailbox): array {
$query = $this->db->getQueryBuilder();
$query->select('uid')
->from($this->getTableName())
- ->where($query->expr()->eq('mailbox_id', $query->createNamedParameter($mailbox->getId())));
+ ->where($query->expr()->eq('mailbox_id', $query->createNamedParameter($mailbox->getId(), IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
+
+ return $this->findUids($query);
+ }
+
+ public function findAllIds(Mailbox $mailbox): array {
+ $query = $this->db->getQueryBuilder();
+
+ $query->select('id')
+ ->from($this->getTableName())
+ ->where($query->expr()->eq('mailbox_id', $query->createNamedParameter($mailbox->getId(), IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT));
+
+ return $this->findIds($query);
+ }
+
+ /**
+ * @param Mailbox $mailbox
+ * @param int[] $ids
+ *
+ * @return int[]
+ */
+ public function findUidsForIds(Mailbox $mailbox, array $ids) {
+ if (empty($ids)) {
+ // Shortcut for empty sets
+ return [];
+ }
+
+ $query = $this->db->getQueryBuilder();
+ $query->select('uid')
+ ->from($this->getTableName())
+ ->where(
+ $query->expr()->eq('mailbox_id', $query->createNamedParameter($mailbox->getId(), IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT),
+ $query->expr()->in('id', $query->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY), IQueryBuilder::PARAM_INT_ARRAY)
+ );
return $this->findUids($query);
}
@@ -382,11 +455,11 @@ class MessageMapper extends QBMapper {
*
* @return int[]
*/
- public function findUidsByQuery(Mailbox $mailbox, SearchQuery $query, ?int $limit, array $uids = null): array {
+ public function findIdsByQuery(Mailbox $mailbox, SearchQuery $query, ?int $limit, array $uids = null): array {
$qb = $this->db->getQueryBuilder();
$select = $qb
- ->selectDistinct('m.uid')
+ ->selectDistinct('m.id')
->addSelect('m.sent_at')
->from($this->getTableName(), 'm');
@@ -477,7 +550,7 @@ class MessageMapper extends QBMapper {
}
return array_map(function (Message $message) {
- return $message->getUid();
+ return $message->getId();
}, $this->findEntities($select));
}
@@ -503,6 +576,28 @@ class MessageMapper extends QBMapper {
}
/**
+ * @param int[] $ids
+ *
+ * @return Message[]
+ */
+ public function findByIds(array $ids): array {
+ if (empty($ids)) {
+ return [];
+ }
+ $qb = $this->db->getQueryBuilder();
+
+ $select = $qb
+ ->select('*')
+ ->from($this->getTableName())
+ ->where(
+ $qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY), IQueryBuilder::PARAM_INT_ARRAY)
+ )
+ ->orderBy('sent_at', 'desc');
+
+ return $this->findRecipients($this->findEntities($select));
+ }
+
+ /**
* @param Message[] $messages
*
* @return Message[]
@@ -558,18 +653,26 @@ class MessageMapper extends QBMapper {
*
* @return Message[]
*/
- public function findNewUids(Mailbox $mailbox, int $highest): array {
+ public function findNewIds(Mailbox $mailbox, array $ids): array {
$qb = $this->db->getQueryBuilder();
+ $sub = $this->db->getQueryBuilder();
+ $subSelect = $sub
+ ->select($sub->func()->max('uid'))
+ ->from($this->getTableName())
+ ->where(
+ $sub->expr()->eq('mailbox_id', $qb->createNamedParameter($mailbox->getId(), IQueryBuilder::PARAM_INT)),
+ $sub->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY), IQueryBuilder::PARAM_INT_ARRAY)
+ );
$select = $qb
- ->select('uid')
+ ->select('id')
->from($this->getTableName())
->where(
$qb->expr()->eq('mailbox_id', $qb->createNamedParameter($mailbox->getId(), IQueryBuilder::PARAM_INT)),
- $qb->expr()->gt('uid', $qb->createNamedParameter($highest, IQueryBuilder::PARAM_INT))
+ $qb->expr()->gt('uid', $qb->createFunction('(' . $subSelect->getSQL() . ')'), IQueryBuilder::PARAM_INT)
);
- return $this->findUids($select);
+ return $this->findIds($select);
}
public function findChanged(Mailbox $mailbox, int $since): array {
@@ -644,4 +747,22 @@ class MessageMapper extends QBMapper {
->where($qb4->expr()->in('id', $qb4->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY), IQueryBuilder::PARAM_INT_ARRAY));
$recipientsQuery->execute();
}
+
+ public function getIdForUid(Mailbox $mailbox, $uid): ?int {
+ $qb = $this->db->getQueryBuilder();
+
+ $select = $qb
+ ->select('m.id')
+ ->from($this->getTableName(), 'm')
+ ->where(
+ $qb->expr()->eq('mailbox_id', $qb->createNamedParameter($mailbox->getId()), IQueryBuilder::PARAM_INT),
+ $qb->expr()->eq('uid', $qb->createNamedParameter($uid, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT)
+ );
+ $result = $select->execute();
+ $rows = $result->fetchAll();
+ if (empty($rows)) {
+ return null;
+ }
+ return (int) $rows[0]['id'];
+ }
}
diff --git a/lib/Events/DraftSavedEvent.php b/lib/Events/DraftSavedEvent.php
index f8b6368da..677b4556c 100644
--- a/lib/Events/DraftSavedEvent.php
+++ b/lib/Events/DraftSavedEvent.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Mail\Events;
use OCA\Mail\Account;
+use OCA\Mail\Db\Message;
use OCA\Mail\Model\NewMessageData;
use OCP\EventDispatcher\Event;
@@ -37,16 +38,16 @@ class DraftSavedEvent extends Event {
/** @var NewMessageData */
private $newMessageData;
- /** @var int|null */
- private $draftUid;
+ /** @var Message|null */
+ private $draft;
public function __construct(Account $account,
NewMessageData $newMessageData,
- ?int $draftUid) {
+ ?Message $draft) {
parent::__construct();
$this->account = $account;
$this->newMessageData = $newMessageData;
- $this->draftUid = $draftUid;
+ $this->draft = $draft;
}
public function getAccount(): Account {
@@ -57,7 +58,7 @@ class DraftSavedEvent extends Event {
return $this->newMessageData;
}
- public function getDraftUid(): ?int {
- return $this->draftUid;
+ public function getDraft(): ?Message {
+ return $this->draft;
}
}
diff --git a/lib/Events/MessageSentEvent.php b/lib/Events/MessageSentEvent.php
index 563467c4c..a2973cb8c 100644
--- a/lib/Events/MessageSentEvent.php
+++ b/lib/Events/MessageSentEvent.php
@@ -27,6 +27,7 @@ namespace OCA\Mail\Events;
use Horde_Mime_Mail;
use OCA\Mail\Account;
+use OCA\Mail\Db\Message;
use OCA\Mail\Model\IMessage;
use OCA\Mail\Model\NewMessageData;
use OCA\Mail\Model\RepliedMessageData;
@@ -43,8 +44,8 @@ class MessageSentEvent extends Event {
/** @var null|RepliedMessageData */
private $repliedMessageData;
- /** @var int|null */
- private $draftUid;
+ /** @var Message|null */
+ private $draft;
/** @var IMessage */
private $message;
@@ -55,14 +56,14 @@ class MessageSentEvent extends Event {
public function __construct(Account $account,
NewMessageData $newMessageData,
?RepliedMessageData $repliedMessageData,
- ?int $draftUid,
+ ?Message $draft,
IMessage $message,
Horde_Mime_Mail $mail) {
parent::__construct();
$this->account = $account;
$this->newMessageData = $newMessageData;
$this->repliedMessageData = $repliedMessageData;
- $this->draftUid = $draftUid;
+ $this->draft = $draft;
$this->message = $message;
$this->mail = $mail;
}
@@ -79,8 +80,8 @@ class MessageSentEvent extends Event {
return $this->repliedMessageData;
}
- public function getDraftUid(): ?int {
- return $this->draftUid;
+ public function getDraft(): ?Message {
+ return $this->draft;
}
public function getMessage(): IMessage {
diff --git a/lib/Events/SaveDraftEvent.php b/lib/Events/SaveDraftEvent.php
index 1f5590281..830bfe976 100644
--- a/lib/Events/SaveDraftEvent.php
+++ b/lib/Events/SaveDraftEvent.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Mail\Events;
use OCA\Mail\Account;
+use OCA\Mail\Db\Message;
use OCA\Mail\Model\NewMessageData;
use OCP\EventDispatcher\Event;
@@ -37,16 +38,16 @@ class SaveDraftEvent extends Event {
/** @var NewMessageData */
private $newMessageData;
- /** @var int|null */
- private $draftUid;
+ /** @var Message|null */
+ private $draft;
public function __construct(Account $account,
NewMessageData $newMessageData,
- ?int $draftUid) {
+ ?Message $draft) {
parent::__construct();
$this->account = $account;
$this->newMessageData = $newMessageData;
- $this->draftUid = $draftUid;
+ $this->draft = $draft;
}
public function getAccount(): Account {
@@ -57,7 +58,7 @@ class SaveDraftEvent extends Event {
return $this->newMessageData;
}
- public function getDraftUid(): ?int {
- return $this->draftUid;
+ public function getDraft(): ?Message {
+ return $this->draft;
}
}
diff --git a/lib/IMAP/MessageMapper.php b/lib/IMAP/MessageMapper.php
index 2d0f3cee8..3b4fde341 100644
--- a/lib/IMAP/MessageMapper.php
+++ b/lib/IMAP/MessageMapper.php
@@ -364,14 +364,14 @@ class MessageMapper {
/**
* @param Horde_Imap_Client_Socket $client
* @param string $mailbox
- * @param int $id
+ * @param int $uid
*
* @return string|null
* @throws ServiceException
*/
public function getSource(Horde_Imap_Client_Socket $client,
string $mailbox,
- int $id): ?string {
+ int $uid): ?string {
$query = new Horde_Imap_Client_Fetch_Query();
$query->uid();
$query->fullText([
@@ -380,7 +380,7 @@ class MessageMapper {
try {
$result = iterator_to_array($client->fetch($mailbox, $query, [
- 'ids' => new Horde_Imap_Client_Ids($id),
+ 'ids' => new Horde_Imap_Client_Ids($uid),
]), false);
} catch (Horde_Imap_Client_Exception $e) {
throw new ServiceException("Could not fetch message source: " . $e->getMessage(), $e->getCode(), $e);
@@ -399,13 +399,13 @@ class MessageMapper {
public function getHtmlBody(Horde_Imap_Client_Socket $client,
string $mailbox,
- int $id): ?string {
+ int $uid): ?string {
$messageQuery = new Horde_Imap_Client_Fetch_Query();
$messageQuery->envelope();
$messageQuery->structure();
$result = $client->fetch($mailbox, $messageQuery, [
- 'ids' => new Horde_Imap_Client_Ids([$id]),
+ 'ids' => new Horde_Imap_Client_Ids([$uid]),
]);
if (($message = $result->first()) === null) {
@@ -435,7 +435,7 @@ class MessageMapper {
}
$parts = $client->fetch($mailbox, $partsQuery, [
- 'ids' => new Horde_Imap_Client_Ids([$id]),
+ 'ids' => new Horde_Imap_Client_Ids([$uid]),
]);
foreach ($parts as $part) {
@@ -456,12 +456,12 @@ class MessageMapper {
public function getRawAttachments(Horde_Imap_Client_Socket $client,
string $mailbox,
- int $id): array {
+ int $uid): array {
$messageQuery = new Horde_Imap_Client_Fetch_Query();
$messageQuery->structure();
$result = $client->fetch($mailbox, $messageQuery, [
- 'ids' => new Horde_Imap_Client_Ids([$id]),
+ 'ids' => new Horde_Imap_Client_Ids([$uid]),
]);
if (($structureResult = $result->first()) === null) {
@@ -488,7 +488,7 @@ class MessageMapper {
}
$parts = $client->fetch($mailbox, $partsQuery, [
- 'ids' => new Horde_Imap_Client_Ids([$id]),
+ 'ids' => new Horde_Imap_Client_Ids([$uid]),
]);
if (($messageData = $parts->first()) === null) {
throw new DoesNotExistException('Message does not exist');
diff --git a/lib/IMAP/Sync/Response.php b/lib/IMAP/Sync/Response.php
index 9e95b342e..d12625775 100644
--- a/lib/IMAP/Sync/Response.php
+++ b/lib/IMAP/Sync/Response.php
@@ -24,14 +24,15 @@ declare(strict_types=1);
namespace OCA\Mail\IMAP\Sync;
use JsonSerializable;
+use OCA\Mail\Db\Message;
use OCA\Mail\Model\IMAPMessage;
class Response implements JsonSerializable {
- /** @var IMAPMessage[] */
+ /** @var IMAPMessage|Message[] */
private $newMessages;
- /** @var IMAPMessage[] */
+ /** @var IMAPMessage|Message[] */
private $changedMessages;
/** @var int[] */
@@ -39,8 +40,8 @@ class Response implements JsonSerializable {
/**
* @param string $syncToken
- * @param IMAPMessage[] $newMessages
- * @param IMAPMessage[] $changedMessages
+ * @param IMAPMessage|Message[] $newMessages
+ * @param IMAPMessage|Message[] $changedMessages
* @param int[] $vanishedMessageUids
*/
public function __construct(array $newMessages = [],
@@ -52,14 +53,14 @@ class Response implements JsonSerializable {
}
/**
- * @return IMAPMessage[]
+ * @return IMAPMessage|Message[]
*/
public function getNewMessages(): array {
return $this->newMessages;
}
/**
- * @return IMAPMessage[]
+ * @return IMAPMessage|Message[]
*/
public function getChangedMessages(): array {
return $this->changedMessages;
diff --git a/lib/IMAP/Threading/ThreadBuilder.php b/lib/IMAP/Threading/ThreadBuilder.php
index 72283423f..8053d045d 100644
--- a/lib/IMAP/Threading/ThreadBuilder.php
+++ b/lib/IMAP/Threading/ThreadBuilder.php
@@ -110,6 +110,9 @@ class ThreadBuilder {
// Step 1.C
//$parentId = $message->getReferences()[count($message->getReferences()) - 1] ?? null;
//$container->setParent($idTable[$parentId] ?? null);
+ if ($parent === $container) {
+ throw new \Exception("about to run into a nasty endless loop");
+ }
if ($parent === null || !$parent->hasAncestor($container)) {
$container->setParent($parent);
}
diff --git a/lib/Listener/DeleteDraftListener.php b/lib/Listener/DeleteDraftListener.php
index 0e76adec6..9758a0fa0 100644
--- a/lib/Listener/DeleteDraftListener.php
+++ b/lib/Listener/DeleteDraftListener.php
@@ -30,6 +30,7 @@ use Horde_Imap_Client_Exception;
use OCA\Mail\Account;
use OCA\Mail\Db\Mailbox;
use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Db\Message;
use OCA\Mail\Events\DraftSavedEvent;
use OCA\Mail\Events\MessageSentEvent;
use OCA\Mail\IMAP\IMAPClientFactory;
@@ -70,17 +71,18 @@ class DeleteDraftListener implements IEventListener {
}
public function handle(Event $event): void {
- if ($event instanceof DraftSavedEvent && $event->getDraftUid() !== null) {
- $this->deleteDraft($event->getAccount(), $event->getDraftUid());
- } elseif ($event instanceof MessageSentEvent && $event->getDraftUid() !== null) {
- $this->deleteDraft($event->getAccount(), $event->getDraftUid());
+ if ($event instanceof DraftSavedEvent && $event->getDraft() !== null) {
+ $this->deleteDraft($event->getAccount(), $event->getDraft());
+ } elseif ($event instanceof MessageSentEvent && $event->getDraft() !== null) {
+ $this->deleteDraft($event->getAccount(), $event->getDraft());
}
}
/**
- * @param DraftSavedEvent $event
+ * @param Account $account
+ * @param Message $draft
*/
- private function deleteDraft(Account $account, int $draftUid): void {
+ private function deleteDraft(Account $account, Message $draft): void {
$client = $this->imapClientFactory->getClient($account);
$draftsMailbox = $this->getDraftsMailbox($account);
@@ -88,7 +90,7 @@ class DeleteDraftListener implements IEventListener {
$this->messageMapper->addFlag(
$client,
$draftsMailbox,
- $draftUid,
+ $draft->getUid(), // TODO: the UID could be from another mailbox
Horde_Imap_Client::FLAG_DELETED
);
} catch (Horde_Imap_Client_Exception $e) {
diff --git a/lib/Mailbox.php b/lib/Mailbox.php
index 09daef680..5aecf8330 100644
--- a/lib/Mailbox.php
+++ b/lib/Mailbox.php
@@ -295,12 +295,13 @@ class Mailbox implements IMailBox {
}
/**
- * @param int $messageId
+ * @param int $messageUid
* @param string $attachmentId
+ *
* @return Attachment
*/
- public function getAttachment(int $messageId, string $attachmentId): Attachment {
- return new Attachment($this->conn, $this->mailBox, $messageId, $attachmentId);
+ public function getAttachment(int $messageUid, string $attachmentId): Attachment {
+ return new Attachment($this->conn, $this->mailBox, $messageUid, $attachmentId);
}
/**
diff --git a/lib/Model/IMAPMessage.php b/lib/Model/IMAPMessage.php
index 1dae7a1d0..8b7ae12a3 100644
--- a/lib/Model/IMAPMessage.php
+++ b/lib/Model/IMAPMessage.php
@@ -48,7 +48,6 @@ use OCA\Mail\Service\Html;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\Files\File;
use OCP\Files\SimpleFS\ISimpleFile;
-use function base64_encode;
use function in_array;
use function mb_convert_encoding;
@@ -422,15 +421,17 @@ class IMAPMessage implements IMessage, JsonSerializable {
}
/**
+ * @param int $id
+ *
* @return array
*/
- public function getFullMessage(int $accountId, string $mailbox, int $id): array {
+ public function getFullMessage(int $id): array {
$mailBody = $this->plainMessage;
$data = $this->jsonSerialize();
if ($this->hasHtmlMessage) {
$data['hasHtmlBody'] = true;
- $data['body'] = $this->getHtmlBody($accountId, $mailbox, $id);
+ $data['body'] = $this->getHtmlBody($id);
} else {
$mailBody = $this->htmlService->convertLinks($mailBody);
list($mailBody, $signature) = $this->htmlService->parseMailBody($mailBody);
@@ -462,17 +463,13 @@ class IMAPMessage implements IMessage, JsonSerializable {
}
/**
- * @param int $accountId
- * @param string $folderId
- * @param int $messageId
+ * @param int $id
*
* @return string
*/
- public function getHtmlBody(int $accountId, string $folderId, int $messageId): string {
+ public function getHtmlBody(int $id): string {
return $this->htmlService->sanitizeHtmlMailBody($this->htmlMessage, [
- 'accountId' => $accountId,
- 'folderId' => base64_encode($folderId),
- 'messageId' => $messageId,
+ 'id' => $id,
], function ($cid) {
$match = array_filter($this->attachments,
function ($a) use ($cid) {
diff --git a/lib/Service/AccountService.php b/lib/Service/AccountService.php
index 83a4a6977..36fbf11a1 100644
--- a/lib/Service/AccountService.php
+++ b/lib/Service/AccountService.php
@@ -89,25 +89,25 @@ class AccountService {
/**
* @param string $uid
- * @param int $accountId
+ * @param int $id
*
* @return Account
* @throws ClientException
*/
- public function find(string $uid, int $accountId): Account {
+ public function find(string $uid, int $id): Account {
if ($this->accounts !== null) {
foreach ($this->accounts as $account) {
- if ($account->getId() === $accountId) {
+ if ($account->getId() === $id) {
return $account;
}
}
- throw new ClientException("Account $accountId does not exist or you don\'t have permission to access it");
+ throw new ClientException("Account $id does not exist or you don\'t have permission to access it");
}
try {
- return new Account($this->mapper->find($uid, $accountId));
+ return new Account($this->mapper->find($uid, $id));
} catch (DoesNotExistException $e) {
- throw new ClientException("Account $accountId does not exist or you don\'t have permission to access it");
+ throw new ClientException("Account $id does not exist or you don\'t have permission to access it");
}
}
diff --git a/lib/Service/IMailBox.php b/lib/Service/IMailBox.php
index 093e3d7f1..d75c5c562 100644
--- a/lib/Service/IMailBox.php
+++ b/lib/Service/IMailBox.php
@@ -47,11 +47,12 @@ interface IMailBox {
public function getMessage(int $id, bool $loadHtmlMessageBody = false);
/**
- * @param int $messageId
+ * @param int $messageUid
* @param string $attachmentId
+ *
* @return Attachment
*/
- public function getAttachment(int $messageId, string $attachmentId): Attachment;
+ public function getAttachment(int $messageUid, string $attachmentId): Attachment;
/**
* @param int $flags
diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php
index 08cceb812..09d04dcc3 100644
--- a/lib/Service/MailManager.php
+++ b/lib/Service/MailManager.php
@@ -30,6 +30,7 @@ use OCA\Mail\Account;
use OCA\Mail\Contracts\IMailManager;
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 OCA\Mail\Events\MessageDeletedEvent;
@@ -100,6 +101,14 @@ class MailManager implements IMailManager {
$this->eventDispatcher = $eventDispatcher;
}
+ public function getMailbox(string $uid, int $id): Mailbox {
+ try {
+ return $this->mailboxMapper->findByUid($id, $uid);
+ } catch (DoesNotExistException $e) {
+ throw new ClientException("Mailbox $id does not exist", 0, $e);
+ }
+ }
+
/**
* @param Account $account
*
@@ -116,10 +125,10 @@ class MailManager implements IMailManager {
* @param Account $account
* @param string $name
*
- * @return Folder
+ * @return Mailbox
* @throws ServiceException
*/
- public function createFolder(Account $account, string $name): Folder {
+ public function createMailbox(Account $account, string $name): Mailbox {
$client = $this->imapClientFactory->getClient($account);
$folder = $this->folderMapper->createFolder($client, $account, $name);
@@ -132,30 +141,33 @@ class MailManager implements IMailManager {
$this->mailboxSync->sync($account, true);
- return $folder;
+ return $this->mailboxMapper->find($account, $name);
}
/**
* @param Account $account
- * @param string $folderId
+ * @param Mailbox $mailbox
*
* @return FolderStats
+ * @throws Horde_Imap_Client_Exception
*/
- public function getFolderStats(Account $account, string $folderId): FolderStats {
+ public function getMailboxStats(Account $account, Mailbox $mailbox): FolderStats {
$client = $this->imapClientFactory->getClient($account);
- return $this->folderMapper->getFoldersStatusAsObject($client, $folderId);
+ return $this->folderMapper->getFoldersStatusAsObject($client, $mailbox->getName());
}
- public function getMessage(Account $account, string $mailbox, int $id, bool $loadBody = false): IMAPMessage {
+ public function getImapMessage(Account $account,
+ Mailbox $mailbox,
+ int $uid,
+ bool $loadBody = false): IMAPMessage {
$client = $this->imapClientFactory->getClient($account);
- $mailbox = $this->mailboxMapper->find($account, $mailbox);
try {
return $this->imapMessageMapper->find(
$client,
$mailbox->getName(),
- $id,
+ $uid,
$loadBody
);
} catch (Horde_Imap_Client_Exception|DoesNotExistException $e) {
@@ -167,24 +179,32 @@ class MailManager implements IMailManager {
return $this->dbMessageMapper->findThread($account, $messageId);
}
+ public function getMessageIdForUid(Mailbox $mailbox, $uid): ?int {
+ return $this->dbMessageMapper->getIdForUid($mailbox, $uid);
+ }
+
+ public function getMessage(string $uid, int $id): Message {
+ return $this->dbMessageMapper->findByUserId($uid, $id);
+ }
+
/**
* @param Account $account
* @param string $mb
- * @param int $id
+ * @param int $uid
*
* @return string
*
* @throws ClientException
* @throws ServiceException
*/
- public function getSource(Account $account, string $mailbox, int $id): string {
+ public function getSource(Account $account, string $mailbox, int $uid): ?string {
$client = $this->imapClientFactory->getClient($account);
try {
return $this->imapMessageMapper->getSource(
$client,
$mailbox,
- $id
+ $uid
);
} catch (Horde_Imap_Client_Exception|DoesNotExistException $e) {
throw new ServiceException("Could not load message", 0, $e);
@@ -194,7 +214,7 @@ class MailManager implements IMailManager {
/**
* @param Account $sourceAccount
* @param string $sourceFolderId
- * @param int $messageId
+ * @param int $uid
* @param Account $destinationAccount
* @param string $destFolderId
*
@@ -204,7 +224,7 @@ class MailManager implements IMailManager {
*/
public function moveMessage(Account $sourceAccount,
string $sourceFolderId,
- int $messageId,
+ int $uid,
Account $destinationAccount,
string $destFolderId) {
if ($sourceAccount->getId() === $destinationAccount->getId()) {
@@ -212,7 +232,7 @@ class MailManager implements IMailManager {
$sourceAccount,
$sourceFolderId,
$destFolderId,
- $messageId
+ $uid
);
} else {
throw new ServiceException('It is not possible to move across accounts yet');
@@ -284,10 +304,10 @@ class MailManager implements IMailManager {
$this->imapMessageMapper->move($client, $sourceFolderId, $messageId, $destFolderId);
}
- public function markFolderAsRead(Account $account, string $folderId): void {
+ public function markFolderAsRead(Account $account, Mailbox $mailbox): void {
$client = $this->imapClientFactory->getClient($account);
- $this->imapMessageMapper->markAllRead($client, $folderId);
+ $this->imapMessageMapper->markAllRead($client, $mailbox->getName());
}
public function flagMessage(Account $account, string $mailbox, int $uid, string $flag, bool $value): void {
@@ -371,18 +391,14 @@ class MailManager implements IMailManager {
/**
* @param Account $account
- * @param string $folderId
+ * @param Mailbox $mailbox
+ *
* @throws ServiceException
*/
public function deleteMailbox(Account $account,
- string $folderId): void {
- try {
- $mailbox = $this->mailboxMapper->find($account, $folderId);
- } catch (DoesNotExistException $e) {
- throw new ServiceException("Source mailbox $folderId does not exist", 0, $e);
- }
+ Mailbox $mailbox): void {
$client = $this->imapClientFactory->getClient($account);
- $this->folderMapper->delete($client, $folderId);
+ $this->folderMapper->delete($client, $mailbox->getName());
$this->mailboxMapper->delete($mailbox);
}
}
diff --git a/lib/Service/MailTransmission.php b/lib/Service/MailTransmission.php
index 9db9c1d4a..e8ff9d135 100644
--- a/lib/Service/MailTransmission.php
+++ b/lib/Service/MailTransmission.php
@@ -39,6 +39,7 @@ use OCA\Mail\Contracts\IAttachmentService;
use OCA\Mail\Contracts\IMailTransmission;
use OCA\Mail\Db\Alias;
use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\Db\Message;
use OCA\Mail\Events\DraftSavedEvent;
use OCA\Mail\Events\MessageSentEvent;
use OCA\Mail\Events\SaveDraftEvent;
@@ -102,22 +103,10 @@ class MailTransmission implements IMailTransmission {
$this->logger = $logger;
}
- /**
- * Send a new message or reply to an existing one
- *
- * @param NewMessageData $messageData
- * @param RepliedMessageData $replyData
- * @param Alias|null $alias
- * @param int|null $draftUID
- *
- * @throws ServiceException
- *
- * @return void
- */
public function sendMessage(NewMessageData $messageData,
RepliedMessageData $replyData = null,
Alias $alias = null,
- int $draftUID = null) {
+ Message $draft = null) {
$account = $messageData->getAccount();
if ($replyData !== null) {
@@ -178,17 +167,22 @@ class MailTransmission implements IMailTransmission {
$this->eventDispatcher->dispatch(
MessageSentEvent::class,
- new MessageSentEvent($account, $messageData, $replyData, $draftUID, $message, $mail)
+ new MessageSentEvent($account, $messageData, $replyData, $draft, $message, $mail)
);
}
/**
+ * @param NewMessageData $message
+ * @param Message|null $previousDraft
+ *
+ * @return array
+ *
* @throws ServiceException
*/
- public function saveDraft(NewMessageData $message, int $draftUID = null): int {
+ public function saveDraft(NewMessageData $message, Message $previousDraft = null): array {
$this->eventDispatcher->dispatch(
SaveDraftEvent::class,
- new SaveDraftEvent($message->getAccount(), $message, $draftUID)
+ new SaveDraftEvent($message->getAccount(), $message, $previousDraft)
);
$account = $message->getAccount();
@@ -243,10 +237,10 @@ class MailTransmission implements IMailTransmission {
$this->eventDispatcher->dispatch(
DraftSavedEvent::class,
- new DraftSavedEvent($account, $message, $draftUID)
+ new DraftSavedEvent($account, $message, $previousDraft)
);
- return $newUid;
+ return [$account, $draftsMailbox, $newUid];
}
private function buildReplyMessage(Account $account,
diff --git a/lib/Service/Search/MailSearch.php b/lib/Service/Search/MailSearch.php
index cead97321..85b021704 100644
--- a/lib/Service/Search/MailSearch.php
+++ b/lib/Service/Search/MailSearch.php
@@ -75,32 +75,26 @@ class MailSearch implements IMailSearch {
$this->logger = $logger;
}
- public function findMessage(Account $account, string $mailboxName, int $uid): Message {
- try {
- $mailbox = $this->mailboxMapper->find($account, $mailboxName);
- } catch (DoesNotExistException $e) {
- throw new ServiceException('Mailbox does not exist', 0, $e);
- }
-
- $messages = $this->previewEnhancer->process(
+ public function findMessage(Account $account,
+ Mailbox $mailbox,
+ Message $message): Message {
+ $processed = $this->previewEnhancer->process(
$account,
$mailbox,
- $this->messageMapper->findByUids(
- $mailbox,
- [$uid]
- )
+ [$message]
);
- if (empty($messages)) {
+ if (empty($processed)) {
throw new DoesNotExistException("Message does not exist");
}
- return $messages[0];
+ return $processed[0];
}
/**
* @param Account $account
- * @param string $mailboxName
+ * @param Mailbox $mailbox
* @param string|null $filter
* @param int|null $cursor
+ * @param int|null $limit
*
* @return Message[]
*
@@ -108,16 +102,10 @@ class MailSearch implements IMailSearch {
* @throws ServiceException
*/
public function findMessages(Account $account,
- string $mailboxName,
+ Mailbox $mailbox,
?string $filter,
?int $cursor,
?int $limit): array {
- try {
- $mailbox = $this->mailboxMapper->find($account, $mailboxName);
- } catch (DoesNotExistException $e) {
- throw new ServiceException('Mailbox does not exist', 0, $e);
- }
-
if ($mailbox->hasLocks()) {
throw MailboxLockedException::from($mailbox);
}
@@ -141,9 +129,8 @@ class MailSearch implements IMailSearch {
return $this->previewEnhancer->process(
$account,
$mailbox,
- $this->messageMapper->findByUids(
- $mailbox,
- $this->getUids($account, $mailbox, $query, $limit)
+ $this->messageMapper->findByIds(
+ $this->getIds($account, $mailbox, $query, $limit)
)
);
}
@@ -153,9 +140,9 @@ class MailSearch implements IMailSearch {
*
* @throws ServiceException
*/
- private function getUids(Account $account, Mailbox $mailbox, SearchQuery $query, ?int $limit): array {
+ private function getIds(Account $account, Mailbox $mailbox, SearchQuery $query, ?int $limit): array {
if (empty($query->getTextTokens())) {
- return $this->messageMapper->findUidsByQuery($mailbox, $query, $limit);
+ return $this->messageMapper->findIdsByQuery($mailbox, $query, $limit);
}
$fromImap = $this->imapSearchProvider->findMatches(
@@ -163,6 +150,6 @@ class MailSearch implements IMailSearch {
$mailbox,
$query
);
- return $this->messageMapper->findUidsByQuery($mailbox, $query, $limit, $fromImap);
+ return $this->messageMapper->findIdsByQuery($mailbox, $query, $limit, $fromImap);
}
}
diff --git a/lib/Service/Sync/SyncService.php b/lib/Service/Sync/SyncService.php
index 484ce597b..385a66b84 100644
--- a/lib/Service/Sync/SyncService.php
+++ b/lib/Service/Sync/SyncService.php
@@ -38,10 +38,8 @@ use OCA\Mail\IMAP\PreviewEnhancer;
use OCA\Mail\IMAP\Sync\Response;
use OCA\Mail\Service\Search\FilterStringParser;
use OCA\Mail\Service\Search\SearchQuery;
-use OCP\AppFramework\Db\DoesNotExistException;
use function array_diff;
use function array_map;
-use function end;
class SyncService {
@@ -74,46 +72,36 @@ class SyncService {
/**
* @param Account $account
- * @param string $mailboxId
+ * @param Mailbox $mailbox
*
* @throws MailboxLockedException
* @throws ServiceException
*/
public function clearCache(Account $account,
- string $mailboxId): void {
- try {
- $mailbox = $this->mailboxMapper->find($account, $mailboxId);
- } catch (DoesNotExistException $e) {
- throw new ServiceException('Mailbox to sync does not exist in the database', 0, $e);
- }
-
+ Mailbox $mailbox): void {
$this->synchronizer->clearCache($account, $mailbox);
}
/**
* @param Account $account
- * @param string $mailboxId
+ * @param Mailbox $mailbox
* @param int $criteria
- * @param array $knownUids
+ * @param int[] $knownIds
* @param bool $partialOnly
*
+ * @param string|null $filter
+ *
* @return Response
* @throws ClientException
* @throws MailboxNotCachedException
* @throws ServiceException
*/
public function syncMailbox(Account $account,
- string $mailboxId,
+ Mailbox $mailbox,
int $criteria,
- array $knownUids,
+ array $knownIds,
bool $partialOnly,
string $filter = null): Response {
- try {
- $mailbox = $this->mailboxMapper->find($account, $mailboxId);
- } catch (DoesNotExistException $e) {
- throw new ServiceException('Mailbox to sync does not exist in the database', 0, $e);
- }
-
if ($partialOnly && !$mailbox->isCached()) {
throw MailboxNotCachedException::from($mailbox);
}
@@ -122,52 +110,57 @@ class SyncService {
$account,
$mailbox,
$criteria,
- $knownUids,
+ $this->messageMapper->findUidsForIds($mailbox, $knownIds),
!$partialOnly
);
$query = $filter === null ? null : $this->filterStringParser->parse($filter);
-
- return $this->getDatabaseSyncChanges($account, $mailbox, $knownUids, $query);
+ return $this->getDatabaseSyncChanges(
+ $account,
+ $mailbox,
+ $knownIds,
+ $query
+ );
}
/**
* @param Account $account
* @param Mailbox $mailbox
- * @param array $knownUids
+ * @param int[] $knownIds
* @param SearchQuery $query
*
* @return Response
* @todo does not work with text token search queries
*
*/
- private function getDatabaseSyncChanges(Account $account, Mailbox $mailbox, array $knownUids, ?SearchQuery $query): Response {
- if (empty($knownUids)) {
- $newUids = $this->messageMapper->findAllUids($mailbox);
+ private function getDatabaseSyncChanges(Account $account,
+ Mailbox $mailbox,
+ array $knownIds,
+ ?SearchQuery $query): Response {
+ if (empty($knownIds)) {
+ $newIds = $this->messageMapper->findAllIds($mailbox);
} else {
- sort($knownUids, SORT_NUMERIC);
- $last = end($knownUids);
- $newUids = $this->messageMapper->findNewUids($mailbox, $last);
+ $newIds = $this->messageMapper->findNewIds($mailbox, $knownIds);
}
if ($query !== null) {
// Filter new messages to those that also match the current filter
- $newUids = $this->messageMapper->findUidsByQuery($mailbox, $query, null, $newUids);
+ $newIds = $this->messageMapper->findIdsByQuery($mailbox, $query, null, $newIds);
}
- $new = $this->messageMapper->findByUids($mailbox, $newUids);
+ $new = $this->messageMapper->findByIds($newIds);
// TODO: $changed = $this->messageMapper->findChanged($mailbox, $uids);
if ($query !== null) {
- $changedUids = $this->messageMapper->findUidsByQuery($mailbox, $query, null, $knownUids);
+ $changedIds = $this->messageMapper->findIdsByQuery($mailbox, $query, null, $knownIds);
} else {
- $changedUids = $knownUids;
+ $changedIds = $knownIds;
}
- $changed = $this->messageMapper->findByUids($mailbox, $changedUids);
+ $changed = $this->messageMapper->findByIds($changedIds);
- $stillKnownUids = array_map(static function (Message $msg) {
- return $msg->getUid();
+ $stillKnownIds = array_map(static function (Message $msg) {
+ return $msg->getId();
}, $changed);
- $vanished = array_values(array_diff($knownUids, $stillKnownUids));
+ $vanished = array_values(array_diff($knownIds, $stillKnownIds));
return new Response(
$this->previewEnhancer->process($account, $mailbox, $new),