Completed
Push — master ( 4c54ca...8e9505 )
by Joas
34:55
created

Manager::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 31
nc 1
nop 15
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Arthur Schiwon <[email protected]>
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OC\Settings;
25
26
use OC\Accounts\AccountManager;
27
use OCP\App\IAppManager;
28
use OCP\AppFramework\QueryException;
29
use OCP\Encryption\IManager as EncryptionManager;
30
use OCP\IConfig;
31
use OCP\IDBConnection;
32
use OCP\IGroupManager;
33
use OCP\IL10N;
34
use OCP\ILogger;
35
use OCP\IRequest;
36
use OCP\IURLGenerator;
37
use OCP\IUserManager;
38
use OCP\L10N\IFactory;
39
use OCP\Lock\ILockingProvider;
40
use OCP\Settings\ISettings;
41
use OCP\Settings\IManager;
42
use OCP\Settings\ISection;
43
44
class Manager implements IManager {
45
	/** @var ILogger */
46
	private $log;
47
	/** @var IDBConnection */
48
	private $dbc;
49
	/** @var Mapper */
50
	private $mapper;
51
	/** @var IL10N */
52
	private $l;
53
	/** @var IConfig */
54
	private $config;
55
	/** @var EncryptionManager */
56
	private $encryptionManager;
57
	/** @var IUserManager */
58
	private $userManager;
59
	/** @var ILockingProvider */
60
	private $lockingProvider;
61
	/** @var IRequest */
62
	private $request;
63
	/** @var IURLGenerator */
64
	private $url;
65
	/** @var AccountManager */
66
	private $accountManager;
67
	/** @var IGroupManager */
68
	private $groupManager;
69
	/** @var IFactory */
70
	private $l10nFactory;
71
	/** @var \OC_Defaults */
72
	private $defaults;
73
	/** @var IAppManager */
74
	private $appManager;
75
76
	/**
77
	 * @param ILogger $log
78
	 * @param IDBConnection $dbc
79
	 * @param IL10N $l
80
	 * @param IConfig $config
81
	 * @param EncryptionManager $encryptionManager
82
	 * @param IUserManager $userManager
83
	 * @param ILockingProvider $lockingProvider
84
	 * @param IRequest $request
85
	 * @param Mapper $mapper
86
	 * @param IURLGenerator $url
87
	 * @param AccountManager $accountManager
88
	 * @param IGroupManager $groupManager
89
	 * @param IFactory $l10nFactory
90
	 * @param \OC_Defaults $defaults
91
	 */
92
	public function __construct(
93
		ILogger $log,
94
		IDBConnection $dbc,
95
		IL10N $l,
96
		IConfig $config,
97
		EncryptionManager $encryptionManager,
98
		IUserManager $userManager,
99
		ILockingProvider $lockingProvider,
100
		IRequest $request,
101
		Mapper $mapper,
102
		IURLGenerator $url,
103
		AccountManager $accountManager,
104
		IGroupManager $groupManager,
105
		IFactory $l10nFactory,
106
		\OC_Defaults $defaults,
107
		IAppManager $appManager
108
	) {
109
		$this->log = $log;
110
		$this->dbc = $dbc;
111
		$this->mapper = $mapper;
112
		$this->l = $l;
113
		$this->config = $config;
114
		$this->encryptionManager = $encryptionManager;
115
		$this->userManager = $userManager;
116
		$this->lockingProvider = $lockingProvider;
117
		$this->request = $request;
118
		$this->url = $url;
119
		$this->accountManager = $accountManager;
120
		$this->groupManager = $groupManager;
121
		$this->l10nFactory = $l10nFactory;
122
		$this->defaults = $defaults;
123
		$this->appManager = $appManager;
124
	}
125
126
	/**
127
	 * @inheritdoc
128
	 */
129
	public function setupSettings(array $settings) {
130
		if (!empty($settings[IManager::KEY_ADMIN_SECTION])) {
131
			foreach ($settings[IManager::KEY_ADMIN_SECTION] as $className) {
132
				$this->setupSectionEntry($className, 'admin');
133
			}
134
		}
135 View Code Duplication
		if (!empty($settings[IManager::KEY_ADMIN_SETTINGS])) {
136
			foreach ($settings[IManager::KEY_ADMIN_SETTINGS] as $className) {
137
				$this->setupSettingsEntry($className, 'admin');
138
			}
139
		}
140
141 View Code Duplication
		if (!empty($settings[IManager::KEY_PERSONAL_SECTION])) {
142
			foreach ($settings[IManager::KEY_PERSONAL_SECTION] as $className) {
143
				$this->setupSectionEntry($className, 'personal');
144
			}
145
		}
146 View Code Duplication
		if (!empty($settings[IManager::KEY_PERSONAL_SETTINGS])) {
147
			foreach ($settings[IManager::KEY_PERSONAL_SETTINGS] as $className) {
148
				$this->setupSettingsEntry($className, 'personal');
149
			}
150
		}
151
	}
152
153
	/**
154
	 * attempts to remove an apps section and/or settings entry. A listener is
155
	 * added centrally making sure that this method is called ones an app was
156
	 * disabled.
157
	 *
158
	 * @param string $appId
159
	 * @since 9.1.0
160
	 */
161
	public function onAppDisabled($appId) {
162
		$appInfo = \OC_App::getAppInfo($appId); // hello static legacy
163
164 View Code Duplication
		if (!empty($appInfo['settings'][IManager::KEY_ADMIN_SECTION])) {
165
			foreach ($appInfo['settings'][IManager::KEY_ADMIN_SECTION] as $className) {
166
				$this->mapper->remove(Mapper::TABLE_ADMIN_SECTIONS, trim($className, '\\'));
167
			}
168
		}
169 View Code Duplication
		if (!empty($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS])) {
170
			foreach ($appInfo['settings'][IManager::KEY_ADMIN_SETTINGS] as $className) {
171
				$this->mapper->remove(Mapper::TABLE_ADMIN_SETTINGS, trim($className, '\\'));
172
			}
173
		}
174
175 View Code Duplication
		if (!empty($appInfo['settings'][IManager::KEY_PERSONAL_SECTION])) {
176
			foreach ($appInfo['settings'][IManager::KEY_PERSONAL_SECTION] as $className) {
177
				$this->mapper->remove(Mapper::TABLE_PERSONAL_SECTIONS, trim($className, '\\'));
178
			}
179
		}
180 View Code Duplication
		if (!empty($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS])) {
181
			foreach ($appInfo['settings'][IManager::KEY_PERSONAL_SETTINGS] as $className) {
182
				$this->mapper->remove(Mapper::TABLE_PERSONAL_SETTINGS, trim($className, '\\'));
183
			}
184
		}
185
	}
186
187
	public function checkForOrphanedClassNames() {
188
		$tables = [Mapper::TABLE_ADMIN_SECTIONS, Mapper::TABLE_ADMIN_SETTINGS, Mapper::TABLE_PERSONAL_SECTIONS, Mapper::TABLE_PERSONAL_SETTINGS];
189
		foreach ($tables as $table) {
190
			$classes = $this->mapper->getClasses($table);
191
			foreach ($classes as $className) {
192
				try {
193
					\OC::$server->query($className);
194
				} catch (QueryException $e) {
195
					$this->mapper->remove($table, $className);
196
				}
197
			}
198
		}
199
	}
200
201
	/**
202
	 * @param string $sectionClassName
203
	 * @param string $type either 'admin' or 'personal'
204
	 */
205 View Code Duplication
	private function setupSectionEntry($sectionClassName, $type) {
206
		if (!class_exists($sectionClassName)) {
207
			$this->log->debug('Could not find ' . ucfirst($type) . ' section class ' . $sectionClassName);
208
			return;
209
		}
210
		try {
211
			$section = $this->query($sectionClassName);
212
		} catch (QueryException $e) {
213
			// cancel
214
			return;
215
		}
216
217
		if (!$section instanceof ISection) {
218
			$this->log->error(
219
				ucfirst($type) .' section instance must implement \OCP\ISection. Invalid class: {class}',
220
				['class' => $sectionClassName]
221
			);
222
			return;
223
		}
224
		$table = $this->getSectionTableForType($type);
225
		if(!$this->hasSection(get_class($section), $table)) {
226
			$this->addSection($section, $table);
227
		} else {
228
			$this->updateSection($section, $table);
229
		}
230
	}
231
232 View Code Duplication
	private function addSection(ISection $section, $table) {
233
		$this->mapper->add($table, [
234
			'id' => $section->getID(),
235
			'class' => get_class($section),
236
			'priority' => $section->getPriority(),
237
		]);
238
	}
239
240 View Code Duplication
	private function addSettings(ISettings $settings, $table) {
241
		$this->mapper->add($table, [
242
			'class' => get_class($settings),
243
			'section' => $settings->getSection(),
244
			'priority' => $settings->getPriority(),
245
		]);
246
	}
247
248 View Code Duplication
	private function updateSettings(ISettings $settings, $table) {
249
		$this->mapper->update(
250
			$table,
251
			'class',
252
			get_class($settings),
253
			[
254
				'section' => $settings->getSection(),
255
				'priority' => $settings->getPriority(),
256
			]
257
		);
258
	}
259
260 View Code Duplication
	private function updateSection(ISection $section, $table) {
261
		$this->mapper->update(
262
			$table,
263
			'class',
264
			get_class($section),
265
			[
266
				'id' => $section->getID(),
267
				'priority' => $section->getPriority(),
268
			]
269
		);
270
	}
271
272
	/**
273
	 * @param string $className
274
	 * @param string $table
275
	 * @return bool
276
	 */
277
	private function hasSection($className, $table) {
278
		return $this->mapper->has($table, $className);
279
	}
280
281
	/**
282
	 * @param string $className
283
	 * @return bool
284
	 */
285
	private function hasSettings($className, $table) {
286
		return $this->mapper->has($table, $className);
287
	}
288
289 View Code Duplication
	private function setupSettingsEntry($settingsClassName, $type) {
290
		if (!class_exists($settingsClassName)) {
291
			$this->log->debug('Could not find ' . $type . ' section class ' . $settingsClassName);
292
			return;
293
		}
294
295
		try {
296
			/** @var ISettings $settings */
297
			$settings = $this->query($settingsClassName);
298
		} catch (QueryException $e) {
299
			// cancel
300
			return;
301
		}
302
303
		if (!$settings instanceof ISettings) {
304
			$this->log->error(
305
				ucfirst($type) . ' section instance must implement \OCP\Settings\ISettings. Invalid class: {class}',
306
				['class' => $settingsClassName]
307
			);
308
			return;
309
		}
310
		$table = $this->getSettingsTableForType($type);
311
		if (!$this->hasSettings(get_class($settings), $table)) {
312
			$this->addSettings($settings, $table);
313
		} else {
314
			$this->updateSettings($settings, $table);
315
		}
316
	}
317
318 View Code Duplication
	private function getSectionTableForType($type) {
319
		if($type === 'admin') {
320
			return Mapper::TABLE_ADMIN_SECTIONS;
321
		} else if($type === 'personal') {
322
			return Mapper::TABLE_PERSONAL_SECTIONS;
323
		}
324
		throw new \InvalidArgumentException('"admin" or "personal" expected');
325
	}
326
327 View Code Duplication
	private function getSettingsTableForType($type) {
328
		if($type === 'admin') {
329
			return Mapper::TABLE_ADMIN_SETTINGS;
330
		} else if($type === 'personal') {
331
			return Mapper::TABLE_PERSONAL_SETTINGS;
332
		}
333
		throw new \InvalidArgumentException('"admin" or "personal" expected');
334
	}
335
336
	private function query($className) {
337
		try {
338
			return \OC::$server->query($className);
339
		} catch (QueryException $e) {
340
			$this->log->logException($e);
341
			throw $e;
342
		}
343
	}
344
345
	/**
346
	 * @inheritdoc
347
	 */
348
	public function getAdminSections() {
349
		// built-in sections
350
		$sections = [
351
			0 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('settings', 'admin.svg'))],
352
			5 => [new Section('sharing', $this->l->t('Sharing'), 0, $this->url->imagePath('core', 'actions/share.svg'))],
353
			10 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('core', 'actions/password.svg'))],
354
			45 => [new Section('encryption', $this->l->t('Encryption'), 0, $this->url->imagePath('core', 'actions/password.svg'))],
355
			98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))],
356
			99 => [new Section('tips-tricks', $this->l->t('Tips & tricks'), 0, $this->url->imagePath('settings', 'help.svg'))],
357
		];
358
359
		$rows = $this->mapper->getAdminSectionsFromDB();
360
361
		foreach ($rows as $row) {
362
			if (!isset($sections[$row['priority']])) {
363
				$sections[$row['priority']] = [];
364
			}
365
			try {
366
				$sections[$row['priority']][] = $this->query($row['class']);
367
			} catch (QueryException $e) {
368
				// skip
369
			}
370
		}
371
372
		ksort($sections);
373
374
		return $sections;
375
	}
376
377
	/**
378
	 * @param string $section
379
	 * @return ISection[]
380
	 */
381
	private function getBuiltInAdminSettings($section) {
382
		$forms = [];
383
		try {
384
			if ($section === 'server') {
385
				/** @var ISettings $form */
386
				$form = new Admin\Server($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l);
387
				$forms[$form->getPriority()] = [$form];
388
				$form = new Admin\ServerDevNotice();
389
				$forms[$form->getPriority()] = [$form];
390
			}
391
			if ($section === 'encryption') {
392
				/** @var ISettings $form */
393
				$form = new Admin\Encryption($this->encryptionManager, $this->userManager);
394
				$forms[$form->getPriority()] = [$form];
395
			}
396
			if ($section === 'sharing') {
397
				/** @var ISettings $form */
398
				$form = new Admin\Sharing($this->config);
399
				$forms[$form->getPriority()] = [$form];
400
			}
401 View Code Duplication
			if ($section === 'additional') {
402
				/** @var ISettings $form */
403
				$form = new Admin\Additional($this->config);
404
				$forms[$form->getPriority()] = [$form];
405
			}
406
			if ($section === 'tips-tricks') {
407
				/** @var ISettings $form */
408
				$form = new Admin\TipsTricks($this->config);
409
				$forms[$form->getPriority()] = [$form];
410
			}
411
		} catch (QueryException $e) {
412
			// skip
413
		}
414
		return $forms;
415
	}
416
417
	/**
418
	 * @param string $section
419
	 * @return ISection[]
420
	 */
421
	private function getBuiltInPersonalSettings($section) {
422
		$forms = [];
423
		try {
424
			if ($section === 'personal-info') {
425
				/** @var ISettings $form */
426
				$form = new Personal\PersonalInfo(
427
					$this->config,
428
					$this->userManager,
429
					$this->groupManager,
430
					$this->accountManager,
431
					$this->appManager,
432
					$this->l10nFactory,
433
					$this->l
434
				);
435
				$forms[$form->getPriority()] = [$form];
436
			}
437
			if($section === 'security') {
438
				/** @var ISettings $form */
439
				$form = new Personal\Security();
440
				$forms[$form->getPriority()] = [$form];
441
			}
442 View Code Duplication
			if ($section === 'additional') {
443
				/** @var ISettings $form */
444
				$form = new Personal\Additional($this->config);
445
				$forms[$form->getPriority()] = [$form];
446
			}
447
		} catch (QueryException $e) {
448
			// skip
449
		}
450
		return $forms;
451
	}
452
453
	/**
454
	 * @inheritdoc
455
	 */
456 View Code Duplication
	public function getAdminSettings($section) {
457
		$settings = $this->getBuiltInAdminSettings($section);
458
		$dbRows = $this->mapper->getAdminSettingsFromDB($section);
459
460
		foreach ($dbRows as $row) {
461
			if (!isset($settings[$row['priority']])) {
462
				$settings[$row['priority']] = [];
463
			}
464
			try {
465
				$settings[$row['priority']][] = $this->query($row['class']);
466
			} catch (QueryException $e) {
467
				// skip
468
			}
469
		}
470
471
		ksort($settings);
472
		return $settings;
473
	}
474
475
	/**
476
	 * @inheritdoc
477
	 */
478
	public function getPersonalSections() {
479
		$sections = [
480
			0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))],
481
			5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))],
482
			15 => [new Section('sync-clients', $this->l->t('Sync clients'), 0, $this->url->imagePath('settings', 'change.svg'))],
483
		];
484
485
		$legacyForms = \OC_App::getForms('personal');
486
		if(count($legacyForms) > 0 && $this->hasLegacyPersonalSettingsToRender($legacyForms)) {
487
			$sections[98] = [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))];
488
		}
489
490
		$rows = $this->mapper->getPersonalSectionsFromDB();
491
492
		foreach ($rows as $row) {
493
			if (!isset($sections[$row['priority']])) {
494
				$sections[$row['priority']] = [];
495
			}
496
			try {
497
				$sections[$row['priority']][] = $this->query($row['class']);
498
			} catch (QueryException $e) {
499
				// skip
500
			}
501
		}
502
503
		ksort($sections);
504
505
		return $sections;
506
	}
507
508
	/**
509
	 * @param $forms
510
	 * @return bool
511
	 */
512
	private function hasLegacyPersonalSettingsToRender($forms) {
513
		foreach ($forms as $form) {
514
			if(trim($form) !== '') {
515
				return true;
516
			}
517
		}
518
		return false;
519
	}
520
521
	/**
522
	 * @inheritdoc
523
	 */
524 View Code Duplication
	public function getPersonalSettings($section) {
525
		$settings = $this->getBuiltInPersonalSettings($section);
526
		$dbRows = $this->mapper->getPersonalSettingsFromDB($section);
527
528
		foreach ($dbRows as $row) {
529
			if (!isset($settings[$row['priority']])) {
530
				$settings[$row['priority']] = [];
531
			}
532
			try {
533
				$settings[$row['priority']][] = $this->query($row['class']);
534
			} catch (QueryException $e) {
535
				// skip
536
			}
537
		}
538
539
		ksort($settings);
540
		return $settings;
541
	}
542
}
543