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