@@ -58,344 +58,344 @@  | 
                                                    ||
| 58 | 58 | use Psr\Log\LoggerInterface;  | 
                                                        
| 59 | 59 | |
| 60 | 60 |  class TemplateLayout extends \OC_Template { | 
                                                        
| 61 | - private static $versionHash = '';  | 
                                                        |
| 62 | -  | 
                                                        |
| 63 | - /** @var IConfig */  | 
                                                        |
| 64 | - private $config;  | 
                                                        |
| 65 | -  | 
                                                        |
| 66 | - /** @var IInitialStateService */  | 
                                                        |
| 67 | - private $initialState;  | 
                                                        |
| 68 | -  | 
                                                        |
| 69 | - /** @var INavigationManager */  | 
                                                        |
| 70 | - private $navigationManager;  | 
                                                        |
| 71 | -  | 
                                                        |
| 72 | - /**  | 
                                                        |
| 73 | - * @param string $renderAs  | 
                                                        |
| 74 | - * @param string $appId application id  | 
                                                        |
| 75 | - */  | 
                                                        |
| 76 | -	public function __construct($renderAs, $appId = '') { | 
                                                        |
| 77 | -  | 
                                                        |
| 78 | - /** @var IConfig */  | 
                                                        |
| 79 | - $this->config = \OC::$server->get(IConfig::class);  | 
                                                        |
| 80 | -  | 
                                                        |
| 81 | - /** @var IInitialStateService */  | 
                                                        |
| 82 | - $this->initialState = \OC::$server->get(IInitialStateService::class);  | 
                                                        |
| 83 | -  | 
                                                        |
| 84 | - // Add fallback theming variables if theming is disabled  | 
                                                        |
| 85 | - if ($renderAs !== TemplateResponse::RENDER_AS_USER  | 
                                                        |
| 86 | -			|| !\OC::$server->getAppManager()->isEnabledForUser('theming')) { | 
                                                        |
| 87 | - // TODO cache generated default theme if enabled for fallback if server is erroring ?  | 
                                                        |
| 88 | -			Util::addStyle('theming', 'default'); | 
                                                        |
| 89 | - }  | 
                                                        |
| 90 | -  | 
                                                        |
| 91 | - // Decide which page we show  | 
                                                        |
| 92 | -		if ($renderAs === TemplateResponse::RENDER_AS_USER) { | 
                                                        |
| 93 | - /** @var INavigationManager */  | 
                                                        |
| 94 | - $this->navigationManager = \OC::$server->get(INavigationManager::class);  | 
                                                        |
| 95 | -  | 
                                                        |
| 96 | -			parent::__construct('core', 'layout.user'); | 
                                                        |
| 97 | -			if (in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { | 
                                                        |
| 98 | -				$this->assign('bodyid', 'body-settings'); | 
                                                        |
| 99 | -			} else { | 
                                                        |
| 100 | -				$this->assign('bodyid', 'body-user'); | 
                                                        |
| 101 | - }  | 
                                                        |
| 102 | -  | 
                                                        |
| 103 | -			$this->initialState->provideInitialState('core', 'active-app', $this->navigationManager->getActiveEntry()); | 
                                                        |
| 104 | -			$this->initialState->provideInitialState('unified-search', 'limit-default', (int)$this->config->getAppValue('core', 'unified-search.limit-default', (string)SearchQuery::LIMIT_DEFAULT)); | 
                                                        |
| 105 | -			$this->initialState->provideInitialState('unified-search', 'min-search-length', (int)$this->config->getAppValue('core', 'unified-search.min-search-length', (string)2)); | 
                                                        |
| 106 | -			$this->initialState->provideInitialState('unified-search', 'live-search', $this->config->getAppValue('core', 'unified-search.live-search', 'yes') === 'yes'); | 
                                                        |
| 107 | -			Util::addScript('core', 'unified-search', 'core'); | 
                                                        |
| 108 | -  | 
                                                        |
| 109 | - // Set body data-theme  | 
                                                        |
| 110 | -			$this->assign('enabledThemes', []); | 
                                                        |
| 111 | -			if (\OC::$server->getAppManager()->isEnabledForUser('theming') && class_exists('\OCA\Theming\Service\ThemesService')) { | 
                                                        |
| 112 | - /** @var \OCA\Theming\Service\ThemesService */  | 
                                                        |
| 113 | - $themesService = \OC::$server->get(\OCA\Theming\Service\ThemesService::class);  | 
                                                        |
| 114 | -				$this->assign('enabledThemes', $themesService->getEnabledThemes()); | 
                                                        |
| 115 | - }  | 
                                                        |
| 116 | -  | 
                                                        |
| 117 | - // set logo link target  | 
                                                        |
| 118 | -			$logoUrl = $this->config->getSystemValueString('logo_url', ''); | 
                                                        |
| 119 | -			$this->assign('logoUrl', $logoUrl); | 
                                                        |
| 120 | -  | 
                                                        |
| 121 | - // Add navigation entry  | 
                                                        |
| 122 | -			$this->assign('application', ''); | 
                                                        |
| 123 | -			$this->assign('appid', $appId); | 
                                                        |
| 124 | -  | 
                                                        |
| 125 | - $navigation = $this->navigationManager->getAll();  | 
                                                        |
| 126 | -			$this->assign('navigation', $navigation); | 
                                                        |
| 127 | -			$settingsNavigation = $this->navigationManager->getAll('settings'); | 
                                                        |
| 128 | -			$this->assign('settingsnavigation', $settingsNavigation); | 
                                                        |
| 129 | -  | 
                                                        |
| 130 | -			foreach ($navigation as $entry) { | 
                                                        |
| 131 | -				if ($entry['active']) { | 
                                                        |
| 132 | -					$this->assign('application', $entry['name']); | 
                                                        |
| 133 | - break;  | 
                                                        |
| 134 | - }  | 
                                                        |
| 135 | - }  | 
                                                        |
| 136 | -  | 
                                                        |
| 137 | -			foreach ($settingsNavigation as $entry) { | 
                                                        |
| 138 | -				if ($entry['active']) { | 
                                                        |
| 139 | -					$this->assign('application', $entry['name']); | 
                                                        |
| 140 | - break;  | 
                                                        |
| 141 | - }  | 
                                                        |
| 142 | - }  | 
                                                        |
| 143 | -  | 
                                                        |
| 144 | - $userDisplayName = false;  | 
                                                        |
| 145 | - $user = \OC::$server->get(IUserSession::class)->getUser();  | 
                                                        |
| 146 | -			if ($user) { | 
                                                        |
| 147 | - $userDisplayName = $user->getDisplayName();  | 
                                                        |
| 148 | - }  | 
                                                        |
| 149 | -			$this->assign('user_displayname', $userDisplayName); | 
                                                        |
| 150 | -			$this->assign('user_uid', \OC_User::getUser()); | 
                                                        |
| 151 | -  | 
                                                        |
| 152 | -			if ($user === null) { | 
                                                        |
| 153 | -				$this->assign('userAvatarSet', false); | 
                                                        |
| 154 | -				$this->assign('userStatus', false); | 
                                                        |
| 155 | -			} else { | 
                                                        |
| 156 | -				$this->assign('userAvatarSet', true); | 
                                                        |
| 157 | -				$this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0)); | 
                                                        |
| 158 | - }  | 
                                                        |
| 159 | -		} elseif ($renderAs === TemplateResponse::RENDER_AS_ERROR) { | 
                                                        |
| 160 | -			parent::__construct('core', 'layout.guest', '', false); | 
                                                        |
| 161 | -			$this->assign('bodyid', 'body-login'); | 
                                                        |
| 162 | -			$this->assign('user_displayname', ''); | 
                                                        |
| 163 | -			$this->assign('user_uid', ''); | 
                                                        |
| 164 | -		} elseif ($renderAs === TemplateResponse::RENDER_AS_GUEST) { | 
                                                        |
| 165 | -			parent::__construct('core', 'layout.guest'); | 
                                                        |
| 166 | -			\OC_Util::addStyle('guest'); | 
                                                        |
| 167 | -			$this->assign('bodyid', 'body-login'); | 
                                                        |
| 168 | -  | 
                                                        |
| 169 | - $userDisplayName = false;  | 
                                                        |
| 170 | - $user = \OC::$server->get(IUserSession::class)->getUser();  | 
                                                        |
| 171 | -			if ($user) { | 
                                                        |
| 172 | - $userDisplayName = $user->getDisplayName();  | 
                                                        |
| 173 | - }  | 
                                                        |
| 174 | -			$this->assign('user_displayname', $userDisplayName); | 
                                                        |
| 175 | -			$this->assign('user_uid', \OC_User::getUser()); | 
                                                        |
| 176 | -		} elseif ($renderAs === TemplateResponse::RENDER_AS_PUBLIC) { | 
                                                        |
| 177 | -			parent::__construct('core', 'layout.public'); | 
                                                        |
| 178 | -			$this->assign('appid', $appId); | 
                                                        |
| 179 | -			$this->assign('bodyid', 'body-public'); | 
                                                        |
| 180 | -  | 
                                                        |
| 181 | - /** @var IRegistry $subscription */  | 
                                                        |
| 182 | - $subscription = \OC::$server->query(IRegistry::class);  | 
                                                        |
| 183 | -			$showSimpleSignup = $this->config->getSystemValueBool('simpleSignUpLink.shown', true); | 
                                                        |
| 184 | -			if ($showSimpleSignup && $subscription->delegateHasValidSubscription()) { | 
                                                        |
| 185 | - $showSimpleSignup = false;  | 
                                                        |
| 186 | - }  | 
                                                        |
| 187 | -			$this->assign('showSimpleSignUpLink', $showSimpleSignup); | 
                                                        |
| 188 | -		} else { | 
                                                        |
| 189 | -			parent::__construct('core', 'layout.base'); | 
                                                        |
| 190 | - }  | 
                                                        |
| 191 | - // Send the language and the locale to our layouts  | 
                                                        |
| 192 | - $lang = \OC::$server->getL10NFactory()->findLanguage();  | 
                                                        |
| 193 | - $locale = \OC::$server->getL10NFactory()->findLocale($lang);  | 
                                                        |
| 194 | -  | 
                                                        |
| 195 | -		$lang = str_replace('_', '-', $lang); | 
                                                        |
| 196 | -		$this->assign('language', $lang); | 
                                                        |
| 197 | -		$this->assign('locale', $locale); | 
                                                        |
| 198 | -  | 
                                                        |
| 199 | -		if (\OC::$server->getSystemConfig()->getValue('installed', false)) { | 
                                                        |
| 200 | -			if (empty(self::$versionHash)) { | 
                                                        |
| 201 | - $v = \OC_App::getAppVersions();  | 
                                                        |
| 202 | -				$v['core'] = implode('.', \OCP\Util::getVersion()); | 
                                                        |
| 203 | -				self::$versionHash = substr(md5(implode(',', $v)), 0, 8); | 
                                                        |
| 204 | - }  | 
                                                        |
| 205 | -		} else { | 
                                                        |
| 206 | -			self::$versionHash = md5('not installed'); | 
                                                        |
| 207 | - }  | 
                                                        |
| 208 | -  | 
                                                        |
| 209 | - // Add the js files  | 
                                                        |
| 210 | - // TODO: remove deprecated OC_Util injection  | 
                                                        |
| 211 | - $jsFiles = self::findJavascriptFiles(array_merge(\OC_Util::$scripts, Util::getScripts()));  | 
                                                        |
| 212 | -		$this->assign('jsfiles', []); | 
                                                        |
| 213 | -		if ($this->config->getSystemValue('installed', false) && $renderAs != TemplateResponse::RENDER_AS_ERROR) { | 
                                                        |
| 214 | - // this is on purpose outside of the if statement below so that the initial state is prefilled (done in the getConfig() call)  | 
                                                        |
| 215 | - // see https://github.com/nextcloud/server/pull/22636 for details  | 
                                                        |
| 216 | - $jsConfigHelper = new JSConfigHelper(  | 
                                                        |
| 217 | -				\OC::$server->getL10N('lib'), | 
                                                        |
| 218 | - \OC::$server->query(Defaults::class),  | 
                                                        |
| 219 | - \OC::$server->getAppManager(),  | 
                                                        |
| 220 | - \OC::$server->getSession(),  | 
                                                        |
| 221 | - \OC::$server->getUserSession()->getUser(),  | 
                                                        |
| 222 | - $this->config,  | 
                                                        |
| 223 | - \OC::$server->getGroupManager(),  | 
                                                        |
| 224 | - \OC::$server->get(IniGetWrapper::class),  | 
                                                        |
| 225 | - \OC::$server->getURLGenerator(),  | 
                                                        |
| 226 | - \OC::$server->getCapabilitiesManager(),  | 
                                                        |
| 227 | - \OC::$server->query(IInitialStateService::class)  | 
                                                        |
| 228 | - );  | 
                                                        |
| 229 | - $config = $jsConfigHelper->getConfig();  | 
                                                        |
| 230 | -			if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) { | 
                                                        |
| 231 | -				$this->assign('inline_ocjs', $config); | 
                                                        |
| 232 | -			} else { | 
                                                        |
| 233 | -				$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash])); | 
                                                        |
| 234 | - }  | 
                                                        |
| 235 | - }  | 
                                                        |
| 236 | -		foreach ($jsFiles as $info) { | 
                                                        |
| 237 | - $web = $info[1];  | 
                                                        |
| 238 | - $file = $info[2];  | 
                                                        |
| 239 | -			$this->append('jsfiles', $web.'/'.$file . $this->getVersionHashSuffix()); | 
                                                        |
| 240 | - }  | 
                                                        |
| 241 | -  | 
                                                        |
| 242 | -		try { | 
                                                        |
| 243 | - $pathInfo = \OC::$server->getRequest()->getPathInfo();  | 
                                                        |
| 244 | -		} catch (\Exception $e) { | 
                                                        |
| 245 | - $pathInfo = '';  | 
                                                        |
| 246 | - }  | 
                                                        |
| 247 | -  | 
                                                        |
| 248 | - // Do not initialise scss appdata until we have a fully installed instance  | 
                                                        |
| 249 | - // Do not load scss for update, errors, installation or login page  | 
                                                        |
| 250 | -		if (\OC::$server->getSystemConfig()->getValue('installed', false) | 
                                                        |
| 251 | - && !\OCP\Util::needUpgrade()  | 
                                                        |
| 252 | - && $pathInfo !== ''  | 
                                                        |
| 253 | -			&& !preg_match('/^\/login/', $pathInfo) | 
                                                        |
| 254 | - && $renderAs !== TemplateResponse::RENDER_AS_ERROR  | 
                                                        |
| 255 | -		) { | 
                                                        |
| 256 | - $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);  | 
                                                        |
| 257 | -		} else { | 
                                                        |
| 258 | - // If we ignore the scss compiler,  | 
                                                        |
| 259 | - // we need to load the guest css fallback  | 
                                                        |
| 260 | -			\OC_Util::addStyle('guest'); | 
                                                        |
| 261 | - $cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);  | 
                                                        |
| 262 | - }  | 
                                                        |
| 263 | -  | 
                                                        |
| 264 | -		$this->assign('cssfiles', []); | 
                                                        |
| 265 | -		$this->assign('printcssfiles', []); | 
                                                        |
| 266 | -		$this->assign('versionHash', self::$versionHash); | 
                                                        |
| 267 | -		foreach ($cssFiles as $info) { | 
                                                        |
| 268 | - $web = $info[1];  | 
                                                        |
| 269 | - $file = $info[2];  | 
                                                        |
| 270 | -  | 
                                                        |
| 271 | -			if (substr($file, -strlen('print.css')) === 'print.css') { | 
                                                        |
| 272 | -				$this->append('printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix()); | 
                                                        |
| 273 | -			} else { | 
                                                        |
| 274 | - $suffix = $this->getVersionHashSuffix($web, $file);  | 
                                                        |
| 275 | -  | 
                                                        |
| 276 | -				if (strpos($file, '?v=') == false) { | 
                                                        |
| 277 | -					$this->append('cssfiles', $web.'/'.$file . $suffix); | 
                                                        |
| 278 | -				} else { | 
                                                        |
| 279 | -					$this->append('cssfiles', $web.'/'.$file . '-' . substr($suffix, 3)); | 
                                                        |
| 280 | - }  | 
                                                        |
| 281 | - }  | 
                                                        |
| 282 | - }  | 
                                                        |
| 283 | -  | 
                                                        |
| 284 | -		$this->assign('initialStates', $this->initialState->getInitialStates()); | 
                                                        |
| 285 | - }  | 
                                                        |
| 286 | -  | 
                                                        |
| 287 | - /**  | 
                                                        |
| 288 | - * @param string $path  | 
                                                        |
| 289 | - * @param string $file  | 
                                                        |
| 290 | - * @return string  | 
                                                        |
| 291 | - */  | 
                                                        |
| 292 | -	protected function getVersionHashSuffix($path = false, $file = false) { | 
                                                        |
| 293 | -		if ($this->config->getSystemValue('debug', false)) { | 
                                                        |
| 294 | - // allows chrome workspace mapping in debug mode  | 
                                                        |
| 295 | - return "";  | 
                                                        |
| 296 | - }  | 
                                                        |
| 297 | - $themingSuffix = '';  | 
                                                        |
| 298 | - $v = [];  | 
                                                        |
| 299 | -  | 
                                                        |
| 300 | -		if ($this->config->getSystemValue('installed', false)) { | 
                                                        |
| 301 | -			if (\OC::$server->getAppManager()->isInstalled('theming')) { | 
                                                        |
| 302 | -				$themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0'); | 
                                                        |
| 303 | - }  | 
                                                        |
| 304 | - $v = \OC_App::getAppVersions();  | 
                                                        |
| 305 | - }  | 
                                                        |
| 306 | -  | 
                                                        |
| 307 | - // Try the webroot path for a match  | 
                                                        |
| 308 | -		if ($path !== false && $path !== '') { | 
                                                        |
| 309 | - $appName = $this->getAppNamefromPath($path);  | 
                                                        |
| 310 | -			if (array_key_exists($appName, $v)) { | 
                                                        |
| 311 | - $appVersion = $v[$appName];  | 
                                                        |
| 312 | - return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;  | 
                                                        |
| 313 | - }  | 
                                                        |
| 314 | - }  | 
                                                        |
| 315 | - // fallback to the file path instead  | 
                                                        |
| 316 | -		if ($file !== false && $file !== '') { | 
                                                        |
| 317 | - $appName = $this->getAppNamefromPath($file);  | 
                                                        |
| 318 | -			if (array_key_exists($appName, $v)) { | 
                                                        |
| 319 | - $appVersion = $v[$appName];  | 
                                                        |
| 320 | - return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;  | 
                                                        |
| 321 | - }  | 
                                                        |
| 322 | - }  | 
                                                        |
| 323 | -  | 
                                                        |
| 324 | - return '?v=' . self::$versionHash . $themingSuffix;  | 
                                                        |
| 325 | - }  | 
                                                        |
| 326 | -  | 
                                                        |
| 327 | - /**  | 
                                                        |
| 328 | - * @param array $styles  | 
                                                        |
| 329 | - * @return array  | 
                                                        |
| 330 | - */  | 
                                                        |
| 331 | -	public static function findStylesheetFiles($styles, $compileScss = true) { | 
                                                        |
| 332 | - // Read the selected theme from the config file  | 
                                                        |
| 333 | - $theme = \OC_Util::getTheme();  | 
                                                        |
| 334 | -  | 
                                                        |
| 335 | -		if ($compileScss) { | 
                                                        |
| 336 | - $SCSSCacher = \OC::$server->query(SCSSCacher::class);  | 
                                                        |
| 337 | -		} else { | 
                                                        |
| 338 | - $SCSSCacher = null;  | 
                                                        |
| 339 | - }  | 
                                                        |
| 340 | -  | 
                                                        |
| 341 | - $locator = new \OC\Template\CSSResourceLocator(  | 
                                                        |
| 342 | - \OC::$server->get(LoggerInterface::class),  | 
                                                        |
| 343 | - $theme,  | 
                                                        |
| 344 | - [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 345 | - [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 346 | - $SCSSCacher  | 
                                                        |
| 347 | - );  | 
                                                        |
| 348 | - $locator->find($styles);  | 
                                                        |
| 349 | - return $locator->getResources();  | 
                                                        |
| 350 | - }  | 
                                                        |
| 351 | -  | 
                                                        |
| 352 | - /**  | 
                                                        |
| 353 | - * @param string $path  | 
                                                        |
| 354 | - * @return string|boolean  | 
                                                        |
| 355 | - */  | 
                                                        |
| 356 | -	public function getAppNamefromPath($path) { | 
                                                        |
| 357 | -		if ($path !== '' && is_string($path)) { | 
                                                        |
| 358 | -			$pathParts = explode('/', $path); | 
                                                        |
| 359 | -			if ($pathParts[0] === 'css') { | 
                                                        |
| 360 | - // This is a scss request  | 
                                                        |
| 361 | - return $pathParts[1];  | 
                                                        |
| 362 | - }  | 
                                                        |
| 363 | - return end($pathParts);  | 
                                                        |
| 364 | - }  | 
                                                        |
| 365 | - return false;  | 
                                                        |
| 366 | - }  | 
                                                        |
| 367 | -  | 
                                                        |
| 368 | - /**  | 
                                                        |
| 369 | - * @param array $scripts  | 
                                                        |
| 370 | - * @return array  | 
                                                        |
| 371 | - */  | 
                                                        |
| 372 | -	public static function findJavascriptFiles($scripts) { | 
                                                        |
| 373 | - // Read the selected theme from the config file  | 
                                                        |
| 374 | - $theme = \OC_Util::getTheme();  | 
                                                        |
| 375 | -  | 
                                                        |
| 376 | - $locator = new \OC\Template\JSResourceLocator(  | 
                                                        |
| 377 | - \OC::$server->get(LoggerInterface::class),  | 
                                                        |
| 378 | - $theme,  | 
                                                        |
| 379 | - [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 380 | - [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 381 | - \OC::$server->query(JSCombiner::class)  | 
                                                        |
| 382 | - );  | 
                                                        |
| 383 | - $locator->find($scripts);  | 
                                                        |
| 384 | - return $locator->getResources();  | 
                                                        |
| 385 | - }  | 
                                                        |
| 386 | -  | 
                                                        |
| 387 | - /**  | 
                                                        |
| 388 | - * Converts the absolute file path to a relative path from \OC::$SERVERROOT  | 
                                                        |
| 389 | - * @param string $filePath Absolute path  | 
                                                        |
| 390 | - * @return string Relative path  | 
                                                        |
| 391 | - * @throws \Exception If $filePath is not under \OC::$SERVERROOT  | 
                                                        |
| 392 | - */  | 
                                                        |
| 393 | -	public static function convertToRelativePath($filePath) { | 
                                                        |
| 394 | - $relativePath = explode(\OC::$SERVERROOT, $filePath);  | 
                                                        |
| 395 | -		if (count($relativePath) !== 2) { | 
                                                        |
| 396 | -			throw new \Exception('$filePath is not under the \OC::$SERVERROOT'); | 
                                                        |
| 397 | - }  | 
                                                        |
| 398 | -  | 
                                                        |
| 399 | - return $relativePath[1];  | 
                                                        |
| 400 | - }  | 
                                                        |
| 61 | + private static $versionHash = '';  | 
                                                        |
| 62 | +  | 
                                                        |
| 63 | + /** @var IConfig */  | 
                                                        |
| 64 | + private $config;  | 
                                                        |
| 65 | +  | 
                                                        |
| 66 | + /** @var IInitialStateService */  | 
                                                        |
| 67 | + private $initialState;  | 
                                                        |
| 68 | +  | 
                                                        |
| 69 | + /** @var INavigationManager */  | 
                                                        |
| 70 | + private $navigationManager;  | 
                                                        |
| 71 | +  | 
                                                        |
| 72 | + /**  | 
                                                        |
| 73 | + * @param string $renderAs  | 
                                                        |
| 74 | + * @param string $appId application id  | 
                                                        |
| 75 | + */  | 
                                                        |
| 76 | +    public function __construct($renderAs, $appId = '') { | 
                                                        |
| 77 | +  | 
                                                        |
| 78 | + /** @var IConfig */  | 
                                                        |
| 79 | + $this->config = \OC::$server->get(IConfig::class);  | 
                                                        |
| 80 | +  | 
                                                        |
| 81 | + /** @var IInitialStateService */  | 
                                                        |
| 82 | + $this->initialState = \OC::$server->get(IInitialStateService::class);  | 
                                                        |
| 83 | +  | 
                                                        |
| 84 | + // Add fallback theming variables if theming is disabled  | 
                                                        |
| 85 | + if ($renderAs !== TemplateResponse::RENDER_AS_USER  | 
                                                        |
| 86 | +            || !\OC::$server->getAppManager()->isEnabledForUser('theming')) { | 
                                                        |
| 87 | + // TODO cache generated default theme if enabled for fallback if server is erroring ?  | 
                                                        |
| 88 | +            Util::addStyle('theming', 'default'); | 
                                                        |
| 89 | + }  | 
                                                        |
| 90 | +  | 
                                                        |
| 91 | + // Decide which page we show  | 
                                                        |
| 92 | +        if ($renderAs === TemplateResponse::RENDER_AS_USER) { | 
                                                        |
| 93 | + /** @var INavigationManager */  | 
                                                        |
| 94 | + $this->navigationManager = \OC::$server->get(INavigationManager::class);  | 
                                                        |
| 95 | +  | 
                                                        |
| 96 | +            parent::__construct('core', 'layout.user'); | 
                                                        |
| 97 | +            if (in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) { | 
                                                        |
| 98 | +                $this->assign('bodyid', 'body-settings'); | 
                                                        |
| 99 | +            } else { | 
                                                        |
| 100 | +                $this->assign('bodyid', 'body-user'); | 
                                                        |
| 101 | + }  | 
                                                        |
| 102 | +  | 
                                                        |
| 103 | +            $this->initialState->provideInitialState('core', 'active-app', $this->navigationManager->getActiveEntry()); | 
                                                        |
| 104 | +            $this->initialState->provideInitialState('unified-search', 'limit-default', (int)$this->config->getAppValue('core', 'unified-search.limit-default', (string)SearchQuery::LIMIT_DEFAULT)); | 
                                                        |
| 105 | +            $this->initialState->provideInitialState('unified-search', 'min-search-length', (int)$this->config->getAppValue('core', 'unified-search.min-search-length', (string)2)); | 
                                                        |
| 106 | +            $this->initialState->provideInitialState('unified-search', 'live-search', $this->config->getAppValue('core', 'unified-search.live-search', 'yes') === 'yes'); | 
                                                        |
| 107 | +            Util::addScript('core', 'unified-search', 'core'); | 
                                                        |
| 108 | +  | 
                                                        |
| 109 | + // Set body data-theme  | 
                                                        |
| 110 | +            $this->assign('enabledThemes', []); | 
                                                        |
| 111 | +            if (\OC::$server->getAppManager()->isEnabledForUser('theming') && class_exists('\OCA\Theming\Service\ThemesService')) { | 
                                                        |
| 112 | + /** @var \OCA\Theming\Service\ThemesService */  | 
                                                        |
| 113 | + $themesService = \OC::$server->get(\OCA\Theming\Service\ThemesService::class);  | 
                                                        |
| 114 | +                $this->assign('enabledThemes', $themesService->getEnabledThemes()); | 
                                                        |
| 115 | + }  | 
                                                        |
| 116 | +  | 
                                                        |
| 117 | + // set logo link target  | 
                                                        |
| 118 | +            $logoUrl = $this->config->getSystemValueString('logo_url', ''); | 
                                                        |
| 119 | +            $this->assign('logoUrl', $logoUrl); | 
                                                        |
| 120 | +  | 
                                                        |
| 121 | + // Add navigation entry  | 
                                                        |
| 122 | +            $this->assign('application', ''); | 
                                                        |
| 123 | +            $this->assign('appid', $appId); | 
                                                        |
| 124 | +  | 
                                                        |
| 125 | + $navigation = $this->navigationManager->getAll();  | 
                                                        |
| 126 | +            $this->assign('navigation', $navigation); | 
                                                        |
| 127 | +            $settingsNavigation = $this->navigationManager->getAll('settings'); | 
                                                        |
| 128 | +            $this->assign('settingsnavigation', $settingsNavigation); | 
                                                        |
| 129 | +  | 
                                                        |
| 130 | +            foreach ($navigation as $entry) { | 
                                                        |
| 131 | +                if ($entry['active']) { | 
                                                        |
| 132 | +                    $this->assign('application', $entry['name']); | 
                                                        |
| 133 | + break;  | 
                                                        |
| 134 | + }  | 
                                                        |
| 135 | + }  | 
                                                        |
| 136 | +  | 
                                                        |
| 137 | +            foreach ($settingsNavigation as $entry) { | 
                                                        |
| 138 | +                if ($entry['active']) { | 
                                                        |
| 139 | +                    $this->assign('application', $entry['name']); | 
                                                        |
| 140 | + break;  | 
                                                        |
| 141 | + }  | 
                                                        |
| 142 | + }  | 
                                                        |
| 143 | +  | 
                                                        |
| 144 | + $userDisplayName = false;  | 
                                                        |
| 145 | + $user = \OC::$server->get(IUserSession::class)->getUser();  | 
                                                        |
| 146 | +            if ($user) { | 
                                                        |
| 147 | + $userDisplayName = $user->getDisplayName();  | 
                                                        |
| 148 | + }  | 
                                                        |
| 149 | +            $this->assign('user_displayname', $userDisplayName); | 
                                                        |
| 150 | +            $this->assign('user_uid', \OC_User::getUser()); | 
                                                        |
| 151 | +  | 
                                                        |
| 152 | +            if ($user === null) { | 
                                                        |
| 153 | +                $this->assign('userAvatarSet', false); | 
                                                        |
| 154 | +                $this->assign('userStatus', false); | 
                                                        |
| 155 | +            } else { | 
                                                        |
| 156 | +                $this->assign('userAvatarSet', true); | 
                                                        |
| 157 | +                $this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0)); | 
                                                        |
| 158 | + }  | 
                                                        |
| 159 | +        } elseif ($renderAs === TemplateResponse::RENDER_AS_ERROR) { | 
                                                        |
| 160 | +            parent::__construct('core', 'layout.guest', '', false); | 
                                                        |
| 161 | +            $this->assign('bodyid', 'body-login'); | 
                                                        |
| 162 | +            $this->assign('user_displayname', ''); | 
                                                        |
| 163 | +            $this->assign('user_uid', ''); | 
                                                        |
| 164 | +        } elseif ($renderAs === TemplateResponse::RENDER_AS_GUEST) { | 
                                                        |
| 165 | +            parent::__construct('core', 'layout.guest'); | 
                                                        |
| 166 | +            \OC_Util::addStyle('guest'); | 
                                                        |
| 167 | +            $this->assign('bodyid', 'body-login'); | 
                                                        |
| 168 | +  | 
                                                        |
| 169 | + $userDisplayName = false;  | 
                                                        |
| 170 | + $user = \OC::$server->get(IUserSession::class)->getUser();  | 
                                                        |
| 171 | +            if ($user) { | 
                                                        |
| 172 | + $userDisplayName = $user->getDisplayName();  | 
                                                        |
| 173 | + }  | 
                                                        |
| 174 | +            $this->assign('user_displayname', $userDisplayName); | 
                                                        |
| 175 | +            $this->assign('user_uid', \OC_User::getUser()); | 
                                                        |
| 176 | +        } elseif ($renderAs === TemplateResponse::RENDER_AS_PUBLIC) { | 
                                                        |
| 177 | +            parent::__construct('core', 'layout.public'); | 
                                                        |
| 178 | +            $this->assign('appid', $appId); | 
                                                        |
| 179 | +            $this->assign('bodyid', 'body-public'); | 
                                                        |
| 180 | +  | 
                                                        |
| 181 | + /** @var IRegistry $subscription */  | 
                                                        |
| 182 | + $subscription = \OC::$server->query(IRegistry::class);  | 
                                                        |
| 183 | +            $showSimpleSignup = $this->config->getSystemValueBool('simpleSignUpLink.shown', true); | 
                                                        |
| 184 | +            if ($showSimpleSignup && $subscription->delegateHasValidSubscription()) { | 
                                                        |
| 185 | + $showSimpleSignup = false;  | 
                                                        |
| 186 | + }  | 
                                                        |
| 187 | +            $this->assign('showSimpleSignUpLink', $showSimpleSignup); | 
                                                        |
| 188 | +        } else { | 
                                                        |
| 189 | +            parent::__construct('core', 'layout.base'); | 
                                                        |
| 190 | + }  | 
                                                        |
| 191 | + // Send the language and the locale to our layouts  | 
                                                        |
| 192 | + $lang = \OC::$server->getL10NFactory()->findLanguage();  | 
                                                        |
| 193 | + $locale = \OC::$server->getL10NFactory()->findLocale($lang);  | 
                                                        |
| 194 | +  | 
                                                        |
| 195 | +        $lang = str_replace('_', '-', $lang); | 
                                                        |
| 196 | +        $this->assign('language', $lang); | 
                                                        |
| 197 | +        $this->assign('locale', $locale); | 
                                                        |
| 198 | +  | 
                                                        |
| 199 | +        if (\OC::$server->getSystemConfig()->getValue('installed', false)) { | 
                                                        |
| 200 | +            if (empty(self::$versionHash)) { | 
                                                        |
| 201 | + $v = \OC_App::getAppVersions();  | 
                                                        |
| 202 | +                $v['core'] = implode('.', \OCP\Util::getVersion()); | 
                                                        |
| 203 | +                self::$versionHash = substr(md5(implode(',', $v)), 0, 8); | 
                                                        |
| 204 | + }  | 
                                                        |
| 205 | +        } else { | 
                                                        |
| 206 | +            self::$versionHash = md5('not installed'); | 
                                                        |
| 207 | + }  | 
                                                        |
| 208 | +  | 
                                                        |
| 209 | + // Add the js files  | 
                                                        |
| 210 | + // TODO: remove deprecated OC_Util injection  | 
                                                        |
| 211 | + $jsFiles = self::findJavascriptFiles(array_merge(\OC_Util::$scripts, Util::getScripts()));  | 
                                                        |
| 212 | +        $this->assign('jsfiles', []); | 
                                                        |
| 213 | +        if ($this->config->getSystemValue('installed', false) && $renderAs != TemplateResponse::RENDER_AS_ERROR) { | 
                                                        |
| 214 | + // this is on purpose outside of the if statement below so that the initial state is prefilled (done in the getConfig() call)  | 
                                                        |
| 215 | + // see https://github.com/nextcloud/server/pull/22636 for details  | 
                                                        |
| 216 | + $jsConfigHelper = new JSConfigHelper(  | 
                                                        |
| 217 | +                \OC::$server->getL10N('lib'), | 
                                                        |
| 218 | + \OC::$server->query(Defaults::class),  | 
                                                        |
| 219 | + \OC::$server->getAppManager(),  | 
                                                        |
| 220 | + \OC::$server->getSession(),  | 
                                                        |
| 221 | + \OC::$server->getUserSession()->getUser(),  | 
                                                        |
| 222 | + $this->config,  | 
                                                        |
| 223 | + \OC::$server->getGroupManager(),  | 
                                                        |
| 224 | + \OC::$server->get(IniGetWrapper::class),  | 
                                                        |
| 225 | + \OC::$server->getURLGenerator(),  | 
                                                        |
| 226 | + \OC::$server->getCapabilitiesManager(),  | 
                                                        |
| 227 | + \OC::$server->query(IInitialStateService::class)  | 
                                                        |
| 228 | + );  | 
                                                        |
| 229 | + $config = $jsConfigHelper->getConfig();  | 
                                                        |
| 230 | +            if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) { | 
                                                        |
| 231 | +                $this->assign('inline_ocjs', $config); | 
                                                        |
| 232 | +            } else { | 
                                                        |
| 233 | +                $this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash])); | 
                                                        |
| 234 | + }  | 
                                                        |
| 235 | + }  | 
                                                        |
| 236 | +        foreach ($jsFiles as $info) { | 
                                                        |
| 237 | + $web = $info[1];  | 
                                                        |
| 238 | + $file = $info[2];  | 
                                                        |
| 239 | +            $this->append('jsfiles', $web.'/'.$file . $this->getVersionHashSuffix()); | 
                                                        |
| 240 | + }  | 
                                                        |
| 241 | +  | 
                                                        |
| 242 | +        try { | 
                                                        |
| 243 | + $pathInfo = \OC::$server->getRequest()->getPathInfo();  | 
                                                        |
| 244 | +        } catch (\Exception $e) { | 
                                                        |
| 245 | + $pathInfo = '';  | 
                                                        |
| 246 | + }  | 
                                                        |
| 247 | +  | 
                                                        |
| 248 | + // Do not initialise scss appdata until we have a fully installed instance  | 
                                                        |
| 249 | + // Do not load scss for update, errors, installation or login page  | 
                                                        |
| 250 | +        if (\OC::$server->getSystemConfig()->getValue('installed', false) | 
                                                        |
| 251 | + && !\OCP\Util::needUpgrade()  | 
                                                        |
| 252 | + && $pathInfo !== ''  | 
                                                        |
| 253 | +            && !preg_match('/^\/login/', $pathInfo) | 
                                                        |
| 254 | + && $renderAs !== TemplateResponse::RENDER_AS_ERROR  | 
                                                        |
| 255 | +        ) { | 
                                                        |
| 256 | + $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);  | 
                                                        |
| 257 | +        } else { | 
                                                        |
| 258 | + // If we ignore the scss compiler,  | 
                                                        |
| 259 | + // we need to load the guest css fallback  | 
                                                        |
| 260 | +            \OC_Util::addStyle('guest'); | 
                                                        |
| 261 | + $cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);  | 
                                                        |
| 262 | + }  | 
                                                        |
| 263 | +  | 
                                                        |
| 264 | +        $this->assign('cssfiles', []); | 
                                                        |
| 265 | +        $this->assign('printcssfiles', []); | 
                                                        |
| 266 | +        $this->assign('versionHash', self::$versionHash); | 
                                                        |
| 267 | +        foreach ($cssFiles as $info) { | 
                                                        |
| 268 | + $web = $info[1];  | 
                                                        |
| 269 | + $file = $info[2];  | 
                                                        |
| 270 | +  | 
                                                        |
| 271 | +            if (substr($file, -strlen('print.css')) === 'print.css') { | 
                                                        |
| 272 | +                $this->append('printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix()); | 
                                                        |
| 273 | +            } else { | 
                                                        |
| 274 | + $suffix = $this->getVersionHashSuffix($web, $file);  | 
                                                        |
| 275 | +  | 
                                                        |
| 276 | +                if (strpos($file, '?v=') == false) { | 
                                                        |
| 277 | +                    $this->append('cssfiles', $web.'/'.$file . $suffix); | 
                                                        |
| 278 | +                } else { | 
                                                        |
| 279 | +                    $this->append('cssfiles', $web.'/'.$file . '-' . substr($suffix, 3)); | 
                                                        |
| 280 | + }  | 
                                                        |
| 281 | + }  | 
                                                        |
| 282 | + }  | 
                                                        |
| 283 | +  | 
                                                        |
| 284 | +        $this->assign('initialStates', $this->initialState->getInitialStates()); | 
                                                        |
| 285 | + }  | 
                                                        |
| 286 | +  | 
                                                        |
| 287 | + /**  | 
                                                        |
| 288 | + * @param string $path  | 
                                                        |
| 289 | + * @param string $file  | 
                                                        |
| 290 | + * @return string  | 
                                                        |
| 291 | + */  | 
                                                        |
| 292 | +    protected function getVersionHashSuffix($path = false, $file = false) { | 
                                                        |
| 293 | +        if ($this->config->getSystemValue('debug', false)) { | 
                                                        |
| 294 | + // allows chrome workspace mapping in debug mode  | 
                                                        |
| 295 | + return "";  | 
                                                        |
| 296 | + }  | 
                                                        |
| 297 | + $themingSuffix = '';  | 
                                                        |
| 298 | + $v = [];  | 
                                                        |
| 299 | +  | 
                                                        |
| 300 | +        if ($this->config->getSystemValue('installed', false)) { | 
                                                        |
| 301 | +            if (\OC::$server->getAppManager()->isInstalled('theming')) { | 
                                                        |
| 302 | +                $themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0'); | 
                                                        |
| 303 | + }  | 
                                                        |
| 304 | + $v = \OC_App::getAppVersions();  | 
                                                        |
| 305 | + }  | 
                                                        |
| 306 | +  | 
                                                        |
| 307 | + // Try the webroot path for a match  | 
                                                        |
| 308 | +        if ($path !== false && $path !== '') { | 
                                                        |
| 309 | + $appName = $this->getAppNamefromPath($path);  | 
                                                        |
| 310 | +            if (array_key_exists($appName, $v)) { | 
                                                        |
| 311 | + $appVersion = $v[$appName];  | 
                                                        |
| 312 | + return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;  | 
                                                        |
| 313 | + }  | 
                                                        |
| 314 | + }  | 
                                                        |
| 315 | + // fallback to the file path instead  | 
                                                        |
| 316 | +        if ($file !== false && $file !== '') { | 
                                                        |
| 317 | + $appName = $this->getAppNamefromPath($file);  | 
                                                        |
| 318 | +            if (array_key_exists($appName, $v)) { | 
                                                        |
| 319 | + $appVersion = $v[$appName];  | 
                                                        |
| 320 | + return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;  | 
                                                        |
| 321 | + }  | 
                                                        |
| 322 | + }  | 
                                                        |
| 323 | +  | 
                                                        |
| 324 | + return '?v=' . self::$versionHash . $themingSuffix;  | 
                                                        |
| 325 | + }  | 
                                                        |
| 326 | +  | 
                                                        |
| 327 | + /**  | 
                                                        |
| 328 | + * @param array $styles  | 
                                                        |
| 329 | + * @return array  | 
                                                        |
| 330 | + */  | 
                                                        |
| 331 | +    public static function findStylesheetFiles($styles, $compileScss = true) { | 
                                                        |
| 332 | + // Read the selected theme from the config file  | 
                                                        |
| 333 | + $theme = \OC_Util::getTheme();  | 
                                                        |
| 334 | +  | 
                                                        |
| 335 | +        if ($compileScss) { | 
                                                        |
| 336 | + $SCSSCacher = \OC::$server->query(SCSSCacher::class);  | 
                                                        |
| 337 | +        } else { | 
                                                        |
| 338 | + $SCSSCacher = null;  | 
                                                        |
| 339 | + }  | 
                                                        |
| 340 | +  | 
                                                        |
| 341 | + $locator = new \OC\Template\CSSResourceLocator(  | 
                                                        |
| 342 | + \OC::$server->get(LoggerInterface::class),  | 
                                                        |
| 343 | + $theme,  | 
                                                        |
| 344 | + [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 345 | + [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 346 | + $SCSSCacher  | 
                                                        |
| 347 | + );  | 
                                                        |
| 348 | + $locator->find($styles);  | 
                                                        |
| 349 | + return $locator->getResources();  | 
                                                        |
| 350 | + }  | 
                                                        |
| 351 | +  | 
                                                        |
| 352 | + /**  | 
                                                        |
| 353 | + * @param string $path  | 
                                                        |
| 354 | + * @return string|boolean  | 
                                                        |
| 355 | + */  | 
                                                        |
| 356 | +    public function getAppNamefromPath($path) { | 
                                                        |
| 357 | +        if ($path !== '' && is_string($path)) { | 
                                                        |
| 358 | +            $pathParts = explode('/', $path); | 
                                                        |
| 359 | +            if ($pathParts[0] === 'css') { | 
                                                        |
| 360 | + // This is a scss request  | 
                                                        |
| 361 | + return $pathParts[1];  | 
                                                        |
| 362 | + }  | 
                                                        |
| 363 | + return end($pathParts);  | 
                                                        |
| 364 | + }  | 
                                                        |
| 365 | + return false;  | 
                                                        |
| 366 | + }  | 
                                                        |
| 367 | +  | 
                                                        |
| 368 | + /**  | 
                                                        |
| 369 | + * @param array $scripts  | 
                                                        |
| 370 | + * @return array  | 
                                                        |
| 371 | + */  | 
                                                        |
| 372 | +    public static function findJavascriptFiles($scripts) { | 
                                                        |
| 373 | + // Read the selected theme from the config file  | 
                                                        |
| 374 | + $theme = \OC_Util::getTheme();  | 
                                                        |
| 375 | +  | 
                                                        |
| 376 | + $locator = new \OC\Template\JSResourceLocator(  | 
                                                        |
| 377 | + \OC::$server->get(LoggerInterface::class),  | 
                                                        |
| 378 | + $theme,  | 
                                                        |
| 379 | + [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 380 | + [ \OC::$SERVERROOT => \OC::$WEBROOT ],  | 
                                                        |
| 381 | + \OC::$server->query(JSCombiner::class)  | 
                                                        |
| 382 | + );  | 
                                                        |
| 383 | + $locator->find($scripts);  | 
                                                        |
| 384 | + return $locator->getResources();  | 
                                                        |
| 385 | + }  | 
                                                        |
| 386 | +  | 
                                                        |
| 387 | + /**  | 
                                                        |
| 388 | + * Converts the absolute file path to a relative path from \OC::$SERVERROOT  | 
                                                        |
| 389 | + * @param string $filePath Absolute path  | 
                                                        |
| 390 | + * @return string Relative path  | 
                                                        |
| 391 | + * @throws \Exception If $filePath is not under \OC::$SERVERROOT  | 
                                                        |
| 392 | + */  | 
                                                        |
| 393 | +    public static function convertToRelativePath($filePath) { | 
                                                        |
| 394 | + $relativePath = explode(\OC::$SERVERROOT, $filePath);  | 
                                                        |
| 395 | +        if (count($relativePath) !== 2) { | 
                                                        |
| 396 | +            throw new \Exception('$filePath is not under the \OC::$SERVERROOT'); | 
                                                        |
| 397 | + }  | 
                                                        |
| 398 | +  | 
                                                        |
| 399 | + return $relativePath[1];  | 
                                                        |
| 400 | + }  | 
                                                        |
| 401 | 401 | }  |