diff --git a/lib/Contracts/IMailManager.php b/lib/Contracts/IMailManager.php
index d7ee53837b..27124b246f 100644
--- a/lib/Contracts/IMailManager.php
+++ b/lib/Contracts/IMailManager.php
@@ -22,8 +22,22 @@
namespace OCA\Mail\Contracts;
use OCA\Mail\Account;
+use OCA\Mail\Folder;
+use OCA\Mail\IMAP\Sync\Request as SyncRequest;
+use OCA\Mail\IMAP\Sync\Response as SyncResponse;
interface IMailManager {
+ /**
+ * @param Account $account
+ * @return Folder[]
+ */
public function getFolders(Account $account);
+
+ /**
+ * @param Account
+ * @param SyncRequest $syncRequest
+ * @return SyncResponse
+ */
+ public function syncMessages(Account $account, SyncRequest $syncRequest);
}
diff --git a/lib/IMAP/MessageMapper.php b/lib/IMAP/MessageMapper.php
new file mode 100644
index 0000000000..61b62ed406
--- /dev/null
+++ b/lib/IMAP/MessageMapper.php
@@ -0,0 +1,41 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\IMAP;
+
+use Exception;
+use Horde_Imap_Client_Base;
+use OCA\Mail\Folder;
+use OCA\Mail\Model\IMAPMessage;
+
+class MessageMapper {
+
+ /**
+ * @param Horde_Imap_Client_Base $imapClient
+ * @param Folder $mailbox
+ * @param array $ids
+ * @return IMAPMessage[]
+ */
+ public function findByIds(Horde_Imap_Client_Base $imapClient, $mailbox, array $ids) {
+ throw new Exception('not implemented');
+ }
+
+}
diff --git a/lib/IMAP/Sync/Request.php b/lib/IMAP/Sync/Request.php
new file mode 100644
index 0000000000..59de0d65cc
--- /dev/null
+++ b/lib/IMAP/Sync/Request.php
@@ -0,0 +1,57 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\IMAP\Sync;
+
+class Request {
+
+ /** @var string */
+ private $mailbox;
+
+ /** @var string */
+ private $syncToken;
+
+ /**
+ * @param string $mailbox
+ * @param string $syncToken
+ */
+ public function __construct($mailbox, $syncToken) {
+ $this->mailbox = $mailbox;
+ $this->syncToken = $syncToken;
+ }
+
+ /**
+ * Get the mailbox name
+ *
+ * @return string
+ */
+ public function getMailbox() {
+ return $this->mailbox;
+ }
+
+ /**
+ * @return string the Horde sync token
+ */
+ public function getToken() {
+ return $this->syncToken;
+ }
+
+}
diff --git a/lib/IMAP/Sync/Response.php b/lib/IMAP/Sync/Response.php
new file mode 100644
index 0000000000..a267b84e8f
--- /dev/null
+++ b/lib/IMAP/Sync/Response.php
@@ -0,0 +1,68 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\IMAP\Sync;
+
+use Exception;
+use JsonSerializable;
+use OCA\Mail\Model\IMAPMessage;
+
+class Response implements JsonSerializable {
+
+ /** @var string */
+ private $syncToken;
+
+ /** @var IMAPMessage[] */
+ private $newMessages;
+
+ /** @var IMAPMessage[] */
+ private $changedMessages;
+
+ /** @var array */
+ private $vanishedMessages;
+
+ /**
+ * @param string $syncToken
+ * @param IMAPMessage[] $newMessages
+ * @param IMAPMessage[] $changedMessages
+ * @param array $vanishedMessages
+ */
+ public function __construct($syncToken, array $newMessages = [], array $changedMessages = [],
+ array $vanishedMessages = []) {
+ $this->syncToken = $syncToken;
+ $this->newMessages = $newMessages;
+ $this->changedMessages = $changedMessages;
+ $this->vanishedMessages = $vanishedMessages;
+ }
+
+ /**
+ * @return array
+ */
+ public function jsonSerialize() {
+ return [
+ 'newMessages' => $this->newMessages,
+ 'changedMessages' => $this->changedMessages,
+ 'vanishedMessages' => $this->vanishedMessages,
+ 'token' => $this->syncToken,
+ ];
+ }
+
+}
diff --git a/lib/IMAP/Sync/Synchronizer.php b/lib/IMAP/Sync/Synchronizer.php
new file mode 100644
index 0000000000..840d8ec592
--- /dev/null
+++ b/lib/IMAP/Sync/Synchronizer.php
@@ -0,0 +1,57 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\IMAP\Sync;
+
+use Horde_Imap_Client_Base;
+use OCA\Mail\IMAP\MessageMapper;
+use OCA\Mail\IMAP\Sync\Request;
+use OCA\Mail\IMAP\Sync\Response;
+
+class Synchronizer {
+
+ /** @var MessageMapper */
+ private $messageMapper;
+
+ /**
+ * @param MessageMapper $messageMapper
+ */
+ public function __construct(MessageMapper $messageMapper) {
+ $this->messageMapper = $messageMapper;
+ }
+
+ /**
+ * @param Horde_Imap_Client_Base $imapClient
+ * @param Request $request
+ * @return Response
+ */
+ public function sync(Horde_Imap_Client_Base $imapClient, Request $request) {
+ $hordeSync = $imapClient->sync($request->getMailbox(), $request->getToken());
+
+ $newMessages = $this->messageMapper->findByIds($imapClient, $request->getMailbox(), $hordeSync->newmsgsuids->ids);
+ $changedMessages = $this->messageMapper->findByIds($imapClient, $request->getMailbox(), $hordeSync->flagsuids->ids);
+ $vanishedMessages = $hordeSync->vanisheduids->ids;
+
+ $newSyncToken = $imapClient->getSyncToken($request->getMailbox());
+ return new Response($newSyncToken, $newMessages, $changedMessages, $vanishedMessages);
+ }
+
+}
diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php
index f04022074d..906bae0bfd 100644
--- a/lib/Service/MailManager.php
+++ b/lib/Service/MailManager.php
@@ -1,5 +1,6 @@
*
@@ -24,7 +25,12 @@
use OCA\Mail\Account;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\Folder;
-use OCA\Mail\Service\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\IMAP\Sync\Request;
+use OCA\Mail\IMAP\Sync\Response;
+use OCA\Mail\IMAP\Sync\Synchronizer;
+use OCA\Mail\Service\FolderMapper;
+use OCA\Mail\Service\FolderNameTranslator;
class MailManager implements IMailManager {
@@ -37,16 +43,21 @@ class MailManager implements IMailManager {
/** @var FolderNameTranslator */
private $folderNameTranslator;
+ /** @var Synchronizer */
+ private $synchronizer;
+
/**
* @param IMAPClientFactory $imapClientFactory
* @param FolderMapper $folderMapper
- * @param FolderNameTranslator
+ * @param FolderNameTranslator $folderNameTranslator
+ * @param Synchronizer $synchronizer
*/
- public function __construct(IMAPClientFactory $imapClientFactory,
- FolderMapper $folderMapper, FolderNameTranslator $folderNameTranslator) {
+ public function __construct(IMAPClientFactory $imapClientFactory, FolderMapper $folderMapper,
+ FolderNameTranslator $folderNameTranslator, Synchronizer $synchronizer) {
$this->imapClientFactory = $imapClientFactory;
$this->folderMapper = $folderMapper;
$this->folderNameTranslator = $folderNameTranslator;
+ $this->synchronizer = $synchronizer;
}
/**
@@ -64,4 +75,15 @@ public function getFolders(Account $account) {
return $this->folderMapper->buildFolderHierarchy($folders);
}
+ /**
+ * @param Account $account
+ * @param Request $syncRequest
+ * @return Response
+ */
+ public function syncMessages(Account $account, Request $syncRequest) {
+ $client = $this->imapClientFactory->getClient($account);
+
+ return $this->synchronizer->sync($client, $syncRequest);
+ }
+
}
diff --git a/tests/IMAP/Sync/RequestTest.php b/tests/IMAP/Sync/RequestTest.php
new file mode 100644
index 0000000000..e54d5703fa
--- /dev/null
+++ b/tests/IMAP/Sync/RequestTest.php
@@ -0,0 +1,55 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\Tests\IMAP\Sync;
+
+use OCA\Mail\IMAP\Sync\Request;
+use PHPUnit_Framework_TestCase;
+
+class RequestTest extends PHPUnit_Framework_TestCase {
+
+ /** @var string */
+ private $mailbox;
+
+ /** @var string */
+ private $syncToken;
+
+ /** @var Request */
+ private $request;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->mailbox = 'inbox';
+ $this->syncToken = 'ab123';
+
+ $this->request = new Request($this->mailbox, $this->syncToken);
+ }
+
+ public function testGetMailbox() {
+ $this->assertEquals($this->mailbox, $this->request->getMailbox());
+ }
+
+ public function testGetSyncToken() {
+ $this->assertEquals($this->syncToken, $this->request->getToken());
+ }
+
+}
diff --git a/tests/IMAP/Sync/ResponseTest.php b/tests/IMAP/Sync/ResponseTest.php
new file mode 100644
index 0000000000..d9b4741ce9
--- /dev/null
+++ b/tests/IMAP/Sync/ResponseTest.php
@@ -0,0 +1,47 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\Tests\IMAP\Sync;
+
+use OCA\Mail\IMAP\Sync\Response;
+use PHPUnit_Framework_TestCase;
+
+class ResponseTest extends PHPUnit_Framework_TestCase {
+
+ public function testJsonSerialize() {
+ $newMessages = [];
+ $changedMessages = [];
+ $vanishedMessages = [];
+ $syncToken = 'bc4564';
+ $response = new Response($syncToken, $newMessages, $changedMessages, $vanishedMessages);
+ $expected = [
+ 'newMessages' => [],
+ 'changedMessages' => [],
+ 'vanishedMessages' => [],
+ 'token' => $syncToken,
+ ];
+
+ $json = $response->jsonSerialize();
+
+ $this->assertEquals($expected, $json);
+ }
+
+}
diff --git a/tests/IMAP/Sync/SynchronizerTest.php b/tests/IMAP/Sync/SynchronizerTest.php
new file mode 100644
index 0000000000..a6381c0b15
--- /dev/null
+++ b/tests/IMAP/Sync/SynchronizerTest.php
@@ -0,0 +1,91 @@
+
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\Mail\Tests\IMAP\Sync;
+
+use Horde_Imap_Client_Base;
+use Horde_Imap_Client_Data_Sync;
+use Horde_Imap_Client_Ids;
+use OCA\Mail\IMAP\MessageMapper;
+use OCA\Mail\IMAP\Sync\Request;
+use OCA\Mail\IMAP\Sync\Response;
+use OCA\Mail\IMAP\Sync\Synchronizer;
+use PHPUnit_Framework_MockObject_MockObject;
+use PHPUnit_Framework_TestCase;
+
+class SynchronizerTest extends PHPUnit_Framework_TestCase {
+
+ /** @var MessageMapper|PHPUnit_Framework_MockObject_MockObject */
+ private $messageMapper;
+
+ /** @var Synchronizer */
+ private $synchronizer;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->messageMapper = $this->createMock(MessageMapper::class);
+
+ $this->synchronizer = new Synchronizer($this->messageMapper);
+ }
+
+ private function getHordeMessageIdMock(array $ids) {
+ $hordeIds = $this->createMock(Horde_Imap_Client_Ids::class);
+ $hordeIds->ids = $ids;
+ return $hordeIds;
+ }
+
+ public function testSync() {
+ $imapClient = $this->createMock(Horde_Imap_Client_Base::class);
+ $request = $this->createMock(Request::class);
+ $request->expects($this->any())
+ ->method('getMailbox')
+ ->willReturn('inbox');
+ $request->expects($this->once())
+ ->method('getToken')
+ ->willReturn('123456');
+ $hordeSync = $this->createMock(Horde_Imap_Client_Data_Sync::class);
+ $imapClient->expects($this->once())
+ ->method('sync')
+ ->with($this->equalTo('inbox'), $this->equalTo('123456'))
+ ->willReturn($hordeSync);
+ $newMessages = [];
+ $changedMessages = [];
+ $vanishedMessages = [4, 5];
+ $hordeSync->newmsgsuids = $this->getHordeMessageIdMock($newMessages);
+ $hordeSync->flagsuids = $this->getHordeMessageIdMock($changedMessages);
+ $hordeSync->vanisheduids = $this->getHordeMessageIdMock($vanishedMessages);
+ $this->messageMapper->expects($this->exactly(2))
+ ->method('findByIds')
+ ->with($imapClient, $this->equalTo('inbox'), $this->equalTo([]))
+ ->willReturn([]);
+ $imapClient->expects($this->once())
+ ->method('getSyncToken')
+ ->with($this->equalTo('inbox'))
+ ->willReturn('54321');
+ $expected = new Response('54321', $newMessages, $changedMessages, $vanishedMessages);
+
+ $response = $this->synchronizer->sync($imapClient, $request);
+
+ $this->assertEquals($expected, $response);
+ }
+
+}