Completed
Pull Request — master (#384)
by Tortue
02:31
created

ConfigService   C

Complexity

Total Complexity 56

Size/Duplication

Total Lines 504
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 56
lcom 1
cbo 0
dl 0
loc 504
rs 5.5199
c 0
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getLocalAddress() 0 4 2
A isCircleAllowed() 0 7 2
A isFilesFilteredCirclesAllowed() 0 8 2
A isListedCirclesAllowed() 0 8 2
A isAddingAnyGroupMembersAllowed() 0 8 2
A isLinkedGroupsAllowed() 0 8 2
A isFederatedCirclesAllowed() 0 8 2
A isInvitationSkipped() 0 3 1
A isLocalNonSSL() 0 8 2
A isNonSSLLinksAllowed() 0 8 2
A generateRemoteHost() 0 9 4
A getCoreValue() 0 5 1
A getAvailableHosts() 0 3 1
A getAppValue() 0 9 2
A setAppValue() 0 3 1
A deleteAppValue() 0 3 1
A getUserValue() 0 3 1
A setUserValue() 0 3 1
A getCoreValueForUser() 0 3 1
A getValueForUser() 0 3 1
A setValueForUser() 0 3 1
A getCloudVersion() 0 9 2
A isAccountOnly() 0 3 1
A isContactsBackend() 0 3 1
A contactsBackendType() 0 3 1
A isGroupsBackend() 0 3 1
A getGroupBackendNamePrefix() 0 10 4
A getGroupBackendNameSuffix() 0 7 3
A stillFrontEnd() 0 11 3
A sendPasswordByMail() 0 7 2
A enforcePasswordProtection() 0 7 2
A getInstanceId() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ConfigService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ConfigService, and based on these observations, apply Extract Interface, too.

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 OC;
30
use OCA\Circles\Model\Circle;
31
use OCP\IConfig;
32
use OCP\IRequest;
33
use OCP\PreConditionNotMetException;
34
use OCP\Util;
35
36
class ConfigService {
37
38
	const CIRCLES_ALLOW_CIRCLES = 'allow_circles';
39
	const CIRCLES_CONTACT_BACKEND = 'contact_backend';
40
	const CIRCLES_STILL_FRONTEND = 'still_frontend';
41
	const CIRCLES_GROUP_BACKEND = 'group_backend';
42
	const CIRCLES_GROUP_BACKEND_NAME_PREFIX = 'group_backend_name_prefix';
43
	const CIRCLES_GROUP_BACKEND_NAME_SUFFIX = 'group_backend_name_suffix';
44
	const CIRCLES_SWAP_TO_TEAMS = 'swap_to_teams';
45
	const CIRCLES_ALLOW_FEDERATED_CIRCLES = 'allow_federated';
46
	const CIRCLES_MEMBERS_LIMIT = 'members_limit';
47
	const CIRCLES_ACCOUNTS_ONLY = 'accounts_only';
48
	const CIRCLES_ALLOW_FILES_CIRCLES_FILTER = 'allow_files_filtered_by_circles';
49
	const CIRCLES_ALLOW_LISTED_CIRCLES = 'allow_listed_circles';
50
	const CIRCLES_ALLOW_ANY_GROUP_MEMBERS = 'allow_adding_any_group_members';
51
	const CIRCLES_ALLOW_LINKED_GROUPS = 'allow_linked_groups';
52
	const CIRCLES_ALLOW_NON_SSL_LINKS = 'allow_non_ssl_links';
53
	const CIRCLES_NON_SSL_LOCAL = 'local_is_non_ssl';
54
	const CIRCLES_ACTIVITY_ON_CREATION = 'creation_activity';
55
	const CIRCLES_SKIP_INVITATION_STEP = 'skip_invitation_to_closed_circles';
56
57
	const CIRCLES_TEST_ASYNC_LOCK = 'test_async_lock';
58
	const CIRCLES_TEST_ASYNC_INIT = 'test_async_init';
59
	const CIRCLES_TEST_ASYNC_HAND = 'test_async_hand';
60
	const CIRCLES_TEST_ASYNC_COUNT = 'test_async_count';
61
62
	private $defaults = [
63
		self::CIRCLES_ALLOW_CIRCLES              => Circle::CIRCLES_ALL,
64
		self::CIRCLES_CONTACT_BACKEND            => '0',
65
		self::CIRCLES_STILL_FRONTEND             => '0',
66
		self::CIRCLES_GROUP_BACKEND              => '0',
67
		self::CIRCLES_GROUP_BACKEND_NAME_PREFIX  => '',
68
		self::CIRCLES_GROUP_BACKEND_NAME_SUFFIX  => '',
69
		self::CIRCLES_TEST_ASYNC_INIT            => '0',
70
		self::CIRCLES_SWAP_TO_TEAMS              => '0',
71
		self::CIRCLES_ACCOUNTS_ONLY              => '0',
72
		self::CIRCLES_MEMBERS_LIMIT              => '50',
73
		self::CIRCLES_ALLOW_FILES_CIRCLES_FILTER => '1',
74
		self::CIRCLES_ALLOW_LISTED_CIRCLES       => '1',
75
		self::CIRCLES_ALLOW_ANY_GROUP_MEMBERS    => '1',
76
		self::CIRCLES_ALLOW_LINKED_GROUPS        => '0',
77
		self::CIRCLES_ALLOW_FEDERATED_CIRCLES    => '0',
78
		self::CIRCLES_ALLOW_NON_SSL_LINKS        => '0',
79
		self::CIRCLES_NON_SSL_LOCAL              => '0',
80
		self::CIRCLES_ACTIVITY_ON_CREATION       => '1',
81
		self::CIRCLES_SKIP_INVITATION_STEP       => '0'
82
	];
83
84
	/** @var string */
85
	private $appName;
86
87
	/** @var IConfig */
88
	private $config;
89
90
	/** @var string */
91
	private $userId;
92
93
	/** @var IRequest */
94
	private $request;
95
96
	/** @var MiscService */
97
	private $miscService;
98
99
	/** @var int */
100
	private $allowedCircle = -1;
101
102
	/** @var int */
103
	private $allowFilesFilteredByCircles = -1;
104
105
	/** @var int */
106
	private $allowedListedCircles = -1;
107
108
	/** @var int */
109
	private $allowAddingAnyGroupMembers = -1;
110
111
	/** @var int */
112
	private $allowedLinkedGroups = -1;
113
114
	/** @var int */
115
	private $allowedFederatedCircles = -1;
116
117
	/** @var int */
118
	private $allowedNonSSLLinks = -1;
119
120
	/** @var int */
121
	private $localNonSSL = -1;
122
123
	/** @var string */
124
	private $groupBackendNamePrefix = null;
125
126
	/** @var string */
127
	private $groupBackendNameSuffix = null;
128
129
	/**
130
	 * ConfigService constructor.
131
	 *
132
	 * @param string $appName
133
	 * @param IConfig $config
134
	 * @param IRequest $request
135
	 * @param string $userId
136
	 * @param MiscService $miscService
137
	 */
138
	public function __construct(
139
		$appName, IConfig $config, IRequest $request, $userId, MiscService $miscService
140
	) {
141
		$this->appName = $appName;
142
		$this->config = $config;
143
		$this->request = $request;
144
		$this->userId = $userId;
145
		$this->miscService = $miscService;
146
	}
147
148
149
	public function getLocalAddress() {
150
		return (($this->isLocalNonSSL()) ? 'http://' : '')
151
			   . $this->request->getServerHost();
152
	}
153
154
155
	/**
156
	 * returns if this type of circle is allowed by the current configuration.
157
	 *
158
	 * @param $type
159
	 *
160
	 * @return int
161
	 */
162
	public function isCircleAllowed($type) {
163
		if ($this->allowedCircle === -1) {
164
			$this->allowedCircle = (int)$this->getAppValue(self::CIRCLES_ALLOW_CIRCLES);
165
		}
166
167
		return ((int)$type & (int)$this->allowedCircle);
168
	}
169
170
	/**
171
	 * returns if the files list could be filtered by circles
172
	 *
173
	 * @return bool
174
	 */
175
	public function isFilesFilteredCirclesAllowed() {
176
		if ($this->allowFilesFilteredByCircles === -1) {
177
			$this->allowFilesFilteredByCircles =
178
				(int)$this->getAppValue(self::CIRCLES_ALLOW_FILES_CIRCLES_FILTER);
179
		}
180
181
		return ($this->allowFilesFilteredByCircles === 1);
182
	}
183
184
	/**
185
	 * returns if the circles are allowed to be listed outside the Circles application.
186
	 *
187
	 * @return bool
188
	 */
189
	public function isListedCirclesAllowed() {
190
		if ($this->allowedListedCircles === -1) {
191
			$this->allowedListedCircles =
192
				(int)$this->getAppValue(self::CIRCLES_ALLOW_LISTED_CIRCLES);
193
		}
194
195
		return ($this->allowedListedCircles === 1);
196
	}
197
198
	/**
199
	 * returns if the current user is allowed to add any group members.
200
	 * even if he isn't a member of these groups
201
	 *
202
	 * @return bool
203
	 */
204
	public function isAddingAnyGroupMembersAllowed() {
205
		if ($this->allowAddingAnyGroupMembers === -1) {
206
			$this->allowAddingAnyGroupMembers =
207
				(int)$this->getAppValue(self::CIRCLES_ALLOW_ANY_GROUP_MEMBERS);
208
		}
209
210
		return ($this->allowAddingAnyGroupMembers === 1);
211
	}
212
213
	/**
214
	 * @return bool
215
	 */
216
	public function isLinkedGroupsAllowed() {
217
		if ($this->allowedLinkedGroups === -1) {
218
			$this->allowedLinkedGroups =
219
				(int)$this->getAppValue(self::CIRCLES_ALLOW_LINKED_GROUPS);
220
		}
221
222
		return ($this->allowedLinkedGroups === 1);
223
	}
224
225
226
	/**
227
	 * @return bool
228
	 */
229
	public function isFederatedCirclesAllowed() {
230
		if ($this->allowedFederatedCircles === -1) {
231
			$this->allowedFederatedCircles =
232
				(int)$this->getAppValue(self::CIRCLES_ALLOW_FEDERATED_CIRCLES);
233
		}
234
235
		return ($this->allowedFederatedCircles === 1);
236
	}
237
238
	/**
239
	 * @return bool
240
	 */
241
	public function isInvitationSkipped() {
242
		return (int)$this->getAppValue(self::CIRCLES_SKIP_INVITATION_STEP) === 1;
243
	}
244
245
	/**
246
	 * @return bool
247
	 */
248
	public function isLocalNonSSL() {
249
		if ($this->localNonSSL === -1) {
250
			$this->localNonSSL =
251
				(int)$this->getAppValue(self::CIRCLES_NON_SSL_LOCAL);
252
		}
253
254
		return ($this->localNonSSL === 1);
255
	}
256
257
258
	/**
259
	 * @return bool
260
	 */
261
	public function isNonSSLLinksAllowed() {
262
		if ($this->allowedNonSSLLinks === -1) {
263
			$this->allowedNonSSLLinks =
264
				(int)$this->getAppValue(self::CIRCLES_ALLOW_NON_SSL_LINKS);
265
		}
266
267
		return ($this->allowedNonSSLLinks === 1);
268
	}
269
270
271
	/**
272
	 * @param string $remote
273
	 *
274
	 * @return string
275
	 */
276
	public function generateRemoteHost($remote) {
277
		if ((!$this->isNonSSLLinksAllowed() || strpos($remote, 'http://') !== 0)
278
			&& strpos($remote, 'https://') !== 0
279
		) {
280
			$remote = 'https://' . $remote;
281
		}
282
283
		return rtrim($remote, '/');
284
	}
285
286
287
	/**
288
	 * Get a value by key
289
	 *
290
	 * @param string $key
291
	 *
292
	 * @return string
293
	 */
294
	public function getCoreValue($key) {
295
		$defaultValue = null;
296
297
		return $this->config->getAppValue('core', $key, $defaultValue);
298
	}
299
300
301
	/**
302
	 * Get available hosts
303
	 *
304
	 * @return array
305
	 */
306
	public function getAvailableHosts(): array {
307
		return $this->config->getSystemValue('trusted_domains', []);
308
	}
309
310
311
	/**
312
	 * Get a value by key
313
	 *
314
	 * @param string $key
315
	 *
316
	 * @return string
317
	 */
318
	public function getAppValue($key) {
319
		$defaultValue = null;
320
321
		if (array_key_exists($key, $this->defaults)) {
322
			$defaultValue = $this->defaults[$key];
323
		}
324
325
		return $this->config->getAppValue($this->appName, $key, $defaultValue);
326
	}
327
328
	/**
329
	 * Set a value by key
330
	 *
331
	 * @param string $key
332
	 * @param string $value
333
	 *
334
	 * @return void
335
	 */
336
	public function setAppValue($key, $value) {
337
		$this->config->setAppValue($this->appName, $key, $value);
338
	}
339
340
	/**
341
	 * remove a key
342
	 *
343
	 * @param string $key
344
	 *
345
	 * @return string
346
	 */
347
	public function deleteAppValue($key) {
348
		return $this->config->deleteAppValue($this->appName, $key);
349
	}
350
351
	/**
352
	 * Get a user value by key
353
	 *
354
	 * @param string $key
355
	 *
356
	 * @return string
357
	 */
358
	public function getUserValue($key) {
359
		return $this->config->getUserValue($this->userId, $this->appName, $key);
360
	}
361
362
	/**
363
	 * Set a user value by key
364
	 *
365
	 * @param string $key
366
	 * @param string $value
367
	 *
368
	 * @return string
369
	 * @throws PreConditionNotMetException
370
	 */
371
	public function setUserValue($key, $value) {
372
		return $this->config->setUserValue($this->userId, $this->appName, $key, $value);
373
	}
374
375
376
	/**
377
	 * Get a user value by key and user
378
	 *
379
	 * @param string $userId
380
	 * @param string $key
381
	 *
382
	 * @param string $default
383
	 *
384
	 * @return string
385
	 */
386
	public function getCoreValueForUser($userId, $key, $default = '') {
387
		return $this->config->getUserValue($userId, 'core', $key, $default);
388
	}
389
390
391
	/**
392
	 * Get a user value by key and user
393
	 *
394
	 * @param string $userId
395
	 * @param string $key
396
	 *
397
	 * @return string
398
	 */
399
	public function getValueForUser($userId, $key) {
400
		return $this->config->getUserValue($userId, $this->appName, $key);
401
	}
402
403
	/**
404
	 * Set a user value by key
405
	 *
406
	 * @param string $userId
407
	 * @param string $key
408
	 * @param string $value
409
	 *
410
	 * @return string
411
	 * @throws PreConditionNotMetException
412
	 */
413
	public function setValueForUser($userId, $key, $value) {
414
		return $this->config->setUserValue($userId, $this->appName, $key, $value);
415
	}
416
417
	/**
418
	 * return the cloud version.
419
	 * if $complete is true, return a string x.y.z
420
	 *
421
	 * @param boolean $complete
422
	 *
423
	 * @return string|integer
424
	 */
425
	public function getCloudVersion($complete = false) {
426
		$ver = Util::getVersion();
427
428
		if ($complete) {
429
			return implode('.', $ver);
430
		}
431
432
		return $ver[0];
433
	}
434
435
436
	/**
437
	 * @return bool
438
	 */
439
	public function isAccountOnly() {
440
		return ($this->getAppValue(self::CIRCLES_ACCOUNTS_ONLY) === '1');
441
	}
442
443
444
	/**
445
	 * @return bool
446
	 */
447
	public function isContactsBackend(): bool {
448
		return ($this->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND) !== '0');
449
	}
450
451
452
	public function contactsBackendType(): int {
453
		return (int)$this->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND);
454
	}
455
456
	/**
457
	 * @return bool
458
	 */
459
	public function isGroupsBackend(): bool {
460
		return ($this->getAppValue(ConfigService::CIRCLES_GROUP_BACKEND) !== '0');
461
	}
462
463
	/**
464
	 * returns the prefix of the group name
465
	 *
466
	 * @return string|null
467
	 */
468
	public function getGroupBackendNamePrefix() {
469
		if ($this->groupBackendNamePrefix === null && $this->isGroupsBackend()) {
470
			$l = OC::$server->getL10N('circles');
471
			$defaultPrefix = $l->t('Circle').' ';
472
			$customPrefix = (string) $this->getAppValue(self::CIRCLES_GROUP_BACKEND_NAME_PREFIX);
473
			$this->groupBackendNamePrefix = ltrim($customPrefix ?: $defaultPrefix);
474
		}
475
476
		return $this->groupBackendNamePrefix;
477
	}
478
479
	/**
480
	 * returns the suffix of the group name
481
	 *
482
	 * @return string|null
483
	 */
484
	public function getGroupBackendNameSuffix() {
485
		if ($this->groupBackendNameSuffix === null && $this->isGroupsBackend()) {
486
			$this->groupBackendNameSuffix = rtrim((string) $this->getAppValue(self::CIRCLES_GROUP_BACKEND_NAME_SUFFIX));
487
		}
488
489
		return $this->groupBackendNameSuffix;
490
	}
491
492
	/**
493
	 * @return bool
494
	 */
495
	public function stillFrontEnd(): bool {
496
		if ($this->getAppValue(self::CIRCLES_CONTACT_BACKEND) !== '1') {
497
			return true;
498
		}
499
500
		if ($this->getAppValue(self::CIRCLES_STILL_FRONTEND) === '1') {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $this->getAppValu...TILL_FRONTEND) === '1';.
Loading history...
501
			return true;
502
		}
503
504
		return false;
505
	}
506
507
508
	/**
509
	 * should the password for a mail share be send to the recipient
510
	 *
511
	 * @return bool
512
	 */
513
	public function sendPasswordByMail() {
514
		if ($this->getAppValue(self::CIRCLES_CONTACT_BACKEND) === '1') {
515
			return false;
516
		}
517
518
		return ($this->config->getAppValue('sharebymail', 'sendpasswordmail', 'yes') === 'yes');
519
	}
520
521
	/**
522
	 * do we require a share by mail to be password protected
523
	 *
524
	 * @return bool
525
	 */
526
	public function enforcePasswordProtection() {
527
		if ($this->getAppValue(self::CIRCLES_CONTACT_BACKEND) === '1') {
528
			return false;
529
		}
530
531
		return ($this->config->getAppValue('sharebymail', 'enforcePasswordProtection', 'no') === 'yes');
532
	}
533
534
535
	public function getInstanceId() {
536
		return $this->config->getSystemValue('instanceid');
537
	}
538
539
}
540