refactor: Consolidate account classes
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Родитель
b1c5609ec9
Коммит
880e2f8beb
|
@ -9,12 +9,9 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Service\Quota;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
class Account implements JsonSerializable {
|
||||
class Account {
|
||||
public function __construct(private MailAccount $account) {
|
||||
}
|
||||
|
||||
|
@ -22,58 +19,4 @@ class Account implements JsonSerializable {
|
|||
return $this->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId() {
|
||||
return $this->account->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->account->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEMailAddress() {
|
||||
return $this->account->getEmail();
|
||||
}
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
return $this->account->toJson();
|
||||
}
|
||||
|
||||
public function getEmail(): string {
|
||||
return $this->account->getEmail();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserId() {
|
||||
return $this->account->getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the quota percentage
|
||||
* @param Quota $quota
|
||||
* @return void
|
||||
*/
|
||||
public function calculateAndSetQuotaPercentage(Quota $quota): void {
|
||||
if ($quota->getLimit() === 0) {
|
||||
$this->account->setQuotaPercentage(0);
|
||||
return;
|
||||
}
|
||||
$percentage = (int)round($quota->getUsage() / $quota->getLimit() * 100);
|
||||
$this->account->setQuotaPercentage($percentage);
|
||||
}
|
||||
|
||||
public function getQuotaPercentage(): ?int {
|
||||
return $this->account->getQuotaPercentage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\BackgroundJob;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccountMapper;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
|
||||
|
@ -65,27 +64,25 @@ class MigrateImportantJob extends QueuedJob {
|
|||
try {
|
||||
$mailAccount = $this->mailAccountMapper->findById($accountId);
|
||||
} catch (DoesNotExistException $e) {
|
||||
$this->logger->debug('Could not find account <' . $accountId . '>');
|
||||
$this->logger->debug('Could not find mailAccount <' . $accountId . '>');
|
||||
return;
|
||||
}
|
||||
|
||||
$account = new Account($mailAccount);
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
|
||||
$client = $this->imapClientFactory->getClient($mailAccount);
|
||||
try {
|
||||
if ($this->mailManager->isPermflagsEnabled($client, $account, $mailbox->getName()) === false) {
|
||||
if ($this->mailManager->isPermflagsEnabled($client, $mailAccount, $mailbox->getName()) === false) {
|
||||
$this->logger->debug('Permflags not enabled for <' . $accountId . '>');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->migration->migrateImportantOnImap($client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($client, $mailbox);
|
||||
} catch (ServiceException $e) {
|
||||
$this->logger->debug('Could not flag messages on IMAP for mailbox <' . $mailboxId . '>.');
|
||||
}
|
||||
|
||||
try {
|
||||
$this->migration->migrateImportantFromDb($client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($client, $mailbox);
|
||||
} catch (ServiceException $e) {
|
||||
$this->logger->debug('Could not flag messages from DB on IMAP for mailbox <' . $mailboxId . '>.');
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ class PreviewEnhancementProcessingJob extends TimedJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$account->getMailAccount()->canAuthenticateImap()) {
|
||||
if (!$account->canAuthenticateImap()) {
|
||||
$this->logger->info('Ignoring preprocessing job for provisioned account as athentication on IMAP not possible');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\BackgroundJob;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
|
@ -18,6 +17,7 @@ use OCP\BackgroundJob\TimedJob;
|
|||
use OCP\IUserManager;
|
||||
use OCP\Notification\IManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function round;
|
||||
use function sprintf;
|
||||
|
||||
class QuotaJob extends TimedJob {
|
||||
|
@ -54,7 +54,6 @@ class QuotaJob extends TimedJob {
|
|||
protected function run($argument): void {
|
||||
$accountId = (int)$argument['accountId'];
|
||||
try {
|
||||
/** @var Account $account */
|
||||
$account = $this->accountService->findById($accountId);
|
||||
} catch (DoesNotExistException $e) {
|
||||
$this->logger->debug('Could not find account <' . $accountId . '> removing from jobs');
|
||||
|
@ -62,7 +61,7 @@ class QuotaJob extends TimedJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!$account->getMailAccount()->canAuthenticateImap()) {
|
||||
if(!$account->canAuthenticateImap()) {
|
||||
$this->logger->debug('No authentication on IMAP possible, skipping quota job');
|
||||
return;
|
||||
}
|
||||
|
@ -82,9 +81,14 @@ class QuotaJob extends TimedJob {
|
|||
$this->logger->debug('Could not get quota information for account <' . $account->getEmail() . '>', ['app' => 'mail']);
|
||||
return;
|
||||
}
|
||||
$previous = $account->getMailAccount()->getQuotaPercentage();
|
||||
$account->calculateAndSetQuotaPercentage($quota);
|
||||
$this->accountService->update($account->getMailAccount());
|
||||
$previous = $account->getQuotaPercentage();
|
||||
if ($quota->getLimit() === 0) {
|
||||
$account->setQuotaPercentage(0);
|
||||
return;
|
||||
}
|
||||
$percentage = (int)round($quota->getUsage() / $quota->getLimit() * 100);
|
||||
$account->setQuotaPercentage($percentage);
|
||||
$this->accountService->update($account);
|
||||
$current = $account->getQuotaPercentage();
|
||||
|
||||
// Only notify if we've reached the rising edge
|
||||
|
|
|
@ -73,7 +73,7 @@ class SyncJob extends TimedJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!$account->getMailAccount()->canAuthenticateImap()) {
|
||||
if(!$account->canAuthenticateImap()) {
|
||||
$this->logger->debug('No authentication on IMAP possible, skipping background sync job');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class TrainImportanceClassifierJob extends TimedJob {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!$account->getMailAccount()->canAuthenticateImap()) {
|
||||
if(!$account->canAuthenticateImap()) {
|
||||
$this->logger->debug('Cron importance classifier training not possible: no authentication on IMAP possible');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\BackgroundJob;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailAccountMapper;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper;
|
||||
|
@ -46,9 +46,7 @@ class TrashRetentionJob extends TimedJob {
|
|||
public function run($argument) {
|
||||
$accounts = $this->accountMapper->getAllAccounts();
|
||||
foreach ($accounts as $account) {
|
||||
$account = new Account($account);
|
||||
|
||||
$retentionDays = $account->getMailAccount()->getTrashRetentionDays();
|
||||
$retentionDays = $account->getTrashRetentionDays();
|
||||
if ($retentionDays === null || $retentionDays <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -62,7 +60,7 @@ class TrashRetentionJob extends TimedJob {
|
|||
'exception' => $e,
|
||||
'userId' => $account->getUserId(),
|
||||
'accountId' => $account->getId(),
|
||||
'trashMailboxId' => $account->getMailAccount()->getTrashMailboxId(),
|
||||
'trashMailboxId' => $account->getTrashMailboxId(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +71,8 @@ class TrashRetentionJob extends TimedJob {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
private function cleanTrash(Account $account, int $retentionSeconds): void {
|
||||
$trashMailboxId = $account->getMailAccount()->getTrashMailboxId();
|
||||
private function cleanTrash(MailAccount $account, int $retentionSeconds): void {
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
if ($trashMailboxId === null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Command;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
|
@ -53,7 +53,7 @@ class DeleteAccount extends Command {
|
|||
}
|
||||
$output->writeLn('<info>Found account with email: ' . $account->getEmail() . '</info>');
|
||||
|
||||
if (!is_null($account->getMailAccount()->getProvisioningId())) {
|
||||
if (!is_null($account->getProvisioningId())) {
|
||||
$output->writeLn('<error>This is a provisioned account which can not be deleted from CLI. Use the Provisioning UI instead.</error>');
|
||||
return 2;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class DeleteAccount extends Command {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private function delete(Account $account, OutputInterface $output): void {
|
||||
private function delete(MailAccount $account, OutputInterface $output): void {
|
||||
$id = $account->getId();
|
||||
try {
|
||||
$this->accountService->deleteByAccountId($account->getId());
|
||||
|
|
|
@ -61,7 +61,7 @@ class DiagnoseAccount extends Command {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ($account->getMailAccount()->getInboundPassword() === null) {
|
||||
if ($account->getInboundPassword() === null) {
|
||||
$output->writeln('<error>No IMAP passwort set. The user might have to log into their account to set it.</error>');
|
||||
}
|
||||
$imapClient = $this->clientFactory->getClient($account);
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Command;
|
||||
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\Security\ICrypto;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ExportAccount extends Command {
|
||||
public const ARGUMENT_USER_ID = 'user-id';
|
||||
public const ARGUMENT_OUTPUT_FORMAT = 'output';
|
||||
|
||||
private AccountService $accountService;
|
||||
private ICrypto $crypto;
|
||||
|
||||
public function __construct(AccountService $service, ICrypto $crypto) {
|
||||
parent::__construct();
|
||||
|
||||
$this->accountService = $service;
|
||||
$this->crypto = $crypto;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function configure() {
|
||||
$this->setName('mail:account:export');
|
||||
$this->setDescription('Exports a user\'s IMAP account(s)');
|
||||
$this->addArgument(self::ARGUMENT_USER_ID, InputArgument::REQUIRED);
|
||||
$this->addOption(self::ARGUMENT_OUTPUT_FORMAT, '', InputOption::VALUE_OPTIONAL);
|
||||
}
|
||||
|
||||
private function getAccountsData($accounts) {
|
||||
$accountsData = [];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$accountsData[] = [
|
||||
'id' => $account->getId(),
|
||||
'email' => $account->getEmail(),
|
||||
'name' => $account->getName(),
|
||||
'provision' => [
|
||||
'status' => $account->getMailAccount()->getProvisioningId() ? 'set' : 'none',
|
||||
'id' => $account->getMailAccount()->getProvisioningId() ?: 'N/A'
|
||||
],
|
||||
'imap' => [
|
||||
'user' => $account->getMailAccount()->getInboundUser(),
|
||||
'host' => $account->getMailAccount()->getInboundHost(),
|
||||
'port' => $account->getMailAccount()->getInboundPort(),
|
||||
'security' => $account->getMailAccount()->getInboundSslMode()
|
||||
],
|
||||
'smtp' => [
|
||||
'user' => $account->getMailAccount()->getOutboundUser(),
|
||||
'host' => $account->getMailAccount()->getOutboundHost(),
|
||||
'port' => $account->getMailAccount()->getOutboundPort(),
|
||||
'security' => $account->getMailAccount()->getOutboundSslMode()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $accountsData;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$userId = $input->getArgument(self::ARGUMENT_USER_ID);
|
||||
|
||||
$accounts = $this->accountService->findByUserId($userId);
|
||||
|
||||
if ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts)));
|
||||
} elseif ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json_pretty') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts), JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
foreach ($accounts as $account) {
|
||||
$output->writeln('<info>Account ' . $account->getId() . ':</info>');
|
||||
$output->writeln('- E-Mail: ' . $account->getEmail());
|
||||
$output->writeln('- Name: ' . $account->getName());
|
||||
$output->writeln('- Provision: ' . ($account->getMailAccount()->getProvisioningId() ? 'set' : 'none'). ' ID: ' . ($account->getMailAccount()->getProvisioningId() ? $account->getMailAccount()->getProvisioningId():'N/A'));
|
||||
$output->writeln('- IMAP user: ' . $account->getMailAccount()->getInboundUser());
|
||||
$output->writeln('- IMAP host: ' . $account->getMailAccount()->getInboundHost() . ':' . $account->getMailAccount()->getInboundPort() . ', security: ' . $account->getMailAccount()->getInboundSslMode());
|
||||
$output->writeln('- SMTP user: ' . $account->getMailAccount()->getOutboundUser());
|
||||
$output->writeln('- SMTP host: ' . $account->getMailAccount()->getOutboundHost() . ':' . $account->getMailAccount()->getOutboundPort() . ', security: ' . $account->getMailAccount()->getOutboundSslMode());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Command;
|
||||
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\Security\ICrypto;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ExportAccount extends Command {
|
||||
public const ARGUMENT_USER_ID = 'user-id';
|
||||
public const ARGUMENT_OUTPUT_FORMAT = 'output';
|
||||
|
||||
private AccountService $accountService;
|
||||
private ICrypto $crypto;
|
||||
|
||||
public function __construct(AccountService $service, ICrypto $crypto) {
|
||||
parent::__construct();
|
||||
|
||||
$this->accountService = $service;
|
||||
$this->crypto = $crypto;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function configure() {
|
||||
$this->setName('mail:account:export');
|
||||
$this->setDescription('Exports a user\'s IMAP account(s)');
|
||||
$this->addArgument(self::ARGUMENT_USER_ID, InputArgument::REQUIRED);
|
||||
$this->addOption(self::ARGUMENT_OUTPUT_FORMAT, '', InputOption::VALUE_OPTIONAL);
|
||||
}
|
||||
|
||||
private function getAccountsData($accounts) {
|
||||
$accountsData = [];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$accountsData[] = [
|
||||
'id' => $account->getId(),
|
||||
'email' => $account->getEmail(),
|
||||
'name' => $account->getName(),
|
||||
'provision' => [
|
||||
'status' => $account->getProvisioningId() ? 'set' : 'none',
|
||||
'id' => $account->getProvisioningId() ?: 'N/A'
|
||||
],
|
||||
'imap' => [
|
||||
'user' => $account->getInboundUser(),
|
||||
'host' => $account->getInboundHost(),
|
||||
'port' => $account->getInboundPort(),
|
||||
'security' => $account->getInboundSslMode()
|
||||
],
|
||||
'smtp' => [
|
||||
'user' => $account->getOutboundUser(),
|
||||
'host' => $account->getOutboundHost(),
|
||||
'port' => $account->getOutboundPort(),
|
||||
'security' => $account->getOutboundSslMode()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $accountsData;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$userId = $input->getArgument(self::ARGUMENT_USER_ID);
|
||||
|
||||
$accounts = $this->accountService->findByUserId($userId);
|
||||
|
||||
if ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts)));
|
||||
} elseif ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json_pretty') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts), JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
foreach ($accounts as $account) {
|
||||
$output->writeln('<info>Account ' . $account->getId() . ':</info>');
|
||||
$output->writeln('- E-Mail: ' . $account->getEmail());
|
||||
$output->writeln('- Name: ' . $account->getName());
|
||||
$output->writeln('- Provision: ' . ($account->getProvisioningId() ? 'set' : 'none'). ' ID: ' . ($account->getProvisioningId() ? $account->getProvisioningId():'N/A'));
|
||||
$output->writeln('- IMAP user: ' . $account->getInboundUser());
|
||||
$output->writeln('- IMAP host: ' . $account->getInboundHost() . ':' . $account->getInboundPort() . ', security: ' . $account->getInboundSslMode());
|
||||
$output->writeln('- SMTP user: ' . $account->getOutboundUser());
|
||||
$output->writeln('- SMTP host: ' . $account->getOutboundHost() . ':' . $account->getOutboundPort() . ', security: ' . $account->getOutboundSslMode());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Command;
|
||||
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\Security\ICrypto;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ExportAccount extends Command {
|
||||
public const ARGUMENT_USER_ID = 'user-id';
|
||||
public const ARGUMENT_OUTPUT_FORMAT = 'output';
|
||||
|
||||
private AccountService $accountService;
|
||||
private ICrypto $crypto;
|
||||
|
||||
public function __construct(AccountService $service, ICrypto $crypto) {
|
||||
parent::__construct();
|
||||
|
||||
$this->accountService = $service;
|
||||
$this->crypto = $crypto;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function configure() {
|
||||
$this->setName('mail:account:export');
|
||||
$this->setDescription('Exports a user\'s IMAP account(s)');
|
||||
$this->addArgument(self::ARGUMENT_USER_ID, InputArgument::REQUIRED);
|
||||
$this->addOption(self::ARGUMENT_OUTPUT_FORMAT, '', InputOption::VALUE_OPTIONAL);
|
||||
}
|
||||
|
||||
private function getAccountsData($accounts) {
|
||||
$accountsData = [];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$accountsData[] = [
|
||||
'id' => $account->getId(),
|
||||
'email' => $account->getEmail(),
|
||||
'name' => $account->getName(),
|
||||
'provision' => [
|
||||
'status' => $account->getProvisioningId() ? 'set' : 'none',
|
||||
'id' => $account->getProvisioningId() ?: 'N/A'
|
||||
],
|
||||
'imap' => [
|
||||
'user' => $account->getInboundUser(),
|
||||
'host' => $account->getInboundHost(),
|
||||
'port' => $account->getInboundPort(),
|
||||
'security' => $account->getInboundSslMode()
|
||||
],
|
||||
'smtp' => [
|
||||
'user' => $account->getOutboundUser(),
|
||||
'host' => $account->getOutboundHost(),
|
||||
'port' => $account->getOutboundPort(),
|
||||
'security' => $account->getOutboundSslMode()
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $accountsData;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||
$userId = $input->getArgument(self::ARGUMENT_USER_ID);
|
||||
|
||||
$accounts = $this->accountService->findByUserId($userId);
|
||||
|
||||
if ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts)));
|
||||
} elseif ($input->getOption(self::ARGUMENT_OUTPUT_FORMAT) === 'json_pretty') {
|
||||
$output->writeln(json_encode($this->getAccountsData($accounts), JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
foreach ($accounts as $account) {
|
||||
<<<<<<< Updated upstream
|
||||
$output->writeln('<info>Account ' . $account->getId() . ':</info>');
|
||||
$output->writeln('- E-Mail: ' . $account->getEmail());
|
||||
$output->writeln('- Name: ' . $account->getName());
|
||||
$output->writeln('- Provision: ' . ($account->getProvisioningId() ? 'set' : 'none'). ' ID: ' . ($account->getProvisioningId() ? $account->getProvisioningId():'N/A'));
|
||||
=======
|
||||
$output->writeln('<info>Account ' . $account->getId() . ':</info>');
|
||||
$output->writeln('- E-Mail: ' . $account->getEmail());
|
||||
$output->writeln('- Name: ' . $account->getName());
|
||||
$output->writeln('- Provision: ' . ($account->getProvisioningId() ? 'set' : 'none'). ' ID: ' . ($account->getProvisioningId() ?: 'N/A'));
|
||||
>>>>>>> Stashed changes
|
||||
$output->writeln('- IMAP user: ' . $account->getInboundUser());
|
||||
$output->writeln('- IMAP host: ' . $account->getInboundHost() . ':' . $account->getInboundPort() . ', security: ' . $account->getInboundSslMode());
|
||||
$output->writeln('- SMTP user: ' . $account->getOutboundUser());
|
||||
$output->writeln('- SMTP host: ' . $account->getOutboundHost() . ':' . $account->getOutboundPort() . ', security: ' . $account->getOutboundSslMode());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Command;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\IncompleteSyncException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\IMAP\MailboxSync;
|
||||
|
@ -77,7 +77,7 @@ class SyncAccount extends Command {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private function sync(Account $account, bool $force, OutputInterface $output): void {
|
||||
private function sync(MailAccount $account, bool $force, OutputInterface $output): void {
|
||||
$consoleLogger = new ConsoleLoggerDecorator(
|
||||
$this->logger,
|
||||
$output
|
||||
|
|
|
@ -9,10 +9,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Contracts;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
|
||||
interface IDkimService {
|
||||
public function validate(Account $account, Mailbox $mailbox, int $id): bool;
|
||||
public function getCached(Account $account, Mailbox $mailbox, int $id): ?bool;
|
||||
public function validate(MailAccount $account, Mailbox $mailbox, int $id): bool;
|
||||
public function getCached(MailAccount $account, Mailbox $mailbox, int $id): ?bool;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Contracts;
|
||||
|
||||
use Horde_Imap_Client_Socket;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Attachment;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\Tag;
|
||||
|
@ -34,23 +34,19 @@ interface IMailManager {
|
|||
public function getMailbox(string $uid, int $id): Mailbox;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Mailbox[]
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getMailboxes(Account $account): array;
|
||||
public function getMailboxes(MailAccount $account): array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $name
|
||||
*
|
||||
* @return Mailbox
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function createMailbox(Account $account, string $name): Mailbox;
|
||||
public function createMailbox(MailAccount $account, string $name): Mailbox;
|
||||
|
||||
/**
|
||||
* @param Mailbox $mailbox
|
||||
|
@ -72,7 +68,6 @@ interface IMailManager {
|
|||
|
||||
/**
|
||||
* @param Horde_Imap_Client_Socket $client
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @param int $uid
|
||||
*
|
||||
|
@ -81,13 +76,12 @@ interface IMailManager {
|
|||
* @throws ServiceException
|
||||
*/
|
||||
public function getSource(Horde_Imap_Client_Socket $client,
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
string $mailbox,
|
||||
int $uid): ?string;
|
||||
|
||||
/**
|
||||
* @param Horde_Imap_Client_Socket $client
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int $uid
|
||||
* @param bool $loadBody
|
||||
|
@ -97,47 +91,42 @@ interface IMailManager {
|
|||
* @throws ServiceException
|
||||
*/
|
||||
public function getImapMessage(Horde_Imap_Client_Socket $client,
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $uid,
|
||||
bool $loadBody = false): IMAPMessage;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $threadRootId thread root id
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function getThread(Account $account, string $threadRootId): array;
|
||||
public function getThread(MailAccount $account, string $threadRootId): array;
|
||||
|
||||
/**
|
||||
* @param Account $sourceAccount
|
||||
* @param string $sourceFolderId
|
||||
* @param int $uid
|
||||
* @param Account $destinationAccount
|
||||
* @param string $destFolderId
|
||||
* @return int the new UID
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function moveMessage(Account $sourceAccount,
|
||||
public function moveMessage(MailAccount $sourceAccount,
|
||||
string $sourceFolderId,
|
||||
int $uid,
|
||||
Account $destinationAccount,
|
||||
MailAccount $destinationAccount,
|
||||
string $destFolderId): int;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $mailboxId
|
||||
* @param int $messageUid
|
||||
*
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function deleteMessage(Account $account, string $mailboxId, int $messageUid): void;
|
||||
public function deleteMessage(MailAccount $account, string $mailboxId, int $messageUid): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int $messageUid
|
||||
* @param Horde_Imap_Client_Socket $client The caller is responsible to close the client.
|
||||
|
@ -147,7 +136,7 @@ interface IMailManager {
|
|||
* @throws TrashMailboxNotSetException If no trash folder is configured for the given account.
|
||||
*/
|
||||
public function deleteMessageWithClient(
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $messageUid,
|
||||
Horde_Imap_Client_Socket $client,
|
||||
|
@ -156,13 +145,11 @@ interface IMailManager {
|
|||
/**
|
||||
* Mark all messages of a folder as read
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*/
|
||||
public function markFolderAsRead(Account $account, Mailbox $mailbox): void;
|
||||
public function markFolderAsRead(MailAccount $account, Mailbox $mailbox): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @param int $uid
|
||||
* @param string $flag
|
||||
|
@ -171,10 +158,9 @@ interface IMailManager {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function flagMessage(Account $account, string $mailbox, int $uid, string $flag, bool $value): void;
|
||||
public function flagMessage(MailAccount $account, string $mailbox, int $uid, string $flag, bool $value): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @param Message $message
|
||||
* @param Tag $tag
|
||||
|
@ -183,19 +169,16 @@ interface IMailManager {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function tagMessage(Account $account, string $mailbox, Message $message, Tag $tag, bool $value): void;
|
||||
public function tagMessage(MailAccount $account, string $mailbox, Message $message, Tag $tag, bool $value): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Quota|null
|
||||
*/
|
||||
public function getQuota(Account $account): ?Quota;
|
||||
public function getQuota(MailAccount $account): ?Quota;
|
||||
|
||||
/**
|
||||
* Rename a mailbox and get the new (cached) version
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param string $name
|
||||
*
|
||||
|
@ -203,26 +186,23 @@ interface IMailManager {
|
|||
*
|
||||
* @throw ServiceException
|
||||
*/
|
||||
public function renameMailbox(Account $account, Mailbox $mailbox, string $name): Mailbox;
|
||||
public function renameMailbox(MailAccount $account, Mailbox $mailbox, string $name): Mailbox;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function deleteMailbox(Account $account, Mailbox $mailbox): void;
|
||||
public function deleteMailbox(MailAccount $account, Mailbox $mailbox): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearMailbox(Account $account, Mailbox $mailbox): void;
|
||||
public function clearMailbox(MailAccount $account, Mailbox $mailbox): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param bool $subscribed
|
||||
*
|
||||
|
@ -230,7 +210,7 @@ interface IMailManager {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function updateSubscription(Account $account,
|
||||
public function updateSubscription(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
bool $subscribed): Mailbox;
|
||||
|
||||
|
@ -246,21 +226,19 @@ interface IMailManager {
|
|||
bool $syncInBackground): Mailbox;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message $message
|
||||
* @return Attachment[]
|
||||
*/
|
||||
public function getMailAttachments(Account $account, Mailbox $mailbox, Message $message) : array;
|
||||
public function getMailAttachments(MailAccount $account, Mailbox $mailbox, Message $message) : array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message $message
|
||||
* @param string $attachmentId
|
||||
* @return Attachment
|
||||
*/
|
||||
public function getMailAttachment(Account $account, Mailbox $mailbox, Message $message, string $attachmentId): Attachment;
|
||||
public function getMailAttachment(MailAccount $account, Mailbox $mailbox, Message $message, string $attachmentId): Attachment;
|
||||
|
||||
/**
|
||||
* @param string $imapLabel
|
||||
|
@ -272,12 +250,8 @@ interface IMailManager {
|
|||
|
||||
/**
|
||||
* Check IMAP server for support for PERMANENTFLAGS
|
||||
*
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPermflagsEnabled(Horde_Imap_Client_Socket $client, Account $account, string $mailbox): bool;
|
||||
public function isPermflagsEnabled(Horde_Imap_Client_Socket $client, MailAccount $account, string $mailbox): bool;
|
||||
|
||||
/**
|
||||
* Create a mail tag
|
||||
|
@ -314,32 +288,29 @@ interface IMailManager {
|
|||
*
|
||||
* @throws ClientException
|
||||
*/
|
||||
public function deleteTagForAccount(int $id, string $userId, Tag $tag, Account $account): void;
|
||||
public function deleteTagForAccount(int $id, string $userId, Tag $tag, MailAccount $account): void;
|
||||
|
||||
/**
|
||||
* @param Account $srcAccount
|
||||
* @param Mailbox $srcMailbox
|
||||
* @param Account $dstAccount
|
||||
* @param Mailbox $dstMailbox
|
||||
* @param string $threadRootId
|
||||
* @return int[] the new UIDs
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function moveThread(Account $srcAccount, Mailbox $srcMailbox, Account $dstAccount, Mailbox $dstMailbox, string $threadRootId): array;
|
||||
public function moveThread(MailAccount $srcAccount, Mailbox $srcMailbox, MailAccount $dstAccount, Mailbox $dstMailbox, string $threadRootId): array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param string $threadRootId
|
||||
* @return void
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function deleteThread(Account $account, Mailbox $mailbox, string $threadRootId): void;
|
||||
public function deleteThread(MailAccount $account, Mailbox $mailbox, string $threadRootId): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $messageId
|
||||
* @return Message[]
|
||||
*/
|
||||
public function getByMessageId(Account $account, string $messageId): array;
|
||||
public function getByMessageId(MailAccount $account, string $messageId): array;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Contracts;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
|
@ -25,12 +25,11 @@ interface IMailSearch {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function findMessage(Account $account,
|
||||
public function findMessage(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
Message $message): Message;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param string $sortOrder
|
||||
* @param string|null $filter
|
||||
|
@ -42,7 +41,7 @@ interface IMailSearch {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function findMessages(Account $account,
|
||||
public function findMessages(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
string $sortOrder,
|
||||
?string $filter,
|
||||
|
|
|
@ -9,8 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Contracts;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
|
@ -22,21 +22,20 @@ interface IMailTransmission {
|
|||
/**
|
||||
* Send a new message or reply to an existing one
|
||||
*
|
||||
* @param Account $account
|
||||
* @param MailAccount $account
|
||||
* @param LocalMessage $localMessage
|
||||
* @throws SentMailboxNotSetException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function sendMessage(Account $account, LocalMessage $localMessage): void;
|
||||
public function sendMessage(MailAccount $account, LocalMessage $localMessage): void;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param LocalMessage $message
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
* @return void
|
||||
*/
|
||||
public function saveLocalDraft(Account $account, LocalMessage $message): void;
|
||||
public function saveLocalDraft(MailAccount $account, LocalMessage $message): void;
|
||||
|
||||
/**
|
||||
* Save a message draft
|
||||
|
@ -54,10 +53,9 @@ interface IMailTransmission {
|
|||
/**
|
||||
* Send a mdn message
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message $message the message to send an mdn for
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function sendMdn(Account $account, Mailbox $mailbox, Message $message): void;
|
||||
public function sendMdn(MailAccount $account, Mailbox $mailbox, Message $message): void;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ use OCP\IL10N;
|
|||
use OCP\IRequest;
|
||||
use OCP\Security\IRemoteHostValidator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
class AccountsController extends Controller {
|
||||
|
@ -92,7 +93,7 @@ class AccountsController extends Controller {
|
|||
|
||||
$json = [];
|
||||
foreach ($mailAccounts as $mailAccount) {
|
||||
$conf = $mailAccount->jsonSerialize();
|
||||
$conf = $mailAccount->toJson();
|
||||
$conf['aliases'] = $this->aliasesService->findAll($conf['accountId'], $this->currentUserId);
|
||||
$json[] = $conf;
|
||||
}
|
||||
|
@ -231,7 +232,7 @@ class AccountsController extends Controller {
|
|||
?bool $searchBody = null): JSONResponse {
|
||||
$account = $this->accountService->find($this->currentUserId, $id);
|
||||
|
||||
$dbAccount = $account->getMailAccount();
|
||||
$dbAccount = $account;
|
||||
|
||||
if ($draftsMailboxId !== null) {
|
||||
$this->mailManager->getMailbox($this->currentUserId, $draftsMailboxId);
|
||||
|
@ -483,7 +484,7 @@ class AccountsController extends Controller {
|
|||
* @throws ClientException
|
||||
*/
|
||||
public function updateSmimeCertificate(int $id, ?int $smimeCertificateId = null) {
|
||||
$account = $this->accountService->find($this->currentUserId, $id)->getMailAccount();
|
||||
$account = $this->accountService->find($this->currentUserId, $id);
|
||||
$account->setSmimeCertificateId($smimeCertificateId);
|
||||
$this->accountService->update($account);
|
||||
return MailJsonResponse::success();
|
||||
|
|
|
@ -142,7 +142,7 @@ class GoogleIntegrationController extends Controller {
|
|||
$account,
|
||||
$code,
|
||||
);
|
||||
$this->accountService->update($updated->getMailAccount());
|
||||
$this->accountService->update($updated);
|
||||
try {
|
||||
$this->mailboxSync->sync($account, $this->logger);
|
||||
} catch (ServiceException $e) {
|
||||
|
|
|
@ -140,7 +140,7 @@ class MicrosoftIntegrationController extends Controller {
|
|||
$account,
|
||||
$code,
|
||||
);
|
||||
$this->accountService->update($updated->getMailAccount());
|
||||
$this->accountService->update($updated);
|
||||
|
||||
return new StandaloneTemplateResponse(
|
||||
Application::APP_ID,
|
||||
|
|
|
@ -53,7 +53,7 @@ class OutOfOfficeController extends Controller {
|
|||
return JsonResponse::fail([], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
$state = $this->outOfOfficeService->parseState($account->getMailAccount());
|
||||
$state = $this->outOfOfficeService->parseState($account);
|
||||
return JsonResponse::success($state);
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ class OutOfOfficeController extends Controller {
|
|||
return JsonResponse::fail([], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
$mailAccount = $account->getMailAccount();
|
||||
$mailAccount = $account;
|
||||
if (!$mailAccount->getOutOfOfficeFollowsSystem()) {
|
||||
$mailAccount->setOutOfOfficeFollowsSystem(true);
|
||||
$this->accountService->update($mailAccount);
|
||||
|
@ -112,7 +112,7 @@ class OutOfOfficeController extends Controller {
|
|||
throw new ServiceException('Missing start date');
|
||||
}
|
||||
|
||||
$mailAccount = $account->getMailAccount();
|
||||
$mailAccount = $account;
|
||||
if ($mailAccount->getOutOfOfficeFollowsSystem()) {
|
||||
$mailAccount->setOutOfOfficeFollowsSystem(false);
|
||||
$this->accountService->update($mailAccount);
|
||||
|
|
|
@ -45,6 +45,7 @@ use OCP\User\IAvailabilityCoordinator;
|
|||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReturnTypeWillChange;
|
||||
use Throwable;
|
||||
use function class_exists;
|
||||
use function http_build_query;
|
||||
|
@ -149,7 +150,7 @@ class PageController extends Controller {
|
|||
$mailAccounts = $this->accountService->findByUserId($this->currentUserId);
|
||||
$accountsJson = [];
|
||||
foreach ($mailAccounts as $mailAccount) {
|
||||
$json = $mailAccount->jsonSerialize();
|
||||
$json = $mailAccount->toJson();
|
||||
$json['aliases'] = $this->aliasesService->findAll($mailAccount->getId(),
|
||||
$this->currentUserId);
|
||||
try {
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Db;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Exception\MailboxLockedException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
|
@ -36,11 +35,9 @@ class MailboxMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Mailbox[]
|
||||
*/
|
||||
public function findAll(Account $account): array {
|
||||
public function findAll(MailAccount $account): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$select = $qb->select('*')
|
||||
|
@ -69,7 +66,7 @@ class MailboxMapper extends QBMapper {
|
|||
* @throws DoesNotExistException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function find(Account $account, string $name): Mailbox {
|
||||
public function find(MailAccount $account, string $name): Mailbox {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$select = $qb->select('*')
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Db;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Address;
|
||||
use OCA\Mail\AddressList;
|
||||
use OCA\Mail\Contracts\IMailSearch;
|
||||
|
@ -179,11 +178,9 @@ class MessageMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return DatabaseMessage[]
|
||||
*/
|
||||
public function findThreadingData(Account $account): array {
|
||||
public function findThreadingData(MailAccount $account): array {
|
||||
$mailboxesQuery = $this->db->getQueryBuilder();
|
||||
$messagesQuery = $this->db->getQueryBuilder();
|
||||
|
||||
|
@ -256,7 +253,7 @@ class MessageMapper extends QBMapper {
|
|||
* @param Message ...$messages
|
||||
* @return void
|
||||
*/
|
||||
public function insertBulk(Account $account, Message ...$messages): void {
|
||||
public function insertBulk(MailAccount $account, Message ...$messages): void {
|
||||
$this->db->beginTransaction();
|
||||
try {
|
||||
$qb1 = $this->db->getQueryBuilder();
|
||||
|
@ -348,12 +345,11 @@ class MessageMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param bool $permflagsEnabled
|
||||
* @param Message[] $messages
|
||||
* @return Message[]
|
||||
*/
|
||||
public function updateBulk(Account $account, bool $permflagsEnabled, Message ...$messages): array {
|
||||
public function updateBulk(MailAccount $account, bool $permflagsEnabled, Message ...$messages): array {
|
||||
$this->db->beginTransaction();
|
||||
|
||||
$perf = $this->performanceLogger->start(
|
||||
|
@ -510,12 +506,11 @@ class MessageMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Message $message
|
||||
* @param Tag[][] $tags
|
||||
* @param PerformanceLoggerTask $perf
|
||||
*/
|
||||
private function updateTags(Account $account, Message $message, array $tags, PerformanceLoggerTask $perf): void {
|
||||
private function updateTags(MailAccount $account, Message $message, array $tags, PerformanceLoggerTask $perf): void {
|
||||
$imapTags = $message->getTags();
|
||||
$dbTags = $tags[$message->getMessageId()] ?? [];
|
||||
|
||||
|
@ -734,12 +729,11 @@ class MessageMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $threadRootId
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function findThread(Account $account, string $threadRootId): array {
|
||||
public function findThread(MailAccount $account, string $threadRootId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('messages.*')
|
||||
->from($this->getTableName(), 'messages')
|
||||
|
@ -754,12 +748,11 @@ class MessageMapper extends QBMapper {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $messageId
|
||||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function findByMessageId(Account $account, string $messageId): array {
|
||||
public function findByMessageId(MailAccount $account, string $messageId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('messages.*')
|
||||
->from($this->getTableName(), 'messages')
|
||||
|
@ -1411,7 +1404,7 @@ class MessageMapper extends QBMapper {
|
|||
/**
|
||||
* Currently unused
|
||||
*/
|
||||
public function findChanged(Account $account, Mailbox $mailbox, int $since): array {
|
||||
public function findChanged(MailAccount $account, Mailbox $mailbox, int $since): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$select = $qb
|
||||
|
|
|
@ -9,22 +9,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class BeforeImapClientCreated extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
private MailAccount $account;
|
||||
|
||||
public function __construct(Account $account) {
|
||||
public function __construct(MailAccount $account) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class BeforeMessageDeletedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
private MailAccount $account;
|
||||
|
||||
/** @var string */
|
||||
private $folderId;
|
||||
|
@ -22,14 +21,14 @@ class BeforeMessageDeletedEvent extends Event {
|
|||
/** @var int */
|
||||
private $messageId;
|
||||
|
||||
public function __construct(Account $account, string $mailbox, int $messageId) {
|
||||
public function __construct(MailAccount $account, string $mailbox, int $messageId) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->folderId = $mailbox;
|
||||
$this->messageId = $messageId;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
|
@ -17,20 +17,17 @@ use OCP\EventDispatcher\Event;
|
|||
* @psalm-immutable
|
||||
*/
|
||||
class DraftMessageCreatedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var Message */
|
||||
private $draft;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
Message $draft) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->draft = $draft;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,31 +9,27 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Model\NewMessageData;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class DraftSavedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var NewMessageData|null */
|
||||
private $newMessageData;
|
||||
|
||||
/** @var Message|null */
|
||||
private $draft;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
?NewMessageData $newMessageData = null,
|
||||
?Message $draft = null) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->newMessageData = $newMessageData;
|
||||
$this->draft = $draft;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,22 +9,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class MailboxesSynchronizedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
public function __construct(Account $account) {
|
||||
public function __construct(private MailAccount $account) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,30 +9,26 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class MessageDeletedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var Mailbox */
|
||||
private $mailbox;
|
||||
|
||||
/** @var int */
|
||||
private $messageId;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $messageId) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->mailbox = $mailbox;
|
||||
$this->messageId = $messageId;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class MessageFlaggedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var Mailbox */
|
||||
private $mailbox;
|
||||
|
||||
|
@ -29,20 +26,19 @@ class MessageFlaggedEvent extends Event {
|
|||
/** @var bool */
|
||||
private $set;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $uid,
|
||||
string $flag,
|
||||
bool $set) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->mailbox = $mailbox;
|
||||
$this->uid = $uid;
|
||||
$this->flag = $flag;
|
||||
$this->set = $set;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,24 +9,21 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class MessageSentEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
private LocalMessage $localMessage) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class NewMessagesSynchronized extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var Mailbox */
|
||||
private $mailbox;
|
||||
|
@ -25,20 +23,18 @@ class NewMessagesSynchronized extends Event {
|
|||
private $messages;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message[] $messages
|
||||
*/
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
array $messages) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->mailbox = $mailbox;
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
|
@ -17,20 +17,16 @@ use OCP\EventDispatcher\Event;
|
|||
* @psalm-immutable
|
||||
*/
|
||||
class OutboxMessageCreatedEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var Message */
|
||||
private $draft;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
Message $draft) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->draft = $draft;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,31 +9,27 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Model\NewMessageData;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
class SaveDraftEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var NewMessageData */
|
||||
private $newMessageData;
|
||||
|
||||
/** @var Message|null */
|
||||
private $draft;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
NewMessageData $newMessageData,
|
||||
?Message $draft) {
|
||||
parent::__construct();
|
||||
$this->account = $account;
|
||||
$this->newMessageData = $newMessageData;
|
||||
$this->draft = $draft;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Events;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class SynchronizationEvent extends Event {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
@ -23,17 +21,15 @@ class SynchronizationEvent extends Event {
|
|||
/** @var bool */
|
||||
private $rebuildThreads;
|
||||
|
||||
public function __construct(Account $account,
|
||||
public function __construct(private MailAccount $account,
|
||||
LoggerInterface $logger,
|
||||
bool $rebuildThreads) {
|
||||
parent::__construct();
|
||||
|
||||
$this->account = $account;
|
||||
$this->logger = $logger;
|
||||
$this->rebuildThreads = $rebuildThreads;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace OCA\Mail\IMAP;
|
|||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use Horde_Imap_Client_Socket;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\Folder;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
@ -40,14 +40,13 @@ class FolderMapper {
|
|||
];
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Horde_Imap_Client_Socket $client
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return Folder[]
|
||||
* @throws Horde_Imap_Client_Exception
|
||||
*/
|
||||
public function getFolders(Account $account, Horde_Imap_Client_Socket $client,
|
||||
public function getFolders(MailAccount $account, Horde_Imap_Client_Socket $client,
|
||||
string $pattern = '*'): array {
|
||||
$mailboxes = $client->listMailboxes($pattern, Horde_Imap_Client::MBOX_ALL_SUBSCRIBED, [
|
||||
'delimiter' => true,
|
||||
|
@ -75,7 +74,7 @@ class FolderMapper {
|
|||
}
|
||||
|
||||
public function createFolder(Horde_Imap_Client_Socket $client,
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
string $name): Folder {
|
||||
$client->createMailbox($name);
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ namespace OCA\Mail\IMAP;
|
|||
use Horde_Imap_Client_Cache_Backend_Null;
|
||||
use Horde_Imap_Client_Password_Xoauth2;
|
||||
use Horde_Imap_Client_Socket;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Cache\Cache;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Events\BeforeImapClientCreated;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
|
@ -60,22 +60,22 @@ class IMAPClientFactory {
|
|||
* responsible to log out as soon as possible to keep the number of open
|
||||
* (and stale) connections at a minimum.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param MailAccount $account
|
||||
* @param bool $useCache
|
||||
* @return Horde_Imap_Client_Socket
|
||||
*/
|
||||
public function getClient(Account $account, bool $useCache = true): Horde_Imap_Client_Socket {
|
||||
public function getClient(MailAccount $account, bool $useCache = true): Horde_Imap_Client_Socket {
|
||||
$this->eventDispatcher->dispatchTyped(
|
||||
new BeforeImapClientCreated($account)
|
||||
);
|
||||
$host = $account->getMailAccount()->getInboundHost();
|
||||
$user = $account->getMailAccount()->getInboundUser();
|
||||
$host = $account->getInboundHost();
|
||||
$user = $account->getInboundUser();
|
||||
$decryptedPassword = null;
|
||||
if ($account->getMailAccount()->getInboundPassword() !== null) {
|
||||
$decryptedPassword = $this->crypto->decrypt($account->getMailAccount()->getInboundPassword());
|
||||
if ($account->getInboundPassword() !== null) {
|
||||
$decryptedPassword = $this->crypto->decrypt($account->getInboundPassword());
|
||||
}
|
||||
$port = $account->getMailAccount()->getInboundPort();
|
||||
$sslMode = $account->getMailAccount()->getInboundSslMode();
|
||||
$port = $account->getInboundPort();
|
||||
$sslMode = $account->getInboundSslMode();
|
||||
if ($sslMode === 'none') {
|
||||
$sslMode = false;
|
||||
}
|
||||
|
@ -94,8 +94,8 @@ class IMAPClientFactory {
|
|||
],
|
||||
],
|
||||
];
|
||||
if ($account->getMailAccount()->getAuthMethod() === 'xoauth2') {
|
||||
$decryptedAccessToken = $this->crypto->decrypt($account->getMailAccount()->getOauthAccessToken());
|
||||
if ($account->getAuthMethod() === 'xoauth2') {
|
||||
$decryptedAccessToken = $this->crypto->decrypt($account->getOauthAccessToken());
|
||||
|
||||
$params['password'] = $decryptedAccessToken; // Not used, but Horde wants this
|
||||
$params['xoauth2_token'] = new Horde_Imap_Client_Password_Xoauth2(
|
||||
|
|
|
@ -13,7 +13,7 @@ use Horde_Imap_Client;
|
|||
use Horde_Imap_Client_Data_Namespace;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use Horde_Imap_Client_Namespace_List;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailAccountMapper;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
|
@ -76,10 +76,10 @@ class MailboxSync {
|
|||
/**
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function sync(Account $account,
|
||||
public function sync(MailAccount $account,
|
||||
LoggerInterface $logger,
|
||||
bool $force = false): void {
|
||||
if (!$force && $account->getMailAccount()->getLastMailboxSync() >= ($this->timeFactory->getTime() - 7200)) {
|
||||
if (!$force && $account->getLastMailboxSync() >= ($this->timeFactory->getTime() - 7200)) {
|
||||
$logger->debug('account is up to date, skipping mailbox sync');
|
||||
return;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ class MailboxSync {
|
|||
'ob_return' => true,
|
||||
]);
|
||||
$personalNamespace = $this->getPersonalNamespace($namespaces);
|
||||
$account->getMailAccount()->setPersonalNamespace(
|
||||
$account->setPersonalNamespace(
|
||||
$personalNamespace
|
||||
);
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
|
@ -139,12 +139,11 @@ class MailboxSync {
|
|||
/**
|
||||
* Sync unread and total message statistics.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function syncStats(Account $account, Mailbox $mailbox): void {
|
||||
public function syncStats(MailAccount $account, Mailbox $mailbox): void {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
$allStats = $this->folderMapper->getFoldersStatusAsObject($client, [$mailbox->getName()]);
|
||||
|
@ -172,7 +171,7 @@ class MailboxSync {
|
|||
/**
|
||||
* @return Mailbox[]
|
||||
*/
|
||||
private function persist(Account $account,
|
||||
private function persist(MailAccount $account,
|
||||
array $folders,
|
||||
array $existing,
|
||||
?Horde_Imap_Client_Namespace_List $namespaces): array {
|
||||
|
@ -199,8 +198,8 @@ class MailboxSync {
|
|||
$this->mailboxMapper->delete($leftover);
|
||||
}
|
||||
|
||||
$account->getMailAccount()->setLastMailboxSync($this->timeFactory->getTime());
|
||||
$this->mailAccountMapper->update($account->getMailAccount());
|
||||
$account->setLastMailboxSync($this->timeFactory->getTime());
|
||||
$this->mailAccountMapper->update($account);
|
||||
|
||||
return $mailboxes;
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ class MailboxSync {
|
|||
return $this->mailboxMapper->update($mailbox);
|
||||
}
|
||||
|
||||
private function createMailboxFromFolder(Account $account, Folder $folder, ?Horde_Imap_Client_Namespace_List $namespaces): Mailbox {
|
||||
private function createMailboxFromFolder(MailAccount $account, Folder $folder, ?Horde_Imap_Client_Namespace_List $namespaces): Mailbox {
|
||||
$mailbox = new Mailbox();
|
||||
$mailbox->setName($folder->getMailbox());
|
||||
$mailbox->setAccountId($account->getId());
|
||||
|
|
|
@ -10,7 +10,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\IMAP;
|
||||
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\MessageMapper as DbMapper;
|
||||
|
@ -49,7 +49,7 @@ class PreviewEnhancer {
|
|||
*
|
||||
* @return Message[]
|
||||
*/
|
||||
public function process(Account $account, Mailbox $mailbox, array $messages): array {
|
||||
public function process(MailAccount $account, Mailbox $mailbox, array $messages): array {
|
||||
$needAnalyze = array_reduce($messages, static function (array $carry, Message $message) {
|
||||
if ($message->getStructureAnalyzed()) {
|
||||
// Nothing to do
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace OCA\Mail\IMAP\Search;
|
|||
|
||||
use Horde_Imap_Client_Exception;
|
||||
use Horde_Imap_Client_Search_Query;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
|
@ -30,7 +30,7 @@ class Provider {
|
|||
* @return int[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function findMatches(Account $account,
|
||||
public function findMatches(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
SearchQuery $searchQuery): array {
|
||||
$client = $this->clientFactory->getClient($account);
|
||||
|
|
|
@ -10,8 +10,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Integration;
|
||||
|
||||
use Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\AppInfo\Application;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IConfig;
|
||||
|
@ -75,13 +75,13 @@ class GoogleIntegration {
|
|||
return $value;
|
||||
}
|
||||
|
||||
public function isGoogleOauthAccount(Account $account): bool {
|
||||
return $account->getMailAccount()->getInboundHost() === 'imap.gmail.com'
|
||||
&& $account->getMailAccount()->getAuthMethod() === 'xoauth2';
|
||||
public function isGoogleOauthAccount(MailAccount $account): bool {
|
||||
return $account->getInboundHost() === 'imap.gmail.com'
|
||||
&& $account->getAuthMethod() === 'xoauth2';
|
||||
}
|
||||
|
||||
public function finishConnect(Account $account,
|
||||
string $code): Account {
|
||||
public function finishConnect(MailAccount $account,
|
||||
string $code): MailAccount {
|
||||
$clientId = $this->config->getAppValue(Application::APP_ID, 'google_oauth_client_id');
|
||||
$encryptedClientSecret = $this->config->getAppValue(Application::APP_ID, 'google_oauth_client_secret');
|
||||
if (empty($clientId) || empty($encryptedClientSecret)) {
|
||||
|
@ -111,21 +111,21 @@ class GoogleIntegration {
|
|||
|
||||
$data = json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
|
||||
$encryptedRefreshToken = $this->crypto->encrypt($data['refresh_token']);
|
||||
$account->getMailAccount()->setOauthRefreshToken($encryptedRefreshToken);
|
||||
$account->setOauthRefreshToken($encryptedRefreshToken);
|
||||
$encryptedAccessToken = $this->crypto->encrypt($data['access_token']);
|
||||
$account->getMailAccount()->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->getMailAccount()->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
$account->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
return $account;
|
||||
}
|
||||
|
||||
public function refresh(Account $account): Account {
|
||||
if ($account->getMailAccount()->getOauthTokenTtl() === null || $account->getMailAccount()->getOauthRefreshToken() === null) {
|
||||
public function refresh(MailAccount $account): MailAccount {
|
||||
if ($account->getOauthTokenTtl() === null || $account->getOauthRefreshToken() === null) {
|
||||
// Account is not authorized yet
|
||||
return $account;
|
||||
}
|
||||
|
||||
// Only refresh if the token expires in the next minute
|
||||
if ($this->timeFactory->getTime() <= ($account->getMailAccount()->getOauthTokenTtl() - 60)) {
|
||||
if ($this->timeFactory->getTime() <= ($account->getOauthTokenTtl() - 60)) {
|
||||
// No need to refresh yet
|
||||
return $account;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ class GoogleIntegration {
|
|||
return $account;
|
||||
}
|
||||
|
||||
$refreshToken = $this->crypto->decrypt($account->getMailAccount()->getOauthRefreshToken());
|
||||
$refreshToken = $this->crypto->decrypt($account->getOauthRefreshToken());
|
||||
$clientSecret = $this->crypto->decrypt($encryptedClientSecret);
|
||||
$httpClient = $this->clientService->newClient();
|
||||
try {
|
||||
|
@ -159,8 +159,8 @@ class GoogleIntegration {
|
|||
|
||||
$data = json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
|
||||
$encryptedAccessToken = $this->crypto->encrypt($data['access_token']);
|
||||
$account->getMailAccount()->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->getMailAccount()->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
$account->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Integration;
|
||||
|
||||
use Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\AppInfo\Application;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IConfig;
|
||||
|
@ -89,13 +89,13 @@ class MicrosoftIntegration {
|
|||
return $value;
|
||||
}
|
||||
|
||||
public function isMicrosoftOauthAccount(Account $account): bool {
|
||||
return $account->getMailAccount()->getInboundHost() === 'outlook.office365.com'
|
||||
&& $account->getMailAccount()->getAuthMethod() === 'xoauth2';
|
||||
public function isMicrosoftOauthAccount(MailAccount $account): bool {
|
||||
return $account->getInboundHost() === 'outlook.office365.com'
|
||||
&& $account->getAuthMethod() === 'xoauth2';
|
||||
}
|
||||
|
||||
public function finishConnect(Account $account,
|
||||
string $code): Account {
|
||||
public function finishConnect(MailAccount $account,
|
||||
string $code): MailAccount {
|
||||
$tenantId = $this->getTenantId();
|
||||
$clientId = $this->config->getAppValue(Application::APP_ID, 'microsoft_oauth_client_id');
|
||||
$encryptedClientSecret = $this->config->getAppValue(Application::APP_ID, 'microsoft_oauth_client_secret');
|
||||
|
@ -125,21 +125,21 @@ class MicrosoftIntegration {
|
|||
|
||||
$data = json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
|
||||
$encryptedRefreshToken = $this->crypto->encrypt($data['refresh_token']);
|
||||
$account->getMailAccount()->setOauthRefreshToken($encryptedRefreshToken);
|
||||
$account->setOauthRefreshToken($encryptedRefreshToken);
|
||||
$encryptedAccessToken = $this->crypto->encrypt($data['access_token']);
|
||||
$account->getMailAccount()->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->getMailAccount()->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
$account->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
return $account;
|
||||
}
|
||||
|
||||
public function refresh(Account $account): Account {
|
||||
if ($account->getMailAccount()->getOauthTokenTtl() === null || $account->getMailAccount()->getOauthRefreshToken() === null) {
|
||||
public function refresh(MailAccount $account): MailAccount {
|
||||
if ($account->getOauthTokenTtl() === null || $account->getOauthRefreshToken() === null) {
|
||||
// Account is not authorized yet
|
||||
return $account;
|
||||
}
|
||||
|
||||
// Only refresh if the token expires in the next minute
|
||||
if ($this->timeFactory->getTime() <= ($account->getMailAccount()->getOauthTokenTtl() - 60)) {
|
||||
if ($this->timeFactory->getTime() <= ($account->getOauthTokenTtl() - 60)) {
|
||||
// No need to refresh yet
|
||||
return $account;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ class MicrosoftIntegration {
|
|||
return $account;
|
||||
}
|
||||
|
||||
$refreshToken = $this->crypto->decrypt($account->getMailAccount()->getOauthRefreshToken());
|
||||
$refreshToken = $this->crypto->decrypt($account->getOauthRefreshToken());
|
||||
$clientSecret = $this->crypto->decrypt($encryptedClientSecret);
|
||||
$httpClient = $this->clientService->newClient();
|
||||
try {
|
||||
|
@ -174,8 +174,8 @@ class MicrosoftIntegration {
|
|||
|
||||
$data = json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
|
||||
$encryptedAccessToken = $this->crypto->encrypt($data['access_token']);
|
||||
$account->getMailAccount()->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->getMailAccount()->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
$account->setOauthAccessToken($encryptedAccessToken);
|
||||
$account->setOauthTokenTtl($this->timeFactory->getTime() + $data['expires_in']);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ class AccountSynchronizedThreadUpdaterListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
$accountId = $event->getAccount()->getId();
|
||||
$account = $event->getAccount();
|
||||
$accountId = $account->getId();
|
||||
$logger->debug("Building threads for account $accountId");
|
||||
$messages = $this->mapper->findThreadingData($event->getAccount());
|
||||
$logger->debug("Account $accountId has " . count($messages) . ' messages with threading information');
|
||||
|
|
|
@ -45,7 +45,8 @@ class AddressCollectionListener implements IEventListener {
|
|||
if (!($event instanceof MessageSentEvent)) {
|
||||
return;
|
||||
}
|
||||
if ($this->preferences->getPreference($event->getAccount()->getUserId(), 'collect-data', 'true') !== 'true') {
|
||||
$account1 = $event->getAccount();
|
||||
if ($this->preferences->getPreference($account1->getUserId(), 'collect-data', 'true') !== 'true') {
|
||||
$this->logger->debug('Not collecting email addresses because the user opted out');
|
||||
return;
|
||||
}
|
||||
|
@ -59,7 +60,8 @@ class AddressCollectionListener implements IEventListener {
|
|||
|
||||
$addresses = $to->merge($cc)->merge($bcc);
|
||||
|
||||
$this->collector->addAddresses($event->getAccount()->getUserId(), $addresses);
|
||||
$account = $event->getAccount();
|
||||
$this->collector->addAddresses($account->getUserId(), $addresses);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->warning('Error while collecting mail addresses: ' . $e, [
|
||||
'exception' => $e,
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace OCA\Mail\Listener;
|
|||
|
||||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -65,10 +65,9 @@ class DeleteDraftListener implements IEventListener {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Message $draft
|
||||
*/
|
||||
private function deleteDraft(Account $account, Message $draft): void {
|
||||
private function deleteDraft(MailAccount $account, Message $draft): void {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
$draftsMailbox = $this->getDraftsMailbox($account);
|
||||
|
@ -108,8 +107,8 @@ class DeleteDraftListener implements IEventListener {
|
|||
/**
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
private function getDraftsMailbox(Account $account): Mailbox {
|
||||
$draftsMailboxId = $account->getMailAccount()->getDraftsMailboxId();
|
||||
private function getDraftsMailbox(MailAccount $account): Mailbox {
|
||||
$draftsMailboxId = $account->getDraftsMailboxId();
|
||||
if ($draftsMailboxId === null) {
|
||||
throw new DoesNotExistException('No drafts mailbox ID set');
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class FollowUpClassifierListener implements IEventListener {
|
|||
}
|
||||
|
||||
if (!$event->getMailbox()->isSpecialUse('sent')
|
||||
&& $event->getAccount()->getMailAccount()->getSentMailboxId() !== $event->getMailbox()->getId()
|
||||
&& $event->getAccount()->getSentMailboxId() !== $event->getMailbox()->getId()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ class FollowUpClassifierListener implements IEventListener {
|
|||
// Do not process emails older than 14D to save some processing power
|
||||
$notBefore = (new DateTimeImmutable('now'))
|
||||
->sub(new DateInterval('P14D'));
|
||||
$userId = $event->getAccount()->getUserId();
|
||||
$account = $event->getAccount();
|
||||
$userId = $account->getUserId();
|
||||
foreach ($event->getMessages() as $message) {
|
||||
if ($message->getSentAt() < $notBefore->getTimestamp()) {
|
||||
continue;
|
||||
|
|
|
@ -51,7 +51,7 @@ class MailboxesSynchronizedSpecialMailboxesUpdater implements IEventListener {
|
|||
public function handle(Event $event): void {
|
||||
/** @var MailboxesSynchronizedEvent $event */
|
||||
$account = $event->getAccount();
|
||||
$mailAccount = $account->getMailAccount();
|
||||
$mailAccount = $account;
|
||||
$mailboxes = $this->indexMailboxes(
|
||||
$this->mailboxMapper->findAll($account)
|
||||
);
|
||||
|
|
|
@ -32,12 +32,12 @@ class MessageKnownSinceListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
$trashRetention = $event->getAccount()->getMailAccount()->getTrashRetentionDays();
|
||||
$trashRetention = $event->getAccount()->getTrashRetentionDays();
|
||||
if ($trashRetention === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$trashMailboxId = $event->getAccount()->getMailAccount()->getTrashMailboxId();
|
||||
$trashMailboxId = $event->getAccount()->getTrashMailboxId();
|
||||
if ($trashMailboxId === null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class MoveJunkListener implements IEventListener {
|
|||
}
|
||||
|
||||
$account = $event->getAccount();
|
||||
$mailAccount = $account->getMailAccount();
|
||||
$mailAccount = $account;
|
||||
|
||||
$junkMailboxId = $mailAccount->getJunkMailboxId();
|
||||
if ($junkMailboxId === null) {
|
||||
|
|
|
@ -65,7 +65,8 @@ class NewMessageClassificationListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$this->classificationSettingsService->isClassificationEnabled($event->getAccount()->getUserId())) {
|
||||
$account3 = $event->getAccount();
|
||||
if (!$this->classificationSettingsService->isClassificationEnabled($account3->getUserId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,9 +80,10 @@ class NewMessageClassificationListener implements IEventListener {
|
|||
$messages = $event->getMessages();
|
||||
|
||||
// if this is a message that's been flagged / tagged as important before, we don't want to reclassify it again.
|
||||
$account2 = $event->getAccount();
|
||||
$doNotReclassify = $this->tagMapper->getTaggedMessageIdsForMessages(
|
||||
$event->getMessages(),
|
||||
$event->getAccount()->getUserId(),
|
||||
$account2->getUserId(),
|
||||
Tag::LABEL_IMPORTANT
|
||||
);
|
||||
$messages = array_filter($messages, static function ($message) use ($doNotReclassify) {
|
||||
|
@ -89,10 +91,12 @@ class NewMessageClassificationListener implements IEventListener {
|
|||
});
|
||||
|
||||
try {
|
||||
$important = $this->tagMapper->getTagByImapLabel(Tag::LABEL_IMPORTANT, $event->getAccount()->getUserId());
|
||||
$account1 = $event->getAccount();
|
||||
$important = $this->tagMapper->getTagByImapLabel(Tag::LABEL_IMPORTANT, $account1->getUserId());
|
||||
} catch (DoesNotExistException $e) {
|
||||
// just in case - if we get here, the tag is missing
|
||||
$this->logger->error('Could not find important tag for ' . $event->getAccount()->getUserId(). ' ' . $e->getMessage(), [
|
||||
$account = $event->getAccount();
|
||||
$this->logger->error('Could not find important tag for ' . $account->getUserId() . ' ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
return;
|
||||
|
|
|
@ -43,6 +43,6 @@ class OauthTokenRefreshListener implements IEventListener {
|
|||
return;
|
||||
}
|
||||
|
||||
$this->accountService->update($updated->getMailAccount());
|
||||
$this->accountService->update($updated);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class OutOfOfficeListener implements IEventListener {
|
|||
|
||||
$accounts = $this->accountService->findByUserId($event->getData()->getUser()->getUID());
|
||||
foreach ($accounts as $account) {
|
||||
if (!$account->getMailAccount()->getOutOfOfficeFollowsSystem()) {
|
||||
if (!$account->getOutOfOfficeFollowsSystem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class OutOfOfficeListener implements IEventListener {
|
|||
$eventData->getMessage(),
|
||||
);
|
||||
try {
|
||||
$this->outOfOfficeService->update($account->getMailAccount(), $state);
|
||||
$this->outOfOfficeService->update($account, $state);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('Failed to apply out-of-office sieve script: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace OCA\Mail\Migration;
|
|||
|
||||
use Horde_Imap_Client_Exception;
|
||||
use Horde_Imap_Client_Socket;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Tag;
|
||||
|
@ -42,7 +41,7 @@ class MigrateImportantFromImapAndDb {
|
|||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function migrateImportantOnImap(Horde_Imap_Client_Socket $client, Account $account, Mailbox $mailbox): void {
|
||||
public function migrateImportantOnImap(Horde_Imap_Client_Socket $client, Mailbox $mailbox): void {
|
||||
try {
|
||||
$uids = $this->messageMapper->getFlagged($client, $mailbox, '$important');
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
|
@ -59,7 +58,7 @@ class MigrateImportantFromImapAndDb {
|
|||
}
|
||||
}
|
||||
|
||||
public function migrateImportantFromDb(Horde_Imap_Client_Socket $client, Account $account, Mailbox $mailbox): void {
|
||||
public function migrateImportantFromDb(Horde_Imap_Client_Socket $client, Mailbox $mailbox): void {
|
||||
$uids = $this->mailboxMapper->findFlaggedImportantUids($mailbox->getId());
|
||||
// store our data on imap
|
||||
if ($uids !== []) {
|
||||
|
|
|
@ -9,8 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Model;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\AddressList;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
|
||||
/**
|
||||
* Simple data class that wraps the request data of a new message or reply
|
||||
|
@ -22,8 +22,7 @@ class NewMessageData {
|
|||
private bool $smimeSign;
|
||||
private bool $smimeEncrypt;
|
||||
|
||||
/** @var Account */
|
||||
private $account;
|
||||
private MailAccount $account;
|
||||
|
||||
/** @var AddressList */
|
||||
private $to;
|
||||
|
@ -50,7 +49,6 @@ class NewMessageData {
|
|||
private $isMdnRequested;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param AddressList $to
|
||||
* @param AddressList $cc
|
||||
* @param AddressList $bcc
|
||||
|
@ -62,7 +60,7 @@ class NewMessageData {
|
|||
* @param bool $smimeSign
|
||||
* @param bool $isMdnRequested
|
||||
*/
|
||||
public function __construct(Account $account,
|
||||
public function __construct(MailAccount $account,
|
||||
AddressList $to,
|
||||
AddressList $cc,
|
||||
AddressList $bcc,
|
||||
|
@ -89,7 +87,6 @@ class NewMessageData {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param string|null $to
|
||||
|
@ -102,7 +99,7 @@ class NewMessageData {
|
|||
* @param bool $smimeSign
|
||||
* @return NewMessageData
|
||||
*/
|
||||
public static function fromRequest(Account $account,
|
||||
public static function fromRequest(MailAccount $account,
|
||||
string $subject,
|
||||
string $body,
|
||||
?string $to = null,
|
||||
|
@ -134,10 +131,7 @@ class NewMessageData {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Model;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
||||
/**
|
||||
|
@ -18,18 +18,17 @@ use OCA\Mail\Db\Message;
|
|||
* @psalm-immutable
|
||||
*/
|
||||
class RepliedMessageData {
|
||||
/** @var Account */
|
||||
private $account;
|
||||
private MailAccount $account;
|
||||
|
||||
/** @var Message */
|
||||
private $message;
|
||||
|
||||
public function __construct(Account $account, Message $message) {
|
||||
public function __construct(MailAccount $account, Message $message) {
|
||||
$this->account = $account;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getAccount(): Account {
|
||||
public function getAccount(): MailAccount {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Provider;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
use OCA\Mail\Service\AccountService;
|
||||
use OCP\IL10N;
|
||||
|
@ -151,11 +151,10 @@ class MailProvider implements IProvider {
|
|||
* @since 4.0.0
|
||||
*
|
||||
* @param string $userId system user id
|
||||
* @param Account $account mail account
|
||||
*
|
||||
* @return IService service object
|
||||
*/
|
||||
protected function serviceFromAccount(string $userId, Account $account): IService {
|
||||
protected function serviceFromAccount(string $userId, MailAccount $account): IService {
|
||||
// extract values
|
||||
$serviceId = (string)$account->getId();
|
||||
$serviceLabel = $account->getName();
|
||||
|
|
|
@ -13,7 +13,7 @@ use Horde_Mail_Transport;
|
|||
use Horde_Mail_Transport_Mail;
|
||||
use Horde_Mail_Transport_Smtphorde;
|
||||
use Horde_Smtp_Password_Xoauth2;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Support\HostNameFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\Security\ICrypto;
|
||||
|
@ -37,12 +37,10 @@ class SmtpClientFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Horde_Mail_Transport
|
||||
*/
|
||||
public function create(Account $account): Horde_Mail_Transport {
|
||||
$mailAccount = $account->getMailAccount();
|
||||
public function create(MailAccount $account): Horde_Mail_Transport {
|
||||
$mailAccount = $account;
|
||||
$transport = $this->config->getSystemValue('app.mail.transport', 'smtp');
|
||||
if ($transport === 'php-mail') {
|
||||
return new Horde_Mail_Transport_Mail();
|
||||
|
@ -68,8 +66,8 @@ class SmtpClientFactory {
|
|||
],
|
||||
],
|
||||
];
|
||||
if ($account->getMailAccount()->getAuthMethod() === 'xoauth2') {
|
||||
$decryptedAccessToken = $this->crypto->decrypt($account->getMailAccount()->getOauthAccessToken());
|
||||
if ($account->getAuthMethod() === 'xoauth2') {
|
||||
$decryptedAccessToken = $this->crypto->decrypt($account->getOauthAccessToken());
|
||||
|
||||
$params['password'] = $decryptedAccessToken; // Not used, but Horde wants this
|
||||
$params['xoauth2_token'] = new Horde_Smtp_Password_Xoauth2(
|
||||
|
|
|
@ -7,8 +7,8 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Send;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
|
||||
abstract class AHandler {
|
||||
|
||||
|
@ -18,9 +18,9 @@ abstract class AHandler {
|
|||
return $next;
|
||||
}
|
||||
|
||||
abstract public function process(Account $account, LocalMessage $localMessage): LocalMessage;
|
||||
abstract public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage;
|
||||
|
||||
protected function processNext(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
protected function processNext(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($this->next !== null) {
|
||||
return $this->next->process($account, $localMessage);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Send;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Service\AntiAbuseService;
|
||||
use OCP\IUserManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
@ -19,7 +19,7 @@ class AntiAbuseHandler extends AHandler {
|
|||
private AntiAbuseService $service,
|
||||
private LoggerInterface $logger) {
|
||||
}
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($localMessage->getStatus() === LocalMessage::STATUS_IMAP_SENT_MAILBOX_FAIL
|
||||
|| $localMessage->getStatus() === LocalMessage::STATUS_PROCESSED) {
|
||||
return $this->processNext($account, $localMessage);
|
||||
|
|
|
@ -7,9 +7,9 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Send;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\LocalMessageMapper;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\Service\Attachment\AttachmentService;
|
||||
use OCP\DB\Exception;
|
||||
|
@ -30,7 +30,7 @@ class Chain {
|
|||
* @throws Exception
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
$handlers = $this->sentMailboxHandler;
|
||||
$handlers->setNext($this->antiAbuseHandler)
|
||||
->setNext($this->sendHandler)
|
||||
|
|
|
@ -8,8 +8,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Send;
|
||||
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
use OCA\Mail\IMAP\MessageMapper;
|
||||
|
@ -23,7 +23,7 @@ class CopySentMessageHandler extends AHandler {
|
|||
private MessageMapper $messageMapper,
|
||||
) {
|
||||
}
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($localMessage->getStatus() === LocalMessage::STATUS_PROCESSED) {
|
||||
return $this->processNext($account, $localMessage);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class CopySentMessageHandler extends AHandler {
|
|||
return $localMessage;
|
||||
}
|
||||
|
||||
$sentMailboxId = $account->getMailAccount()->getSentMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
if ($sentMailboxId === null) {
|
||||
// We can't write the "sent mailbox" status here bc that would trigger an additional send.
|
||||
// Thus, we leave the "imap copy to sent mailbox" status.
|
||||
|
|
|
@ -9,8 +9,8 @@ namespace OCA\Mail\Send;
|
|||
|
||||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper as DbMessageMapper;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
|
@ -27,7 +27,7 @@ class FlagRepliedMessageHandler extends AHandler {
|
|||
) {
|
||||
}
|
||||
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($localMessage->getStatus() !== LocalMessage::STATUS_PROCESSED) {
|
||||
return $localMessage;
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Send;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailTransmission;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
|
||||
class SendHandler extends AHandler {
|
||||
public function __construct(private IMailTransmission $transmission,
|
||||
) {
|
||||
}
|
||||
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($localMessage->getStatus() === LocalMessage::STATUS_IMAP_SENT_MAILBOX_FAIL
|
||||
|| $localMessage->getStatus() === LocalMessage::STATUS_PROCESSED) {
|
||||
return $this->processNext($account, $localMessage);
|
||||
|
|
|
@ -7,12 +7,12 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Send;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
|
||||
class SentMailboxHandler extends AHandler {
|
||||
public function process(Account $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($account->getMailAccount()->getSentMailboxId() === null) {
|
||||
public function process(MailAccount $account, LocalMessage $localMessage): LocalMessage {
|
||||
if ($account->getSentMailboxId() === null) {
|
||||
$localMessage->setStatus(LocalMessage::STATUS_NO_SENT_MAILBOX);
|
||||
return $localMessage;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\BackgroundJob\PreviewEnhancementProcessingJob;
|
||||
use OCA\Mail\BackgroundJob\QuotaJob;
|
||||
use OCA\Mail\BackgroundJob\SyncJob;
|
||||
|
@ -31,7 +30,7 @@ class AccountService {
|
|||
/**
|
||||
* Cache accounts for multiple calls to 'findByUserId'
|
||||
*
|
||||
* @var array<string, Account[]>
|
||||
* @var array<string, MailAccount[]>
|
||||
*/
|
||||
private array $accounts = [];
|
||||
|
||||
|
@ -56,13 +55,11 @@ class AccountService {
|
|||
|
||||
/**
|
||||
* @param string $currentUserId
|
||||
* @return Account[]
|
||||
* @return MailAccount[]
|
||||
*/
|
||||
public function findByUserId(string $currentUserId): array {
|
||||
if (!isset($this->accounts[$currentUserId])) {
|
||||
$this->accounts[$currentUserId] = array_map(static function ($a) {
|
||||
return new Account($a);
|
||||
}, $this->mapper->findByUserId($currentUserId));
|
||||
$this->accounts[$currentUserId] = $this->mapper->findByUserId($currentUserId);
|
||||
}
|
||||
|
||||
return $this->accounts[$currentUserId];
|
||||
|
@ -71,11 +68,10 @@ class AccountService {
|
|||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return Account
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
public function findById(int $id): Account {
|
||||
return new Account($this->mapper->findById($id));
|
||||
public function findById(int $id): MailAccount {
|
||||
return $this->mapper->findById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,10 +107,9 @@ class AccountService {
|
|||
* @param string $userId
|
||||
* @param int $id
|
||||
*
|
||||
* @return Account
|
||||
* @throws ClientException
|
||||
*/
|
||||
public function find(string $userId, int $id): Account {
|
||||
public function find(string $userId, int $id): MailAccount {
|
||||
if (isset($this->accounts[$userId])) {
|
||||
foreach ($this->accounts[$userId] as $account) {
|
||||
if ($account->getId() === $id) {
|
||||
|
@ -125,7 +120,7 @@ class AccountService {
|
|||
}
|
||||
|
||||
try {
|
||||
return new Account($this->mapper->find($userId, $id));
|
||||
return $this->mapper->find($userId, $id);
|
||||
} catch (DoesNotExistException $e) {
|
||||
throw new ClientException("Account $id does not exist or you don\'t have permission to access it");
|
||||
}
|
||||
|
@ -191,7 +186,7 @@ class AccountService {
|
|||
*/
|
||||
public function updateSignature(int $id, string $uid, ?string $signature = null): void {
|
||||
$account = $this->find($uid, $id);
|
||||
$mailAccount = $account->getMailAccount();
|
||||
$mailAccount = $account;
|
||||
$mailAccount->setSignature($signature);
|
||||
$this->mapper->save($mailAccount);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Service\AiIntegrations;
|
||||
|
||||
use JsonException;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\AppInfo\Application;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
|
@ -62,7 +62,6 @@ PROMPT;
|
|||
$this->config = $config;
|
||||
}
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $threadId
|
||||
* @param array $messages
|
||||
* @param string $currentUserId
|
||||
|
@ -71,7 +70,7 @@ PROMPT;
|
|||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function summarizeThread(Account $account, string $threadId, array $messages, string $currentUserId): null|string {
|
||||
public function summarizeThread(MailAccount $account, string $threadId, array $messages, string $currentUserId): null|string {
|
||||
try {
|
||||
$manager = $this->container->get(IManager::class);
|
||||
} catch (\Throwable $e) {
|
||||
|
@ -118,7 +117,7 @@ PROMPT;
|
|||
/**
|
||||
* @param Message[] $messages
|
||||
*/
|
||||
public function generateEventData(Account $account, string $threadId, array $messages, string $currentUserId): ?EventData {
|
||||
public function generateEventData(MailAccount $account, string $threadId, array $messages, string $currentUserId): ?EventData {
|
||||
try {
|
||||
/** @var IManager $manager */
|
||||
$manager = $this->container->get(IManager::class);
|
||||
|
@ -164,7 +163,7 @@ PROMPT;
|
|||
* @return ?string[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getSmartReply(Account $account, Mailbox $mailbox, Message $message, string $currentUserId): ?array {
|
||||
public function getSmartReply(MailAccount $account, Mailbox $mailbox, Message $message, string $currentUserId): ?array {
|
||||
try {
|
||||
$manager = $this->container->get(IManager::class);
|
||||
} catch (\Throwable $e) {
|
||||
|
@ -226,7 +225,7 @@ PROMPT;
|
|||
* @throws ServiceException
|
||||
*/
|
||||
public function requiresFollowUp(
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
Message $message,
|
||||
string $currentUserId,
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace OCA\Mail\Service;
|
|||
use Horde_Imap_Client_Exception;
|
||||
use Horde_Mime_Exception;
|
||||
use Horde_Mime_Mail;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Address;
|
||||
use OCA\Mail\AddressList;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MessageMapper;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
|
@ -72,13 +72,13 @@ class AntiSpamService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param MailAccount $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int $uid
|
||||
* @param string $flag
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function sendReportEmail(Account $account, Mailbox $mailbox, int $uid, string $flag): void {
|
||||
public function sendReportEmail(MailAccount $account, Mailbox $mailbox, int $uid, string $flag): void {
|
||||
$reportEmail = ($flag === '$junk') ? $this->getSpamEmail() : $this->getHamEmail();
|
||||
if ($reportEmail === '') {
|
||||
return;
|
||||
|
@ -91,13 +91,13 @@ class AntiSpamService {
|
|||
throw new ServiceException('Could not find reported message');
|
||||
}
|
||||
|
||||
if ($account->getMailAccount()->getSentMailboxId() === null) {
|
||||
if ($account->getSentMailboxId() === null) {
|
||||
throw new ServiceException('Could not find sent mailbox');
|
||||
}
|
||||
|
||||
$message = new Message();
|
||||
$from = new AddressList([
|
||||
Address::fromRaw($account->getName(), $account->getEMailAddress()),
|
||||
Address::fromRaw($account->getName(), $account->getEmail()),
|
||||
]);
|
||||
$to = new AddressList([
|
||||
Address::fromRaw($reportEmail, $reportEmail),
|
||||
|
@ -108,7 +108,7 @@ class AntiSpamService {
|
|||
$message->setContent($subject);
|
||||
|
||||
// Gets original of other message
|
||||
$userId = $account->getMailAccount()->getUserId();
|
||||
$userId = $account->getUserId();
|
||||
try {
|
||||
$attachmentMessage = $this->mailManager->getMessage($userId, $messageId);
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
@ -175,7 +175,7 @@ class AntiSpamService {
|
|||
);
|
||||
}
|
||||
|
||||
$sentMailboxId = $account->getMailAccount()->getSentMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
if ($sentMailboxId === null) {
|
||||
$this->logger->warning("No sent mailbox exists, can't save sent message");
|
||||
return;
|
||||
|
|
|
@ -12,12 +12,12 @@ namespace OCA\Mail\Service\Attachment;
|
|||
use finfo;
|
||||
use InvalidArgumentException;
|
||||
use OCA\Files_Sharing\SharedStorage;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IAttachmentService;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\LocalAttachment;
|
||||
use OCA\Mail\Db\LocalAttachmentMapper;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Exception\AttachmentNotFoundException;
|
||||
use OCA\Mail\Exception\UploadException;
|
||||
use OCA\Mail\IMAP\MessageMapper;
|
||||
|
@ -213,7 +213,7 @@ class AttachmentService implements IAttachmentService {
|
|||
* @param array $attachments
|
||||
* @return int[]
|
||||
*/
|
||||
public function handleAttachments(Account $account, array $attachments, \Horde_Imap_Client_Socket $client): array {
|
||||
public function handleAttachments(MailAccount $account, array $attachments, \Horde_Imap_Client_Socket $client): array {
|
||||
$attachmentIds = [];
|
||||
|
||||
if ($attachments === []) {
|
||||
|
@ -249,12 +249,11 @@ class AttachmentService implements IAttachmentService {
|
|||
/**
|
||||
* Add a message as attachment
|
||||
*
|
||||
* @param Account $account
|
||||
* @param mixed[] $attachment
|
||||
* @param \Horde_Imap_Client_Socket $client
|
||||
* @return int|null
|
||||
*/
|
||||
private function handleForwardedMessageAttachment(Account $account, array $attachment, \Horde_Imap_Client_Socket $client): ?int {
|
||||
private function handleForwardedMessageAttachment(MailAccount $account, array $attachment, \Horde_Imap_Client_Socket $client): ?int {
|
||||
$attachmentMessage = $this->mailManager->getMessage($account->getUserId(), (int)$attachment['id']);
|
||||
$mailbox = $this->mailManager->getMailbox($account->getUserId(), $attachmentMessage->getMailboxId());
|
||||
$fullText = $this->messageMapper->getFullText(
|
||||
|
@ -286,13 +285,12 @@ class AttachmentService implements IAttachmentService {
|
|||
/**
|
||||
* Adds an emails attachments
|
||||
*
|
||||
* @param Account $account
|
||||
* @param mixed[] $attachment
|
||||
* @param \Horde_Imap_Client_Socket $client
|
||||
* @return int
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
private function handleForwardedAttachment(Account $account, array $attachment, \Horde_Imap_Client_Socket $client): ?int {
|
||||
private function handleForwardedAttachment(MailAccount $account, array $attachment, \Horde_Imap_Client_Socket $client): ?int {
|
||||
$mailbox = $this->mailManager->getMailbox($account->getUserId(), $attachment['mailboxId']);
|
||||
|
||||
$attachments = $this->messageMapper->getRawAttachments(
|
||||
|
@ -346,11 +344,10 @@ class AttachmentService implements IAttachmentService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $attachment
|
||||
* @return int|null
|
||||
*/
|
||||
private function handleCloudAttachment(Account $account, array $attachment): ?int {
|
||||
private function handleCloudAttachment(MailAccount $account, array $attachment): ?int {
|
||||
if (!isset($attachment['fileName'])) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use function OCA\Mail\array_flat_map;
|
||||
|
||||
|
@ -32,7 +32,7 @@ class CompositeExtractor implements IExtractor {
|
|||
];
|
||||
}
|
||||
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void {
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
||||
|
@ -18,12 +18,11 @@ interface IExtractor {
|
|||
* Initialize any data that is used for all messages and return whether the
|
||||
* extractor is applicable for this account
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox[] $incomingMailboxes
|
||||
* @param Mailbox[] $outgoingMailboxes
|
||||
* @param Message[] $messages
|
||||
*/
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void;
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\StatisticsDao;
|
||||
use RuntimeException;
|
||||
|
@ -30,7 +30,7 @@ class ImportantMessagesExtractor implements IExtractor {
|
|||
$this->statisticsDao = $statisticsDao;
|
||||
}
|
||||
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void {
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\StatisticsDao;
|
||||
use RuntimeException;
|
||||
|
@ -30,7 +30,7 @@ class ReadMessagesExtractor implements IExtractor {
|
|||
$this->statisticsDao = $statisticsDao;
|
||||
}
|
||||
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void {
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\StatisticsDao;
|
||||
use RuntimeException;
|
||||
|
@ -30,7 +30,7 @@ class RepliedMessagesExtractor implements IExtractor {
|
|||
$this->statisticsDao = $statisticsDao;
|
||||
}
|
||||
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void {
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification\FeatureExtraction;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Db\StatisticsDao;
|
||||
use RuntimeException;
|
||||
|
@ -30,7 +30,7 @@ class SentMessagesExtractor implements IExtractor {
|
|||
$this->statisticsDao = $statisticsDao;
|
||||
}
|
||||
|
||||
public function prepare(Account $account,
|
||||
public function prepare(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): void {
|
||||
|
|
|
@ -10,8 +10,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Service\Classification;
|
||||
|
||||
use Horde_Imap_Client;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\Classifier;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -135,10 +135,8 @@ class ImportanceClassifier {
|
|||
*
|
||||
* To prevent memory exhaustion, the process will only load a fixed maximum
|
||||
* number of messages per account.
|
||||
*
|
||||
* @param Account $account
|
||||
*/
|
||||
public function train(Account $account, LoggerInterface $logger): void {
|
||||
public function train(MailAccount $account, LoggerInterface $logger): void {
|
||||
$perf = $this->performanceLogger->start('importance classifier training');
|
||||
$incomingMailboxes = $this->getIncomingMailboxes($account);
|
||||
$logger->debug('found ' . count($incomingMailboxes) . ' incoming mailbox(es)');
|
||||
|
@ -210,11 +208,9 @@ class ImportanceClassifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Mailbox[]
|
||||
*/
|
||||
private function getIncomingMailboxes(Account $account): array {
|
||||
private function getIncomingMailboxes(MailAccount $account): array {
|
||||
return array_filter($this->mailboxMapper->findAll($account), static function (Mailbox $mailbox) {
|
||||
foreach (self::EXEMPT_FROM_TRAINING as $excluded) {
|
||||
if ($mailbox->isSpecialUse($excluded)) {
|
||||
|
@ -226,14 +222,12 @@ class ImportanceClassifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Mailbox[]
|
||||
* @todo allow more than one outgoing mailbox
|
||||
*/
|
||||
private function getOutgoingMailboxes(Account $account): array {
|
||||
private function getOutgoingMailboxes(MailAccount $account): array {
|
||||
try {
|
||||
$sentMailboxId = $account->getMailAccount()->getSentMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
if ($sentMailboxId === null) {
|
||||
return [];
|
||||
}
|
||||
|
@ -249,14 +243,13 @@ class ImportanceClassifier {
|
|||
/**
|
||||
* Get the feature vector of every message
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox[] $incomingMailboxes
|
||||
* @param Mailbox[] $outgoingMailboxes
|
||||
* @param Message[] $messages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getFeaturesAndImportance(Account $account,
|
||||
private function getFeaturesAndImportance(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): array {
|
||||
|
@ -277,13 +270,12 @@ class ImportanceClassifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Message[] $messages
|
||||
*
|
||||
* @return bool[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function classifyImportance(Account $account, array $messages): array {
|
||||
public function classifyImportance(MailAccount $account, array $messages): array {
|
||||
$estimator = null;
|
||||
try {
|
||||
$estimator = $this->persistenceService->loadLatest($account);
|
||||
|
|
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\Message;
|
||||
use OCA\Mail\Service\Classification\FeatureExtraction\ImportantMessagesExtractor;
|
||||
|
@ -43,14 +43,13 @@ class ImportanceRulesClassifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox[] $incomingMailboxes
|
||||
* @param Mailbox[] $outgoingMailboxes
|
||||
* @param Message[] $messages
|
||||
*
|
||||
* @return bool[]
|
||||
*/
|
||||
public function classifyImportance(Account $account,
|
||||
public function classifyImportance(MailAccount $account,
|
||||
array $incomingMailboxes,
|
||||
array $outgoingMailboxes,
|
||||
array $messages): array {
|
||||
|
|
|
@ -9,10 +9,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Classification;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\AppInfo\Application;
|
||||
use OCA\Mail\Db\Classifier;
|
||||
use OCA\Mail\Db\ClassifierMapper;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailAccountMapper;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCP\App\IAppManager;
|
||||
|
@ -140,12 +140,10 @@ class PersistenceService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Estimator|null
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function loadLatest(Account $account): ?Estimator {
|
||||
public function loadLatest(MailAccount $account): ?Estimator {
|
||||
try {
|
||||
$latestModel = $this->mapper->findLatest($account->getId());
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
|
|
@ -9,9 +9,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IDkimService;
|
||||
use OCA\Mail\Contracts\IDkimValidator;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
|
@ -46,7 +46,7 @@ class DkimService implements IDkimService {
|
|||
$this->dkimValidator = $dkimValidator;
|
||||
}
|
||||
|
||||
public function validate(Account $account, Mailbox $mailbox, int $id): bool {
|
||||
public function validate(MailAccount $account, Mailbox $mailbox, int $id): bool {
|
||||
$cached = $this->getCached($account, $mailbox, $id);
|
||||
if (is_bool($cached)) {
|
||||
return $cached;
|
||||
|
@ -77,11 +77,11 @@ class DkimService implements IDkimService {
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function getCached(Account $account, Mailbox $mailbox, int $id): ?bool {
|
||||
public function getCached(MailAccount $account, Mailbox $mailbox, int $id): ?bool {
|
||||
return $this->cache->get($this->buildCacheKey($account, $mailbox, $id));
|
||||
}
|
||||
|
||||
private function buildCacheKey(Account $account, Mailbox $mailbox, int $id): string {
|
||||
private function buildCacheKey(MailAccount $account, Mailbox $mailbox, int $id): string {
|
||||
return $account->getId() . '_' . $mailbox->getName() . '_' . $id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Contracts\IMailTransmission;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\LocalMessageMapper;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Recipient;
|
||||
use OCA\Mail\Events\DraftMessageCreatedEvent;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
|
@ -83,7 +83,6 @@ class DraftsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param LocalMessage $message
|
||||
* @param array<int, string[]> $to
|
||||
* @param array<int, string[]> $cc
|
||||
|
@ -91,7 +90,7 @@ class DraftsService {
|
|||
* @param array $attachments
|
||||
* @return LocalMessage
|
||||
*/
|
||||
public function saveMessage(Account $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
public function saveMessage(MailAccount $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
$toRecipients = self::convertToRecipient($to, Recipient::TYPE_TO);
|
||||
$ccRecipients = self::convertToRecipient($cc, Recipient::TYPE_CC);
|
||||
$bccRecipients = self::convertToRecipient($bcc, Recipient::TYPE_BCC);
|
||||
|
@ -125,7 +124,6 @@ class DraftsService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param LocalMessage $message
|
||||
* @param array<int, string[]> $to
|
||||
* @param array<int, string[]> $cc
|
||||
|
@ -133,7 +131,7 @@ class DraftsService {
|
|||
* @param array $attachments
|
||||
* @return LocalMessage
|
||||
*/
|
||||
public function updateMessage(Account $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
public function updateMessage(MailAccount $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
$toRecipients = self::convertToRecipient($to, Recipient::TYPE_TO);
|
||||
$ccRecipients = self::convertToRecipient($cc, Recipient::TYPE_CC);
|
||||
$bccRecipients = self::convertToRecipient($bcc, Recipient::TYPE_BCC);
|
||||
|
@ -156,7 +154,7 @@ class DraftsService {
|
|||
return $message;
|
||||
}
|
||||
|
||||
public function handleDraft(Account $account, int $draftId): void {
|
||||
public function handleDraft(MailAccount $account, int $draftId): void {
|
||||
$message = $this->mailManager->getMessage($account->getUserId(), $draftId);
|
||||
$this->eventDispatcher->dispatchTyped(new DraftMessageCreatedEvent($account, $message));
|
||||
}
|
||||
|
@ -165,10 +163,9 @@ class DraftsService {
|
|||
* "Send" the message
|
||||
*
|
||||
* @param LocalMessage $message
|
||||
* @param Account $account
|
||||
* @return void
|
||||
*/
|
||||
public function sendMessage(LocalMessage $message, Account $account): void {
|
||||
public function sendMessage(LocalMessage $message, MailAccount $account): void {
|
||||
try {
|
||||
$this->transmission->saveLocalDraft($account, $message);
|
||||
} catch (ClientException|ServiceException $e) {
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -83,7 +82,6 @@ class IMipService {
|
|||
|
||||
/** @var Mailbox $mailbox */
|
||||
foreach ($mailboxes as $mailbox) {
|
||||
/** @var Account $account */
|
||||
$account = $accounts[$mailbox->getAccountId()];
|
||||
$filteredMessages = array_filter($messages, static function ($message) use ($mailbox) {
|
||||
return $message->getMailboxId() === $mailbox->getId();
|
||||
|
@ -96,11 +94,11 @@ class IMipService {
|
|||
// Check for accounts or mailboxes that no longer exist,
|
||||
// no processing for drafts, sent items, junk or archive
|
||||
if ($account === null
|
||||
|| $account->getMailAccount()->getArchiveMailboxId() === $mailbox->getId()
|
||||
|| $account->getMailAccount()->getSnoozeMailboxId() === $mailbox->getId()
|
||||
|| $account->getMailAccount()->getTrashMailboxId() === $mailbox->getId()
|
||||
|| $account->getMailAccount()->getSentMailboxId() === $mailbox->getId()
|
||||
|| $account->getMailAccount()->getDraftsMailboxId() === $mailbox->getId()
|
||||
|| $account->getArchiveMailboxId() === $mailbox->getId()
|
||||
|| $account->getSnoozeMailboxId() === $mailbox->getId()
|
||||
|| $account->getTrashMailboxId() === $mailbox->getId()
|
||||
|| $account->getSentMailboxId() === $mailbox->getId()
|
||||
|| $account->getDraftsMailboxId() === $mailbox->getId()
|
||||
|| $mailbox->isSpecialUse(\Horde_Imap_Client::SPECIALUSE_ARCHIVE)
|
||||
) {
|
||||
$processedMessages = array_map(static function (Message $message) {
|
||||
|
|
|
@ -10,7 +10,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Service;
|
||||
|
||||
use Nextcloud\KItinerary\Itinerary;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
use OCA\Mail\IMAP\MessageMapper;
|
||||
|
@ -53,11 +53,11 @@ class ItineraryService {
|
|||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
private function buildCacheKey(Account $account, Mailbox $mailbox, int $id): string {
|
||||
private function buildCacheKey(MailAccount $account, Mailbox $mailbox, int $id): string {
|
||||
return $account->getId() . '_' . $mailbox->getName() . '_' . $id;
|
||||
}
|
||||
|
||||
public function getCached(Account $account, Mailbox $mailbox, int $id): ?Itinerary {
|
||||
public function getCached(MailAccount $account, Mailbox $mailbox, int $id): ?Itinerary {
|
||||
if ($cached = ($this->cache->get($this->buildCacheKey($account, $mailbox, $id)))) {
|
||||
return Itinerary::fromJson($cached);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class ItineraryService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function extract(Account $account, Mailbox $mailbox, int $id): Itinerary {
|
||||
public function extract(MailAccount $account, Mailbox $mailbox, int $id): Itinerary {
|
||||
if ($cached = ($this->getCached($account, $mailbox, $id))) {
|
||||
return $cached;
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ use Horde_Imap_Client_Exception;
|
|||
use Horde_Imap_Client_Exception_NoSupportExtension;
|
||||
use Horde_Imap_Client_Socket;
|
||||
use Horde_Mime_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Attachment;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -125,25 +125,22 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Mailbox[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getMailboxes(Account $account): array {
|
||||
public function getMailboxes(MailAccount $account): array {
|
||||
$this->mailboxSync->sync($account, $this->logger);
|
||||
|
||||
return $this->mailboxMapper->findAll($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $name
|
||||
*
|
||||
* @return Mailbox
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function createMailbox(Account $account, string $name): Mailbox {
|
||||
public function createMailbox(MailAccount $account, string $name): Mailbox {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
$folder = $this->folderMapper->createFolder($client, $account, $name);
|
||||
|
@ -166,7 +163,6 @@ class MailManager implements IMailManager {
|
|||
|
||||
/**
|
||||
* @param Horde_Imap_Client_Socket $client
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int $uid
|
||||
* @param bool $loadBody
|
||||
|
@ -177,7 +173,7 @@ class MailManager implements IMailManager {
|
|||
* @throws SmimeDecryptException
|
||||
*/
|
||||
public function getImapMessage(Horde_Imap_Client_Socket $client,
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $uid,
|
||||
bool $loadBody = false): IMAPMessage {
|
||||
|
@ -199,13 +195,12 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int[] $uids
|
||||
* @return IMAPMessage[]
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getImapMessagesForScheduleProcessing(Account $account,
|
||||
public function getImapMessagesForScheduleProcessing(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
array $uids): array {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
|
@ -228,7 +223,7 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
}
|
||||
|
||||
public function getThread(Account $account, string $threadRootId): array {
|
||||
public function getThread(MailAccount $account, string $threadRootId): array {
|
||||
return $this->dbMessageMapper->findThread($account, $threadRootId);
|
||||
}
|
||||
|
||||
|
@ -242,7 +237,6 @@ class MailManager implements IMailManager {
|
|||
|
||||
/**
|
||||
* @param Horde_Imap_Client_Socket $client
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @param int $uid
|
||||
*
|
||||
|
@ -251,7 +245,7 @@ class MailManager implements IMailManager {
|
|||
* @throws ServiceException
|
||||
*/
|
||||
public function getSource(Horde_Imap_Client_Socket $client,
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
string $mailbox,
|
||||
int $uid): ?string {
|
||||
try {
|
||||
|
@ -268,19 +262,17 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $sourceAccount
|
||||
* @param string $sourceFolderId
|
||||
* @param int $uid
|
||||
* @param Account $destinationAccount
|
||||
* @param string $destFolderId
|
||||
*
|
||||
* @return int
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function moveMessage(Account $sourceAccount,
|
||||
public function moveMessage(MailAccount $sourceAccount,
|
||||
string $sourceFolderId,
|
||||
int $uid,
|
||||
Account $destinationAccount,
|
||||
MailAccount $destinationAccount,
|
||||
string $destFolderId): int {
|
||||
if ($sourceAccount->getId() === $destinationAccount->getId()) {
|
||||
try {
|
||||
|
@ -313,7 +305,7 @@ class MailManager implements IMailManager {
|
|||
* @throws ServiceException
|
||||
* @todo evaluate if we should sync mailboxes first
|
||||
*/
|
||||
public function deleteMessage(Account $account,
|
||||
public function deleteMessage(MailAccount $account,
|
||||
string $mailboxId,
|
||||
int $messageUid): void {
|
||||
try {
|
||||
|
@ -338,7 +330,7 @@ class MailManager implements IMailManager {
|
|||
* @todo evaluate if we should sync mailboxes first
|
||||
*/
|
||||
public function deleteMessageWithClient(
|
||||
Account $account,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $messageUid,
|
||||
Horde_Imap_Client_Socket $client,
|
||||
|
@ -348,7 +340,7 @@ class MailManager implements IMailManager {
|
|||
);
|
||||
|
||||
try {
|
||||
$trashMailboxId = $account->getMailAccount()->getTrashMailboxId();
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
if ($trashMailboxId === null) {
|
||||
throw new TrashMailboxNotSetException();
|
||||
}
|
||||
|
@ -379,7 +371,6 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $sourceFolderId
|
||||
* @param string $destFolderId
|
||||
* @param int $messageId
|
||||
|
@ -388,7 +379,7 @@ class MailManager implements IMailManager {
|
|||
* @throws ServiceException
|
||||
*
|
||||
*/
|
||||
private function moveMessageOnSameAccount(Account $account,
|
||||
private function moveMessageOnSameAccount(MailAccount $account,
|
||||
string $sourceFolderId,
|
||||
string $destFolderId,
|
||||
int $messageId): int {
|
||||
|
@ -400,7 +391,7 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
}
|
||||
|
||||
public function markFolderAsRead(Account $account, Mailbox $mailbox): void {
|
||||
public function markFolderAsRead(MailAccount $account, Mailbox $mailbox): void {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
$this->imapMessageMapper->markAllRead($client, $mailbox->getName());
|
||||
|
@ -409,7 +400,7 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
}
|
||||
|
||||
public function updateSubscription(Account $account, Mailbox $mailbox, bool $subscribed): Mailbox {
|
||||
public function updateSubscription(MailAccount $account, Mailbox $mailbox, bool $subscribed): Mailbox {
|
||||
/**
|
||||
* 1. Change subscription on IMAP
|
||||
*/
|
||||
|
@ -444,7 +435,7 @@ class MailManager implements IMailManager {
|
|||
return $this->mailboxMapper->update($mailbox);
|
||||
}
|
||||
|
||||
public function flagMessage(Account $account, string $mailbox, int $uid, string $flag, bool $value): void {
|
||||
public function flagMessage(MailAccount $account, string $mailbox, int $uid, string $flag, bool $value): void {
|
||||
try {
|
||||
$mb = $this->mailboxMapper->find($account, $mailbox);
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
@ -495,7 +486,7 @@ class MailManager implements IMailManager {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function tagMessagesWithClient(Horde_Imap_Client_Socket $client, Account $account, Mailbox $mailbox, array $messages, Tag $tag, bool $value):void {
|
||||
public function tagMessagesWithClient(Horde_Imap_Client_Socket $client, MailAccount $account, Mailbox $mailbox, array $messages, Tag $tag, bool $value):void {
|
||||
if ($this->isPermflagsEnabled($client, $account, $mailbox->getName()) === true) {
|
||||
$messageIds = array_map(static function (Message $message) {
|
||||
return $message->getUid();
|
||||
|
@ -530,7 +521,6 @@ class MailManager implements IMailManager {
|
|||
/**
|
||||
* Tag (flag) a message on IMAP
|
||||
*
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @param Message $message
|
||||
* @param Tag $tag
|
||||
|
@ -543,7 +533,7 @@ class MailManager implements IMailManager {
|
|||
*
|
||||
* @link https://github.com/nextcloud/mail/issues/25
|
||||
*/
|
||||
public function tagMessage(Account $account, string $mailbox, Message $message, Tag $tag, bool $value): void {
|
||||
public function tagMessage(MailAccount $account, string $mailbox, Message $message, Tag $tag, bool $value): void {
|
||||
try {
|
||||
$mb = $this->mailboxMapper->find($account, $mailbox);
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
@ -558,12 +548,10 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Quota|null
|
||||
* @see https://tools.ietf.org/html/rfc2087
|
||||
*/
|
||||
public function getQuota(Account $account): ?Quota {
|
||||
public function getQuota(MailAccount $account): ?Quota {
|
||||
/**
|
||||
* Get all the quotas roots of the user's mailboxes
|
||||
*/
|
||||
|
@ -608,7 +596,7 @@ class MailManager implements IMailManager {
|
|||
);
|
||||
}
|
||||
|
||||
public function renameMailbox(Account $account, Mailbox $mailbox, string $name): Mailbox {
|
||||
public function renameMailbox(MailAccount $account, Mailbox $mailbox, string $name): Mailbox {
|
||||
/*
|
||||
* 1. Rename on IMAP
|
||||
*/
|
||||
|
@ -639,12 +627,11 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function deleteMailbox(Account $account,
|
||||
public function deleteMailbox(MailAccount $account,
|
||||
Mailbox $mailbox): void {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
|
@ -658,7 +645,6 @@ class MailManager implements IMailManager {
|
|||
/**
|
||||
* Clear messages in folder
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws DoesNotExistException
|
||||
|
@ -666,10 +652,10 @@ class MailManager implements IMailManager {
|
|||
* @throws Horde_Imap_Client_Exception_NoSupportExtension
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearMailbox(Account $account,
|
||||
public function clearMailbox(MailAccount $account,
|
||||
Mailbox $mailbox): void {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
$trashMailboxId = $account->getMailAccount()->getTrashMailboxId();
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
$currentMailboxId = $mailbox->getId();
|
||||
try {
|
||||
if (($currentMailboxId !== $trashMailboxId) && !is_null($trashMailboxId)) {
|
||||
|
@ -689,12 +675,11 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message $message
|
||||
* @return Attachment[]
|
||||
*/
|
||||
public function getMailAttachments(Account $account, Mailbox $mailbox, Message $message): array {
|
||||
public function getMailAttachments(MailAccount $account, Mailbox $mailbox, Message $message): array {
|
||||
$client = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
return $this->imapMessageMapper->getAttachments(
|
||||
|
@ -709,7 +694,6 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param Message $message
|
||||
* @param string $attachmentId
|
||||
|
@ -721,7 +705,7 @@ class MailManager implements IMailManager {
|
|||
* @throws ServiceException
|
||||
* @throws Horde_Mime_Exception
|
||||
*/
|
||||
public function getMailAttachment(Account $account,
|
||||
public function getMailAttachment(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
Message $message,
|
||||
string $attachmentId): Attachment {
|
||||
|
@ -760,7 +744,7 @@ class MailManager implements IMailManager {
|
|||
* @param string $mailbox
|
||||
* @return array
|
||||
*/
|
||||
public function filterFlags(Horde_Imap_Client_Socket $client, Account $account, string $flag, string $mailbox): array {
|
||||
public function filterFlags(Horde_Imap_Client_Socket $client, MailAccount $account, string $flag, string $mailbox): array {
|
||||
// check for RFC server flags
|
||||
if (array_key_exists($flag, self::ALLOWED_FLAGS) === true) {
|
||||
return self::ALLOWED_FLAGS[$flag];
|
||||
|
@ -776,12 +760,8 @@ class MailManager implements IMailManager {
|
|||
|
||||
/**
|
||||
* Check IMAP server for support for PERMANENTFLAGS
|
||||
*
|
||||
* @param Account $account
|
||||
* @param string $mailbox
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPermflagsEnabled(Horde_Imap_Client_Socket $client, Account $account, string $mailbox): bool {
|
||||
public function isPermflagsEnabled(Horde_Imap_Client_Socket $client, MailAccount $account, string $mailbox): bool {
|
||||
try {
|
||||
$capabilities = $client->status($mailbox, Horde_Imap_Client::STATUS_PERMFLAGS);
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
|
@ -844,7 +824,7 @@ class MailManager implements IMailManager {
|
|||
return $this->tagMapper->delete($tag);
|
||||
}
|
||||
|
||||
public function deleteTagForAccount(int $id, string $userId, Tag $tag, Account $account) :void {
|
||||
public function deleteTagForAccount(int $id, string $userId, Tag $tag, MailAccount $account) :void {
|
||||
try {
|
||||
$messageTags = $this->messageTagsMapper->getMessagesByTag($id);
|
||||
$messages = array_merge(... array_map(function ($messageTag) use ($account) {
|
||||
|
@ -878,8 +858,8 @@ class MailManager implements IMailManager {
|
|||
}
|
||||
}
|
||||
|
||||
public function moveThread(Account $srcAccount, Mailbox $srcMailbox, Account $dstAccount, Mailbox $dstMailbox, string $threadRootId): array {
|
||||
$mailAccount = $srcAccount->getMailAccount();
|
||||
public function moveThread(MailAccount $srcAccount, Mailbox $srcMailbox, MailAccount $dstAccount, Mailbox $dstMailbox, string $threadRootId): array {
|
||||
$mailAccount = $srcAccount;
|
||||
$messageInTrash = $srcMailbox->getId() === $mailAccount->getTrashMailboxId();
|
||||
|
||||
$messages = $this->threadMapper->findMessageUidsAndMailboxNamesByAccountAndThreadRoot(
|
||||
|
@ -911,8 +891,8 @@ class MailManager implements IMailManager {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function deleteThread(Account $account, Mailbox $mailbox, string $threadRootId): void {
|
||||
$mailAccount = $account->getMailAccount();
|
||||
public function deleteThread(MailAccount $account, Mailbox $mailbox, string $threadRootId): void {
|
||||
$mailAccount = $account;
|
||||
$messageInTrash = $mailbox->getId() === $mailAccount->getTrashMailboxId();
|
||||
|
||||
$messages = $this->threadMapper->findMessageUidsAndMailboxNamesByAccountAndThreadRoot(
|
||||
|
@ -938,7 +918,7 @@ class MailManager implements IMailManager {
|
|||
/**
|
||||
* @return Message[]
|
||||
*/
|
||||
public function getByMessageId(Account $account, string $messageId): array {
|
||||
public function getByMessageId(MailAccount $account, string $messageId): array {
|
||||
return $this->dbMessageMapper->findByMessageId($account, $messageId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ use Horde_Mime_Headers_Subject;
|
|||
use Horde_Mime_Mail;
|
||||
use Horde_Mime_Mdn;
|
||||
use Horde_Smtp_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Address;
|
||||
use OCA\Mail\AddressList;
|
||||
use OCA\Mail\Contracts\IMailTransmission;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -70,7 +70,7 @@ class MailTransmission implements IMailTransmission {
|
|||
) {
|
||||
}
|
||||
|
||||
public function sendMessage(Account $account, LocalMessage $localMessage): void {
|
||||
public function sendMessage(MailAccount $account, LocalMessage $localMessage): void {
|
||||
$to = $this->transmissionService->getAddressList($localMessage, Recipient::TYPE_TO);
|
||||
$cc = $this->transmissionService->getAddressList($localMessage, Recipient::TYPE_CC);
|
||||
$bcc = $this->transmissionService->getAddressList($localMessage, Recipient::TYPE_BCC);
|
||||
|
@ -80,7 +80,7 @@ class MailTransmission implements IMailTransmission {
|
|||
if ($localMessage->getAliasId() !== null) {
|
||||
$alias = $this->aliasesService->find($localMessage->getAliasId(), $account->getUserId());
|
||||
}
|
||||
$fromEmail = $alias ? $alias->getAlias() : $account->getEMailAddress();
|
||||
$fromEmail = $alias ? $alias->getAlias() : $account->getEmail();
|
||||
$from = new AddressList([
|
||||
Address::fromRaw($account->getName(), $fromEmail),
|
||||
]);
|
||||
|
@ -165,7 +165,7 @@ class MailTransmission implements IMailTransmission {
|
|||
);
|
||||
}
|
||||
|
||||
public function saveLocalDraft(Account $account, LocalMessage $message): void {
|
||||
public function saveLocalDraft(MailAccount $account, LocalMessage $message): void {
|
||||
$to = $this->transmissionService->getAddressList($message, Recipient::TYPE_TO);
|
||||
$cc = $this->transmissionService->getAddressList($message, Recipient::TYPE_CC);
|
||||
$bcc = $this->transmissionService->getAddressList($message, Recipient::TYPE_BCC);
|
||||
|
@ -177,7 +177,7 @@ class MailTransmission implements IMailTransmission {
|
|||
$imapMessage->setTo($to);
|
||||
$imapMessage->setSubject($message->getSubject());
|
||||
$from = new AddressList([
|
||||
Address::fromRaw($account->getName(), $account->getEMailAddress()),
|
||||
Address::fromRaw($account->getName(), $account->getEmail()),
|
||||
]);
|
||||
$imapMessage->setFrom($from);
|
||||
$imapMessage->setCC($cc);
|
||||
|
@ -215,7 +215,7 @@ class MailTransmission implements IMailTransmission {
|
|||
$mail->send($transport, false, false);
|
||||
$perfLogger->step('create IMAP draft message');
|
||||
// save the message in the drafts folder
|
||||
$draftsMailboxId = $account->getMailAccount()->getDraftsMailboxId();
|
||||
$draftsMailboxId = $account->getDraftsMailboxId();
|
||||
if ($draftsMailboxId === null) {
|
||||
throw new ClientException('No drafts mailbox configured');
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ class MailTransmission implements IMailTransmission {
|
|||
$imapMessage->setTo($message->getTo());
|
||||
$imapMessage->setSubject($message->getSubject());
|
||||
$from = new AddressList([
|
||||
Address::fromRaw($account->getName(), $account->getEMailAddress()),
|
||||
Address::fromRaw($account->getName(), $account->getEmail()),
|
||||
]);
|
||||
$imapMessage->setFrom($from);
|
||||
$imapMessage->setCC($message->getCc());
|
||||
|
@ -297,7 +297,7 @@ class MailTransmission implements IMailTransmission {
|
|||
$mail->send($transport, false, false);
|
||||
$perfLogger->step('create IMAP message');
|
||||
// save the message in the drafts folder
|
||||
$draftsMailboxId = $account->getMailAccount()->getDraftsMailboxId();
|
||||
$draftsMailboxId = $account->getDraftsMailboxId();
|
||||
if ($draftsMailboxId === null) {
|
||||
throw new ClientException('No drafts mailbox configured');
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ class MailTransmission implements IMailTransmission {
|
|||
return [$account, $draftsMailbox, $newUid];
|
||||
}
|
||||
|
||||
public function sendMdn(Account $account, Mailbox $mailbox, Message $message): void {
|
||||
public function sendMdn(MailAccount $account, Mailbox $mailbox, Message $message): void {
|
||||
$query = new Horde_Imap_Client_Fetch_Query();
|
||||
$query->flags();
|
||||
$query->uid();
|
||||
|
@ -384,10 +384,10 @@ class MailTransmission implements IMailTransmission {
|
|||
true,
|
||||
true,
|
||||
'displayed',
|
||||
$account->getMailAccount()->getOutboundHost(),
|
||||
$account->getOutboundHost(),
|
||||
$smtpClient,
|
||||
[
|
||||
'from_addr' => $account->getEMailAddress(),
|
||||
'from_addr' => $account->getEmail(),
|
||||
'charset' => 'UTF-8',
|
||||
]
|
||||
);
|
||||
|
|
|
@ -9,11 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Contracts\IMailTransmission;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\LocalMessageMapper;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Recipient;
|
||||
use OCA\Mail\Events\OutboxMessageCreatedEvent;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
|
@ -122,12 +122,11 @@ class OutboxService {
|
|||
* @throws Exception
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function sendMessage(LocalMessage $message, Account $account): LocalMessage {
|
||||
public function sendMessage(LocalMessage $message, MailAccount $account): LocalMessage {
|
||||
return $this->sendChain->process($account, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param LocalMessage $message
|
||||
* @param array<int, array{email: string, label?: string}> $to
|
||||
* @param array<int, array{email: string, label?: string}> $cc
|
||||
|
@ -135,7 +134,7 @@ class OutboxService {
|
|||
* @param array $attachments
|
||||
* @return LocalMessage
|
||||
*/
|
||||
public function saveMessage(Account $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
public function saveMessage(MailAccount $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
$toRecipients = self::convertToRecipient($to, Recipient::TYPE_TO);
|
||||
$ccRecipients = self::convertToRecipient($cc, Recipient::TYPE_CC);
|
||||
$bccRecipients = self::convertToRecipient($bcc, Recipient::TYPE_BCC);
|
||||
|
@ -158,7 +157,6 @@ class OutboxService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param LocalMessage $message
|
||||
* @param array<int, array{email: string, label?: string}> $to
|
||||
* @param array<int, array{email: string, label?: string}> $cc
|
||||
|
@ -166,7 +164,7 @@ class OutboxService {
|
|||
* @param array $attachments
|
||||
* @return LocalMessage
|
||||
*/
|
||||
public function updateMessage(Account $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
public function updateMessage(MailAccount $account, LocalMessage $message, array $to, array $cc, array $bcc, array $attachments = []): LocalMessage {
|
||||
$toRecipients = self::convertToRecipient($to, Recipient::TYPE_TO);
|
||||
$ccRecipients = self::convertToRecipient($cc, Recipient::TYPE_CC);
|
||||
$bccRecipients = self::convertToRecipient($bcc, Recipient::TYPE_BCC);
|
||||
|
@ -189,11 +187,10 @@ class OutboxService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param int $draftId
|
||||
* @return void
|
||||
*/
|
||||
public function handleDraft(Account $account, int $draftId): void {
|
||||
public function handleDraft(MailAccount $account, int $draftId): void {
|
||||
$message = $this->mailManager->getMessage($account->getUserId(), $draftId);
|
||||
$this->eventDispatcher->dispatch(
|
||||
OutboxMessageCreatedEvent::class,
|
||||
|
|
|
@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper;
|
||||
|
@ -32,7 +32,7 @@ class PreprocessingService {
|
|||
$this->previewEnhancer = $previewEnhancer;
|
||||
}
|
||||
|
||||
public function process(int $limitTimestamp, Account $account): void {
|
||||
public function process(int $limitTimestamp, MailAccount $account): void {
|
||||
$mailboxes = $this->mailboxMapper->findAll($account);
|
||||
if ($mailboxes === []) {
|
||||
$this->logger->debug('No mailboxes found.');
|
||||
|
|
|
@ -10,8 +10,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Service\Search;
|
||||
|
||||
use Horde_Imap_Client;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailSearch;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -59,7 +59,7 @@ class MailSearch implements IMailSearch {
|
|||
$this->timeFactory = $timeFactory;
|
||||
}
|
||||
|
||||
public function findMessage(Account $account,
|
||||
public function findMessage(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
Message $message): Message {
|
||||
$processed = $this->previewEnhancer->process(
|
||||
|
@ -74,7 +74,6 @@ class MailSearch implements IMailSearch {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param string $sortOrder
|
||||
* @param string|null $filter
|
||||
|
@ -86,7 +85,7 @@ class MailSearch implements IMailSearch {
|
|||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function findMessages(Account $account,
|
||||
public function findMessages(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
string $sortOrder,
|
||||
?string $filter,
|
||||
|
@ -152,7 +151,7 @@ class MailSearch implements IMailSearch {
|
|||
*
|
||||
* @throws ServiceException
|
||||
*/
|
||||
private function getIdsLocally(Account $account, Mailbox $mailbox, SearchQuery $query, string $sortOrder, ?int $limit): array {
|
||||
private function getIdsLocally(MailAccount $account, Mailbox $mailbox, SearchQuery $query, string $sortOrder, ?int $limit): array {
|
||||
if (empty($query->getBodies())) {
|
||||
return $this->messageMapper->findIdsByQuery($mailbox, $query, $sortOrder, $limit);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use Horde_Imap_Client_Exception;
|
|||
use Horde_Mail_Exception;
|
||||
use Horde_Mail_Transport_Smtphorde;
|
||||
use InvalidArgumentException;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\TagMapper;
|
||||
use OCA\Mail\Exception\CouldNotConnectException;
|
||||
|
@ -60,8 +59,6 @@ class SetupService {
|
|||
/**
|
||||
* @throws CouldNotConnectException
|
||||
* @throws ServiceException
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function createNewAccount(string $accountName,
|
||||
string $emailAddress,
|
||||
|
@ -77,7 +74,7 @@ class SetupService {
|
|||
?string $smtpPassword,
|
||||
string $uid,
|
||||
string $authMethod,
|
||||
?int $accountId = null): Account {
|
||||
?int $accountId = null): MailAccount {
|
||||
$this->logger->info('Setting up manually configured account');
|
||||
$newAccount = new MailAccount([
|
||||
'accountId' => $accountId,
|
||||
|
@ -104,10 +101,9 @@ class SetupService {
|
|||
}
|
||||
$newAccount->setAuthMethod($authMethod);
|
||||
|
||||
$account = new Account($newAccount);
|
||||
if ($authMethod === 'password' && $imapPassword !== null) {
|
||||
$this->logger->debug('Connecting to account {account}', ['account' => $newAccount->getEmail()]);
|
||||
$this->testConnectivity($account);
|
||||
$this->testConnectivity($newAccount);
|
||||
}
|
||||
|
||||
$this->accountService->save($newAccount);
|
||||
|
@ -115,15 +111,14 @@ class SetupService {
|
|||
|
||||
$this->tagMapper->createDefaultTags($newAccount);
|
||||
|
||||
return $account;
|
||||
return $newAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @throws CouldNotConnectException
|
||||
*/
|
||||
protected function testConnectivity(Account $account): void {
|
||||
$mailAccount = $account->getMailAccount();
|
||||
protected function testConnectivity(MailAccount $account): void {
|
||||
$mailAccount = $account;
|
||||
|
||||
$imapClient = $this->imapClientFactory->getClient($account);
|
||||
try {
|
||||
|
|
|
@ -63,14 +63,14 @@ class SieveService {
|
|||
private function getClient(string $userId, int $accountId): \Horde\ManageSieve {
|
||||
$account = $this->accountService->find($userId, $accountId);
|
||||
|
||||
if (!$account->getMailAccount()->isSieveEnabled()) {
|
||||
if (!$account->isSieveEnabled()) {
|
||||
throw new ClientException('ManageSieve is disabled');
|
||||
}
|
||||
|
||||
try {
|
||||
$sieve = $this->sieveClientFactory->getClient($account);
|
||||
} catch (ManagesieveException $e) {
|
||||
throw new CouldNotConnectException($e, 'ManageSieve', $account->getMailAccount()->getSieveHost(), $account->getMailAccount()->getSievePort());
|
||||
throw new CouldNotConnectException($e, 'ManageSieve', $account->getSieveHost(), $account->getSievePort());
|
||||
}
|
||||
|
||||
return $sieve;
|
||||
|
|
|
@ -9,8 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\MailAccountMapper;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
|
@ -50,8 +50,6 @@ class SnoozeService {
|
|||
public function wakeMessages(): void {
|
||||
$accounts = $this->accountMapper->getAllAccounts();
|
||||
foreach ($accounts as $account) {
|
||||
$account = new Account($account);
|
||||
|
||||
try {
|
||||
$this->wakeMessagesByAccount($account);
|
||||
} catch (ServiceException|ClientException $e) {
|
||||
|
@ -59,7 +57,7 @@ class SnoozeService {
|
|||
'exception' => $e,
|
||||
'userId' => $account->getUserId(),
|
||||
'accountId' => $account->getId(),
|
||||
'snoozeMailboxId' => $account->getMailAccount()->getSnoozeMailboxId(),
|
||||
'snoozeMailboxId' => $account->getSnoozeMailboxId(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +66,7 @@ class SnoozeService {
|
|||
/**
|
||||
* @param Message $message
|
||||
* @param int $unixTimestamp
|
||||
* @param Account $srcAccount
|
||||
* @param Mailbox $srcMailbox
|
||||
* @param Account $dstAccount
|
||||
* @param Mailbox $dstMailbox
|
||||
*
|
||||
* @return void
|
||||
|
@ -80,9 +76,9 @@ class SnoozeService {
|
|||
public function snoozeMessage(
|
||||
Message $message,
|
||||
int $unixTimestamp,
|
||||
Account $srcAccount,
|
||||
MailAccount $srcAccount,
|
||||
Mailbox $srcMailbox,
|
||||
Account $dstAccount,
|
||||
MailAccount $dstAccount,
|
||||
Mailbox $dstMailbox
|
||||
): void {
|
||||
$newUid = $this->mailManager->moveMessage(
|
||||
|
@ -146,9 +142,7 @@ class SnoozeService {
|
|||
/**
|
||||
* @param Message $selectedMessage
|
||||
* @param int $unixTimestamp
|
||||
* @param Account $srcAccount
|
||||
* @param Mailbox $srcMailbox
|
||||
* @param Account $dstAccount
|
||||
* @param Mailbox $dstMailbox
|
||||
*
|
||||
* @return void
|
||||
|
@ -158,9 +152,9 @@ class SnoozeService {
|
|||
public function snoozeThread(
|
||||
Message $selectedMessage,
|
||||
int $unixTimestamp,
|
||||
Account $srcAccount,
|
||||
MailAccount $srcAccount,
|
||||
Mailbox $srcMailbox,
|
||||
Account $dstAccount,
|
||||
MailAccount $dstAccount,
|
||||
Mailbox $dstMailbox
|
||||
): void {
|
||||
$newUids = $this->mailManager->moveThread(
|
||||
|
@ -271,8 +265,8 @@ class SnoozeService {
|
|||
/**
|
||||
* @throws ServiceException
|
||||
*/
|
||||
private function wakeMessagesByAccount(Account $account): void {
|
||||
$snoozeMailboxId = $account->getMailAccount()->getSnoozeMailboxId();
|
||||
private function wakeMessagesByAccount(MailAccount $account): void {
|
||||
$snoozeMailboxId = $account->getSnoozeMailboxId();
|
||||
if ($snoozeMailboxId === null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,488 +1,486 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Service\Sync;
|
||||
|
||||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Base;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper as DatabaseMessageMapper;
|
||||
use OCA\Mail\Events\NewMessagesSynchronized;
|
||||
use OCA\Mail\Events\SynchronizationEvent;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
use OCA\Mail\Exception\IncompleteSyncException;
|
||||
use OCA\Mail\Exception\MailboxDoesNotSupportModSequencesException;
|
||||
use OCA\Mail\Exception\MailboxLockedException;
|
||||
use OCA\Mail\Exception\MailboxNotCachedException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\Exception\UidValidityChangedException;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper;
|
||||
use OCA\Mail\IMAP\Sync\Request;
|
||||
use OCA\Mail\IMAP\Sync\Synchronizer;
|
||||
use OCA\Mail\Model\IMAPMessage;
|
||||
use OCA\Mail\Support\PerformanceLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use function array_chunk;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
||||
class ImapToDbSynchronizer {
|
||||
/** @var int */
|
||||
public const MAX_NEW_MESSAGES = 5000;
|
||||
|
||||
/** @var DatabaseMessageMapper */
|
||||
private $dbMapper;
|
||||
|
||||
/** @var IMAPClientFactory */
|
||||
private $clientFactory;
|
||||
|
||||
/** @var ImapMessageMapper */
|
||||
private $imapMapper;
|
||||
|
||||
/** @var MailboxMapper */
|
||||
private $mailboxMapper;
|
||||
|
||||
/** @var Synchronizer */
|
||||
private $synchronizer;
|
||||
|
||||
/** @var IEventDispatcher */
|
||||
private $dispatcher;
|
||||
|
||||
/** @var PerformanceLogger */
|
||||
private $performanceLogger;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var IMailManager */
|
||||
private $mailManager;
|
||||
|
||||
public function __construct(DatabaseMessageMapper $dbMapper,
|
||||
IMAPClientFactory $clientFactory,
|
||||
ImapMessageMapper $imapMapper,
|
||||
MailboxMapper $mailboxMapper,
|
||||
Synchronizer $synchronizer,
|
||||
IEventDispatcher $dispatcher,
|
||||
PerformanceLogger $performanceLogger,
|
||||
LoggerInterface $logger,
|
||||
IMailManager $mailManager) {
|
||||
$this->dbMapper = $dbMapper;
|
||||
$this->clientFactory = $clientFactory;
|
||||
$this->imapMapper = $imapMapper;
|
||||
$this->mailboxMapper = $mailboxMapper;
|
||||
$this->synchronizer = $synchronizer;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->performanceLogger = $performanceLogger;
|
||||
$this->logger = $logger;
|
||||
$this->mailManager = $mailManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function syncAccount(Account $account,
|
||||
LoggerInterface $logger,
|
||||
bool $force = false,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS): void {
|
||||
$rebuildThreads = false;
|
||||
$trashMailboxId = $account->getMailAccount()->getTrashMailboxId();
|
||||
$snoozeMailboxId = $account->getMailAccount()->getSnoozeMailboxId();
|
||||
$sentMailboxId = $account->getMailAccount()->getSentMailboxId();
|
||||
$trashRetentionDays = $account->getMailAccount()->getTrashRetentionDays();
|
||||
|
||||
$client = $this->clientFactory->getClient($account);
|
||||
|
||||
foreach ($this->mailboxMapper->findAll($account) as $mailbox) {
|
||||
$syncTrash = $trashMailboxId === $mailbox->getId() && $trashRetentionDays !== null;
|
||||
$syncSnooze = $snoozeMailboxId === $mailbox->getId();
|
||||
$syncSent = $sentMailboxId === $mailbox->getId() || $mailbox->isSpecialUse('sent');
|
||||
|
||||
if (!$syncTrash && !$mailbox->isInbox() && !$syncSnooze && !$mailbox->getSyncInBackground() && !$syncSent) {
|
||||
$logger->debug('Skipping mailbox sync for ' . $mailbox->getId());
|
||||
continue;
|
||||
}
|
||||
$logger->debug('Syncing ' . $mailbox->getId());
|
||||
if ($this->sync(
|
||||
$account,
|
||||
$client,
|
||||
$mailbox,
|
||||
$logger,
|
||||
$criteria,
|
||||
null,
|
||||
$force,
|
||||
true
|
||||
)) {
|
||||
$rebuildThreads = true;
|
||||
}
|
||||
}
|
||||
|
||||
$client->logout();
|
||||
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached data of a mailbox
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws MailboxLockedException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearCache(Account $account,
|
||||
Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
try {
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
|
||||
$this->resetCache($account, $mailbox);
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException("Could not clear mailbox cache for $id: " . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe all cached messages of a mailbox from the database
|
||||
*
|
||||
* Warning: the caller has to ensure the mailbox is locked
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*/
|
||||
private function resetCache(Account $account, Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
$this->dbMapper->deleteAll($mailbox);
|
||||
$this->logger->debug("All messages of $id cleared");
|
||||
$mailbox->setSyncNewToken(null);
|
||||
$mailbox->setSyncChangedToken(null);
|
||||
$mailbox->setSyncVanishedToken(null);
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws MailboxNotCachedException
|
||||
* @throws ServiceException
|
||||
* @return bool whether to rebuild threads or not
|
||||
*/
|
||||
public function sync(Account $account,
|
||||
Horde_Imap_Client_Base $client,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
|
||||
?array $knownUids = null,
|
||||
bool $force = false,
|
||||
bool $batchSync = false): bool {
|
||||
$rebuildThreads = true;
|
||||
if ($mailbox->getSelectable() === false) {
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
$client->login(); // Need to login before fetching capabilities.
|
||||
|
||||
// There is no partial sync when using QRESYNC. As per RFC the client will always pull
|
||||
// all changes. This is a cheap operation when using QRESYNC as the server keeps track
|
||||
// of a client's state through the sync token. We could just update the sync tokens and
|
||||
// call it a day because Horde caches unrelated/unrequested changes until the next
|
||||
// operation. However, our cache is not reliable as some instance might use APCu which
|
||||
// isn't shared between cron and web requests.
|
||||
if ($client->capability->isEnabled('QRESYNC')) {
|
||||
$this->logger->debug('Forcing full sync due to QRESYNC');
|
||||
$criteria |= Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
| Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
| Horde_Imap_Client::SYNC_VANISHEDUIDS;
|
||||
}
|
||||
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for new messages sync');
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for changed messages sync');
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for vanished messages sync');
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($force
|
||||
|| $mailbox->getSyncNewToken() === null
|
||||
|| $mailbox->getSyncChangedToken() === null
|
||||
|| $mailbox->getSyncVanishedToken() === null) {
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId());
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} else {
|
||||
try {
|
||||
$logger->debug('Running partial sync for ' . $mailbox->getId());
|
||||
// Only rebuild threads if there were new or vanished messages
|
||||
$rebuildThreads = $this->runPartialSync($client, $account, $mailbox, $logger, $criteria, $knownUids);
|
||||
} catch (UidValidityChangedException $e) {
|
||||
$logger->warning('Mailbox UID validity changed. Wiping cache and performing full sync for ' . $mailbox->getId());
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} catch (MailboxDoesNotSupportModSequencesException $e) {
|
||||
$logger->warning('Mailbox does not support mod-sequences error occured. Wiping cache and performing full sync for ' . $mailbox->getId(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset - no mod-sequences error');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
}
|
||||
}
|
||||
} catch (ServiceException $e) {
|
||||
// Just rethrow, don't wrap into another exception
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException('Sync failed for ' . $account->getId() . ':' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from vanished messages sync');
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from changed messages sync');
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from new messages sync');
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$batchSync) {
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$this->logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ServiceException
|
||||
* @throws IncompleteSyncException
|
||||
*/
|
||||
private function runInitialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
Account $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger): void {
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'Initial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
// Need a client without a cache
|
||||
$client->logout();
|
||||
$client = $this->clientFactory->getClient($account, false);
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
try {
|
||||
$imapMessages = $this->imapMapper->findAll(
|
||||
$client,
|
||||
$mailbox->getName(),
|
||||
self::MAX_NEW_MESSAGES,
|
||||
$highestKnownUid ?? 0,
|
||||
$logger,
|
||||
$perf,
|
||||
$account->getUserId(),
|
||||
);
|
||||
$perf->step(sprintf('fetch %d messages from IMAP', count($imapMessages)));
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
throw new ServiceException('Can not get messages from mailbox ' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
foreach (array_chunk($imapMessages['messages'], 500) as $chunk) {
|
||||
$messages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
|
||||
}, $chunk);
|
||||
$this->dbMapper->insertBulk($account, ...$messages);
|
||||
$perf->step(sprintf('persist %d messages in database', count($chunk)));
|
||||
// Free the memory
|
||||
unset($messages);
|
||||
}
|
||||
|
||||
if (!$imapMessages['all']) {
|
||||
// We might need more attempts to fill the cache
|
||||
$loggingMailboxId = $account->getId() . ':' . $mailbox->getName();
|
||||
$total = $imapMessages['total'];
|
||||
$cached = count($this->dbMapper->findAllUids($mailbox));
|
||||
$perf->step('find number of cached UIDs');
|
||||
|
||||
$perf->end();
|
||||
throw new IncompleteSyncException("Initial sync is not complete for $loggingMailboxId ($cached of $total messages cached).");
|
||||
}
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
|
||||
$perf->end();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $knownUids
|
||||
*
|
||||
* @throws ServiceException
|
||||
* @throws UidValidityChangedException
|
||||
* @return bool whether there are new or vanished messages
|
||||
*/
|
||||
private function runPartialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
Account $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria,
|
||||
?array $knownUids = null): bool {
|
||||
$newOrVanished = false;
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'partial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
$uids = $knownUids ?? $this->dbMapper->findAllUids($mailbox);
|
||||
$perf->step('get all known UIDs');
|
||||
|
||||
if ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncNewToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
);
|
||||
$perf->step('get new messages via Horde');
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
if ($highestKnownUid === null) {
|
||||
// Everything is relevant
|
||||
$newMessages = $response->getNewMessages();
|
||||
} else {
|
||||
// Filter out anything that is already in the DB. Ideally this never happens, but if there is an error
|
||||
// during a consecutive chunk INSERT, the sync token won't be updated. In that case the same message(s)
|
||||
// will be seen as *new* and therefore cause conflicts.
|
||||
$newMessages = array_filter($response->getNewMessages(), static function (IMAPMessage $imapMessage) use ($highestKnownUid) {
|
||||
return $imapMessage->getUid() > $highestKnownUid;
|
||||
});
|
||||
}
|
||||
|
||||
foreach (array_chunk($newMessages, 500) as $chunk) {
|
||||
$dbMessages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
|
||||
}, $chunk);
|
||||
|
||||
$this->dbMapper->insertBulk($account, ...$dbMessages);
|
||||
|
||||
$this->dispatcher->dispatch(
|
||||
NewMessagesSynchronized::class,
|
||||
new NewMessagesSynchronized($account, $mailbox, $dbMessages)
|
||||
);
|
||||
$perf->step('classified a chunk of new messages');
|
||||
}
|
||||
$perf->step('persist new messages');
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$newOrVanished = $newMessages !== [];
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncChangedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
);
|
||||
$perf->step('get changed messages via Horde');
|
||||
|
||||
$permflagsEnabled = $this->mailManager->isPermflagsEnabled($client, $account, $mailbox->getName());
|
||||
|
||||
foreach (array_chunk($response->getChangedMessages(), 500) as $chunk) {
|
||||
$this->dbMapper->updateBulk($account, $permflagsEnabled, ...array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
|
||||
}, $chunk));
|
||||
}
|
||||
$perf->step('persist changed messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the change token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncVanishedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_VANISHEDUIDS
|
||||
);
|
||||
$perf->step('get vanished messages via Horde');
|
||||
|
||||
foreach (array_chunk($response->getVanishedMessageUids(), 500) as $chunk) {
|
||||
$this->dbMapper->deleteByUid($mailbox, ...$chunk);
|
||||
}
|
||||
$perf->step('delete vanished messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the vanish token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
$newOrVanished = $newOrVanished || !empty($response->getVanishedMessageUids());
|
||||
}
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
$perf->end();
|
||||
|
||||
return $newOrVanished;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Service\Sync;
|
||||
|
||||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Base;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper as DatabaseMessageMapper;
|
||||
use OCA\Mail\Events\NewMessagesSynchronized;
|
||||
use OCA\Mail\Events\SynchronizationEvent;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
use OCA\Mail\Exception\IncompleteSyncException;
|
||||
use OCA\Mail\Exception\MailboxDoesNotSupportModSequencesException;
|
||||
use OCA\Mail\Exception\MailboxLockedException;
|
||||
use OCA\Mail\Exception\MailboxNotCachedException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\Exception\UidValidityChangedException;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper;
|
||||
use OCA\Mail\IMAP\Sync\Request;
|
||||
use OCA\Mail\IMAP\Sync\Synchronizer;
|
||||
use OCA\Mail\Model\IMAPMessage;
|
||||
use OCA\Mail\Support\PerformanceLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use function array_chunk;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
||||
class ImapToDbSynchronizer {
|
||||
/** @var int */
|
||||
public const MAX_NEW_MESSAGES = 5000;
|
||||
|
||||
/** @var DatabaseMessageMapper */
|
||||
private $dbMapper;
|
||||
|
||||
/** @var IMAPClientFactory */
|
||||
private $clientFactory;
|
||||
|
||||
/** @var ImapMessageMapper */
|
||||
private $imapMapper;
|
||||
|
||||
/** @var MailboxMapper */
|
||||
private $mailboxMapper;
|
||||
|
||||
/** @var Synchronizer */
|
||||
private $synchronizer;
|
||||
|
||||
/** @var IEventDispatcher */
|
||||
private $dispatcher;
|
||||
|
||||
/** @var PerformanceLogger */
|
||||
private $performanceLogger;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var IMailManager */
|
||||
private $mailManager;
|
||||
|
||||
public function __construct(DatabaseMessageMapper $dbMapper,
|
||||
IMAPClientFactory $clientFactory,
|
||||
ImapMessageMapper $imapMapper,
|
||||
MailboxMapper $mailboxMapper,
|
||||
Synchronizer $synchronizer,
|
||||
IEventDispatcher $dispatcher,
|
||||
PerformanceLogger $performanceLogger,
|
||||
LoggerInterface $logger,
|
||||
IMailManager $mailManager) {
|
||||
$this->dbMapper = $dbMapper;
|
||||
$this->clientFactory = $clientFactory;
|
||||
$this->imapMapper = $imapMapper;
|
||||
$this->mailboxMapper = $mailboxMapper;
|
||||
$this->synchronizer = $synchronizer;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->performanceLogger = $performanceLogger;
|
||||
$this->logger = $logger;
|
||||
$this->mailManager = $mailManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function syncAccount(MailAccount $account,
|
||||
LoggerInterface $logger,
|
||||
bool $force = false,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS): void {
|
||||
$rebuildThreads = false;
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
$snoozeMailboxId = $account->getSnoozeMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
$trashRetentionDays = $account->getTrashRetentionDays();
|
||||
|
||||
$client = $this->clientFactory->getClient($account);
|
||||
|
||||
foreach ($this->mailboxMapper->findAll($account) as $mailbox) {
|
||||
$syncTrash = $trashMailboxId === $mailbox->getId() && $trashRetentionDays !== null;
|
||||
$syncSnooze = $snoozeMailboxId === $mailbox->getId();
|
||||
$syncSent = $sentMailboxId === $mailbox->getId() || $mailbox->isSpecialUse('sent');
|
||||
|
||||
if (!$syncTrash && !$mailbox->isInbox() && !$syncSnooze && !$mailbox->getSyncInBackground() && !$syncSent) {
|
||||
$logger->debug('Skipping mailbox sync for ' . $mailbox->getId());
|
||||
continue;
|
||||
}
|
||||
$logger->debug('Syncing ' . $mailbox->getId());
|
||||
if ($this->sync(
|
||||
$account,
|
||||
$client,
|
||||
$mailbox,
|
||||
$logger,
|
||||
$criteria,
|
||||
null,
|
||||
$force,
|
||||
true
|
||||
)) {
|
||||
$rebuildThreads = true;
|
||||
}
|
||||
}
|
||||
|
||||
$client->logout();
|
||||
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached data of a mailbox
|
||||
*
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws MailboxLockedException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearCache(MailAccount $account,
|
||||
Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
try {
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
|
||||
$this->resetCache($account, $mailbox);
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException("Could not clear mailbox cache for $id: " . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe all cached messages of a mailbox from the database
|
||||
*
|
||||
* Warning: the caller has to ensure the mailbox is locked
|
||||
*
|
||||
* @param Mailbox $mailbox
|
||||
*/
|
||||
private function resetCache(MailAccount $account, Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
$this->dbMapper->deleteAll($mailbox);
|
||||
$this->logger->debug("All messages of $id cleared");
|
||||
$mailbox->setSyncNewToken(null);
|
||||
$mailbox->setSyncChangedToken(null);
|
||||
$mailbox->setSyncVanishedToken(null);
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws MailboxNotCachedException
|
||||
* @throws ServiceException
|
||||
* @return bool whether to rebuild threads or not
|
||||
*/
|
||||
public function sync(MailAccount $account,
|
||||
Horde_Imap_Client_Base $client,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
|
||||
?array $knownUids = null,
|
||||
bool $force = false,
|
||||
bool $batchSync = false): bool {
|
||||
$rebuildThreads = true;
|
||||
if ($mailbox->getSelectable() === false) {
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
$client->login(); // Need to login before fetching capabilities.
|
||||
|
||||
// There is no partial sync when using QRESYNC. As per RFC the client will always pull
|
||||
// all changes. This is a cheap operation when using QRESYNC as the server keeps track
|
||||
// of a client's state through the sync token. We could just update the sync tokens and
|
||||
// call it a day because Horde caches unrelated/unrequested changes until the next
|
||||
// operation. However, our cache is not reliable as some instance might use APCu which
|
||||
// isn't shared between cron and web requests.
|
||||
if ($client->capability->isEnabled('QRESYNC')) {
|
||||
$this->logger->debug('Forcing full sync due to QRESYNC');
|
||||
$criteria |= Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
| Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
| Horde_Imap_Client::SYNC_VANISHEDUIDS;
|
||||
}
|
||||
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for new messages sync');
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for changed messages sync');
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for vanished messages sync');
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($force
|
||||
|| $mailbox->getSyncNewToken() === null
|
||||
|| $mailbox->getSyncChangedToken() === null
|
||||
|| $mailbox->getSyncVanishedToken() === null) {
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId());
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} else {
|
||||
try {
|
||||
$logger->debug('Running partial sync for ' . $mailbox->getId());
|
||||
// Only rebuild threads if there were new or vanished messages
|
||||
$rebuildThreads = $this->runPartialSync($client, $account, $mailbox, $logger, $criteria, $knownUids);
|
||||
} catch (UidValidityChangedException $e) {
|
||||
$logger->warning('Mailbox UID validity changed. Wiping cache and performing full sync for ' . $mailbox->getId());
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} catch (MailboxDoesNotSupportModSequencesException $e) {
|
||||
$logger->warning('Mailbox does not support mod-sequences error occured. Wiping cache and performing full sync for ' . $mailbox->getId(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset - no mod-sequences error');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
}
|
||||
}
|
||||
} catch (ServiceException $e) {
|
||||
// Just rethrow, don't wrap into another exception
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException('Sync failed for ' . $account->getId() . ':' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from vanished messages sync');
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from changed messages sync');
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from new messages sync');
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$batchSync) {
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$this->logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ServiceException
|
||||
* @throws IncompleteSyncException
|
||||
*/
|
||||
private function runInitialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger): void {
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'Initial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
// Need a client without a cache
|
||||
$client->logout();
|
||||
$client = $this->clientFactory->getClient($account, false);
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
try {
|
||||
$imapMessages = $this->imapMapper->findAll(
|
||||
$client,
|
||||
$mailbox->getName(),
|
||||
self::MAX_NEW_MESSAGES,
|
||||
$highestKnownUid ?? 0,
|
||||
$logger,
|
||||
$perf,
|
||||
$account->getUserId(),
|
||||
);
|
||||
$perf->step(sprintf('fetch %d messages from IMAP', count($imapMessages)));
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
throw new ServiceException('Can not get messages from mailbox ' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
foreach (array_chunk($imapMessages['messages'], 500) as $chunk) {
|
||||
$messages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk);
|
||||
$this->dbMapper->insertBulk($account, ...$messages);
|
||||
$perf->step(sprintf('persist %d messages in database', count($chunk)));
|
||||
// Free the memory
|
||||
unset($messages);
|
||||
}
|
||||
|
||||
if (!$imapMessages['all']) {
|
||||
// We might need more attempts to fill the cache
|
||||
$loggingMailboxId = $account->getId() . ':' . $mailbox->getName();
|
||||
$total = $imapMessages['total'];
|
||||
$cached = count($this->dbMapper->findAllUids($mailbox));
|
||||
$perf->step('find number of cached UIDs');
|
||||
|
||||
$perf->end();
|
||||
throw new IncompleteSyncException("Initial sync is not complete for $loggingMailboxId ($cached of $total messages cached).");
|
||||
}
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
|
||||
$perf->end();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $knownUids
|
||||
*
|
||||
* @throws ServiceException
|
||||
* @throws UidValidityChangedException
|
||||
* @return bool whether there are new or vanished messages
|
||||
*/
|
||||
private function runPartialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria,
|
||||
?array $knownUids = null): bool {
|
||||
$newOrVanished = false;
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'partial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
$uids = $knownUids ?? $this->dbMapper->findAllUids($mailbox);
|
||||
$perf->step('get all known UIDs');
|
||||
|
||||
if ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncNewToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
);
|
||||
$perf->step('get new messages via Horde');
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
if ($highestKnownUid === null) {
|
||||
// Everything is relevant
|
||||
$newMessages = $response->getNewMessages();
|
||||
} else {
|
||||
// Filter out anything that is already in the DB. Ideally this never happens, but if there is an error
|
||||
// during a consecutive chunk INSERT, the sync token won't be updated. In that case the same message(s)
|
||||
// will be seen as *new* and therefore cause conflicts.
|
||||
$newMessages = array_filter($response->getNewMessages(), static function (IMAPMessage $imapMessage) use ($highestKnownUid) {
|
||||
return $imapMessage->getUid() > $highestKnownUid;
|
||||
});
|
||||
}
|
||||
|
||||
foreach (array_chunk($newMessages, 500) as $chunk) {
|
||||
$dbMessages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk);
|
||||
|
||||
$this->dbMapper->insertBulk($account, ...$dbMessages);
|
||||
|
||||
$this->dispatcher->dispatch(
|
||||
NewMessagesSynchronized::class,
|
||||
new NewMessagesSynchronized($account, $mailbox, $dbMessages)
|
||||
);
|
||||
$perf->step('classified a chunk of new messages');
|
||||
}
|
||||
$perf->step('persist new messages');
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$newOrVanished = $newMessages !== [];
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncChangedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
);
|
||||
$perf->step('get changed messages via Horde');
|
||||
|
||||
$permflagsEnabled = $this->mailManager->isPermflagsEnabled($client, $account, $mailbox->getName());
|
||||
|
||||
foreach (array_chunk($response->getChangedMessages(), 500) as $chunk) {
|
||||
$this->dbMapper->updateBulk($account, $permflagsEnabled, ...array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk));
|
||||
}
|
||||
$perf->step('persist changed messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the change token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncVanishedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_VANISHEDUIDS
|
||||
);
|
||||
$perf->step('get vanished messages via Horde');
|
||||
|
||||
foreach (array_chunk($response->getVanishedMessageUids(), 500) as $chunk) {
|
||||
$this->dbMapper->deleteByUid($mailbox, ...$chunk);
|
||||
}
|
||||
$perf->step('delete vanished messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the vanish token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
$newOrVanished = $newOrVanished || !empty($response->getVanishedMessageUids());
|
||||
}
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
$perf->end();
|
||||
|
||||
return $newOrVanished;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,497 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Mail\Service\Sync;
|
||||
|
||||
use Horde_Imap_Client;
|
||||
use Horde_Imap_Client_Base;
|
||||
use Horde_Imap_Client_Exception;
|
||||
use OCA\Mail\Contracts\IMailManager;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\MessageMapper as DatabaseMessageMapper;
|
||||
use OCA\Mail\Events\NewMessagesSynchronized;
|
||||
use OCA\Mail\Events\SynchronizationEvent;
|
||||
use OCA\Mail\Exception\ClientException;
|
||||
use OCA\Mail\Exception\IncompleteSyncException;
|
||||
use OCA\Mail\Exception\MailboxDoesNotSupportModSequencesException;
|
||||
use OCA\Mail\Exception\MailboxLockedException;
|
||||
use OCA\Mail\Exception\MailboxNotCachedException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
use OCA\Mail\Exception\UidValidityChangedException;
|
||||
use OCA\Mail\IMAP\IMAPClientFactory;
|
||||
use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper;
|
||||
use OCA\Mail\IMAP\Sync\Request;
|
||||
use OCA\Mail\IMAP\Sync\Synchronizer;
|
||||
use OCA\Mail\Model\IMAPMessage;
|
||||
use OCA\Mail\Support\PerformanceLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use function array_chunk;
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
||||
class ImapToDbSynchronizer {
|
||||
/** @var int */
|
||||
public const MAX_NEW_MESSAGES = 5000;
|
||||
|
||||
/** @var DatabaseMessageMapper */
|
||||
private $dbMapper;
|
||||
|
||||
/** @var IMAPClientFactory */
|
||||
private $clientFactory;
|
||||
|
||||
/** @var ImapMessageMapper */
|
||||
private $imapMapper;
|
||||
|
||||
/** @var MailboxMapper */
|
||||
private $mailboxMapper;
|
||||
|
||||
/** @var Synchronizer */
|
||||
private $synchronizer;
|
||||
|
||||
/** @var IEventDispatcher */
|
||||
private $dispatcher;
|
||||
|
||||
/** @var PerformanceLogger */
|
||||
private $performanceLogger;
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var IMailManager */
|
||||
private $mailManager;
|
||||
|
||||
public function __construct(DatabaseMessageMapper $dbMapper,
|
||||
IMAPClientFactory $clientFactory,
|
||||
ImapMessageMapper $imapMapper,
|
||||
MailboxMapper $mailboxMapper,
|
||||
Synchronizer $synchronizer,
|
||||
IEventDispatcher $dispatcher,
|
||||
PerformanceLogger $performanceLogger,
|
||||
LoggerInterface $logger,
|
||||
IMailManager $mailManager) {
|
||||
$this->dbMapper = $dbMapper;
|
||||
$this->clientFactory = $clientFactory;
|
||||
$this->imapMapper = $imapMapper;
|
||||
$this->mailboxMapper = $mailboxMapper;
|
||||
$this->synchronizer = $synchronizer;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->performanceLogger = $performanceLogger;
|
||||
$this->logger = $logger;
|
||||
$this->mailManager = $mailManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function syncAccount(MailAccount $account,
|
||||
LoggerInterface $logger,
|
||||
bool $force = false,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS): void {
|
||||
$rebuildThreads = false;
|
||||
<<<<<<< Updated upstream
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
$snoozeMailboxId = $account->getSnoozeMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
$trashRetentionDays = $account->getTrashRetentionDays();
|
||||
|
||||
$client = $this->clientFactory->getClient($account);
|
||||
|
||||
=======
|
||||
$trashMailboxId = $account->getTrashMailboxId();
|
||||
$snoozeMailboxId = $account->getSnoozeMailboxId();
|
||||
$sentMailboxId = $account->getSentMailboxId();
|
||||
$trashRetentionDays = $account->getTrashRetentionDays();
|
||||
>>>>>>> Stashed changes
|
||||
foreach ($this->mailboxMapper->findAll($account) as $mailbox) {
|
||||
$syncTrash = $trashMailboxId === $mailbox->getId() && $trashRetentionDays !== null;
|
||||
$syncSnooze = $snoozeMailboxId === $mailbox->getId();
|
||||
$syncSent = $sentMailboxId === $mailbox->getId() || $mailbox->isSpecialUse('sent');
|
||||
|
||||
if (!$syncTrash && !$mailbox->isInbox() && !$syncSnooze && !$mailbox->getSyncInBackground() && !$syncSent) {
|
||||
$logger->debug('Skipping mailbox sync for ' . $mailbox->getId());
|
||||
continue;
|
||||
}
|
||||
$logger->debug('Syncing ' . $mailbox->getId());
|
||||
if ($this->sync(
|
||||
$account,
|
||||
$client,
|
||||
$mailbox,
|
||||
$logger,
|
||||
$criteria,
|
||||
null,
|
||||
$force,
|
||||
true
|
||||
)) {
|
||||
$rebuildThreads = true;
|
||||
}
|
||||
}
|
||||
|
||||
$client->logout();
|
||||
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached data of a mailbox
|
||||
*
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws MailboxLockedException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearCache(MailAccount $account,
|
||||
Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
try {
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
|
||||
$this->resetCache($account, $mailbox);
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException("Could not clear mailbox cache for $id: " . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipe all cached messages of a mailbox from the database
|
||||
*
|
||||
* Warning: the caller has to ensure the mailbox is locked
|
||||
*
|
||||
* @param Mailbox $mailbox
|
||||
*/
|
||||
private function resetCache(MailAccount $account, Mailbox $mailbox): void {
|
||||
$id = $account->getId() . ':' . $mailbox->getName();
|
||||
$this->dbMapper->deleteAll($mailbox);
|
||||
$this->logger->debug("All messages of $id cleared");
|
||||
$mailbox->setSyncNewToken(null);
|
||||
$mailbox->setSyncChangedToken(null);
|
||||
$mailbox->setSyncVanishedToken(null);
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ClientException
|
||||
* @throws MailboxNotCachedException
|
||||
* @throws ServiceException
|
||||
* @return bool whether to rebuild threads or not
|
||||
*/
|
||||
<<<<<<< Updated upstream
|
||||
public function sync(Account $account,
|
||||
Horde_Imap_Client_Base $client,
|
||||
=======
|
||||
public function sync(MailAccount $account,
|
||||
>>>>>>> Stashed changes
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria = Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS,
|
||||
?array $knownUids = null,
|
||||
bool $force = false,
|
||||
bool $batchSync = false): bool {
|
||||
$rebuildThreads = true;
|
||||
if ($mailbox->getSelectable() === false) {
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
$client->login(); // Need to login before fetching capabilities.
|
||||
|
||||
// There is no partial sync when using QRESYNC. As per RFC the client will always pull
|
||||
// all changes. This is a cheap operation when using QRESYNC as the server keeps track
|
||||
// of a client's state through the sync token. We could just update the sync tokens and
|
||||
// call it a day because Horde caches unrelated/unrequested changes until the next
|
||||
// operation. However, our cache is not reliable as some instance might use APCu which
|
||||
// isn't shared between cron and web requests.
|
||||
if ($client->capability->isEnabled('QRESYNC')) {
|
||||
$this->logger->debug('Forcing full sync due to QRESYNC');
|
||||
$criteria |= Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
| Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
| Horde_Imap_Client::SYNC_VANISHEDUIDS;
|
||||
}
|
||||
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for new messages sync');
|
||||
$this->mailboxMapper->lockForNewSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for changed messages sync');
|
||||
$this->mailboxMapper->lockForChangeSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Locking mailbox ' . $mailbox->getId() . ' for vanished messages sync');
|
||||
$this->mailboxMapper->lockForVanishedSync($mailbox);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($force
|
||||
|| $mailbox->getSyncNewToken() === null
|
||||
|| $mailbox->getSyncChangedToken() === null
|
||||
|| $mailbox->getSyncVanishedToken() === null) {
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId());
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} else {
|
||||
try {
|
||||
$logger->debug('Running partial sync for ' . $mailbox->getId());
|
||||
// Only rebuild threads if there were new or vanished messages
|
||||
$rebuildThreads = $this->runPartialSync($client, $account, $mailbox, $logger, $criteria, $knownUids);
|
||||
} catch (UidValidityChangedException $e) {
|
||||
$logger->warning('Mailbox UID validity changed. Wiping cache and performing full sync for ' . $mailbox->getId());
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
} catch (MailboxDoesNotSupportModSequencesException $e) {
|
||||
$logger->warning('Mailbox does not support mod-sequences error occured. Wiping cache and performing full sync for ' . $mailbox->getId(), [
|
||||
'exception' => $e,
|
||||
]);
|
||||
$this->resetCache($account, $mailbox);
|
||||
$logger->debug('Running initial sync for ' . $mailbox->getId() . ' after cache reset - no mod-sequences error');
|
||||
$this->runInitialSync($client, $account, $mailbox, $logger);
|
||||
}
|
||||
}
|
||||
} catch (ServiceException $e) {
|
||||
// Just rethrow, don't wrap into another exception
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
throw new ServiceException('Sync failed for ' . $account->getId() . ':' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
} finally {
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from vanished messages sync');
|
||||
$this->mailboxMapper->unlockFromVanishedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from changed messages sync');
|
||||
$this->mailboxMapper->unlockFromChangedSync($mailbox);
|
||||
}
|
||||
if ($force || ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) {
|
||||
$logger->debug('Unlocking mailbox ' . $mailbox->getId() . ' from new messages sync');
|
||||
$this->mailboxMapper->unlockFromNewSync($mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$batchSync) {
|
||||
$this->dispatcher->dispatchTyped(
|
||||
new SynchronizationEvent(
|
||||
$account,
|
||||
$this->logger,
|
||||
$rebuildThreads,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rebuildThreads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ServiceException
|
||||
* @throws IncompleteSyncException
|
||||
*/
|
||||
private function runInitialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger): void {
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'Initial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
// Need a client without a cache
|
||||
$client->logout();
|
||||
$client = $this->clientFactory->getClient($account, false);
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
try {
|
||||
$imapMessages = $this->imapMapper->findAll(
|
||||
$client,
|
||||
$mailbox->getName(),
|
||||
self::MAX_NEW_MESSAGES,
|
||||
$highestKnownUid ?? 0,
|
||||
$logger,
|
||||
$perf,
|
||||
$account->getUserId(),
|
||||
);
|
||||
$perf->step(sprintf('fetch %d messages from IMAP', count($imapMessages)));
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
throw new ServiceException('Can not get messages from mailbox ' . $mailbox->getName() . ': ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
foreach (array_chunk($imapMessages['messages'], 500) as $chunk) {
|
||||
$messages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk);
|
||||
$this->dbMapper->insertBulk($account, ...$messages);
|
||||
$perf->step(sprintf('persist %d messages in database', count($chunk)));
|
||||
// Free the memory
|
||||
unset($messages);
|
||||
}
|
||||
|
||||
if (!$imapMessages['all']) {
|
||||
// We might need more attempts to fill the cache
|
||||
$loggingMailboxId = $account->getId() . ':' . $mailbox->getName();
|
||||
$total = $imapMessages['total'];
|
||||
$cached = count($this->dbMapper->findAllUids($mailbox));
|
||||
$perf->step('find number of cached UIDs');
|
||||
|
||||
$perf->end();
|
||||
throw new IncompleteSyncException("Initial sync is not complete for $loggingMailboxId ($cached of $total messages cached).");
|
||||
}
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
|
||||
$perf->end();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $knownUids
|
||||
*
|
||||
* @throws ServiceException
|
||||
* @throws UidValidityChangedException
|
||||
* @return bool whether there are new or vanished messages
|
||||
*/
|
||||
private function runPartialSync(
|
||||
Horde_Imap_Client_Base $client,
|
||||
MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
LoggerInterface $logger,
|
||||
int $criteria,
|
||||
?array $knownUids = null): bool {
|
||||
$newOrVanished = false;
|
||||
$perf = $this->performanceLogger->startWithLogger(
|
||||
'partial sync ' . $account->getId() . ':' . $mailbox->getName(),
|
||||
$logger
|
||||
);
|
||||
|
||||
$uids = $knownUids ?? $this->dbMapper->findAllUids($mailbox);
|
||||
$perf->step('get all known UIDs');
|
||||
|
||||
if ($criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncNewToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_NEWMSGSUIDS
|
||||
);
|
||||
$perf->step('get new messages via Horde');
|
||||
|
||||
$highestKnownUid = $this->dbMapper->findHighestUid($mailbox);
|
||||
if ($highestKnownUid === null) {
|
||||
// Everything is relevant
|
||||
$newMessages = $response->getNewMessages();
|
||||
} else {
|
||||
// Filter out anything that is already in the DB. Ideally this never happens, but if there is an error
|
||||
// during a consecutive chunk INSERT, the sync token won't be updated. In that case the same message(s)
|
||||
// will be seen as *new* and therefore cause conflicts.
|
||||
$newMessages = array_filter($response->getNewMessages(), static function (IMAPMessage $imapMessage) use ($highestKnownUid) {
|
||||
return $imapMessage->getUid() > $highestKnownUid;
|
||||
});
|
||||
}
|
||||
|
||||
foreach (array_chunk($newMessages, 500) as $chunk) {
|
||||
$dbMessages = array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk);
|
||||
|
||||
$this->dbMapper->insertBulk($account, ...$dbMessages);
|
||||
|
||||
$this->dispatcher->dispatch(
|
||||
NewMessagesSynchronized::class,
|
||||
new NewMessagesSynchronized($account, $mailbox, $dbMessages)
|
||||
);
|
||||
$perf->step('classified a chunk of new messages');
|
||||
}
|
||||
$perf->step('persist new messages');
|
||||
|
||||
$mailbox->setSyncNewToken($client->getSyncToken($mailbox->getName()));
|
||||
$newOrVanished = $newMessages !== [];
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncChangedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_FLAGSUIDS
|
||||
);
|
||||
$perf->step('get changed messages via Horde');
|
||||
|
||||
$permflagsEnabled = $this->mailManager->isPermflagsEnabled($client, $account, $mailbox->getName());
|
||||
|
||||
foreach (array_chunk($response->getChangedMessages(), 500) as $chunk) {
|
||||
$this->dbMapper->updateBulk($account, $permflagsEnabled, ...array_map(static function (IMAPMessage $imapMessage) use ($mailbox, $account) {
|
||||
return $imapMessage->toDbMessage($mailbox->getId(), $account);
|
||||
}, $chunk));
|
||||
}
|
||||
$perf->step('persist changed messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the change token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncChangedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
}
|
||||
if ($criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) {
|
||||
$response = $this->synchronizer->sync(
|
||||
$client,
|
||||
new Request(
|
||||
$mailbox->getName(),
|
||||
$mailbox->getSyncVanishedToken(),
|
||||
$uids
|
||||
),
|
||||
$account->getUserId(),
|
||||
Horde_Imap_Client::SYNC_VANISHEDUIDS
|
||||
);
|
||||
$perf->step('get vanished messages via Horde');
|
||||
|
||||
foreach (array_chunk($response->getVanishedMessageUids(), 500) as $chunk) {
|
||||
$this->dbMapper->deleteByUid($mailbox, ...$chunk);
|
||||
}
|
||||
$perf->step('delete vanished messages');
|
||||
|
||||
// If a list of UIDs was *provided* (as opposed to loaded from the DB,
|
||||
// we can not assume that all changes were detected, hence this is kinda
|
||||
// a silent sync and we don't update the vanish token until the next full
|
||||
// mailbox sync
|
||||
if ($knownUids === null) {
|
||||
$mailbox->setSyncVanishedToken($client->getSyncToken($mailbox->getName()));
|
||||
}
|
||||
$newOrVanished = $newOrVanished || !empty($response->getVanishedMessageUids());
|
||||
}
|
||||
$this->mailboxMapper->update($mailbox);
|
||||
$perf->end();
|
||||
|
||||
return $newOrVanished;
|
||||
}
|
||||
}
|
|
@ -9,8 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Mail\Service\Sync;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Contracts\IMailSearch;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Mailbox;
|
||||
use OCA\Mail\Db\MailboxMapper;
|
||||
use OCA\Mail\Db\Message;
|
||||
|
@ -30,7 +30,7 @@ use function array_diff;
|
|||
use function array_map;
|
||||
|
||||
class SyncService {
|
||||
|
||||
|
||||
private IMAPClientFactory $clientFactory;
|
||||
|
||||
/** @var ImapToDbSynchronizer */
|
||||
|
@ -74,19 +74,17 @@ class SyncService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
*
|
||||
* @throws MailboxLockedException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function clearCache(Account $account,
|
||||
public function clearCache(MailAccount $account,
|
||||
Mailbox $mailbox): void {
|
||||
$this->synchronizer->clearCache($account, $mailbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int $criteria
|
||||
* @param bool $partialOnly
|
||||
|
@ -99,7 +97,7 @@ class SyncService {
|
|||
* @throws MailboxNotCachedException
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function syncMailbox(Account $account,
|
||||
public function syncMailbox(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
int $criteria,
|
||||
bool $partialOnly,
|
||||
|
@ -110,9 +108,9 @@ class SyncService {
|
|||
if ($partialOnly && !$mailbox->isCached()) {
|
||||
throw MailboxNotCachedException::from($mailbox);
|
||||
}
|
||||
|
||||
|
||||
$client = $this->clientFactory->getClient($account);
|
||||
|
||||
|
||||
$this->synchronizer->sync(
|
||||
$account,
|
||||
$client,
|
||||
|
@ -139,7 +137,6 @@ class SyncService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Mailbox $mailbox
|
||||
* @param int[] $knownIds
|
||||
* @param SearchQuery $query
|
||||
|
@ -148,7 +145,7 @@ class SyncService {
|
|||
* @todo does not work with text token search queries
|
||||
*
|
||||
*/
|
||||
private function getDatabaseSyncChanges(Account $account,
|
||||
private function getDatabaseSyncChanges(MailAccount $account,
|
||||
Mailbox $mailbox,
|
||||
array $knownIds,
|
||||
?int $lastMessageTimestamp,
|
||||
|
|
|
@ -7,11 +7,11 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Mail\Service;
|
||||
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Address;
|
||||
use OCA\Mail\AddressList;
|
||||
use OCA\Mail\Db\LocalAttachment;
|
||||
use OCA\Mail\Db\LocalMessage;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCA\Mail\Db\Recipient;
|
||||
use OCA\Mail\Exception\AttachmentNotFoundException;
|
||||
use OCA\Mail\Exception\ServiceException;
|
||||
|
@ -68,18 +68,17 @@ class TransmissionService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $attachment
|
||||
* @return \Horde_Mime_Part|null
|
||||
*/
|
||||
public function handleAttachment(Account $account, array $attachment): ?\Horde_Mime_Part {
|
||||
public function handleAttachment(MailAccount $account, array $attachment): ?\Horde_Mime_Part {
|
||||
if (!isset($attachment['id'])) {
|
||||
$this->logger->warning('ignoring local attachment because its id is unknown');
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
[$localAttachment, $file] = $this->attachmentService->getAttachment($account->getMailAccount()->getUserId(), (int)$attachment['id']);
|
||||
[$localAttachment, $file] = $this->attachmentService->getAttachment($account->getUserId(), (int)$attachment['id']);
|
||||
$part = new \Horde_Mime_Part();
|
||||
$part->setCharset('us-ascii');
|
||||
$part->setDisposition('attachment');
|
||||
|
@ -110,12 +109,11 @@ class TransmissionService {
|
|||
|
||||
/**
|
||||
* @param LocalMessage $localMessage
|
||||
* @param Account $account
|
||||
* @param \Horde_Mime_Part $mimePart
|
||||
* @return \Horde_Mime_Part
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getSignMimePart(LocalMessage $localMessage, Account $account, \Horde_Mime_Part $mimePart): \Horde_Mime_Part {
|
||||
public function getSignMimePart(LocalMessage $localMessage, MailAccount $account, \Horde_Mime_Part $mimePart): \Horde_Mime_Part {
|
||||
if ($localMessage->getSmimeSign()) {
|
||||
if ($localMessage->getSmimeCertificateId() === null) {
|
||||
$localMessage->setStatus(LocalMessage::STATUS_SMIME_SIGN_NO_CERT_ID);
|
||||
|
@ -152,12 +150,11 @@ class TransmissionService {
|
|||
* @param AddressList $to
|
||||
* @param AddressList $cc
|
||||
* @param AddressList $bcc
|
||||
* @param Account $account
|
||||
* @param \Horde_Mime_Part $mimePart
|
||||
* @return \Horde_Mime_Part
|
||||
* @throws ServiceException
|
||||
*/
|
||||
public function getEncryptMimePart(LocalMessage $localMessage, AddressList $to, AddressList $cc, AddressList $bcc, Account $account, \Horde_Mime_Part $mimePart): \Horde_Mime_Part {
|
||||
public function getEncryptMimePart(LocalMessage $localMessage, AddressList $to, AddressList $cc, AddressList $bcc, MailAccount $account, \Horde_Mime_Part $mimePart): \Horde_Mime_Part {
|
||||
if ($localMessage->getSmimeEncrypt()) {
|
||||
if ($localMessage->getSmimeCertificateId() === null) {
|
||||
$localMessage->setStatus(LocalMessage::STATUS_SMIME_ENCRYPT_NO_CERT_ID);
|
||||
|
|
|
@ -10,7 +10,7 @@ declare(strict_types=1);
|
|||
namespace OCA\Mail\Sieve;
|
||||
|
||||
use Horde\ManageSieve;
|
||||
use OCA\Mail\Account;
|
||||
use OCA\Mail\Db\MailAccount;
|
||||
use OCP\IConfig;
|
||||
use OCP\Security\ICrypto;
|
||||
|
||||
|
@ -33,31 +33,30 @@ class SieveClientFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @return ManageSieve
|
||||
* @throws ManageSieve\Exception
|
||||
*/
|
||||
public function getClient(Account $account): ManageSieve {
|
||||
if (!isset($this->cache[$account->getId()])) {
|
||||
$user = $account->getMailAccount()->getSieveUser();
|
||||
public function getClient(MailAccount $account): ManageSieve {
|
||||
if (!isset($this->cache[($account->getId())])) {
|
||||
$user = $account->getSieveUser();
|
||||
if (empty($user)) {
|
||||
$user = $account->getMailAccount()->getInboundUser();
|
||||
$user = $account->getInboundUser();
|
||||
}
|
||||
$password = $account->getMailAccount()->getSievePassword();
|
||||
$password = $account->getSievePassword();
|
||||
if (empty($password)) {
|
||||
$password = $account->getMailAccount()->getInboundPassword();
|
||||
$password = $account->getInboundPassword();
|
||||
}
|
||||
|
||||
$this->cache[$account->getId()] = $this->createClient(
|
||||
$account->getMailAccount()->getSieveHost(),
|
||||
$account->getMailAccount()->getSievePort(),
|
||||
$this->cache[($account->getId())] = $this->createClient(
|
||||
$account->getSieveHost(),
|
||||
$account->getSievePort(),
|
||||
$user,
|
||||
$password,
|
||||
$account->getMailAccount()->getSieveSslMode()
|
||||
$account->getSieveSslMode()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->cache[$account->getId()];
|
||||
return $this->cache[($account->getId())];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,7 +58,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapNoUids() {
|
||||
|
@ -75,7 +75,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapExceptionGetFlagged() {
|
||||
|
@ -93,7 +93,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->method('debug');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapExceptionOnFlag() {
|
||||
|
@ -116,7 +116,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function migrateImportantFromDb() {
|
||||
|
@ -135,7 +135,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantFromDbNoUids() {
|
||||
|
@ -153,7 +153,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantFromDbExceptionOnFlag() {
|
||||
|
@ -177,6 +177,6 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,8 @@ class MailTransmissionIntegrationTest extends TestCase {
|
|||
|
||||
$this->localMessageMapper = Server::get(LocalMessageMapper::class);
|
||||
$this->message = new LocalMessage();
|
||||
$this->message->setAccountId($this->account->getId());
|
||||
$account = $this->account;
|
||||
$this->message->setAccountId($account->getId());
|
||||
$this->message->setSubject('greetings');
|
||||
$this->message->setBody('hello there');
|
||||
$this->message->setType(LocalMessage::TYPE_OUTGOING);
|
||||
|
|
|
@ -53,10 +53,7 @@ class SieveClientFactoryTest extends TestCase {
|
|||
$this->factory = new SieveClientFactory($this->crypto, $this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
private function getTestAccount() {
|
||||
private function getTestAccount(): MailAccount {
|
||||
$mailAccount = new MailAccount();
|
||||
$mailAccount->setId(123);
|
||||
$mailAccount->setEmail('user@domain.tld');
|
||||
|
@ -70,14 +67,14 @@ class SieveClientFactoryTest extends TestCase {
|
|||
$mailAccount->setSieveSslMode('');
|
||||
$mailAccount->setSieveUser('');
|
||||
$mailAccount->setSievePassword('');
|
||||
return new Account($mailAccount);
|
||||
return $mailAccount;
|
||||
}
|
||||
|
||||
public function testClientConnectivity() {
|
||||
$account = $this->getTestAccount();
|
||||
$this->crypto->expects($this->once())
|
||||
->method('decrypt')
|
||||
->with($account->getMailAccount()->getInboundPassword())
|
||||
->with($account->getInboundPassword())
|
||||
->willReturn('mypassword');
|
||||
|
||||
$client = $this->factory->getClient($account);
|
||||
|
@ -88,7 +85,7 @@ class SieveClientFactoryTest extends TestCase {
|
|||
$account = $this->getTestAccount();
|
||||
$this->crypto->expects($this->once())
|
||||
->method('decrypt')
|
||||
->with($account->getMailAccount()->getInboundPassword())
|
||||
->with($account->getInboundPassword())
|
||||
->willReturn('mypassword');
|
||||
|
||||
$client = $this->factory->getClient($account);
|
||||
|
|
|
@ -205,7 +205,7 @@ class DraftsControllerTest extends TestCase {
|
|||
$to = [['label' => 'Lewis', 'email' => 'tent@stardewvalley.com']];
|
||||
$cc = [['label' => 'Pierre', 'email' => 'generalstore@stardewvalley.com']];
|
||||
|
||||
$account = new Account(new MailAccount());
|
||||
$account = new MailAccount();
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $message->getAccountId())
|
||||
|
|
|
@ -402,9 +402,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
public function testSend($messageStatus, $expected): void {
|
||||
$this->message->setStatus($messageStatus);
|
||||
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::never())
|
||||
->method('findByAliasAndUserId');
|
||||
|
@ -436,9 +437,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
public function testSendNoRecipient(): void {
|
||||
$this->message->setStatus(LocalMessage::STATUS_RAW);
|
||||
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::never())
|
||||
->method('findByAliasAndUserId');
|
||||
|
@ -481,9 +483,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
* @dataProvider exceptionData
|
||||
*/
|
||||
public function testSendException($exception, $expected): void {
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::never())
|
||||
->method('findByAliasAndUserId');
|
||||
|
@ -546,9 +549,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
$localAttachment = new LocalAttachment();
|
||||
$localAttachment->setId(1);
|
||||
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::never())
|
||||
->method('findByAliasAndUserId');
|
||||
|
@ -603,9 +607,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
],
|
||||
];
|
||||
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::never())
|
||||
->method('findByAliasAndUserId');
|
||||
|
@ -686,9 +691,10 @@ class MessageApiControllerTest extends TestCase {
|
|||
public function testNoAlias(): void {
|
||||
$aliasMail = 'john-alias@test.com';
|
||||
|
||||
$account = $this->account;
|
||||
$this->accountService->expects(self::once())
|
||||
->method('find')
|
||||
->with($this->userId, $this->account->getId())
|
||||
->with($this->userId, $account->getId())
|
||||
->willReturn($this->account);
|
||||
$this->aliasesService->expects(self::once())
|
||||
->method('findByAliasAndUserId')
|
||||
|
|
|
@ -66,7 +66,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapNoUids() {
|
||||
|
@ -83,7 +83,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapExceptionGetFlagged() {
|
||||
|
@ -101,7 +101,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->method('debug');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantOnImapExceptionOnFlag() {
|
||||
|
@ -124,7 +124,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantOnImap($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantOnImap($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function migrateImportantFromDb() {
|
||||
|
@ -143,7 +143,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantFromDbNoUids() {
|
||||
|
@ -161,7 +161,7 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
$this->logger->expects($this->never())
|
||||
->method('debug');
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
|
||||
public function testMigrateImportantFromDbExceptionOnFlag() {
|
||||
|
@ -185,6 +185,6 @@ class MigrateImportantFromImapAndDbTest extends TestCase {
|
|||
->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>');
|
||||
$this->expectException(ServiceException::class);
|
||||
|
||||
$this->migration->migrateImportantFromDb($this->client, $account, $mailbox);
|
||||
$this->migration->migrateImportantFromDb($this->client, $mailbox);
|
||||
}
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче