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