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; } }