Completed
Pull Request — master (#226)
by Lukas
18:43 queued 09:50
created

AddressBookImpl::getPermissions()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 5
nop 0
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Björn Schießle <[email protected]>
4
 * @author Thomas Müller <[email protected]>
5
 *
6
 * @copyright Copyright (c) 2016, ownCloud, Inc.
7
 * @license AGPL-3.0
8
 *
9
 * This code is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License, version 3,
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License, version 3,
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20
 *
21
 */
22
23
namespace OCA\DAV\CardDAV;
24
25
use OCP\Constants;
26
use OCP\IAddressBook;
27
use OCP\IURLGenerator;
28
use Sabre\VObject\Component\VCard;
29
use Sabre\VObject\Property\Text;
30
use Sabre\VObject\Reader;
31
use Sabre\VObject\UUIDUtil;
32
33
class AddressBookImpl implements IAddressBook {
34
35
	/** @var CardDavBackend */
36
	private $backend;
37
38
	/** @var array */
39
	private $addressBookInfo;
40
41
	/** @var AddressBook */
42
	private $addressBook;
43
44
	/** @var IURLGenerator */
45
	private $urlGenerator;
46
47
	/**
48
	 * AddressBookImpl constructor.
49
	 *
50
	 * @param AddressBook $addressBook
51
	 * @param array $addressBookInfo
52
	 * @param CardDavBackend $backend
53
	 * @param IUrlGenerator $urlGenerator
54
	 */
55
	public function __construct(
56
			AddressBook $addressBook,
57
			array $addressBookInfo,
58
			CardDavBackend $backend,
59
			IURLGenerator $urlGenerator) {
60
61
		$this->addressBook = $addressBook;
62
		$this->addressBookInfo = $addressBookInfo;
63
		$this->backend = $backend;
64
		$this->urlGenerator = $urlGenerator;
65
	}
66
67
	/**
68
	 * @return string defining the technical unique key
69
	 * @since 5.0.0
70
	 */
71
	public function getKey() {
72
		return $this->addressBookInfo['id'];
73
	}
74
75
	/**
76
	 * In comparison to getKey() this function returns a human readable (maybe translated) name
77
	 *
78
	 * @return mixed
79
	 * @since 5.0.0
80
	 */
81
	public function getDisplayName() {
82
		return $this->addressBookInfo['{DAV:}displayname'];
83
	}
84
85
	/**
86
	 * @param string $pattern which should match within the $searchProperties
87
	 * @param array $searchProperties defines the properties within the query pattern should match
88
	 * @param array $options - for future use. One should always have options!
89
	 * @return array an array of contacts which are arrays of key-value-pairs
90
	 * @since 5.0.0
91
	 */
92
	public function search($pattern, $searchProperties, $options) {
93
		$results = $this->backend->search($this->getKey(), $pattern, $searchProperties);
94
95
		$vCards = [];
96
		foreach ($results as $result) {
97
			$vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata']));
98
		}
99
100
		return $vCards;
101
	}
102
103
	/**
104
	 * @param array $properties this array if key-value-pairs defines a contact
105
	 * @return array an array representing the contact just created or updated
106
	 * @since 5.0.0
107
	 */
108
	public function createOrUpdate($properties) {
109
		$update = false;
110
		if (!isset($properties['URI'])) { // create a new contact
111
			$uid = $this->createUid();
112
			$uri = $uid . '.vcf';
113
			$vCard = $this->createEmptyVCard($uid);
114
		} else { // update existing contact
115
			$uri = $properties['URI'];
116
			$vCardData = $this->backend->getCard($this->getKey(), $uri);
117
			$vCard = $this->readCard($vCardData['carddata']);
118
			$update = true;
119
		}
120
121
		foreach ($properties as $key => $value) {
122
			$vCard->$key = $vCard->createProperty($key, $value);
123
		}
124
125
		if ($update) {
126
			$this->backend->updateCard($this->getKey(), $uri, $vCard->serialize());
127
		} else {
128
			$this->backend->createCard($this->getKey(), $uri, $vCard->serialize());
129
		}
130
131
		return $this->vCard2Array($uri, $vCard);
132
133
	}
134
135
	/**
136
	 * @return mixed
137
	 * @since 5.0.0
138
	 */
139
	public function getPermissions() {
140
		$permissions = $this->addressBook->getACL();
141
		$result = 0;
142
		foreach ($permissions as $permission) {
143
			switch($permission['privilege']) {
144
				case '{DAV:}read':
145
					$result |= Constants::PERMISSION_READ;
146
					break;
147
				case '{DAV:}write':
148
					$result |= Constants::PERMISSION_CREATE;
149
					$result |= Constants::PERMISSION_UPDATE;
150
					break;
151
				case '{DAV:}all':
152
					$result |= Constants::PERMISSION_ALL;
153
					break;
154
			}
155
		}
156
157
		return $result;
158
	}
159
160
	/**
161
	 * @param object $id the unique identifier to a contact
162
	 * @return bool successful or not
163
	 * @since 5.0.0
164
	 */
165
	public function delete($id) {
166
		$uri = $this->backend->getCardUri($id);
167
		return $this->backend->deleteCard($this->addressBookInfo['id'], $uri);
168
	}
169
170
	/**
171
	 * read vCard data into a vCard object
172
	 *
173
	 * @param string $cardData
174
	 * @return VCard
175
	 */
176
	protected function readCard($cardData) {
177
		return  Reader::read($cardData);
178
	}
179
180
	/**
181
	 * create UID for contact
182
	 *
183
	 * @return string
184
	 */
185
	protected function createUid() {
186
		do {
187
			$uid = $this->getUid();
188
			$contact = $this->backend->getContact($this->getKey(), $uid . '.vcf');
189
		} while (!empty($contact));
190
191
		return $uid;
192
	}
193
194
	/**
195
	 * getUid is only there for testing, use createUid instead
196
	 */
197
	protected function getUid() {
198
		return UUIDUtil::getUUID();
199
	}
200
201
	/**
202
	 * create empty vcard
203
	 *
204
	 * @param string $uid
205
	 * @return VCard
206
	 */
207
	protected function createEmptyVCard($uid) {
208
		$vCard = new VCard();
209
		$vCard->add(new Text($vCard, 'UID', $uid));
210
		return $vCard;
211
	}
212
213
	/**
214
	 * create array with all vCard properties
215
	 *
216
	 * @param string $uri
217
	 * @param VCard $vCard
218
	 * @return array
219
	 */
220
	protected function vCard2Array($uri, VCard $vCard) {
221
		$result = [
222
			'URI' => $uri,
223
		];
224
225
		foreach ($vCard->children as $property) {
226
			$result[$property->name] = $property->getValue();
227
			if ($property->name === 'PHOTO' && $property->getValueType() === 'BINARY') {
228
				$url = $this->urlGenerator->getAbsoluteURL(
229
					$this->urlGenerator->linkTo('', 'remote.php') . '/dav/');
230
				$url .= implode('/', [
231
					'addressbooks',
232
					substr($this->addressBookInfo['principaluri'], 11), //cut off 'principals/'
233
					$this->addressBookInfo['uri'],
234
					$uri
235
				]) . '?photo';
236
237
				$result['PHOTO'] = 'VALUE=uri:' . $url;
238
			} else {
239
				$result[$property->name] = $property->getValue();
240
			}
241
		}
242
		if ($this->addressBookInfo['principaluri'] === 'principals/system/system' &&
243
			$this->addressBookInfo['uri'] === 'system') {
244
			$result['isLocalSystemBook'] = true;
245
		}
246
		return $result;
247
	}
248
}
249