Passed
Push — master ( 60d45f...a37810 )
by René
05:02 queued 01:25
created

Contact::getContact()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
c 0
b 0
f 0
dl 0
loc 15
rs 9.9
cc 4
nc 8
nop 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
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
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Model;
25
26
use OCP\App\IAppManager;
27
use OCP\Contacts\IManager as IContactsManager;
28
use OCA\Polls\Exceptions\MultipleContactsFound;
29
use OCA\Polls\Exceptions\ContactsNotEnabledExceptions;
30
31
class Contact extends UserGroupClass {
32
	public const TYPE = 'contact';
33
	public const ICON = 'icon-mail';
34
35
	/** @var Array */
36
	private $contact = [];
37
38
	public function __construct(
39
		$id
40
	) {
41
		parent::__construct($id, self::TYPE);
42
		if (self::isEnabled()) {
43
			$this->icon = self::ICON;
44
			$this->getContact();
45
		} else {
46
			throw new ContactsNotEnabledExceptions();
47
		}
48
	}
49
50
51
	/**
52
	 * 	 * must use displayName for contact's user id, because contact id
53
	 * 	 * is not accessable outside the owners's scope
54
	 *
55
	 * @return string
56
	 */
57
	public function getPublicId(): string {
58
		return $this->displayName;
59
	}
60
61
	/**
62
	 * We just need the contact's UID, so make sure, the any prefix is removed
63
	 */
64
	private function resolveContactId(): void {
65
		$parts = explode(":", $this->id);
66
		$this->id = end($parts);
67
	}
68
69
	/**
70
	 * The contacts app just provides a search, so we have to load the contact
71
	 * after searching via the contact's id and use the first contact.
72
	 * Currently only the contact's first email address is supported
73
	 * From Version 1.5 on:
74
	 * For compatibility reasons, we have to search for the contacts name too.
75
	 * Before this implementation contacts where stored with their FN property.
76
	 * TODO: Remove FN as search range for loading a contact in a polls version
77
	 * later than 1.6.
78
	 */
79
	private function loadContact(): void {
80
		$contacts = self::listRaw($this->id, ['UID', 'FN']);
81
82
		if (count($contacts) > 1) {
83
			throw new MultipleContactsFound('Multiple contacts found for id ' . $this->id);
84
		}
85
86
		$this->contact = $contacts[0];
87
	}
88
89
	private function getContact(): void {
90
		$this->resolveContactId();
91
		$this->loadContact();
92
93
		$this->id = $this->contact['UID'];
94
		$this->displayName = $this->contact['FN'] ?? $this->displayName;
95
		$this->emailAddress = $this->contact['EMAIL'][0] ?? $this->emailAddress;
96
		$this->organisation = $this->contact['ORG'] ?? '';
97
		$this->categories = isset($this->contact['CATEGORIES']) ? explode(',', $this->contact['CATEGORIES']) : [];
98
		$description = $this->categories;
99
100
		if (isset($this->contact['ORG'])) {
101
			array_unshift($description, $this->organisation);
102
		}
103
		$this->description = count($description) ? implode(", ", $description) : \OC::$server->getL10N('polls')->t('Contact');
104
	}
105
106
	public static function isEnabled(): bool {
107
		return self::getContainer()->query(IAppManager::class)->isEnabledForUser('contacts');
108
	}
109
110
	/**
111
	 * 	 * List all contacts with email adresses
112
	 * 	 * excluding contacts from localSystemBook
113
	 *
114
	 * @param string[] $queryRange
115
	 */
116
	private static function listRaw(string $query = '', array $queryRange = ['FN', 'EMAIL', 'ORG', 'CATEGORIES']): array {
117
		$contacts = [];
118
119
		if (self::isEnabled()) {
120
			foreach (self::getContainer()->query(IContactsManager::class)->search($query, $queryRange) as $contact) {
121
				if (!array_key_exists('isLocalSystemBook', $contact) && array_key_exists('EMAIL', $contact)) {
122
					$contacts[] = $contact;
123
				}
124
			}
125
		}
126
		return $contacts;
127
	}
128
129
	/**
130
	 * @return Contact[]
131
	 */
132
	public static function search(string $query = '', $queryRange = ['FN', 'EMAIL', 'ORG', 'CATEGORIES']): array {
133
		$contacts = [];
134
		foreach (self::listRaw($query, $queryRange) as $contact) {
135
			$contacts[] = new Self($contact['UID']);
136
		}
137
		return $contacts;
138
	}
139
}
140