Passed
Push — master ( 7c3f83...68c8fa )
by Morris
19:13 queued 12s
created
apps/dav/lib/CardDAV/AddressBookImpl.php 1 patch
Indentation   +304 added lines, -304 removed lines patch added patch discarded remove patch
@@ -41,308 +41,308 @@
 block discarded – undo
41 41
 
42 42
 class AddressBookImpl implements IAddressBook {
43 43
 
44
-	/** @var CardDavBackend */
45
-	private $backend;
46
-
47
-	/** @var array */
48
-	private $addressBookInfo;
49
-
50
-	/** @var AddressBook */
51
-	private $addressBook;
52
-
53
-	/** @var IURLGenerator */
54
-	private $urlGenerator;
55
-
56
-	/**
57
-	 * AddressBookImpl constructor.
58
-	 *
59
-	 * @param AddressBook $addressBook
60
-	 * @param array $addressBookInfo
61
-	 * @param CardDavBackend $backend
62
-	 * @param IUrlGenerator $urlGenerator
63
-	 */
64
-	public function __construct(
65
-			AddressBook $addressBook,
66
-			array $addressBookInfo,
67
-			CardDavBackend $backend,
68
-			IURLGenerator $urlGenerator) {
69
-		$this->addressBook = $addressBook;
70
-		$this->addressBookInfo = $addressBookInfo;
71
-		$this->backend = $backend;
72
-		$this->urlGenerator = $urlGenerator;
73
-	}
74
-
75
-	/**
76
-	 * @return string defining the technical unique key
77
-	 * @since 5.0.0
78
-	 */
79
-	public function getKey() {
80
-		return $this->addressBookInfo['id'];
81
-	}
82
-
83
-	/**
84
-	 * @return string defining the unique uri
85
-	 * @since 16.0.0
86
-	 */
87
-	public function getUri(): string {
88
-		return $this->addressBookInfo['uri'];
89
-	}
90
-
91
-	/**
92
-	 * In comparison to getKey() this function returns a human readable (maybe translated) name
93
-	 *
94
-	 * @return mixed
95
-	 * @since 5.0.0
96
-	 */
97
-	public function getDisplayName() {
98
-		return $this->addressBookInfo['{DAV:}displayname'];
99
-	}
100
-
101
-	/**
102
-	 * @param string $pattern which should match within the $searchProperties
103
-	 * @param array $searchProperties defines the properties within the query pattern should match
104
-	 * @param array $options Options to define the output format and search behavior
105
-	 * 	- 'types' boolean (since 15.0.0) If set to true, fields that come with a TYPE property will be an array
106
-	 *    example: ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['type => 'HOME', 'value' => '[email protected]']]
107
-	 * 	- 'escape_like_param' - If set to false wildcards _ and % are not escaped
108
-	 * 	- 'limit' - Set a numeric limit for the search results
109
-	 * 	- 'offset' - Set the offset for the limited search results
110
-	 * @return array an array of contacts which are arrays of key-value-pairs
111
-	 *  example result:
112
-	 *  [
113
-	 *		['id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => '[email protected]', 'GEO' => '37.386013;-122.082932'],
114
-	 *		['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['[email protected]', '[email protected]']]
115
-	 *	]
116
-	 * @since 5.0.0
117
-	 */
118
-	public function search($pattern, $searchProperties, $options) {
119
-		$results = $this->backend->search($this->getKey(), $pattern, $searchProperties, $options);
120
-
121
-		$withTypes = \array_key_exists('types', $options) && $options['types'] === true;
122
-
123
-		$vCards = [];
124
-		foreach ($results as $result) {
125
-			$vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata']), $withTypes);
126
-		}
127
-
128
-		return $vCards;
129
-	}
130
-
131
-	/**
132
-	 * @param array $properties this array if key-value-pairs defines a contact
133
-	 * @return array an array representing the contact just created or updated
134
-	 * @since 5.0.0
135
-	 */
136
-	public function createOrUpdate($properties) {
137
-		$update = false;
138
-		if (!isset($properties['URI'])) { // create a new contact
139
-			$uid = $this->createUid();
140
-			$uri = $uid . '.vcf';
141
-			$vCard = $this->createEmptyVCard($uid);
142
-		} else { // update existing contact
143
-			$uri = $properties['URI'];
144
-			$vCardData = $this->backend->getCard($this->getKey(), $uri);
145
-			$vCard = $this->readCard($vCardData['carddata']);
146
-			$update = true;
147
-		}
148
-
149
-		foreach ($properties as $key => $value) {
150
-			if (is_array($value)) {
151
-				$vCard->remove($key);
152
-				foreach ($value as $entry) {
153
-					if (is_string($entry)) {
154
-						$property = $vCard->createProperty($key, $entry);
155
-					} else {
156
-						if (($key === "ADR" || $key === "PHOTO") && is_string($entry["value"])) {
157
-							$entry["value"] = stripslashes($entry["value"]);
158
-							$entry["value"] = explode(';', $entry["value"]);
159
-						}
160
-						$property = $vCard->createProperty($key, $entry["value"]);
161
-						if (isset($entry["type"])) {
162
-							$property->add('TYPE', $entry["type"]);
163
-						}
164
-					}
165
-					$vCard->add($property);
166
-				}
167
-			} elseif ($key !== 'URI') {
168
-				$vCard->$key = $vCard->createProperty($key, $value);
169
-			}
170
-		}
171
-
172
-		if ($update) {
173
-			$this->backend->updateCard($this->getKey(), $uri, $vCard->serialize());
174
-		} else {
175
-			$this->backend->createCard($this->getKey(), $uri, $vCard->serialize());
176
-		}
177
-
178
-		return $this->vCard2Array($uri, $vCard);
179
-	}
180
-
181
-	/**
182
-	 * @return mixed
183
-	 * @since 5.0.0
184
-	 */
185
-	public function getPermissions() {
186
-		$permissions = $this->addressBook->getACL();
187
-		$result = 0;
188
-		foreach ($permissions as $permission) {
189
-			switch ($permission['privilege']) {
190
-				case '{DAV:}read':
191
-					$result |= Constants::PERMISSION_READ;
192
-					break;
193
-				case '{DAV:}write':
194
-					$result |= Constants::PERMISSION_CREATE;
195
-					$result |= Constants::PERMISSION_UPDATE;
196
-					break;
197
-				case '{DAV:}all':
198
-					$result |= Constants::PERMISSION_ALL;
199
-					break;
200
-			}
201
-		}
202
-
203
-		return $result;
204
-	}
205
-
206
-	/**
207
-	 * @param object $id the unique identifier to a contact
208
-	 * @return bool successful or not
209
-	 * @since 5.0.0
210
-	 */
211
-	public function delete($id) {
212
-		$uri = $this->backend->getCardUri($id);
213
-		return $this->backend->deleteCard($this->addressBookInfo['id'], $uri);
214
-	}
215
-
216
-	/**
217
-	 * read vCard data into a vCard object
218
-	 *
219
-	 * @param string $cardData
220
-	 * @return VCard
221
-	 */
222
-	protected function readCard($cardData) {
223
-		return  Reader::read($cardData);
224
-	}
225
-
226
-	/**
227
-	 * create UID for contact
228
-	 *
229
-	 * @return string
230
-	 */
231
-	protected function createUid() {
232
-		do {
233
-			$uid = $this->getUid();
234
-			$contact = $this->backend->getContact($this->getKey(), $uid . '.vcf');
235
-		} while (!empty($contact));
236
-
237
-		return $uid;
238
-	}
239
-
240
-	/**
241
-	 * getUid is only there for testing, use createUid instead
242
-	 */
243
-	protected function getUid() {
244
-		return UUIDUtil::getUUID();
245
-	}
246
-
247
-	/**
248
-	 * create empty vcard
249
-	 *
250
-	 * @param string $uid
251
-	 * @return VCard
252
-	 */
253
-	protected function createEmptyVCard($uid) {
254
-		$vCard = new VCard();
255
-		$vCard->UID = $uid;
256
-		return $vCard;
257
-	}
258
-
259
-	/**
260
-	 * create array with all vCard properties
261
-	 *
262
-	 * @param string $uri
263
-	 * @param VCard $vCard
264
-	 * @param boolean $withTypes (optional) return the values as arrays of value/type pairs
265
-	 * @return array
266
-	 */
267
-	protected function vCard2Array($uri, VCard $vCard, $withTypes = false) {
268
-		$result = [
269
-			'URI' => $uri,
270
-		];
271
-
272
-		foreach ($vCard->children() as $property) {
273
-			if ($property->name === 'PHOTO' && $property->getValueType() === 'BINARY') {
274
-				$url = $this->urlGenerator->getAbsoluteURL(
275
-					$this->urlGenerator->linkTo('', 'remote.php') . '/dav/');
276
-				$url .= implode('/', [
277
-					'addressbooks',
278
-					substr($this->addressBookInfo['principaluri'], 11), //cut off 'principals/'
279
-					$this->addressBookInfo['uri'],
280
-					$uri
281
-				]) . '?photo';
282
-
283
-				$result['PHOTO'] = 'VALUE=uri:' . $url;
284
-			} elseif (in_array($property->name, ['URL', 'GEO', 'CLOUD', 'ADR', 'EMAIL', 'IMPP', 'TEL', 'X-SOCIALPROFILE', 'RELATED', 'LANG', 'X-ADDRESSBOOKSERVER-MEMBER'])) {
285
-				if (!isset($result[$property->name])) {
286
-					$result[$property->name] = [];
287
-				}
288
-
289
-				$type = $this->getTypeFromProperty($property);
290
-				if ($withTypes) {
291
-					$result[$property->name][] = [
292
-						'type' => $type,
293
-						'value' => $property->getValue()
294
-					];
295
-				} else {
296
-					$result[$property->name][] = $property->getValue();
297
-				}
298
-			} else {
299
-				$result[$property->name] = $property->getValue();
300
-			}
301
-		}
302
-
303
-		if ($this->isSystemAddressBook()) {
304
-			$result['isLocalSystemBook'] = true;
305
-		}
306
-		return $result;
307
-	}
308
-
309
-	/**
310
-	 * Get the type of the current property
311
-	 *
312
-	 * @param Property $property
313
-	 * @return null|string
314
-	 */
315
-	protected function getTypeFromProperty(Property $property) {
316
-		$parameters = $property->parameters();
317
-		// Type is the social network, when it's empty we don't need this.
318
-		if (isset($parameters['TYPE'])) {
319
-			/** @var \Sabre\VObject\Parameter $type */
320
-			$type = $parameters['TYPE'];
321
-			return $type->getValue();
322
-		}
323
-
324
-		return null;
325
-	}
326
-
327
-	/**
328
-	 * @inheritDoc
329
-	 */
330
-	public function isShared(): bool {
331
-		if (!isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
332
-			return false;
333
-		}
334
-
335
-		return $this->addressBookInfo['principaluri']
336
-			!== $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'];
337
-	}
338
-
339
-	/**
340
-	 * @inheritDoc
341
-	 */
342
-	public function isSystemAddressBook(): bool {
343
-		return $this->addressBookInfo['principaluri'] === 'principals/system/system' && (
344
-			$this->addressBookInfo['uri'] === 'system' ||
345
-			$this->addressBookInfo['{DAV:}displayname'] === $this->urlGenerator->getBaseUrl()
346
-		);
347
-	}
44
+    /** @var CardDavBackend */
45
+    private $backend;
46
+
47
+    /** @var array */
48
+    private $addressBookInfo;
49
+
50
+    /** @var AddressBook */
51
+    private $addressBook;
52
+
53
+    /** @var IURLGenerator */
54
+    private $urlGenerator;
55
+
56
+    /**
57
+     * AddressBookImpl constructor.
58
+     *
59
+     * @param AddressBook $addressBook
60
+     * @param array $addressBookInfo
61
+     * @param CardDavBackend $backend
62
+     * @param IUrlGenerator $urlGenerator
63
+     */
64
+    public function __construct(
65
+            AddressBook $addressBook,
66
+            array $addressBookInfo,
67
+            CardDavBackend $backend,
68
+            IURLGenerator $urlGenerator) {
69
+        $this->addressBook = $addressBook;
70
+        $this->addressBookInfo = $addressBookInfo;
71
+        $this->backend = $backend;
72
+        $this->urlGenerator = $urlGenerator;
73
+    }
74
+
75
+    /**
76
+     * @return string defining the technical unique key
77
+     * @since 5.0.0
78
+     */
79
+    public function getKey() {
80
+        return $this->addressBookInfo['id'];
81
+    }
82
+
83
+    /**
84
+     * @return string defining the unique uri
85
+     * @since 16.0.0
86
+     */
87
+    public function getUri(): string {
88
+        return $this->addressBookInfo['uri'];
89
+    }
90
+
91
+    /**
92
+     * In comparison to getKey() this function returns a human readable (maybe translated) name
93
+     *
94
+     * @return mixed
95
+     * @since 5.0.0
96
+     */
97
+    public function getDisplayName() {
98
+        return $this->addressBookInfo['{DAV:}displayname'];
99
+    }
100
+
101
+    /**
102
+     * @param string $pattern which should match within the $searchProperties
103
+     * @param array $searchProperties defines the properties within the query pattern should match
104
+     * @param array $options Options to define the output format and search behavior
105
+     * 	- 'types' boolean (since 15.0.0) If set to true, fields that come with a TYPE property will be an array
106
+     *    example: ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['type => 'HOME', 'value' => '[email protected]']]
107
+     * 	- 'escape_like_param' - If set to false wildcards _ and % are not escaped
108
+     * 	- 'limit' - Set a numeric limit for the search results
109
+     * 	- 'offset' - Set the offset for the limited search results
110
+     * @return array an array of contacts which are arrays of key-value-pairs
111
+     *  example result:
112
+     *  [
113
+     *		['id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => '[email protected]', 'GEO' => '37.386013;-122.082932'],
114
+     *		['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['[email protected]', '[email protected]']]
115
+     *	]
116
+     * @since 5.0.0
117
+     */
118
+    public function search($pattern, $searchProperties, $options) {
119
+        $results = $this->backend->search($this->getKey(), $pattern, $searchProperties, $options);
120
+
121
+        $withTypes = \array_key_exists('types', $options) && $options['types'] === true;
122
+
123
+        $vCards = [];
124
+        foreach ($results as $result) {
125
+            $vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata']), $withTypes);
126
+        }
127
+
128
+        return $vCards;
129
+    }
130
+
131
+    /**
132
+     * @param array $properties this array if key-value-pairs defines a contact
133
+     * @return array an array representing the contact just created or updated
134
+     * @since 5.0.0
135
+     */
136
+    public function createOrUpdate($properties) {
137
+        $update = false;
138
+        if (!isset($properties['URI'])) { // create a new contact
139
+            $uid = $this->createUid();
140
+            $uri = $uid . '.vcf';
141
+            $vCard = $this->createEmptyVCard($uid);
142
+        } else { // update existing contact
143
+            $uri = $properties['URI'];
144
+            $vCardData = $this->backend->getCard($this->getKey(), $uri);
145
+            $vCard = $this->readCard($vCardData['carddata']);
146
+            $update = true;
147
+        }
148
+
149
+        foreach ($properties as $key => $value) {
150
+            if (is_array($value)) {
151
+                $vCard->remove($key);
152
+                foreach ($value as $entry) {
153
+                    if (is_string($entry)) {
154
+                        $property = $vCard->createProperty($key, $entry);
155
+                    } else {
156
+                        if (($key === "ADR" || $key === "PHOTO") && is_string($entry["value"])) {
157
+                            $entry["value"] = stripslashes($entry["value"]);
158
+                            $entry["value"] = explode(';', $entry["value"]);
159
+                        }
160
+                        $property = $vCard->createProperty($key, $entry["value"]);
161
+                        if (isset($entry["type"])) {
162
+                            $property->add('TYPE', $entry["type"]);
163
+                        }
164
+                    }
165
+                    $vCard->add($property);
166
+                }
167
+            } elseif ($key !== 'URI') {
168
+                $vCard->$key = $vCard->createProperty($key, $value);
169
+            }
170
+        }
171
+
172
+        if ($update) {
173
+            $this->backend->updateCard($this->getKey(), $uri, $vCard->serialize());
174
+        } else {
175
+            $this->backend->createCard($this->getKey(), $uri, $vCard->serialize());
176
+        }
177
+
178
+        return $this->vCard2Array($uri, $vCard);
179
+    }
180
+
181
+    /**
182
+     * @return mixed
183
+     * @since 5.0.0
184
+     */
185
+    public function getPermissions() {
186
+        $permissions = $this->addressBook->getACL();
187
+        $result = 0;
188
+        foreach ($permissions as $permission) {
189
+            switch ($permission['privilege']) {
190
+                case '{DAV:}read':
191
+                    $result |= Constants::PERMISSION_READ;
192
+                    break;
193
+                case '{DAV:}write':
194
+                    $result |= Constants::PERMISSION_CREATE;
195
+                    $result |= Constants::PERMISSION_UPDATE;
196
+                    break;
197
+                case '{DAV:}all':
198
+                    $result |= Constants::PERMISSION_ALL;
199
+                    break;
200
+            }
201
+        }
202
+
203
+        return $result;
204
+    }
205
+
206
+    /**
207
+     * @param object $id the unique identifier to a contact
208
+     * @return bool successful or not
209
+     * @since 5.0.0
210
+     */
211
+    public function delete($id) {
212
+        $uri = $this->backend->getCardUri($id);
213
+        return $this->backend->deleteCard($this->addressBookInfo['id'], $uri);
214
+    }
215
+
216
+    /**
217
+     * read vCard data into a vCard object
218
+     *
219
+     * @param string $cardData
220
+     * @return VCard
221
+     */
222
+    protected function readCard($cardData) {
223
+        return  Reader::read($cardData);
224
+    }
225
+
226
+    /**
227
+     * create UID for contact
228
+     *
229
+     * @return string
230
+     */
231
+    protected function createUid() {
232
+        do {
233
+            $uid = $this->getUid();
234
+            $contact = $this->backend->getContact($this->getKey(), $uid . '.vcf');
235
+        } while (!empty($contact));
236
+
237
+        return $uid;
238
+    }
239
+
240
+    /**
241
+     * getUid is only there for testing, use createUid instead
242
+     */
243
+    protected function getUid() {
244
+        return UUIDUtil::getUUID();
245
+    }
246
+
247
+    /**
248
+     * create empty vcard
249
+     *
250
+     * @param string $uid
251
+     * @return VCard
252
+     */
253
+    protected function createEmptyVCard($uid) {
254
+        $vCard = new VCard();
255
+        $vCard->UID = $uid;
256
+        return $vCard;
257
+    }
258
+
259
+    /**
260
+     * create array with all vCard properties
261
+     *
262
+     * @param string $uri
263
+     * @param VCard $vCard
264
+     * @param boolean $withTypes (optional) return the values as arrays of value/type pairs
265
+     * @return array
266
+     */
267
+    protected function vCard2Array($uri, VCard $vCard, $withTypes = false) {
268
+        $result = [
269
+            'URI' => $uri,
270
+        ];
271
+
272
+        foreach ($vCard->children() as $property) {
273
+            if ($property->name === 'PHOTO' && $property->getValueType() === 'BINARY') {
274
+                $url = $this->urlGenerator->getAbsoluteURL(
275
+                    $this->urlGenerator->linkTo('', 'remote.php') . '/dav/');
276
+                $url .= implode('/', [
277
+                    'addressbooks',
278
+                    substr($this->addressBookInfo['principaluri'], 11), //cut off 'principals/'
279
+                    $this->addressBookInfo['uri'],
280
+                    $uri
281
+                ]) . '?photo';
282
+
283
+                $result['PHOTO'] = 'VALUE=uri:' . $url;
284
+            } elseif (in_array($property->name, ['URL', 'GEO', 'CLOUD', 'ADR', 'EMAIL', 'IMPP', 'TEL', 'X-SOCIALPROFILE', 'RELATED', 'LANG', 'X-ADDRESSBOOKSERVER-MEMBER'])) {
285
+                if (!isset($result[$property->name])) {
286
+                    $result[$property->name] = [];
287
+                }
288
+
289
+                $type = $this->getTypeFromProperty($property);
290
+                if ($withTypes) {
291
+                    $result[$property->name][] = [
292
+                        'type' => $type,
293
+                        'value' => $property->getValue()
294
+                    ];
295
+                } else {
296
+                    $result[$property->name][] = $property->getValue();
297
+                }
298
+            } else {
299
+                $result[$property->name] = $property->getValue();
300
+            }
301
+        }
302
+
303
+        if ($this->isSystemAddressBook()) {
304
+            $result['isLocalSystemBook'] = true;
305
+        }
306
+        return $result;
307
+    }
308
+
309
+    /**
310
+     * Get the type of the current property
311
+     *
312
+     * @param Property $property
313
+     * @return null|string
314
+     */
315
+    protected function getTypeFromProperty(Property $property) {
316
+        $parameters = $property->parameters();
317
+        // Type is the social network, when it's empty we don't need this.
318
+        if (isset($parameters['TYPE'])) {
319
+            /** @var \Sabre\VObject\Parameter $type */
320
+            $type = $parameters['TYPE'];
321
+            return $type->getValue();
322
+        }
323
+
324
+        return null;
325
+    }
326
+
327
+    /**
328
+     * @inheritDoc
329
+     */
330
+    public function isShared(): bool {
331
+        if (!isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
332
+            return false;
333
+        }
334
+
335
+        return $this->addressBookInfo['principaluri']
336
+            !== $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'];
337
+    }
338
+
339
+    /**
340
+     * @inheritDoc
341
+     */
342
+    public function isSystemAddressBook(): bool {
343
+        return $this->addressBookInfo['principaluri'] === 'principals/system/system' && (
344
+            $this->addressBookInfo['uri'] === 'system' ||
345
+            $this->addressBookInfo['{DAV:}displayname'] === $this->urlGenerator->getBaseUrl()
346
+        );
347
+    }
348 348
 }
Please login to merge, or discard this patch.