Completed
Push — master ( b4b3e8...fb5007 )
by Maxence
02:30 queued 42s
created

MiscService::updateCachedName()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 3
nc 5
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 Exception;
30
use OC;
31
use OC\User\NoUserException;
32
use OCA\Circles\AppInfo\Application;
33
use OCA\Circles\Exceptions\MissingKeyInArrayException;
34
use OCA\Circles\Model\Member;
35
use OCP\AppFramework\Http;
36
use OCP\AppFramework\Http\DataResponse;
37
use OCP\Contacts\ContactsMenu\IContactsStore;
38
use OCP\ILogger;
39
use OCP\IUserManager;
40
41
class MiscService {
42
43
	/** @var ILogger */
44
	private $logger;
45
46
	/** @var IContactsStore */
47
	private $contactsStore;
48
49
	/** @var string */
50
	private $appName;
51
52
	/** @var IUserManager */
53
	private $userManager;
54
55
	public function __construct(
56
		ILogger $logger, IContactsStore $contactsStore, $appName, IUserManager $userManager
57
	) {
58
		$this->logger = $logger;
59
		$this->contactsStore = $contactsStore;
60
		$this->appName = $appName;
61
		$this->userManager = $userManager;
62
	}
63
64
	public function log($message, $level = 4) {
65
		$data = array(
66
			'app'   => $this->appName,
67
			'level' => $level
68
		);
69
70
		$this->logger->log($level, $message, $data);
71
	}
72
73
74
	/**
75
	 * @param $arr
76
	 * @param $k
77
	 *
78
	 * @param string $default
79
	 *
80
	 * @return array|string
81
	 */
82
	public static function get($arr, $k, $default = '') {
83
		if (!key_exists($k, $arr)) {
84
			return $default;
85
		}
86
87
		return $arr[$k];
88
	}
89
90
91
	public static function mustContains($data, $arr) {
92
		if (!is_array($arr)) {
93
			$arr = [$arr];
94
		}
95
96
		foreach ($arr as $k) {
97
			if (!key_exists($k, $data)) {
98
				throw new MissingKeyInArrayException('missing_key_in_array');
99
			}
100
		}
101
	}
102
103
104
	/**
105
	 * @param $data
106
	 *
107
	 * @return DataResponse
108
	 */
109
	public function fail($data) {
110
		$this->log(json_encode($data));
111
112
		return new DataResponse(
113
			array_merge($data, array('status' => 0)),
114
			Http::STATUS_NON_AUTHORATIVE_INFORMATION
115
		);
116
	}
117
118
119
	/**
120
	 * @param $data
121
	 *
122
	 * @return DataResponse
123
	 */
124
	public function success($data) {
125
		return new DataResponse(
126
			array_merge($data, array('status' => 1)),
127
			Http::STATUS_CREATED
128
		);
129
	}
130
131
132
	/**
133
	 * return the real userId, with its real case
134
	 *
135
	 * @param $userId
136
	 *
137
	 * @return string
138
	 * @throws NoUserException
139
	 */
140
	public function getRealUserId($userId) {
141
		if ($this->userManager->userExists($userId)) {
142
			return $this->userManager->get($userId)
143
									 ->getUID();
144
		}
145
146
		$result = $this->userManager->search($userId);
147
		if (sizeof($result) !== 1) {
148
			throw new NoUserException();
149
		}
150
151
		$user = array_shift($result);
152
153
		return $user->getUID();
154
	}
155
156
157
	/**
158
	 * @param Member $member
159
	 */
160
	public function updateCachedName(Member $member) {
161
		try {
162
			$cachedName = $this->getDisplay($member->getUserId(), $member->getType());
163
			if ($cachedName !== $member->getUserId()) {
164
				$member->setCachedName($cachedName);
165
			}
166
		} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
167
		}
168
	}
169
170
171
	/**
172
	 * @param string $ident
173
	 * @param int $type
174
	 *
175
	 * @return string
176
	 */
177
	public static function getDisplay($ident, $type) {
178
		$display = $ident;
179
180
		self::getDisplayMember($display, $ident, $type);
181
		self::getDisplayContact($display, $ident, $type);
182
183
		return $display;
184
	}
185
186
187
	/**
188
	 * @param string $display
189
	 * @param string $ident
190
	 * @param int $type
191
	 */
192
	private static function getDisplayMember(&$display, $ident, $type) {
193
		if ($type !== Member::TYPE_USER) {
194
			return;
195
		}
196
197
		$user = OC::$server->getUserManager()
198
						   ->get($ident);
199
		if ($user !== null) {
200
			$display = $user->getDisplayName();
201
		}
202
	}
203
204
205
	/**
206
	 * @param string $display
207
	 * @param string $ident
208
	 * @param int $type
209
	 */
210
	private static function getDisplayContact(&$display, $ident, $type) {
211
		if ($type !== Member::TYPE_CONTACT) {
212
			return;
213
		}
214
215
		$contact = self::getContactData($ident);
216
		if ($contact === null) {
217
			return;
218
		}
219
		self::getDisplayContactFromArray($display, $contact);
220
	}
221
222
223
	/**
224
	 * @param $ident
225
	 *
226
	 * @return mixed|string
227
	 */
228
	public static function getContactData($ident) {
229
		if (!class_exists(\OCA\DAV\CardDAV\ContactsManager::class) || !strpos($ident, ':')) {
230
			return [];
231
		}
232
233
		list($userId, $contactId) = explode(':', $ident);
234
235
		try {
236
			/** @var \OCA\DAV\CardDAV\ContactsManager $cManager */
237
			$cManager = OC::$server->query(\OCA\DAV\CardDAV\ContactsManager::class);
238
			$urlGenerator = OC::$server->getURLGenerator();
239
240
			$cm = OC::$server->getContactsManager();
241
			$cManager->setupContactsProvider($cm, $userId, $urlGenerator);
242
			$contact = $cm->search($contactId, ['UID']);
243
244
			return array_shift($contact);
245
		} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
246
		}
247
248
		return [];
249
	}
250
251
252
	/**
253
	 * @param string $display
254
	 * @param array $contact
255
	 */
256
	private static function getDisplayContactFromArray(string &$display, array $contact) {
257
		if (!is_array($contact)) {
258
			return;
259
		}
260
261
		if (key_exists('FN', $contact) && $contact['FN'] !== '') {
262
			$display = $contact['FN'];
263
264
			return;
265
		}
266
267
		if (key_exists('EMAIL', $contact) && $contact['EMAIL'] !== '') {
268
			$display = $contact['EMAIL'];
269
270
			return;
271
		}
272
	}
273
274
	/**
275
	 * return Display Name if user exists and display name exists.
276
	 * returns Exception if user does not exist.
277
	 *
278
	 * However, with noException set to true, will return userId even if user does not exist
279
	 *
280
	 * @param $userId
281
	 * @param bool $noException
282
	 *
283
	 * @return string
284
	 * @throws NoUserException
285
	 */
286
	public function getDisplayName($userId, $noException = false) {
287
		$user = $this->userManager->get($userId);
288
		if ($user === null) {
289
			if ($noException) {
290
				return $userId;
291
			} else {
292
				throw new NoUserException();
293
			}
294
		}
295
296
		return $user->getDisplayName();
297
	}
298
299
300
	/**
301
	 * @param array $options
302
	 *
303
	 * @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...
304
	 */
305
	public static function generateClientBodyData($options = []) {
306
		return [
307
			'body'            => ['data' => $options],
308
			'timeout'         => Application::CLIENT_TIMEOUT,
309
			'connect_timeout' => Application::CLIENT_TIMEOUT
310
		];
311
	}
312
313
314
	/**
315
	 * Hacky way to async the rest of the process without keeping client on hold.
316
	 *
317
	 * @param string $result
318
	 */
319
	public function asyncAndLeaveClientOutOfThis($result = '') {
320
		if (ob_get_contents() !== false) {
321
			ob_end_clean();
322
		}
323
324
		header('Connection: close');
325
		ignore_user_abort();
326
		ob_start();
327
		echo(json_encode($result));
328
		$size = ob_get_length();
329
		header('Content-Length: ' . $size);
330
		ob_end_flush();
331
		flush();
332
	}
333
334
335
	/**
336
	 * Generate uuid: 2b5a7a87-8db1-445f-a17b-405790f91c80
337
	 *
338
	 * @param int $length
339
	 *
340
	 * @return string
341
	 */
342 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...
343
		$chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
344
345
		$str = '';
346
		$max = strlen($chars) - 1;
347
		for ($i = 0; $i <= $length; $i++) {
348
			try {
349
				$str .= $chars[random_int(0, $max)];
350
			} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
351
			}
352
		}
353
354
		return $str;
355
	}
356
357
}
358
359