1<?php
2
3declare(strict_types=1);
4
5/**
6 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
7 *
8 * Mail
9 *
10 * This code is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License, version 3,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License, version 3,
20 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23
24namespace OCA\Mail\Service\AutoCompletion;
25
26use Horde_Mail_Exception;
27use OCA\Mail\Address;
28use OCA\Mail\AddressList;
29use OCA\Mail\Db\CollectedAddress;
30use OCA\Mail\Db\CollectedAddressMapper;
31use Psr\Log\LoggerInterface;
32
33class AddressCollector {
34
35	/** @var CollectedAddressMapper */
36	private $mapper;
37
38	/** @var string */
39	private $userId;
40
41	/** @var LoggerInterface */
42	private $logger;
43
44	public function __construct(CollectedAddressMapper $mapper,
45								?string $UserId,
46								LoggerInterface $logger) {
47		$this->mapper = $mapper;
48		$this->userId = $UserId;
49		$this->logger = $logger;
50	}
51
52	/**
53	 * Add a new email addresses
54	 *
55	 * Duplicates are ignored
56	 *
57	 * @param AddressList $addressList
58	 *
59	 * @return void
60	 */
61	public function addAddresses(AddressList $addressList): void {
62		$this->logger->debug("collecting " . count($addressList) . " email addresses");
63		foreach ($addressList->iterate() as $address) {
64			/* @var $address Address */
65			$this->saveAddress($address);
66		}
67	}
68
69	/**
70	 * @param Address $address
71	 *
72	 * @return void
73	 */
74	private function saveAddress(Address $address): void {
75		try {
76			$hordeAddress = $address->toHorde();
77			if (!$hordeAddress->valid) {
78				throw new Horde_Mail_Exception();
79			}
80		} catch (Horde_Mail_Exception $ex) {
81			// Ignore it
82			$this->logger->debug("<" . $address->getEmail() . "> is not a valid RFC822 mail address");
83			return;
84		}
85		if ($address->getEmail() !== null && !$this->mapper->exists($this->userId, $address->getEmail())) {
86			$this->logger->debug("saving new address <{$address->getEmail()}>");
87
88			$entity = new CollectedAddress();
89			$entity->setUserId($this->userId);
90			if ($address->getLabel() !== $address->getEmail()) {
91				$entity->setDisplayName($address->getLabel());
92			}
93			$entity->setEmail($address->getEmail());
94			$this->mapper->insert($entity);
95		}
96	}
97
98	/**
99	 * Find and return all known and matching email addresses
100	 *
101	 * @param string $term
102	 * @return CollectedAddress[]
103	 */
104	public function searchAddress(string $term): array {
105		$this->logger->debug("searching for collected address <$term>");
106		$result = $this->mapper->findMatching($this->userId, $term);
107		$this->logger->debug("found " . count($result) . " matches in collected addresses");
108		return $result;
109	}
110}
111