Passed
Push — master ( f116c8...be892d )
by John
15:58 queued 12s
created

ThemingDefaults::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 9
dl 0
loc 31
rs 9.6
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 Bjoern Schiessle <[email protected]>
4
 * @copyright Copyright (c) 2017 Lukas Reschke <[email protected]>
5
 *
6
 * @author Arthur Schiwon <[email protected]>
7
 * @author Bjoern Schiessle <[email protected]>
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Daniel Kesselberg <[email protected]>
10
 * @author Guillaume COMPAGNON <[email protected]>
11
 * @author Jan-Christoph Borchardt <[email protected]>
12
 * @author Joachim Bauch <[email protected]>
13
 * @author Joas Schilling <[email protected]>
14
 * @author John Molakvoæ <[email protected]>
15
 * @author Julien Veyssier <[email protected]>
16
 * @author Julius Haertl <[email protected]>
17
 * @author Julius Härtl <[email protected]>
18
 * @author Lukas Reschke <[email protected]>
19
 * @author Michael Weimann <[email protected]>
20
 * @author Morris Jobke <[email protected]>
21
 * @author Patrik Kernstock <[email protected]>
22
 * @author Robin Appelman <[email protected]>
23
 * @author Roeland Jago Douma <[email protected]>
24
 *
25
 * @license GNU AGPL version 3 or any later version
26
 *
27
 * This program is free software: you can redistribute it and/or modify
28
 * it under the terms of the GNU Affero General Public License as
29
 * published by the Free Software Foundation, either version 3 of the
30
 * License, or (at your option) any later version.
31
 *
32
 * This program is distributed in the hope that it will be useful,
33
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35
 * GNU Affero General Public License for more details.
36
 *
37
 * You should have received a copy of the GNU Affero General Public License
38
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
39
 *
40
 */
41
namespace OCA\Theming;
42
43
use OCA\Theming\AppInfo\Application;
44
use OCA\Theming\Service\BackgroundService;
45
use OCP\App\AppPathNotFoundException;
46
use OCP\App\IAppManager;
47
use OCP\Files\NotFoundException;
48
use OCP\Files\SimpleFS\ISimpleFile;
49
use OCP\ICacheFactory;
50
use OCP\IConfig;
51
use OCP\IL10N;
52
use OCP\INavigationManager;
53
use OCP\IURLGenerator;
54
use OCP\IUserSession;
55
56
class ThemingDefaults extends \OC_Defaults {
57
58
	private IConfig $config;
59
	private IL10N $l;
60
	private ImageManager $imageManager;
61
	private IUserSession $userSession;
62
	private IURLGenerator $urlGenerator;
63
	private ICacheFactory $cacheFactory;
64
	private Util $util;
65
	private IAppManager $appManager;
66
	private INavigationManager $navigationManager;
67
68
	private string $name;
69
	private string $title;
70
	private string $entity;
71
	private string $productName;
72
	private string $url;
73
	private string $color;
74
75
	private string $iTunesAppId;
76
	private string $iOSClientUrl;
77
	private string $AndroidClientUrl;
78
	private string $FDroidClientUrl;
79
80
	/**
81
	 * ThemingDefaults constructor.
82
	 *
83
	 * @param IConfig $config
84
	 * @param IL10N $l
85
	 * @param ImageManager $imageManager
86
	 * @param IUserSession $userSession
87
	 * @param IURLGenerator $urlGenerator
88
	 * @param ICacheFactory $cacheFactory
89
	 * @param Util $util
90
	 * @param IAppManager $appManager
91
	 */
92
	public function __construct(IConfig $config,
93
								IL10N $l,
94
								IUserSession $userSession,
95
								IURLGenerator $urlGenerator,
96
								ICacheFactory $cacheFactory,
97
								Util $util,
98
								ImageManager $imageManager,
99
								IAppManager $appManager,
100
								INavigationManager $navigationManager
101
	) {
102
		parent::__construct();
103
		$this->config = $config;
104
		$this->l = $l;
105
		$this->imageManager = $imageManager;
106
		$this->userSession = $userSession;
107
		$this->urlGenerator = $urlGenerator;
108
		$this->cacheFactory = $cacheFactory;
109
		$this->util = $util;
110
		$this->appManager = $appManager;
111
		$this->navigationManager = $navigationManager;
112
113
		$this->name = parent::getName();
114
		$this->title = parent::getTitle();
115
		$this->entity = parent::getEntity();
116
		$this->productName = parent::getProductName();
117
		$this->url = parent::getBaseUrl();
118
		$this->color = parent::getColorPrimary();
119
		$this->iTunesAppId = parent::getiTunesAppId();
120
		$this->iOSClientUrl = parent::getiOSClientUrl();
121
		$this->AndroidClientUrl = parent::getAndroidClientUrl();
122
		$this->FDroidClientUrl = parent::getFDroidClientUrl();
123
	}
124
125
	public function getName() {
126
		return strip_tags($this->config->getAppValue('theming', 'name', $this->name));
127
	}
128
129
	public function getHTMLName() {
130
		return $this->config->getAppValue('theming', 'name', $this->name);
131
	}
132
133
	public function getTitle() {
134
		return strip_tags($this->config->getAppValue('theming', 'name', $this->title));
135
	}
136
137
	public function getEntity() {
138
		return strip_tags($this->config->getAppValue('theming', 'name', $this->entity));
139
	}
140
141
	public function getProductName() {
142
		return strip_tags($this->config->getAppValue('theming', 'productName', $this->productName));
143
	}
144
145
	public function getBaseUrl() {
146
		return $this->config->getAppValue('theming', 'url', $this->url);
147
	}
148
149
	/**
150
	 * We pass a string and sanitizeHTML will return a string too in that case
151
	 * @psalm-suppress InvalidReturnStatement
152
	 * @psalm-suppress InvalidReturnType
153
	 */
154
	public function getSlogan(?string $lang = null) {
155
		return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', parent::getSlogan($lang)));
156
	}
157
158
	public function getImprintUrl() {
159
		return (string)$this->config->getAppValue('theming', 'imprintUrl', '');
160
	}
161
162
	public function getPrivacyUrl() {
163
		return (string)$this->config->getAppValue('theming', 'privacyUrl', '');
164
	}
165
166
	public function getShortFooter() {
167
		$slogan = $this->getSlogan();
168
		$baseUrl = $this->getBaseUrl();
169
		if ($baseUrl !== '') {
170
			$footer = '<a href="' . $baseUrl . '" target="_blank"' .
171
				' rel="noreferrer noopener" class="entity-name">' . $this->getEntity() . '</a>';
172
		} else {
173
			$footer = '<span class="entity-name">' .$this->getEntity() . '</span>';
174
		}
175
		$footer .= ($slogan !== '' ? ' – ' . $slogan : '');
176
177
		$links = [
178
			[
179
				'text' => $this->l->t('Legal notice'),
180
				'url' => (string)$this->getImprintUrl()
181
			],
182
			[
183
				'text' => $this->l->t('Privacy policy'),
184
				'url' => (string)$this->getPrivacyUrl()
185
			],
186
		];
187
188
		$navigation = $this->navigationManager->getAll(INavigationManager::TYPE_GUEST);
189
		$guestNavigation = array_map(function ($nav) {
190
			return [
191
				'text' => $nav['name'],
192
				'url' => $nav['href']
193
			];
194
		}, $navigation);
195
		$links = array_merge($links, $guestNavigation);
196
197
		$legalLinks = '';
198
		$divider = '';
199
		foreach ($links as $link) {
200
			if ($link['url'] !== ''
201
				&& filter_var($link['url'], FILTER_VALIDATE_URL)
202
			) {
203
				$legalLinks .= $divider . '<a href="' . $link['url'] . '" class="legal" target="_blank"' .
204
					' rel="noreferrer noopener">' . $link['text'] . '</a>';
205
				$divider = ' · ';
206
			}
207
		}
208
		if ($legalLinks !== '') {
209
			$footer .= '<br/>' . $legalLinks;
210
		}
211
212
		return $footer;
213
	}
214
215
	/**
216
	 * Color that is used for the header as well as for mail headers
217
	 */
218
	public function getColorPrimary(): string {
219
		$user = $this->userSession->getUser();
220
221
		// admin-defined primary color
222
		$defaultColor = $this->getDefaultColorPrimary();
223
224
		if ($this->isUserThemingDisabled()) {
225
			return $defaultColor;
226
		}
227
		
228
		// user-defined primary color
229
		$themingBackground = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $themingBackground is dead and can be removed.
Loading history...
230
		if (!empty($user)) {
231
			$themingBackground = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background', '');
232
			// If the user selected the default background
233
			if ($themingBackground === '') {
234
				return BackgroundService::DEFAULT_COLOR;
235
			}
236
237
			// If the user selected a specific colour
238
			if (preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $themingBackground)) {
239
				return $themingBackground;
240
			}
241
242
			// if the user-selected background is a background reference
243
			if (isset(BackgroundService::SHIPPED_BACKGROUNDS[$themingBackground]['primary_color'])) {
244
				return BackgroundService::SHIPPED_BACKGROUNDS[$themingBackground]['primary_color'];
245
			}
246
		}
247
248
		// If the default color is not valid, return the default background one
249
		if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $defaultColor)) {
250
			return BackgroundService::DEFAULT_COLOR;
251
		}
252
253
		// Finally, return the system global primary color
254
		return $defaultColor;
255
	}
256
257
	/**
258
	 * Return the default color primary
259
	 */
260
	public function getDefaultColorPrimary(): string {
261
		$color = $this->config->getAppValue(Application::APP_ID, 'color');
262
		if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $color)) {
263
			$color = '#0082c9';
264
		}
265
		return $color;
266
	}
267
268
	/**
269
	 * Themed logo url
270
	 *
271
	 * @param bool $useSvg Whether to point to the SVG image or a fallback
272
	 * @return string
273
	 */
274
	public function getLogo($useSvg = true): string {
275
		$logo = $this->config->getAppValue('theming', 'logoMime', '');
276
277
		// short cut to avoid setting up the filesystem just to check if the logo is there
278
		//
279
		// explanation: if an SVG is requested and the app config value for logoMime is set then the logo is there.
280
		// otherwise we need to check it and maybe also generate a PNG from the SVG (that's done in getImage() which
281
		// needs to be called then)
282
		if ($useSvg === true && $logo !== false) {
283
			$logoExists = true;
284
		} else {
285
			try {
286
				$this->imageManager->getImage('logo', $useSvg);
287
				$logoExists = true;
288
			} catch (\Exception $e) {
289
				$logoExists = false;
290
			}
291
		}
292
293
		$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
294
295
		if (!$logo || !$logoExists) {
296
			if ($useSvg) {
297
				$logo = $this->urlGenerator->imagePath('core', 'logo/logo.svg');
298
			} else {
299
				$logo = $this->urlGenerator->imagePath('core', 'logo/logo.png');
300
			}
301
			return $logo . '?v=' . $cacheBusterCounter;
302
		}
303
304
		return $this->urlGenerator->linkToRoute('theming.Theming.getImage', [ 'key' => 'logo', 'useSvg' => $useSvg, 'v' => $cacheBusterCounter ]);
305
	}
306
307
	/**
308
	 * Themed background image url
309
	 *
310
	 * @return string
311
	 */
312
	public function getBackground(): string {
313
		return $this->imageManager->getImageUrl('background');
314
	}
315
316
	/**
317
	 * @return string
318
	 */
319
	public function getiTunesAppId() {
320
		return $this->config->getAppValue('theming', 'iTunesAppId', $this->iTunesAppId);
321
	}
322
323
	/**
324
	 * @return string
325
	 */
326
	public function getiOSClientUrl() {
327
		return $this->config->getAppValue('theming', 'iOSClientUrl', $this->iOSClientUrl);
328
	}
329
330
	/**
331
	 * @return string
332
	 */
333
	public function getAndroidClientUrl() {
334
		return $this->config->getAppValue('theming', 'AndroidClientUrl', $this->AndroidClientUrl);
335
	}
336
337
	/**
338
	 * @return string
339
	 */
340
	public function getFDroidClientUrl() {
341
		return $this->config->getAppValue('theming', 'FDroidClientUrl', $this->FDroidClientUrl);
342
	}
343
344
	/**
345
	 * @return array scss variables to overwrite
346
	 */
347
	public function getScssVariables() {
348
		$cacheBuster = $this->config->getAppValue('theming', 'cachebuster', '0');
349
		$cache = $this->cacheFactory->createDistributed('theming-' . $cacheBuster . '-' . $this->urlGenerator->getBaseUrl());
350
		if ($value = $cache->get('getScssVariables')) {
351
			return $value;
352
		}
353
354
		$variables = [
355
			'theming-cachebuster' => "'" . $cacheBuster . "'",
356
			'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime') . "'",
357
			'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime') . "'",
358
			'theming-logoheader-mime' => "'" . $this->config->getAppValue('theming', 'logoheaderMime') . "'",
359
			'theming-favicon-mime' => "'" . $this->config->getAppValue('theming', 'faviconMime') . "'"
360
		];
361
362
		$variables['image-logo'] = "url('".$this->imageManager->getImageUrl('logo')."')";
363
		$variables['image-logoheader'] = "url('".$this->imageManager->getImageUrl('logoheader')."')";
364
		$variables['image-favicon'] = "url('".$this->imageManager->getImageUrl('favicon')."')";
365
		$variables['image-login-background'] = "url('".$this->imageManager->getImageUrl('background')."')";
366
		$variables['image-login-plain'] = 'false';
367
368
		if ($this->config->getAppValue('theming', 'color', '') !== '') {
369
			$variables['color-primary'] = $this->getColorPrimary();
370
			$variables['color-primary-text'] = $this->getTextColorPrimary();
371
			$variables['color-primary-element'] = $this->util->elementColor($this->getColorPrimary());
372
		}
373
374
		if ($this->config->getAppValue('theming', 'backgroundMime', '') === 'backgroundColor') {
375
			$variables['image-login-plain'] = 'true';
376
		}
377
378
		$variables['has-legal-links'] = 'false';
379
		if ($this->getImprintUrl() !== '' || $this->getPrivacyUrl() !== '') {
380
			$variables['has-legal-links'] = 'true';
381
		}
382
383
		$cache->set('getScssVariables', $variables);
384
		return $variables;
385
	}
386
387
	/**
388
	 * Check if the image should be replaced by the theming app
389
	 * and return the new image location then
390
	 *
391
	 * @param string $app name of the app
392
	 * @param string $image filename of the image
393
	 * @return bool|string false if image should not replaced, otherwise the location of the image
394
	 */
395
	public function replaceImagePath($app, $image) {
396
		if ($app === '' || $app === 'files_sharing') {
397
			$app = 'core';
398
		}
399
		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
400
401
		$route = false;
402
		if ($image === 'favicon.ico' && ($this->imageManager->shouldReplaceIcons() || $this->getCustomFavicon() !== null)) {
403
			$route = $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]);
404
		}
405
		if (($image === 'favicon-touch.png' || $image === 'favicon-fb.png') && ($this->imageManager->shouldReplaceIcons() || $this->getCustomFavicon() !== null)) {
406
			$route = $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]);
407
		}
408
		if ($image === 'manifest.json') {
409
			try {
410
				$appPath = $this->appManager->getAppPath($app);
411
				if (file_exists($appPath . '/img/manifest.json')) {
412
					return false;
413
				}
414
			} catch (AppPathNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
415
			}
416
			$route = $this->urlGenerator->linkToRoute('theming.Theming.getManifest', ['app' => $app ]);
417
		}
418
		if (strpos($image, 'filetypes/') === 0 && file_exists(\OC::$SERVERROOT . '/core/img/' . $image)) {
419
			$route = $this->urlGenerator->linkToRoute('theming.Icon.getThemedIcon', ['app' => $app, 'image' => $image]);
420
		}
421
422
		if ($route) {
423
			return $route . '?v=' . $cacheBusterValue;
424
		}
425
426
		return false;
427
	}
428
429
	protected function getCustomFavicon(): ?ISimpleFile {
430
		try {
431
			return $this->imageManager->getImage('favicon');
432
		} catch (NotFoundException $e) {
433
			return null;
434
		}
435
	}
436
437
	/**
438
	 * Increases the cache buster key
439
	 */
440
	public function increaseCacheBuster(): void {
441
		$cacheBusterKey = (int)$this->config->getAppValue('theming', 'cachebuster', '0');
442
		$this->config->setAppValue('theming', 'cachebuster', (string)($cacheBusterKey + 1));
443
		$this->cacheFactory->createDistributed('theming-')->clear();
444
		$this->cacheFactory->createDistributed('imagePath')->clear();
445
	}
446
447
	/**
448
	 * Update setting in the database
449
	 *
450
	 * @param string $setting
451
	 * @param string $value
452
	 */
453
	public function set($setting, $value) {
454
		$this->config->setAppValue('theming', $setting, $value);
455
		$this->increaseCacheBuster();
456
	}
457
458
	/**
459
	 * Revert settings to the default value
460
	 *
461
	 * @param string $setting setting which should be reverted
462
	 * @return string default value
463
	 */
464
	public function undo($setting) {
465
		$this->config->deleteAppValue('theming', $setting);
466
		$this->increaseCacheBuster();
467
468
		$returnValue = '';
469
		switch ($setting) {
470
			case 'name':
471
				$returnValue = $this->getEntity();
472
				break;
473
			case 'url':
474
				$returnValue = $this->getBaseUrl();
475
				break;
476
			case 'slogan':
477
				$returnValue = $this->getSlogan();
478
				break;
479
			case 'color':
480
				$returnValue = $this->getColorPrimary();
481
				break;
482
			case 'logo':
483
			case 'logoheader':
484
			case 'background':
485
			case 'favicon':
486
				$this->imageManager->delete($setting);
487
				break;
488
		}
489
490
		return $returnValue;
491
	}
492
493
	/**
494
	 * Color of text in the header and primary buttons
495
	 *
496
	 * @return string
497
	 */
498
	public function getTextColorPrimary() {
499
		return $this->util->invertTextColor($this->getColorPrimary()) ? '#000000' : '#ffffff';
500
	}
501
502
	/**
503
	 * Has the admin disabled user customization
504
	 */
505
	public function isUserThemingDisabled(): bool {
506
		return $this->config->getAppValue('theming', 'disable-user-theming', 'no') === 'yes';
507
	}
508
}
509