Completed
Push — master ( e9dd6a...c6b1c2 )
by Morris
22:31
created

Manager::getAdminSections()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 26

Duplication

Lines 8
Ratio 30.77 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 8
loc 26
rs 9.504
c 0
b 0
f 0
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\Encryption\IManager as EncryptionManager;
36
use OCP\IConfig;
37
use OCP\IDBConnection;
38
use OCP\IGroupManager;
39
use OCP\IL10N;
40
use OCP\ILogger;
41
use OCP\IRequest;
42
use OCP\IURLGenerator;
43
use OCP\IUserManager;
44
use OCP\L10N\IFactory;
45
use OCP\Lock\ILockingProvider;
46
use OCP\Settings\ISettings;
47
use OCP\Settings\IManager;
48
use OCP\Settings\ISection;
49
use OCP\Util;
50
51
class Manager implements IManager {
52
	/** @var ILogger */
53
	private $log;
54
	/** @var IDBConnection */
55
	private $dbc;
56
	/** @var IL10N */
57
	private $l;
58
	/** @var IConfig */
59
	private $config;
60
	/** @var EncryptionManager */
61
	private $encryptionManager;
62
	/** @var IUserManager */
63
	private $userManager;
64
	/** @var ILockingProvider */
65
	private $lockingProvider;
66
	/** @var IRequest */
67
	private $request;
68
	/** @var IURLGenerator */
69
	private $url;
70
	/** @var AccountManager */
71
	private $accountManager;
72
	/** @var IGroupManager */
73
	private $groupManager;
74
	/** @var IFactory */
75
	private $l10nFactory;
76
	/** @var IAppManager */
77
	private $appManager;
78
79
	/**
80
	 * @param ILogger $log
81
	 * @param IDBConnection $dbc
82
	 * @param IL10N $l
83
	 * @param IConfig $config
84
	 * @param EncryptionManager $encryptionManager
85
	 * @param IUserManager $userManager
86
	 * @param ILockingProvider $lockingProvider
87
	 * @param IRequest $request
88
	 * @param IURLGenerator $url
89
	 * @param AccountManager $accountManager
90
	 * @param IGroupManager $groupManager
91
	 * @param IFactory $l10nFactory
92
	 * @param IAppManager $appManager
93
	 */
94
	public function __construct(
95
		ILogger $log,
96
		IDBConnection $dbc,
97
		IL10N $l,
98
		IConfig $config,
99
		EncryptionManager $encryptionManager,
100
		IUserManager $userManager,
101
		ILockingProvider $lockingProvider,
102
		IRequest $request,
103
		IURLGenerator $url,
104
		AccountManager $accountManager,
105
		IGroupManager $groupManager,
106
		IFactory $l10nFactory,
107
		IAppManager $appManager
108
	) {
109
		$this->log = $log;
110
		$this->dbc = $dbc;
111
		$this->l = $l;
112
		$this->config = $config;
113
		$this->encryptionManager = $encryptionManager;
114
		$this->userManager = $userManager;
115
		$this->lockingProvider = $lockingProvider;
116
		$this->request = $request;
117
		$this->url = $url;
118
		$this->accountManager = $accountManager;
119
		$this->groupManager = $groupManager;
120
		$this->l10nFactory = $l10nFactory;
121
		$this->appManager = $appManager;
122
	}
123
124
	/** @var array */
125
	protected $sectionClasses = [];
126
127
	/** @var array */
128
	protected $sections = [];
129
130
	/**
131
	 * @param string $type 'admin' or 'personal'
132
	 * @param string $section Class must implement OCP\Settings\ISection
133
	 * @return void
134
	 */
135
	public function registerSection(string $type, string $section) {
136
		if (!isset($this->sectionClasses[$type])) {
137
			$this->sectionClasses[$type] = [];
138
		}
139
140
		$this->sectionClasses[$type][] = $section;
141
	}
142
143
	/**
144
	 * @param string $type 'admin' or 'personal'
145
	 * @return ISection[]
146
	 */
147
	protected function getSections(string $type): array {
148
		if (!isset($this->sections[$type])) {
149
			$this->sections[$type] = [];
150
		}
151
152
		if (!isset($this->sectionClasses[$type])) {
153
			return $this->sections[$type];
154
		}
155
156
		foreach ($this->sectionClasses[$type] as $index => $class) {
157
			try {
158
				/** @var ISection $section */
159
				$section = \OC::$server->query($class);
160
			} catch (QueryException $e) {
161
				$this->log->logException($e, ['level' => ILogger::INFO]);
0 ignored issues
show
Documentation introduced by
$e is of type object<OCP\AppFramework\QueryException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162
				continue;
163
			}
164
165
			if (!$section instanceof ISection) {
166
				$this->log->logException(new \InvalidArgumentException('Invalid settings section registered'), ['level' => ILogger::INFO]);
0 ignored issues
show
Documentation introduced by
new \InvalidArgumentExce...gs section registered') is of type object<InvalidArgumentException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
167
				continue;
168
			}
169
170
			$sectionID = $section->getID();
171
172
			if (isset($this->sections[$type][$sectionID])) {
173
				$this->log->logException(new \InvalidArgumentException('Section with the same ID already registered'), ['level' => ILogger::INFO]);
0 ignored issues
show
Documentation introduced by
new \InvalidArgumentExce...ID already registered') is of type object<InvalidArgumentException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
174
				continue;
175
			}
176
177
			$this->sections[$type][$sectionID] = $section;
178
179
			unset($this->sectionClasses[$type][$index]);
180
		}
181
182
		return $this->sections[$type];
183
	}
184
185
	/** @var array */
186
	protected $settingClasses = [];
187
188
	/** @var array */
189
	protected $settings = [];
190
191
	/**
192
	 * @param string $type 'admin' or 'personal'
193
	 * @param string $setting Class must implement OCP\Settings\ISetting
194
	 * @return void
195
	 */
196
	public function registerSetting(string $type, string $setting) {
197
		$this->settingClasses[$setting] = $type;
198
	}
199
200
	/**
201
	 * @param string $type 'admin' or 'personal'
202
	 * @param string $section
203
	 * @return ISettings[]
204
	 */
205
	protected function getSettings(string $type, string $section): array {
206
		if (!isset($this->settings[$type])) {
207
			$this->settings[$type] = [];
208
		}
209
		if (!isset($this->settings[$type][$section])) {
210
			$this->settings[$type][$section] = [];
211
		}
212
213
		foreach ($this->settingClasses as $class => $settingsType) {
214
			try {
215
				/** @var ISettings $setting */
216
				$setting = \OC::$server->query($class);
217
			} catch (QueryException $e) {
218
				$this->log->logException($e, ['level' => ILogger::INFO]);
0 ignored issues
show
Documentation introduced by
$e is of type object<OCP\AppFramework\QueryException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
219
				continue;
220
			}
221
222
			if (!$setting instanceof ISettings) {
223
				$this->log->logException(new \InvalidArgumentException('Invalid settings setting registered'), ['level' => ILogger::INFO]);
0 ignored issues
show
Documentation introduced by
new \InvalidArgumentExce...gs setting registered') is of type object<InvalidArgumentException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
224
				continue;
225
			}
226
227
			if (!isset($this->settings[$settingsType][$setting->getSection()])) {
228
				$this->settings[$settingsType][$setting->getSection()] = [];
229
			}
230
			$this->settings[$settingsType][$setting->getSection()][] = $setting;
231
232
			unset($this->settingClasses[$class]);
233
		}
234
235
		return $this->settings[$type][$section];
236
	}
237
238
	/**
239
	 * @inheritdoc
240
	 */
241
	public function getAdminSections(): array {
242
		// built-in sections
243
		$sections = [
244
			0 => [new Section('overview', $this->l->t('Overview'), 0, $this->url->imagePath('settings', 'admin.svg'))],
245
			1 => [new Section('server', $this->l->t('Basic settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))],
246
			5 => [new Section('sharing', $this->l->t('Sharing'), 0, $this->url->imagePath('core', 'actions/share.svg'))],
247
			10 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('core', 'actions/password.svg'))],
248
			50 => [new Section('groupware', $this->l->t('Groupware'), 0, $this->url->imagePath('core', 'places/contacts.svg'))],
249
			98 => [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))],
250
		];
251
252
		$appSections = $this->getSections('admin');
253
254 View Code Duplication
		foreach ($appSections as $section) {
255
			/** @var ISection $section */
256
			if (!isset($sections[$section->getPriority()])) {
257
				$sections[$section->getPriority()] = [];
258
			}
259
260
			$sections[$section->getPriority()][] = $section;
261
		}
262
263
		ksort($sections);
264
265
		return $sections;
266
	}
267
268
	/**
269
	 * @param string $section
270
	 * @return ISection[]
271
	 */
272
	private function getBuiltInAdminSettings($section): array {
273
		$forms = [];
274
275
		if ($section === 'overview') {
276
			/** @var ISettings $form */
277
			$form = new Admin\Overview($this->config);
278
			$forms[$form->getPriority()] = [$form];
279
		}
280
		if ($section === 'server') {
281
			/** @var ISettings $form */
282
			$form = new Admin\Server($this->dbc, $this->request, $this->config, $this->lockingProvider, $this->l);
283
			$forms[$form->getPriority()] = [$form];
284
			$form = new Admin\Mail($this->config);
285
			$forms[$form->getPriority()] = [$form];
286
		}
287
		if ($section === 'security') {
288
			/** @var ISettings $form */
289
			$form = new Admin\Encryption($this->encryptionManager, $this->userManager);
290
			$forms[$form->getPriority()] = [$form];
291
		}
292
		if ($section === 'sharing') {
293
			/** @var ISettings $form */
294
			$form = new Admin\Sharing($this->config, $this->l);
295
			$forms[$form->getPriority()] = [$form];
296
		}
297
298
		return $forms;
299
	}
300
301
	/**
302
	 * @param string $section
303
	 * @return ISection[]
304
	 */
305
	private function getBuiltInPersonalSettings($section): array {
306
		$forms = [];
307
308
		if ($section === 'personal-info') {
309
			/** @var ISettings $form */
310
			$form = new Personal\PersonalInfo(
311
				$this->config,
312
				$this->userManager,
313
				$this->groupManager,
314
				$this->accountManager,
315
				$this->appManager,
316
				$this->l10nFactory,
317
				$this->l
318
			);
319
			$forms[$form->getPriority()] = [$form];
320
			$form = new Personal\ServerDevNotice();
321
			$forms[$form->getPriority()] = [$form];
322
		}
323
		if($section === 'security') {
324
			/** @var ISettings $form */
325
			$form = new Personal\Security($this->userManager);
326
			$forms[$form->getPriority()] = [$form];
327
		}
328
		if ($section === 'additional') {
329
			/** @var ISettings $form */
330
			$form = new Personal\Additional();
331
			$forms[$form->getPriority()] = [$form];
332
		}
333
334
		return $forms;
335
	}
336
337
	/**
338
	 * @inheritdoc
339
	 */
340 View Code Duplication
	public function getAdminSettings($section): array {
341
		$settings = $this->getBuiltInAdminSettings($section);
342
		$appSettings = $this->getSettings('admin', $section);
343
344
		foreach ($appSettings as $setting) {
345
			if (!isset($settings[$setting->getPriority()])) {
346
				$settings[$setting->getPriority()] = [];
347
			}
348
			$settings[$setting->getPriority()][] = $setting;
349
		}
350
351
		ksort($settings);
352
		return $settings;
353
	}
354
355
	/**
356
	 * @inheritdoc
357
	 */
358
	public function getPersonalSections(): array {
359
		$sections = [
360
			0 => [new Section('personal-info', $this->l->t('Personal info'), 0, $this->url->imagePath('core', 'actions/info.svg'))],
361
			5 => [new Section('security', $this->l->t('Security'), 0, $this->url->imagePath('settings', 'password.svg'))],
362
			15 => [new Section('sync-clients', $this->l->t('Mobile & desktop'), 0, $this->url->imagePath('core', 'clients/phone.svg'))],
363
		];
364
365
		$legacyForms = \OC_App::getForms('personal');
366
		if(!empty($legacyForms) && $this->hasLegacyPersonalSettingsToRender($legacyForms)) {
367
			$sections[98] = [new Section('additional', $this->l->t('Additional settings'), 0, $this->url->imagePath('core', 'actions/settings-dark.svg'))];
368
		}
369
370
		$appSections = $this->getSections('personal');
371
372 View Code Duplication
		foreach ($appSections as $section) {
373
			/** @var ISection $section */
374
			if (!isset($sections[$section->getPriority()])) {
375
				$sections[$section->getPriority()] = [];
376
			}
377
378
			$sections[$section->getPriority()][] = $section;
379
		}
380
381
		ksort($sections);
382
383
		return $sections;
384
	}
385
386
	/**
387
	 * @param string[] $forms
388
	 * @return bool
389
	 */
390
	private function hasLegacyPersonalSettingsToRender(array $forms): bool {
391
		foreach ($forms as $form) {
392
			if(trim($form) !== '') {
393
				return true;
394
			}
395
		}
396
		return false;
397
	}
398
399
	/**
400
	 * @inheritdoc
401
	 */
402 View Code Duplication
	public function getPersonalSettings($section): array {
403
		$settings = $this->getBuiltInPersonalSettings($section);
404
		$appSettings = $this->getSettings('personal', $section);
405
406
		foreach ($appSettings as $setting) {
407
			if (!isset($settings[$setting->getPriority()])) {
408
				$settings[$setting->getPriority()] = [];
409
			}
410
			$settings[$setting->getPriority()][] = $setting;
411
		}
412
413
		ksort($settings);
414
		return $settings;
415
	}
416
}
417