Skip to content

Commit 0478031

Browse files
authored
Merge pull request #11889 from nextcloud/fix/noid/create-drafts-folder-on-demand
fix: ensure drafts folder exists
2 parents b6d82ce + c01706f commit 0478031

File tree

6 files changed

+58
-19
lines changed

6 files changed

+58
-19
lines changed

lib/Contracts/IMailManager.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ public function getMailboxes(Account $account, bool $forceSync = false): array;
4646
/**
4747
* @param Account $account
4848
* @param string $name
49+
* @param string[] $specialUse
4950
*
5051
* @return Mailbox
5152
*
5253
* @throws ServiceException
5354
*/
54-
public function createMailbox(Account $account, string $name): Mailbox;
55+
public function createMailbox(Account $account, string $name, array $specialUse = []): Mailbox;
5556

5657
/**
5758
* @param Mailbox $mailbox

lib/IMAP/FolderMapper.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ public function getFolders(Account $account, Horde_Imap_Client_Socket $client,
7171
), $toPersist);
7272
}
7373

74-
public function createFolder(Horde_Imap_Client_Socket $client,
75-
string $name): Folder {
76-
$client->createMailbox($name);
74+
public function createFolder(Horde_Imap_Client_Socket $client, string $name, array $specialUse = []): Folder {
75+
$client->createMailbox($name, [
76+
'special_use' => $specialUse,
77+
]);
7778

7879
$list = $client->listMailboxes($name, Horde_Imap_Client::MBOX_ALL_SUBSCRIBED, [
7980
'delimiter' => true,

lib/Service/MailManager.php

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,11 @@ public function getMailboxes(Account $account, bool $forceSync = false): array {
142142
return $this->mailboxMapper->findAll($account);
143143
}
144144

145-
/**
146-
* @param Account $account
147-
* @param string $name
148-
*
149-
* @return Mailbox
150-
* @throws ServiceException
151-
*/
152145
#[\Override]
153-
public function createMailbox(Account $account, string $name): Mailbox {
146+
public function createMailbox(Account $account, string $name, array $specialUse = []): Mailbox {
154147
$client = $this->imapClientFactory->getClient($account);
155148
try {
156-
$folder = $this->folderMapper->createFolder($client, $name);
149+
$folder = $this->folderMapper->createFolder($client, $name, $specialUse);
157150
$this->folderMapper->fetchFolderAcls([$folder], $client);
158151
} catch (Horde_Imap_Client_Exception $e) {
159152
throw new ServiceException(

lib/Service/MailTransmission.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use OCA\Mail\Account;
2929
use OCA\Mail\Address;
3030
use OCA\Mail\AddressList;
31+
use OCA\Mail\Contracts\IMailManager;
3132
use OCA\Mail\Contracts\IMailTransmission;
3233
use OCA\Mail\Db\LocalMessage;
3334
use OCA\Mail\Db\Mailbox;
@@ -67,6 +68,7 @@ public function __construct(
6768
private PerformanceLogger $performanceLogger,
6869
private AliasesService $aliasesService,
6970
private TransmissionService $transmissionService,
71+
private IMailManager $mailManager,
7072
) {
7173
}
7274

@@ -231,12 +233,7 @@ public function saveLocalDraft(Account $account, LocalMessage $message): void {
231233
$transport = new Horde_Mail_Transport_Null();
232234
$mail->send($transport, false, false);
233235
$perfLogger->step('create IMAP draft message');
234-
// save the message in the drafts folder
235-
$draftsMailboxId = $account->getMailAccount()->getDraftsMailboxId();
236-
if ($draftsMailboxId === null) {
237-
throw new ClientException('No drafts mailbox configured');
238-
}
239-
$draftsMailbox = $this->mailboxMapper->findById($draftsMailboxId);
236+
$draftsMailbox = $this->findOrCreateDraftsMailbox($account);
240237
$this->messageMapper->save(
241238
$client,
242239
$draftsMailbox,
@@ -258,6 +255,20 @@ public function saveLocalDraft(Account $account, LocalMessage $message): void {
258255
$perfLogger->end();
259256
}
260257

258+
private function findOrCreateDraftsMailbox(Account $account): Mailbox {
259+
$draftsMailboxId = $account->getMailAccount()->getDraftsMailboxId();
260+
261+
if ($draftsMailboxId === null) {
262+
return $this->mailManager->createMailbox(
263+
$account,
264+
'Drafts',
265+
[Horde_Imap_Client::SPECIALUSE_DRAFTS]
266+
);
267+
}
268+
269+
return $this->mailboxMapper->findById($draftsMailboxId);
270+
}
271+
261272
/**
262273
* @param NewMessageData $message
263274
* @param Message|null $previousDraft

tests/Integration/Service/MailTransmissionIntegrationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OC;
1414
use OCA\Mail\Account;
1515
use OCA\Mail\Contracts\IAttachmentService;
16+
use OCA\Mail\Contracts\IMailManager;
1617
use OCA\Mail\Contracts\IMailTransmission;
1718
use OCA\Mail\Db\LocalMessage;
1819
use OCA\Mail\Db\LocalMessageMapper;
@@ -140,6 +141,7 @@ protected function setUp(): void {
140141
Server::get(PerformanceLogger::class),
141142
Server::get(AliasesService::class),
142143
Server::get(TransmissionService::class),
144+
Server::get(IMailManager::class)
143145
);
144146
}
145147

tests/Unit/Service/MailTransmissionTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ protected function setUp(): void {
6262
$this->performanceLogger = $this->createMock(PerformanceLogger::class);
6363
$this->aliasService = $this->createMock(AliasesService::class);
6464
$this->transmissionService = $this->createMock(TransmissionService::class);
65+
$this->mailManager = $this->createMock(IMailManager::class);
6566

6667
$this->transmission = new MailTransmission(
6768
$this->imapClientFactory,
@@ -73,6 +74,7 @@ protected function setUp(): void {
7374
$this->performanceLogger,
7475
$this->aliasService,
7576
$this->transmissionService,
77+
$this->mailManager,
7678
);
7779
}
7880

@@ -402,4 +404,33 @@ public function testSendLocalDraft(): void {
402404

403405
$this->transmission->saveLocalDraft(new Account($mailAccount), $localMessage);
404406
}
407+
408+
public function testCreateDraftsMailboxAndSave(): void {
409+
$mailAccount = new MailAccount();
410+
$mailAccount->setId(10);
411+
$mailAccount->setUserId('alice');
412+
$mailAccount->setName('Alice');
413+
$mailAccount->setEmail('[email protected]');
414+
$mailAccount->setDraftsMailboxId(null);
415+
$localMessage = new LocalMessage();
416+
$localMessage->setType(LocalMessage::TYPE_DRAFT);
417+
$localMessage->setAccountId($mailAccount->getId());
418+
$localMessage->setAliasId(1);
419+
$localMessage->setSendAt(1000);
420+
$localMessage->setSubject('Subject');
421+
$localMessage->setBodyHtml('<p>Body</p>');
422+
$localMessage->setHtml(true);
423+
$to = new Recipient();
424+
$to->setLabel('Bob');
425+
$to->setEmail('[email protected]');
426+
$to->setType(Recipient::TYPE_TO);
427+
$localMessage->setRecipients([$to]);
428+
429+
$this->mailManager->expects(self::once())
430+
->method('createMailbox');
431+
$this->messageMapper->expects(self::once())
432+
->method('save');
433+
434+
$this->transmission->saveLocalDraft(new Account($mailAccount), $localMessage);
435+
}
405436
}

0 commit comments

Comments
 (0)