108 lines
2.8 KiB
PHP
108 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2019 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Mail\IMAP\Search;
|
|
|
|
use Horde_Imap_Client_Exception;
|
|
use Horde_Imap_Client_Search_Query;
|
|
use OCA\Mail\Account;
|
|
use OCA\Mail\Db\Mailbox;
|
|
use OCA\Mail\Exception\ServiceException;
|
|
use OCA\Mail\IMAP\IMAPClientFactory;
|
|
use OCA\Mail\Service\Search\SearchQuery;
|
|
|
|
class Provider {
|
|
/** @var IMAPClientFactory */
|
|
private $clientFactory;
|
|
|
|
public function __construct(IMAPClientFactory $clientFactory) {
|
|
$this->clientFactory = $clientFactory;
|
|
}
|
|
|
|
/**
|
|
* @return int[]
|
|
* @throws ServiceException
|
|
*/
|
|
public function findMatches(Account $account,
|
|
Mailbox $mailbox,
|
|
SearchQuery $searchQuery): array {
|
|
$client = $this->clientFactory->getClient($account);
|
|
try {
|
|
$fetchResult = $client->search(
|
|
$mailbox->getName(),
|
|
$this->convertMailQueryToHordeQuery($searchQuery)
|
|
);
|
|
} catch (Horde_Imap_Client_Exception $e) {
|
|
throw new ServiceException('Could not get message IDs: ' . $e->getMessage(), 0, $e);
|
|
} finally {
|
|
$client->logout();
|
|
}
|
|
|
|
return $fetchResult['match']->ids;
|
|
}
|
|
|
|
/**
|
|
* @param SearchQuery $searchQuery
|
|
*
|
|
* @todo possible optimization: filter flags here as well as it might speed up IMAP search
|
|
*
|
|
* @return Horde_Imap_Client_Search_Query
|
|
*/
|
|
private function convertMailQueryToHordeQuery(SearchQuery $searchQuery): Horde_Imap_Client_Search_Query {
|
|
$baseQuery = new Horde_Imap_Client_Search_Query();
|
|
$subjects = $searchQuery->getSubjects();
|
|
$from = $searchQuery->getFrom();
|
|
$to = $searchQuery->getTo();
|
|
$bodies = $searchQuery->getBodies();
|
|
$matchAny = ($searchQuery->getMatch() === 'anyof');
|
|
|
|
if ($matchAny && ($subjects !== [] || $from !== [] || $to !== [] || $bodies !== [])) {
|
|
$orQueries = [];
|
|
foreach ($subjects as $token) {
|
|
$q = new Horde_Imap_Client_Search_Query();
|
|
$q->headerText('SUBJECT', $token);
|
|
$orQueries[] = $q;
|
|
}
|
|
foreach ($from as $token) {
|
|
$q = new Horde_Imap_Client_Search_Query();
|
|
$q->headerText('FROM', $token);
|
|
$orQueries[] = $q;
|
|
}
|
|
foreach ($to as $token) {
|
|
$q = new Horde_Imap_Client_Search_Query();
|
|
$q->headerText('TO', $token);
|
|
$orQueries[] = $q;
|
|
}
|
|
foreach ($bodies as $token) {
|
|
$q = new Horde_Imap_Client_Search_Query();
|
|
$q->text($token, true);
|
|
$orQueries[] = $q;
|
|
}
|
|
if ($orQueries !== []) {
|
|
$baseQuery->orSearch($orQueries);
|
|
}
|
|
} else {
|
|
foreach ($subjects as $token) {
|
|
$baseQuery->headerText('SUBJECT', $token);
|
|
}
|
|
foreach ($from as $token) {
|
|
$baseQuery->headerText('FROM', $token);
|
|
}
|
|
foreach ($to as $token) {
|
|
$baseQuery->headerText('TO', $token);
|
|
}
|
|
foreach ($bodies as $token) {
|
|
$baseQuery->text($token, true);
|
|
}
|
|
}
|
|
|
|
return $baseQuery;
|
|
}
|
|
}
|