Completed
Push — master ( aff5d0...3918b2 )
by Maxence
02:32
created

MiscService::fail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Circles\Service;
28
29
use daita\MySmallPhpTools\Traits\TArrayTools;
30
use Exception;
31
use OC;
32
use OC\User\NoUserException;
33
use OCA\Circles\AppInfo\Application;
34
use OCA\Circles\Exceptions\MissingKeyInArrayException;
35
use OCA\Circles\Model\Member;
36
use OCP\AppFramework\Http;
37
use OCP\AppFramework\Http\DataResponse;
38
use OCP\Contacts\ContactsMenu\IContactsStore;
39
use OCP\ILogger;
40
use OCP\IUserManager;
41
42
class MiscService {
43
44
45
	use TArrayTools;
46
47
48
	/** @var ILogger */
49
	private $logger;
50
51
	/** @var IContactsStore */
52
	private $contactsStore;
53
54
	/** @var string */
55
	private $appName;
56
57
	/** @var IUserManager */
58
	private $userManager;
59
60
	public function __construct(
61
		ILogger $logger, IContactsStore $contactsStore, $appName, IUserManager $userManager
62
	) {
63
		$this->logger = $logger;
64
		$this->contactsStore = $contactsStore;
65
		$this->appName = $appName;
66
		$this->userManager = $userManager;
67
	}
68
69
	public function log($message, $level = 4) {
70
		$data = array(
71
			'app'   => $this->appName,
72
			'level' => $level
73
		);
74
75
		$this->logger->log($level, $message, $data);
76
	}
77
78
79
	/**
80
	 * @param Exception $e
81
	 */
82
	public function e(Exception $e) {
83
		$this->logger->logException($e, ['app' => 'circles']);
84
	}
85
86
87
	/**
88
	 * @param $arr
89
	 * @param $k
90
	 *
91
	 * @param string $default
92
	 *
93
	 * @return array|string
94
	 */
95
	public static function get($arr, $k, $default = '') {
96
		if (!key_exists($k, $arr)) {
97
			return $default;
98
		}
99
100
		return $arr[$k];
101
	}
102
103
104
	public static function mustContains($data, $arr) {
105
		if (!is_array($arr)) {
106
			$arr = [$arr];
107
		}
108
109
		foreach ($arr as $k) {
110
			if (!key_exists($k, $data)) {
111
				throw new MissingKeyInArrayException('missing_key_in_array');
112
			}
113
		}
114
	}
115
116
117
	/**
118
	 * @param $data
119
	 *
120
	 * @return DataResponse
121
	 */
122
	public function fail($data) {
123
		$this->log(json_encode($data));
124
125
		return new DataResponse(
126
			array_merge($data, array('status' => 0)),
127
			Http::STATUS_NON_AUTHORATIVE_INFORMATION
128
		);
129
	}
130
131
132
	/**
133
	 * @param $data
134
	 *
135
	 * @return DataResponse
136
	 */
137
	public function success($data) {
138
		return new DataResponse(
139
			array_merge($data, array('status' => 1)),
140
			Http::STATUS_CREATED
141
		);
142
	}
143
144
145
	/**
146
	 * return the real userId, with its real case
147
	 *
148
	 * @param $userId
149
	 *
150
	 * @return string
151
	 * @throws NoUserException
152
	 */
153
	public function getRealUserId($userId) {
154
		if ($this->userManager->userExists($userId)) {
155
			return $this->userManager->get($userId)
156
									 ->getUID();
157
		}
158
159
		$result = $this->userManager->search($userId);
160
		if (sizeof($result) !== 1) {
161
			throw new NoUserException();
162
		}
163
164
		$user = array_shift($result);
165
166
		return $user->getUID();
167
	}
168
169
170
	/**
171
	 * @param string $ident
172
	 *
173
	 * @return string
174
	 */
175
	public function getContactDisplayName(string $ident): string {
176
		if (!class_exists(\OCA\DAV\CardDAV\ContactsManager::class) || !strpos($ident, ':')) {
177
			return '';
178
		}
179
180
		list($userId, $contactId) = explode(':', $ident);
181
		$entries = [];
182
		try {
183
			/** @var \OCA\DAV\CardDAV\ContactsManager $cManager */
184
			$cManager = OC::$server->query(\OCA\DAV\CardDAV\ContactsManager::class);
185
			$urlGenerator = OC::$server->getURLGenerator();
186
187
			$cm = OC::$server->getContactsManager();
188
			$cManager->setupContactsProvider($cm, $userId, $urlGenerator);
189
			$contact = $cm->search($contactId, ['UID']);
190
191
			$entries = array_shift($contact);
192
		} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
193
		}
194
195
		if (key_exists('FN', $entries) && $entries['FN'] !== '') {
196
			return $entries['FN'];
197
		}
198
199
		if (key_exists('EMAIL', $entries) && $entries['EMAIL'] !== '') {
200
			return $entries['EMAIL'];
201
		}
202
	}
203
204
205
	/**
206
	 * @param string $ident
207
	 * @param int $type
208
	 *
209
	 * @return string
210
	 * @deprecated
211
	 *
212
	 */
213
	public static function getDisplay($ident, $type) {
214
		$display = $ident;
215
216
		self::getDisplayMember($display, $ident, $type);
217
		self::getDisplayContact($display, $ident, $type);
218
219
		return $display;
220
	}
221
222
223
	/**
224
	 * @param string $display
225
	 * @param string $ident
226
	 * @param int $type
227
	 */
228
	private static function getDisplayMember(&$display, $ident, $type) {
229
		if ($type !== Member::TYPE_USER) {
230
			return;
231
		}
232
233
		$user = OC::$server->getUserManager()
234
						   ->get($ident);
235
		if ($user !== null) {
236
			$display = $user->getDisplayName();
237
		}
238
	}
239
240
241
	/**
242
	 * @param string $display
243
	 * @param string $ident
244
	 * @param int $type
245
	 */
246
	private static function getDisplayContact(&$display, $ident, $type) {
247
		if ($type !== Member::TYPE_CONTACT) {
248
			return;
249
		}
250
251
		$contact = self::getContactData($ident);
0 ignored issues
show
Deprecated Code introduced by
The method OCA\Circles\Service\MiscService::getContactData() has been deprecated.

This method has been deprecated.

Loading history...
252
		if ($contact === null) {
253
			return;
254
		}
255
		self::getDisplayContactFromArray($display, $contact);
0 ignored issues
show
Deprecated Code introduced by
The method OCA\Circles\Service\Misc...splayContactFromArray() has been deprecated.

This method has been deprecated.

Loading history...
256
	}
257
258
259
	/**
260
	 * @param $ident
261
	 *
262
	 * @return mixed|string
263
	 * @deprecated
264
	 *
265
	 */
266
	public static function getContactData($ident) {
267
		if (!class_exists(\OCA\DAV\CardDAV\ContactsManager::class) || !strpos($ident, ':')) {
268
			return [];
269
		}
270
271
		list($userId, $contactId) = explode(':', $ident);
272
273
		try {
274
			/** @var \OCA\DAV\CardDAV\ContactsManager $cManager */
275
			$cManager = OC::$server->query(\OCA\DAV\CardDAV\ContactsManager::class);
276
			$urlGenerator = OC::$server->getURLGenerator();
277
278
			$cm = OC::$server->getContactsManager();
279
			$cManager->setupContactsProvider($cm, $userId, $urlGenerator);
280
			$contact = $cm->search($contactId, ['UID']);
281
282
			return array_shift($contact);
283
		} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
284
		}
285
286
		return [];
287
	}
288
289
290
	/**
291
	 * @param string $display
292
	 * @param array $contact
293
	 *
294
	 * @deprecated
295
	 */
296
	private static function getDisplayContactFromArray(string &$display, array $contact) {
297
		if (!is_array($contact)) {
298
			return;
299
		}
300
301
		if (key_exists('FN', $contact) && $contact['FN'] !== '') {
302
			$display = $contact['FN'];
303
304
			return;
305
		}
306
307
		if (key_exists('EMAIL', $contact) && $contact['EMAIL'] !== '') {
308
			$display = $contact['EMAIL'];
309
310
			return;
311
		}
312
	}
313
314
315
	/**
316
	 * return Display Name if user exists and display name exists.
317
	 * returns Exception if user does not exist.
318
	 *
319
	 * However, with noException set to true, will return userId even if user does not exist
320
	 *
321
	 * @param $userId
322
	 * @param bool $noException
323
	 *
324
	 * @return string
325
	 * @throws NoUserException
326
	 */
327
	public function getDisplayName($userId, $noException = false) {
328
		$user = $this->userManager->get($userId);
329
		if ($user === null) {
330
			if ($noException) {
331
				return $userId;
332
			} else {
333
				throw new NoUserException();
334
			}
335
		}
336
337
		return $user->getDisplayName();
338
	}
339
340
341
	/**
342
	 * @param array $options
343
	 *
344
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string,array>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
345
	 */
346
	public static function generateClientBodyData($options = []) {
347
		return [
348
			'body'            => ['data' => $options],
349
			'timeout'         => Application::CLIENT_TIMEOUT,
350
			'connect_timeout' => Application::CLIENT_TIMEOUT
351
		];
352
	}
353
354
355
	/**
356
	 * Hacky way to async the rest of the process without keeping client on hold.
357
	 *
358
	 * @param string $result
359
	 */
360
	public function asyncAndLeaveClientOutOfThis($result = '') {
361
		if (ob_get_contents() !== false) {
362
			ob_end_clean();
363
		}
364
365
		header('Connection: close');
366
		ignore_user_abort();
367
		ob_start();
368
		echo(json_encode($result));
369
		$size = ob_get_length();
370
		header('Content-Length: ' . $size);
371
		ob_end_flush();
372
		flush();
373
	}
374
375
376
	/**
377
	 * Generate uuid: 2b5a7a87-8db1-445f-a17b-405790f91c80
378
	 *
379
	 * @param int $length
380
	 *
381
	 * @return string
382
	 */
383 View Code Duplication
	public function token(int $length = 0): string {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
384
		$chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
385
386
		$str = '';
387
		$max = strlen($chars) - 1;
388
		for ($i = 0; $i <= $length; $i++) {
389
			try {
390
				$str .= $chars[random_int(0, $max)];
391
			} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
392
			}
393
		}
394
395
		return $str;
396
	}
397
398
399
	/**
400
	 * @param Member $member
401
	 *
402
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
403
	 */
404
	public function getInfosFromContact(Member $member) {
405
		$contact = MiscService::getContactData($member->getUserId());
0 ignored issues
show
Deprecated Code introduced by
The method OCA\Circles\Service\MiscService::getContactData() has been deprecated.

This method has been deprecated.

Loading history...
406
407
		return [
408
			'memberId' => $member->getMemberId(),
409
			'emails'   => $this->getArray('EMAIL', $contact),
410
			'cloudIds' => $this->getArray('CLOUD', $contact)
411
		];
412
413
	}
414
415
}
416
417