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