Completed
Push — master ( 5bc8c9...07e638 )
by Morris
52:34 queued 36:57
created

TemplateLayout::getVersionHashSuffix()   D

Complexity

Conditions 10
Paths 22

Size

Total Lines 34
Code Lines 20

Duplication

Lines 14
Ratio 41.18 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 10
eloc 20
nc 22
nop 2
dl 14
loc 34
rs 4.8196
c 2
b 0
f 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Bart Visscher <[email protected]>
6
 * @author Christopher Schäpers <[email protected]>
7
 * @author Clark Tomlinson <[email protected]>
8
 * @author Hendrik Leppelsack <[email protected]>
9
 * @author Joas Schilling <[email protected]>
10
 * @author John Molakvoæ (skjnldsv) <[email protected]>
11
 * @author Julius Haertl <[email protected]>
12
 * @author Julius Härtl <[email protected]>
13
 * @author Jörn Friedrich Dreyer <[email protected]>
14
 * @author Lukas Reschke <[email protected]>
15
 * @author Michael Gapczynski <[email protected]>
16
 * @author Morris Jobke <[email protected]>
17
 * @author Nils <[email protected]>
18
 * @author Remco Brenninkmeijer <[email protected]>
19
 * @author Robin Appelman <[email protected]>
20
 * @author Robin McCorkell <[email protected]>
21
 * @author Roeland Jago Douma <[email protected]>
22
 * @author Thomas Müller <[email protected]>
23
 *
24
 * @license AGPL-3.0
25
 *
26
 * This code is free software: you can redistribute it and/or modify
27
 * it under the terms of the GNU Affero General Public License, version 3,
28
 * as published by the Free Software Foundation.
29
 *
30
 * This program is distributed in the hope that it will be useful,
31
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33
 * GNU Affero General Public License for more details.
34
 *
35
 * You should have received a copy of the GNU Affero General Public License, version 3,
36
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
37
 *
38
 */
39
namespace OC;
40
41
use OC\Template\JSCombiner;
42
use OC\Template\JSConfigHelper;
43
use OC\Template\SCSSCacher;
44
use OCP\Defaults;
45
46
class TemplateLayout extends \OC_Template {
47
48
	private static $versionHash = '';
49
50
	/**
51
	 * @var \OCP\IConfig
52
	 */
53
	private $config;
54
55
	/**
56
	 * @param string $renderAs
57
	 * @param string $appId application id
58
	 */
59
	public function __construct( $renderAs, $appId = '' ) {
60
61
		// yes - should be injected ....
62
		$this->config = \OC::$server->getConfig();
63
64
65
		// Decide which page we show
66
		if($renderAs == 'user') {
67
			parent::__construct( 'core', 'layout.user' );
68
			if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
69
				$this->assign('bodyid', 'body-settings');
70
			}else{
71
				$this->assign('bodyid', 'body-user');
72
			}
73
74
			// Code integrity notification
75
			$integrityChecker = \OC::$server->getIntegrityCodeChecker();
76
			if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) {
77
				\OCP\Util::addScript('core', 'integritycheck-failed-notification');
78
			}
79
80
			// Add navigation entry
81
			$this->assign( 'application', '');
82
			$this->assign( 'appid', $appId );
83
			$navigation = \OC_App::getNavigation();
84
			$this->assign( 'navigation', $navigation);
85
			$settingsNavigation = \OC_App::getSettingsNavigation();
86
			$this->assign( 'settingsnavigation', $settingsNavigation);
87
			foreach($navigation as $entry) {
88
				if ($entry['active']) {
89
					$this->assign( 'application', $entry['name'] );
90
					break;
91
				}
92
			}
93
94
			foreach($settingsNavigation as $entry) {
95
				if ($entry['active']) {
96
					$this->assign( 'application', $entry['name'] );
97
					break;
98
				}
99
			}
100
			$userDisplayName = \OC_User::getDisplayName();
101
			$this->assign('user_displayname', $userDisplayName);
102
			$this->assign('user_uid', \OC_User::getUser());
103
104
			if (\OC_User::getUser() === false) {
105
				$this->assign('userAvatarSet', false);
106
			} else {
107
				$this->assign('userAvatarSet', \OC::$server->getAvatarManager()->getAvatar(\OC_User::getUser())->exists());
108
				$this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0));
109
			}
110
111
		} else if ($renderAs == 'error') {
112
			parent::__construct('core', 'layout.guest', '', false);
113
			$this->assign('bodyid', 'body-login');
114
		} else if ($renderAs == 'guest') {
115
			parent::__construct('core', 'layout.guest');
116
			$this->assign('bodyid', 'body-login');
117
		} else {
118
			parent::__construct('core', 'layout.base');
119
120
		}
121
		// Send the language to our layouts
122
		$this->assign('language', \OC::$server->getL10NFactory()->findLanguage());
123
124
		if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
125
			if (empty(self::$versionHash)) {
126
				$v = \OC_App::getAppVersions();
127
				$v['core'] = implode('.', \OCP\Util::getVersion());
128
				self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
129
			}
130
		} else {
131
			self::$versionHash = md5('not installed');
132
		}
133
134
		// Add the js files
135
		$jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
136
		$this->assign('jsfiles', array());
137
		if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') {
138
			if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
139
				$jsConfigHelper = new JSConfigHelper(
140
					\OC::$server->getL10N('core'),
141
					\OC::$server->query(Defaults::class),
142
					\OC::$server->getAppManager(),
143
					\OC::$server->getSession(),
144
					\OC::$server->getUserSession()->getUser(),
145
					$this->config,
146
					\OC::$server->getGroupManager(),
147
					\OC::$server->getIniWrapper(),
148
					\OC::$server->getURLGenerator()
149
				);
150
				$this->assign('inline_ocjs', $jsConfigHelper->getConfig());
151
			} else {
152
				$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
153
			}
154
		}
155
		foreach($jsFiles as $info) {
156
			$web = $info[1];
157
			$file = $info[2];
158
			$this->append( 'jsfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
159
		}
160
161
		try {
162
			$pathInfo = \OC::$server->getRequest()->getPathInfo();
163
		} catch (\Exception $e) {
164
			$pathInfo = '';
165
		}
166
167
		// Do not initialise scss appdata until we have a fully installed instance
168
		// Do not load scss for update, errors, installation or login page
169
		if(\OC::$server->getSystemConfig()->getValue('installed', false)
170
			&& !\OCP\Util::needUpgrade()
171
			&& $pathInfo !== ''
172
			&& !preg_match('/^\/login/', $pathInfo)) {
173
			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
174
		} else {
175
			// If we ignore the scss compiler,
176
			// we need to load the guest css fallback
177
			\OC_Util::addStyle('guest');
178
			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);
179
		}
180
181
		$this->assign('cssfiles', array());
182
		$this->assign('printcssfiles', []);
183
		$this->assign('versionHash', self::$versionHash);
184
		foreach($cssFiles as $info) {
185
			$web = $info[1];
186
			$file = $info[2];
187
188
			if (substr($file, -strlen('print.css')) === 'print.css') {
189
				$this->append( 'printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
190
			} else {
191
				$this->append( 'cssfiles', $web.'/'.$file . $this->getVersionHashSuffix($web, $file)  );
192
			}
193
		}
194
	}
195
196
	/**
197
	 * @param string $path
198
 	 * @param string $file
199
	 * @return string
200
	 */
201
	protected function getVersionHashSuffix($path = false, $file = false) {
202
		if ($this->config->getSystemValue('debug', false)) {
203
			// allows chrome workspace mapping in debug mode
204
			return "";
205
		}
206
		$themingSuffix = '';
207
		$v = [];
208
209
		if ($this->config->getSystemValue('installed', false)) {
210
			if (\OC::$server->getAppManager()->isInstalled('theming')) {
211
				$themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
212
			}
213
			$v = \OC_App::getAppVersions();
214
		}
215
216
		// Try the webroot path for a match
217 View Code Duplication
		if ($path !== false && $path !== '') {
218
			$appName = $this->getAppNamefromPath($path);
219
			if(array_key_exists($appName, $v)) {
220
				$appVersion = $v[$appName];
221
				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
222
			}
223
		}
224
		// fallback to the file path instead
225 View Code Duplication
		if ($file !== false && $file !== '') {
226
			$appName = $this->getAppNamefromPath($file);
227
			if(array_key_exists($appName, $v)) {
228
				$appVersion = $v[$appName];
229
				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
230
			}
231
		}
232
233
		return '?v=' . self::$versionHash . $themingSuffix;
234
	}
235
236
	/**
237
	 * @param array $styles
238
	 * @return array
239
	 */
240
	static public function findStylesheetFiles($styles, $compileScss = true) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
241
		// Read the selected theme from the config file
242
		$theme = \OC_Util::getTheme();
243
244
		if($compileScss) {
245
			$SCSSCacher = \OC::$server->query(SCSSCacher::class);
246
		} else {
247
			$SCSSCacher = null;
248
		}
249
250
		$locator = new \OC\Template\CSSResourceLocator(
251
			\OC::$server->getLogger(),
252
			$theme,
253
			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
254
			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
255
			$SCSSCacher
256
		);
257
		$locator->find($styles);
258
		return $locator->getResources();
259
	}
260
261
	/**
262
	 * @param string $path
263
	 * @return string|boolean
264
	 */
265
	public function getAppNamefromPath($path) {
266
		if ($path !== '' && is_string($path)) {
267
			$pathParts = explode('/', $path);
268
			if ($pathParts[0] === 'css') {
269
				// This is a scss request
270
				return $pathParts[1];
271
			}
272
			return end($pathParts);
273
		}
274
		return false;
275
276
	}
277
278
	/**
279
	 * @param array $scripts
280
	 * @return array
281
	 */
282
	static public function findJavascriptFiles($scripts) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
283
		// Read the selected theme from the config file
284
		$theme = \OC_Util::getTheme();
285
286
		$locator = new \OC\Template\JSResourceLocator(
287
			\OC::$server->getLogger(),
288
			$theme,
289
			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
290
			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
291
			new JSCombiner(
292
				\OC::$server->getAppDataDir('js'),
293
				\OC::$server->getURLGenerator(),
294
				\OC::$server->getMemCacheFactory()->create('JS'),
295
				\OC::$server->getSystemConfig(),
296
				\OC::$server->getLogger()
297
			)
298
			);
299
		$locator->find($scripts);
300
		return $locator->getResources();
301
	}
302
303
	/**
304
	 * Converts the absolute file path to a relative path from \OC::$SERVERROOT
305
	 * @param string $filePath Absolute path
306
	 * @return string Relative path
307
	 * @throws \Exception If $filePath is not under \OC::$SERVERROOT
308
	 */
309
	public static function convertToRelativePath($filePath) {
310
		$relativePath = explode(\OC::$SERVERROOT, $filePath);
311
		if(count($relativePath) !== 2) {
312
			throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
313
		}
314
315
		return $relativePath[1];
316
	}
317
}
318