Completed
Pull Request — master (#9912)
by Morris
199:02 queued 174:06
created
lib/private/legacy/template.php 1 patch
Indentation   +347 added lines, -347 removed lines patch added patch discarded remove patch
@@ -46,351 +46,351 @@
 block discarded – undo
46 46
  */
47 47
 class OC_Template extends \OC\Template\Base {
48 48
 
49
-	/** @var string */
50
-	private $renderAs; // Create a full page?
51
-
52
-	/** @var string */
53
-	private $path; // The path to the template
54
-
55
-	/** @var array */
56
-	private $headers = array(); //custom headers
57
-
58
-	/** @var string */
59
-	protected $app; // app id
60
-
61
-	protected static $initTemplateEngineFirstRun = true;
62
-
63
-	/**
64
-	 * Constructor
65
-	 *
66
-	 * @param string $app app providing the template
67
-	 * @param string $name of the template file (without suffix)
68
-	 * @param string $renderAs If $renderAs is set, OC_Template will try to
69
-	 *                         produce a full page in the according layout. For
70
-	 *                         now, $renderAs can be set to "guest", "user" or
71
-	 *                         "admin".
72
-	 * @param bool $registerCall = true
73
-	 */
74
-	public function __construct( $app, $name, $renderAs = "", $registerCall = true ) {
75
-		// Read the selected theme from the config file
76
-		self::initTemplateEngine($renderAs);
77
-
78
-		$theme = OC_Util::getTheme();
79
-
80
-		$requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
81
-
82
-		$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
83
-		$l10n = \OC::$server->getL10N($parts[0]);
84
-		/** @var \OCP\Defaults $themeDefaults */
85
-		$themeDefaults = \OC::$server->query(\OCP\Defaults::class);
86
-
87
-		list($path, $template) = $this->findTemplate($theme, $app, $name);
88
-
89
-		// Set the private data
90
-		$this->renderAs = $renderAs;
91
-		$this->path = $path;
92
-		$this->app = $app;
93
-
94
-		parent::__construct($template, $requestToken, $l10n, $themeDefaults);
95
-	}
96
-
97
-	/**
98
-	 * @param string $renderAs
99
-	 */
100
-	public static function initTemplateEngine($renderAs) {
101
-		if (self::$initTemplateEngineFirstRun){
102
-
103
-			//apps that started before the template initialization can load their own scripts/styles
104
-			//so to make sure this scripts/styles here are loaded first we use OC_Util::addScript() with $prepend=true
105
-			//meaning the last script/style in this list will be loaded first
106
-			if (\OC::$server->getSystemConfig()->getValue ('installed', false) && $renderAs !== 'error' && !\OCP\Util::needUpgrade()) {
107
-				if (\OC::$server->getConfig ()->getAppValue ( 'core', 'backgroundjobs_mode', 'ajax' ) == 'ajax') {
108
-					OC_Util::addScript ( 'backgroundjobs', null, true );
109
-				}
110
-			}
111
-
112
-			OC_Util::addStyle('server', null, true);
113
-			OC_Util::addStyle('jquery-ui-fixes',null,true);
114
-			OC_Util::addVendorStyle('jquery-ui/themes/base/jquery-ui',null,true);
115
-			OC_Util::addVendorStyle('select2/select2', null, true);
116
-			OC_Util::addStyle('jquery.ocdialog');
117
-			OC_Util::addTranslations("core", null, true);
118
-			OC_Util::addStyle('search', 'results');
119
-			OC_Util::addScript('search', 'search', true);
120
-			OC_Util::addScript('search', 'searchprovider');
121
-			OC_Util::addScript('merged-template-prepend', null, true);
122
-			OC_Util::addScript('jquery-ui-fixes');
123
-			OC_Util::addScript('files/fileinfo');
124
-			OC_Util::addScript('files/client');
125
-			OC_Util::addScript('contactsmenu');
126
-
127
-			if (\OC::$server->getConfig()->getSystemValue('debug')) {
128
-				// Add the stuff we need always
129
-				// following logic will import all vendor libraries that are
130
-				// specified in core/js/core.json
131
-				$fileContent = file_get_contents(OC::$SERVERROOT . '/core/js/core.json');
132
-				if($fileContent !== false) {
133
-					$coreDependencies = json_decode($fileContent, true);
134
-					foreach(array_reverse($coreDependencies['vendor']) as $vendorLibrary) {
135
-						//remove trailing ".js" as addVendorScript will append it
136
-						OC_Util::addVendorScript(
137
-							substr($vendorLibrary, 0, -3),null,true);
138
-						}
139
- 				} else {
140
-					throw new \Exception('Cannot read core/js/core.json');
141
-				}
142
-			} else {
143
-				// Import all (combined) default vendor libraries
144
-				OC_Util::addVendorScript('core', null, true);
145
-			}
146
-
147
-			if (\OC::$server->getRequest()->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE])) {
148
-				// polyfill for btoa/atob for IE friends
149
-				OC_Util::addVendorScript('base64/base64');
150
-				// shim for the davclient.js library
151
-				\OCP\Util::addScript('files/iedavclient');
152
-			}
153
-
154
-			self::$initTemplateEngineFirstRun = false;
155
-		}
156
-
157
-	}
158
-
159
-
160
-	/**
161
-	 * find the template with the given name
162
-	 * @param string $name of the template file (without suffix)
163
-	 *
164
-	 * Will select the template file for the selected theme.
165
-	 * Checking all the possible locations.
166
-	 * @param string $theme
167
-	 * @param string $app
168
-	 * @return string[]
169
-	 */
170
-	protected function findTemplate($theme, $app, $name) {
171
-		// Check if it is a app template or not.
172
-		if( $app !== '' ) {
173
-			$dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app));
174
-		} else {
175
-			$dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT);
176
-		}
177
-		$locator = new \OC\Template\TemplateFileLocator( $dirs );
178
-		$template = $locator->find($name);
179
-		$path = $locator->getPath();
180
-		return array($path, $template);
181
-	}
182
-
183
-	/**
184
-	 * Add a custom element to the header
185
-	 * @param string $tag tag name of the element
186
-	 * @param array $attributes array of attributes for the element
187
-	 * @param string $text the text content for the element. If $text is null then the
188
-	 * element will be written as empty element. So use "" to get a closing tag.
189
-	 */
190
-	public function addHeader($tag, $attributes, $text=null) {
191
-		$this->headers[]= array(
192
-			'tag' => $tag,
193
-			'attributes' => $attributes,
194
-			'text' => $text
195
-		);
196
-	}
197
-
198
-	/**
199
-	 * Process the template
200
-	 * @return boolean|string
201
-	 *
202
-	 * This function process the template. If $this->renderAs is set, it
203
-	 * will produce a full page.
204
-	 */
205
-	public function fetchPage($additionalParams = null) {
206
-		$data = parent::fetchPage($additionalParams);
207
-
208
-		if( $this->renderAs ) {
209
-			$page = new TemplateLayout($this->renderAs, $this->app);
210
-
211
-			if(is_array($additionalParams)) {
212
-				foreach ($additionalParams as $key => $value) {
213
-					$page->assign($key, $value);
214
-				}
215
-			}
216
-
217
-			// Add custom headers
218
-			$headers = '';
219
-			foreach(OC_Util::$headers as $header) {
220
-				$headers .= '<'.\OCP\Util::sanitizeHTML($header['tag']);
221
-				if ( strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes']))) ) {
222
-					$headers .= ' defer';
223
-				}
224
-				foreach($header['attributes'] as $name=>$value) {
225
-					$headers .= ' '.\OCP\Util::sanitizeHTML($name).'="'.\OCP\Util::sanitizeHTML($value).'"';
226
-				}
227
-				if ($header['text'] !== null) {
228
-					$headers .= '>'.\OCP\Util::sanitizeHTML($header['text']).'</'.\OCP\Util::sanitizeHTML($header['tag']).'>';
229
-				} else {
230
-					$headers .= '/>';
231
-				}
232
-			}
233
-
234
-			$page->assign('headers', $headers);
235
-
236
-			$page->assign('content', $data);
237
-			return $page->fetchPage($additionalParams);
238
-		}
239
-
240
-		return $data;
241
-	}
242
-
243
-	/**
244
-	 * Include template
245
-	 *
246
-	 * @param string $file
247
-	 * @param array|null $additionalParams
248
-	 * @return string returns content of included template
249
-	 *
250
-	 * Includes another template. use <?php echo $this->inc('template'); ?> to
251
-	 * do this.
252
-	 */
253
-	public function inc( $file, $additionalParams = null ) {
254
-		return $this->load($this->path.$file.'.php', $additionalParams);
255
-	}
256
-
257
-	/**
258
-	 * Shortcut to print a simple page for users
259
-	 * @param string $application The application we render the template for
260
-	 * @param string $name Name of the template
261
-	 * @param array $parameters Parameters for the template
262
-	 * @return boolean|null
263
-	 */
264
-	public static function printUserPage( $application, $name, $parameters = array() ) {
265
-		$content = new OC_Template( $application, $name, "user" );
266
-		foreach( $parameters as $key => $value ) {
267
-			$content->assign( $key, $value );
268
-		}
269
-		print $content->printPage();
270
-	}
271
-
272
-	/**
273
-	 * Shortcut to print a simple page for admins
274
-	 * @param string $application The application we render the template for
275
-	 * @param string $name Name of the template
276
-	 * @param array $parameters Parameters for the template
277
-	 * @return bool
278
-	 */
279
-	public static function printAdminPage( $application, $name, $parameters = array() ) {
280
-		$content = new OC_Template( $application, $name, "admin" );
281
-		foreach( $parameters as $key => $value ) {
282
-			$content->assign( $key, $value );
283
-		}
284
-		return $content->printPage();
285
-	}
286
-
287
-	/**
288
-	 * Shortcut to print a simple page for guests
289
-	 * @param string $application The application we render the template for
290
-	 * @param string $name Name of the template
291
-	 * @param array|string $parameters Parameters for the template
292
-	 * @return bool
293
-	 */
294
-	public static function printGuestPage( $application, $name, $parameters = array() ) {
295
-		$content = new OC_Template( $application, $name, "guest" );
296
-		foreach( $parameters as $key => $value ) {
297
-			$content->assign( $key, $value );
298
-		}
299
-		return $content->printPage();
300
-	}
301
-
302
-	/**
303
-	 * Print a fatal error page and terminates the script
304
-	 * @param string $error_msg The error message to show
305
-	 * @param string $hint An optional hint message - needs to be properly escape
306
-	 * @suppress PhanAccessMethodInternal
307
-	 */
308
-	public static function printErrorPage( $error_msg, $hint = '' ) {
309
-		if (\OC::$server->getAppManager()->isEnabledForUser('theming') && !\OC_App::isAppLoaded('theming')) {
310
-			\OC_App::loadApp('theming');
311
-		}
312
-
313
-
314
-		if ($error_msg === $hint) {
315
-			// If the hint is the same as the message there is no need to display it twice.
316
-			$hint = '';
317
-		}
318
-
319
-		try {
320
-			$content = new \OC_Template( '', 'error', 'error', false );
321
-			$errors = array(array('error' => $error_msg, 'hint' => $hint));
322
-			$content->assign( 'errors', $errors );
323
-			$content->printPage();
324
-		} catch (\Exception $e) {
325
-			$logger = \OC::$server->getLogger();
326
-			$logger->error("$error_msg $hint", ['app' => 'core']);
327
-			$logger->logException($e, ['app' => 'core']);
328
-
329
-			header(self::getHttpProtocol() . ' 500 Internal Server Error');
330
-			header('Content-Type: text/plain; charset=utf-8');
331
-			print("$error_msg $hint");
332
-		}
333
-		die();
334
-	}
335
-
336
-	/**
337
-	 * print error page using Exception details
338
-	 * @param Exception|Throwable $exception
339
-	 * @param bool $fetchPage
340
-	 * @return bool|string
341
-	 * @suppress PhanAccessMethodInternal
342
-	 */
343
-	public static function printExceptionErrorPage($exception, $fetchPage = false) {
344
-		try {
345
-			$request = \OC::$server->getRequest();
346
-			$content = new \OC_Template('', 'exception', 'error', false);
347
-			$content->assign('errorClass', get_class($exception));
348
-			$content->assign('errorMsg', $exception->getMessage());
349
-			$content->assign('errorCode', $exception->getCode());
350
-			$content->assign('file', $exception->getFile());
351
-			$content->assign('line', $exception->getLine());
352
-			$content->assign('trace', $exception->getTraceAsString());
353
-			$content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false));
354
-			$content->assign('remoteAddr', $request->getRemoteAddress());
355
-			$content->assign('requestID', $request->getId());
356
-			if ($fetchPage) {
357
-				return $content->fetchPage();
358
-			}
359
-			$content->printPage();
360
-		} catch (\Exception $e) {
361
-			$logger = \OC::$server->getLogger();
362
-			$logger->logException($exception, ['app' => 'core']);
363
-			$logger->logException($e, ['app' => 'core']);
364
-
365
-			header(self::getHttpProtocol() . ' 500 Internal Server Error');
366
-			header('Content-Type: text/plain; charset=utf-8');
367
-			print("Internal Server Error\n\n");
368
-			print("The server encountered an internal error and was unable to complete your request.\n");
369
-			print("Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n");
370
-			print("More details can be found in the server log.\n");
371
-		}
372
-		die();
373
-	}
374
-
375
-	/**
376
-	 * This is only here to reduce the dependencies in case of an exception to
377
-	 * still be able to print a plain error message.
378
-	 *
379
-	 * Returns the used HTTP protocol.
380
-	 *
381
-	 * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
382
-	 * @internal Don't use this - use AppFramework\Http\Request->getHttpProtocol instead
383
-	 */
384
-	protected static function getHttpProtocol() {
385
-		$claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
386
-		$validProtocols = [
387
-			'HTTP/1.0',
388
-			'HTTP/1.1',
389
-			'HTTP/2',
390
-		];
391
-		if(in_array($claimedProtocol, $validProtocols, true)) {
392
-			return $claimedProtocol;
393
-		}
394
-		return 'HTTP/1.1';
395
-	}
49
+    /** @var string */
50
+    private $renderAs; // Create a full page?
51
+
52
+    /** @var string */
53
+    private $path; // The path to the template
54
+
55
+    /** @var array */
56
+    private $headers = array(); //custom headers
57
+
58
+    /** @var string */
59
+    protected $app; // app id
60
+
61
+    protected static $initTemplateEngineFirstRun = true;
62
+
63
+    /**
64
+     * Constructor
65
+     *
66
+     * @param string $app app providing the template
67
+     * @param string $name of the template file (without suffix)
68
+     * @param string $renderAs If $renderAs is set, OC_Template will try to
69
+     *                         produce a full page in the according layout. For
70
+     *                         now, $renderAs can be set to "guest", "user" or
71
+     *                         "admin".
72
+     * @param bool $registerCall = true
73
+     */
74
+    public function __construct( $app, $name, $renderAs = "", $registerCall = true ) {
75
+        // Read the selected theme from the config file
76
+        self::initTemplateEngine($renderAs);
77
+
78
+        $theme = OC_Util::getTheme();
79
+
80
+        $requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
81
+
82
+        $parts = explode('/', $app); // fix translation when app is something like core/lostpassword
83
+        $l10n = \OC::$server->getL10N($parts[0]);
84
+        /** @var \OCP\Defaults $themeDefaults */
85
+        $themeDefaults = \OC::$server->query(\OCP\Defaults::class);
86
+
87
+        list($path, $template) = $this->findTemplate($theme, $app, $name);
88
+
89
+        // Set the private data
90
+        $this->renderAs = $renderAs;
91
+        $this->path = $path;
92
+        $this->app = $app;
93
+
94
+        parent::__construct($template, $requestToken, $l10n, $themeDefaults);
95
+    }
96
+
97
+    /**
98
+     * @param string $renderAs
99
+     */
100
+    public static function initTemplateEngine($renderAs) {
101
+        if (self::$initTemplateEngineFirstRun){
102
+
103
+            //apps that started before the template initialization can load their own scripts/styles
104
+            //so to make sure this scripts/styles here are loaded first we use OC_Util::addScript() with $prepend=true
105
+            //meaning the last script/style in this list will be loaded first
106
+            if (\OC::$server->getSystemConfig()->getValue ('installed', false) && $renderAs !== 'error' && !\OCP\Util::needUpgrade()) {
107
+                if (\OC::$server->getConfig ()->getAppValue ( 'core', 'backgroundjobs_mode', 'ajax' ) == 'ajax') {
108
+                    OC_Util::addScript ( 'backgroundjobs', null, true );
109
+                }
110
+            }
111
+
112
+            OC_Util::addStyle('server', null, true);
113
+            OC_Util::addStyle('jquery-ui-fixes',null,true);
114
+            OC_Util::addVendorStyle('jquery-ui/themes/base/jquery-ui',null,true);
115
+            OC_Util::addVendorStyle('select2/select2', null, true);
116
+            OC_Util::addStyle('jquery.ocdialog');
117
+            OC_Util::addTranslations("core", null, true);
118
+            OC_Util::addStyle('search', 'results');
119
+            OC_Util::addScript('search', 'search', true);
120
+            OC_Util::addScript('search', 'searchprovider');
121
+            OC_Util::addScript('merged-template-prepend', null, true);
122
+            OC_Util::addScript('jquery-ui-fixes');
123
+            OC_Util::addScript('files/fileinfo');
124
+            OC_Util::addScript('files/client');
125
+            OC_Util::addScript('contactsmenu');
126
+
127
+            if (\OC::$server->getConfig()->getSystemValue('debug')) {
128
+                // Add the stuff we need always
129
+                // following logic will import all vendor libraries that are
130
+                // specified in core/js/core.json
131
+                $fileContent = file_get_contents(OC::$SERVERROOT . '/core/js/core.json');
132
+                if($fileContent !== false) {
133
+                    $coreDependencies = json_decode($fileContent, true);
134
+                    foreach(array_reverse($coreDependencies['vendor']) as $vendorLibrary) {
135
+                        //remove trailing ".js" as addVendorScript will append it
136
+                        OC_Util::addVendorScript(
137
+                            substr($vendorLibrary, 0, -3),null,true);
138
+                        }
139
+                    } else {
140
+                    throw new \Exception('Cannot read core/js/core.json');
141
+                }
142
+            } else {
143
+                // Import all (combined) default vendor libraries
144
+                OC_Util::addVendorScript('core', null, true);
145
+            }
146
+
147
+            if (\OC::$server->getRequest()->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE])) {
148
+                // polyfill for btoa/atob for IE friends
149
+                OC_Util::addVendorScript('base64/base64');
150
+                // shim for the davclient.js library
151
+                \OCP\Util::addScript('files/iedavclient');
152
+            }
153
+
154
+            self::$initTemplateEngineFirstRun = false;
155
+        }
156
+
157
+    }
158
+
159
+
160
+    /**
161
+     * find the template with the given name
162
+     * @param string $name of the template file (without suffix)
163
+     *
164
+     * Will select the template file for the selected theme.
165
+     * Checking all the possible locations.
166
+     * @param string $theme
167
+     * @param string $app
168
+     * @return string[]
169
+     */
170
+    protected function findTemplate($theme, $app, $name) {
171
+        // Check if it is a app template or not.
172
+        if( $app !== '' ) {
173
+            $dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app));
174
+        } else {
175
+            $dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT);
176
+        }
177
+        $locator = new \OC\Template\TemplateFileLocator( $dirs );
178
+        $template = $locator->find($name);
179
+        $path = $locator->getPath();
180
+        return array($path, $template);
181
+    }
182
+
183
+    /**
184
+     * Add a custom element to the header
185
+     * @param string $tag tag name of the element
186
+     * @param array $attributes array of attributes for the element
187
+     * @param string $text the text content for the element. If $text is null then the
188
+     * element will be written as empty element. So use "" to get a closing tag.
189
+     */
190
+    public function addHeader($tag, $attributes, $text=null) {
191
+        $this->headers[]= array(
192
+            'tag' => $tag,
193
+            'attributes' => $attributes,
194
+            'text' => $text
195
+        );
196
+    }
197
+
198
+    /**
199
+     * Process the template
200
+     * @return boolean|string
201
+     *
202
+     * This function process the template. If $this->renderAs is set, it
203
+     * will produce a full page.
204
+     */
205
+    public function fetchPage($additionalParams = null) {
206
+        $data = parent::fetchPage($additionalParams);
207
+
208
+        if( $this->renderAs ) {
209
+            $page = new TemplateLayout($this->renderAs, $this->app);
210
+
211
+            if(is_array($additionalParams)) {
212
+                foreach ($additionalParams as $key => $value) {
213
+                    $page->assign($key, $value);
214
+                }
215
+            }
216
+
217
+            // Add custom headers
218
+            $headers = '';
219
+            foreach(OC_Util::$headers as $header) {
220
+                $headers .= '<'.\OCP\Util::sanitizeHTML($header['tag']);
221
+                if ( strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes']))) ) {
222
+                    $headers .= ' defer';
223
+                }
224
+                foreach($header['attributes'] as $name=>$value) {
225
+                    $headers .= ' '.\OCP\Util::sanitizeHTML($name).'="'.\OCP\Util::sanitizeHTML($value).'"';
226
+                }
227
+                if ($header['text'] !== null) {
228
+                    $headers .= '>'.\OCP\Util::sanitizeHTML($header['text']).'</'.\OCP\Util::sanitizeHTML($header['tag']).'>';
229
+                } else {
230
+                    $headers .= '/>';
231
+                }
232
+            }
233
+
234
+            $page->assign('headers', $headers);
235
+
236
+            $page->assign('content', $data);
237
+            return $page->fetchPage($additionalParams);
238
+        }
239
+
240
+        return $data;
241
+    }
242
+
243
+    /**
244
+     * Include template
245
+     *
246
+     * @param string $file
247
+     * @param array|null $additionalParams
248
+     * @return string returns content of included template
249
+     *
250
+     * Includes another template. use <?php echo $this->inc('template'); ?> to
251
+     * do this.
252
+     */
253
+    public function inc( $file, $additionalParams = null ) {
254
+        return $this->load($this->path.$file.'.php', $additionalParams);
255
+    }
256
+
257
+    /**
258
+     * Shortcut to print a simple page for users
259
+     * @param string $application The application we render the template for
260
+     * @param string $name Name of the template
261
+     * @param array $parameters Parameters for the template
262
+     * @return boolean|null
263
+     */
264
+    public static function printUserPage( $application, $name, $parameters = array() ) {
265
+        $content = new OC_Template( $application, $name, "user" );
266
+        foreach( $parameters as $key => $value ) {
267
+            $content->assign( $key, $value );
268
+        }
269
+        print $content->printPage();
270
+    }
271
+
272
+    /**
273
+     * Shortcut to print a simple page for admins
274
+     * @param string $application The application we render the template for
275
+     * @param string $name Name of the template
276
+     * @param array $parameters Parameters for the template
277
+     * @return bool
278
+     */
279
+    public static function printAdminPage( $application, $name, $parameters = array() ) {
280
+        $content = new OC_Template( $application, $name, "admin" );
281
+        foreach( $parameters as $key => $value ) {
282
+            $content->assign( $key, $value );
283
+        }
284
+        return $content->printPage();
285
+    }
286
+
287
+    /**
288
+     * Shortcut to print a simple page for guests
289
+     * @param string $application The application we render the template for
290
+     * @param string $name Name of the template
291
+     * @param array|string $parameters Parameters for the template
292
+     * @return bool
293
+     */
294
+    public static function printGuestPage( $application, $name, $parameters = array() ) {
295
+        $content = new OC_Template( $application, $name, "guest" );
296
+        foreach( $parameters as $key => $value ) {
297
+            $content->assign( $key, $value );
298
+        }
299
+        return $content->printPage();
300
+    }
301
+
302
+    /**
303
+     * Print a fatal error page and terminates the script
304
+     * @param string $error_msg The error message to show
305
+     * @param string $hint An optional hint message - needs to be properly escape
306
+     * @suppress PhanAccessMethodInternal
307
+     */
308
+    public static function printErrorPage( $error_msg, $hint = '' ) {
309
+        if (\OC::$server->getAppManager()->isEnabledForUser('theming') && !\OC_App::isAppLoaded('theming')) {
310
+            \OC_App::loadApp('theming');
311
+        }
312
+
313
+
314
+        if ($error_msg === $hint) {
315
+            // If the hint is the same as the message there is no need to display it twice.
316
+            $hint = '';
317
+        }
318
+
319
+        try {
320
+            $content = new \OC_Template( '', 'error', 'error', false );
321
+            $errors = array(array('error' => $error_msg, 'hint' => $hint));
322
+            $content->assign( 'errors', $errors );
323
+            $content->printPage();
324
+        } catch (\Exception $e) {
325
+            $logger = \OC::$server->getLogger();
326
+            $logger->error("$error_msg $hint", ['app' => 'core']);
327
+            $logger->logException($e, ['app' => 'core']);
328
+
329
+            header(self::getHttpProtocol() . ' 500 Internal Server Error');
330
+            header('Content-Type: text/plain; charset=utf-8');
331
+            print("$error_msg $hint");
332
+        }
333
+        die();
334
+    }
335
+
336
+    /**
337
+     * print error page using Exception details
338
+     * @param Exception|Throwable $exception
339
+     * @param bool $fetchPage
340
+     * @return bool|string
341
+     * @suppress PhanAccessMethodInternal
342
+     */
343
+    public static function printExceptionErrorPage($exception, $fetchPage = false) {
344
+        try {
345
+            $request = \OC::$server->getRequest();
346
+            $content = new \OC_Template('', 'exception', 'error', false);
347
+            $content->assign('errorClass', get_class($exception));
348
+            $content->assign('errorMsg', $exception->getMessage());
349
+            $content->assign('errorCode', $exception->getCode());
350
+            $content->assign('file', $exception->getFile());
351
+            $content->assign('line', $exception->getLine());
352
+            $content->assign('trace', $exception->getTraceAsString());
353
+            $content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false));
354
+            $content->assign('remoteAddr', $request->getRemoteAddress());
355
+            $content->assign('requestID', $request->getId());
356
+            if ($fetchPage) {
357
+                return $content->fetchPage();
358
+            }
359
+            $content->printPage();
360
+        } catch (\Exception $e) {
361
+            $logger = \OC::$server->getLogger();
362
+            $logger->logException($exception, ['app' => 'core']);
363
+            $logger->logException($e, ['app' => 'core']);
364
+
365
+            header(self::getHttpProtocol() . ' 500 Internal Server Error');
366
+            header('Content-Type: text/plain; charset=utf-8');
367
+            print("Internal Server Error\n\n");
368
+            print("The server encountered an internal error and was unable to complete your request.\n");
369
+            print("Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n");
370
+            print("More details can be found in the server log.\n");
371
+        }
372
+        die();
373
+    }
374
+
375
+    /**
376
+     * This is only here to reduce the dependencies in case of an exception to
377
+     * still be able to print a plain error message.
378
+     *
379
+     * Returns the used HTTP protocol.
380
+     *
381
+     * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
382
+     * @internal Don't use this - use AppFramework\Http\Request->getHttpProtocol instead
383
+     */
384
+    protected static function getHttpProtocol() {
385
+        $claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
386
+        $validProtocols = [
387
+            'HTTP/1.0',
388
+            'HTTP/1.1',
389
+            'HTTP/2',
390
+        ];
391
+        if(in_array($claimedProtocol, $validProtocols, true)) {
392
+            return $claimedProtocol;
393
+        }
394
+        return 'HTTP/1.1';
395
+    }
396 396
 }
Please login to merge, or discard this patch.
core/templates/layout.user.php 1 patch
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 		<meta charset="utf-8">
5 5
 		<title>
6 6
 			<?php
7
-				p(!empty($_['application'])?$_['application'].' - ':'');
7
+				p(!empty($_['application']) ? $_['application'].' - ' : '');
8 8
 				p($theme->getTitle());
9 9
 			?>
10 10
 		</title>
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 		<meta name="apple-itunes-app" content="app-id=<?php p($theme->getiTunesAppId()); ?>">
15 15
 		<meta name="apple-mobile-web-app-capable" content="yes">
16 16
 		<meta name="apple-mobile-web-app-status-bar-style" content="black">
17
-		<meta name="apple-mobile-web-app-title" content="<?php p((!empty($_['application']) && $_['appid']!='files')? $_['application']:$theme->getTitle()); ?>">
17
+		<meta name="apple-mobile-web-app-title" content="<?php p((!empty($_['application']) && $_['appid'] != 'files') ? $_['application'] : $theme->getTitle()); ?>">
18 18
 		<meta name="mobile-web-app-capable" content="yes">
19 19
 		<meta name="theme-color" content="<?php p($theme->getColorPrimary()); ?>">
20 20
 		<link rel="icon" href="<?php print_unescaped(image_path($_['appid'], 'favicon.ico')); /* IE11+ supports png */ ?>">
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
 		<?php emit_script_loading_tags($_); ?>
26 26
 		<?php print_unescaped($_['headers']); ?>
27 27
 	</head>
28
-	<body id="<?php p($_['bodyid']);?>">
28
+	<body id="<?php p($_['bodyid']); ?>">
29 29
 	<?php include 'layout.noscript.warning.php'; ?>
30 30
 	<div id="notification-container">
31 31
 		<div id="notification"></div>
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
 					id="nextcloud">
37 37
 					<div class="logo logo-icon">
38 38
 						<h1 class="hidden-visually">
39
-							<?php p($theme->getName()); ?> <?php p(!empty($_['application'])?$_['application']: $l->t('Apps')); ?>
39
+							<?php p($theme->getName()); ?> <?php p(!empty($_['application']) ? $_['application'] : $l->t('Apps')); ?>
40 40
 						</h1>
41 41
 					</div>
42 42
 				</a>
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
 										<?php if ($_['themingInvertMenu']) { ?>
52 52
 										<defs><filter id="invertMenuMain-<?php p($entry['id']); ?>"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" /></filter></defs>
53 53
 										<?php } ?>
54
-										<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet"<?php if ($_['themingInvertMenu']) { ?> filter="url(#invertMenuMain-<?php p($entry['id']); ?>)"<?php } ?> xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>"  class="app-icon" />
54
+										<image x="0" y="0" width="20" height="20" preserveAspectRatio="xMinYMin meet"<?php if ($_['themingInvertMenu']) { ?> filter="url(#invertMenuMain-<?php p($entry['id']); ?>)"<?php } ?> xlink:href="<?php print_unescaped($entry['icon'].'?v='.$_['versionHash']); ?>"  class="app-icon" />
55 55
 									</svg>
56 56
 								<div class="icon-loading-small-dark"
57 57
 									 style="display:none;"></div>
@@ -74,14 +74,14 @@  discard block
 block discarded – undo
74 74
 					<div id="navigation" style="display: none;"  aria-label="<?php p($l->t('More apps menu')); ?>">
75 75
 						<div id="apps">
76 76
 							<ul>
77
-								<?php foreach($_['navigation'] as $entry): ?>
77
+								<?php foreach ($_['navigation'] as $entry): ?>
78 78
 									<li data-id="<?php p($entry['id']); ?>">
79 79
 									<a href="<?php print_unescaped($entry['href']); ?>"
80
-										<?php if( $entry['active'] ): ?> class="active"<?php endif; ?>
80
+										<?php if ($entry['active']): ?> class="active"<?php endif; ?>
81 81
 										aria-label="<?php p($entry['name']); ?>">
82 82
 										<svg width="16" height="16" viewBox="0 0 16 16" alt="">
83 83
 											<defs><filter id="invertMenuMore-<?php p($entry['id']); ?>"><feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix></filter></defs>
84
-											<image x="0" y="0" width="16" height="16" preserveAspectRatio="xMinYMin meet" filter="url(#invertMenuMore-<?php p($entry['id']); ?>)" xlink:href="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>"  class="app-icon"></image>
84
+											<image x="0" y="0" width="16" height="16" preserveAspectRatio="xMinYMin meet" filter="url(#invertMenuMore-<?php p($entry['id']); ?>)" xlink:href="<?php print_unescaped($entry['icon'].'?v='.$_['versionHash']); ?>"  class="app-icon"></image>
85 85
 										</svg>
86 86
 										<div class="icon-loading-small" style="display:none;"></div>
87 87
 										<span><?php p($entry['name']); ?></span>
@@ -98,43 +98,43 @@  discard block
 block discarded – undo
98 98
 			<div class="header-right">
99 99
 				<form class="searchbox" action="#" method="post" role="search" novalidate>
100 100
 					<label for="searchbox" class="hidden-visually">
101
-						<?php p($l->t('Search'));?>
101
+						<?php p($l->t('Search')); ?>
102 102
 					</label>
103 103
 					<input id="searchbox" type="search" name="query"
104 104
 						value="" required class="hidden"
105 105
 						autocomplete="off">
106
-					<button class="icon-close-white" type="reset"><span class="hidden-visually"><?php p($l->t('Reset search'));?></span></button>
106
+					<button class="icon-close-white" type="reset"><span class="hidden-visually"><?php p($l->t('Reset search')); ?></span></button>
107 107
 				</form>
108 108
 				<div id="contactsmenu">
109 109
 					<div class="icon-contacts menutoggle" tabindex="0" role="button"
110 110
 					aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false">
111
-						<span class="hidden-visually"><?php p($l->t('Contacts'));?>
111
+						<span class="hidden-visually"><?php p($l->t('Contacts')); ?>
112 112
 					</div>
113 113
 					<div id="contactsmenu-menu" class="menu"
114
-						aria-label="<?php p($l->t('Contacts menu'));?>"></div>
114
+						aria-label="<?php p($l->t('Contacts menu')); ?>"></div>
115 115
 				</div>
116 116
 				<div id="settings">
117 117
 					<div id="expand" tabindex="0" role="button" class="menutoggle"
118
-						aria-label="<?php p($l->t('Settings'));?>"
118
+						aria-label="<?php p($l->t('Settings')); ?>"
119 119
 						aria-haspopup="true" aria-controls="expanddiv" aria-expanded="false">
120 120
 						<div class="avatardiv<?php if ($_['userAvatarSet']) { print_unescaped(' avatardiv-shown'); } else { print_unescaped('" style="display: none'); } ?>">
121 121
 							<?php if ($_['userAvatarSet']): ?>
122 122
 								<img alt="" width="32" height="32"
123
-								src="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 32, 'v' => $_['userAvatarVersion']]));?>"
124
-								srcset="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 64, 'v' => $_['userAvatarVersion']]));?> 2x, <?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 128, 'v' => $_['userAvatarVersion']]));?> 4x"
123
+								src="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 32, 'v' => $_['userAvatarVersion']])); ?>"
124
+								srcset="<?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 64, 'v' => $_['userAvatarVersion']])); ?> 2x, <?php p(\OC::$server->getURLGenerator()->linkToRoute('core.avatar.getAvatar', ['userId' => $_['user_uid'], 'size' => 128, 'v' => $_['userAvatarVersion']])); ?> 4x"
125 125
 								>
126 126
 							<?php endif; ?>
127 127
 						</div>
128 128
 						<div id="expandDisplayName" class="icon-settings-white"></div>
129 129
 					</div>
130 130
 					<nav id="expanddiv" style="display:none;"
131
-						aria-label="<?php p($l->t('Settings menu'));?>">
131
+						aria-label="<?php p($l->t('Settings menu')); ?>">
132 132
 					<ul>
133
-					<?php foreach($_['settingsnavigation'] as $entry):?>
133
+					<?php foreach ($_['settingsnavigation'] as $entry):?>
134 134
 						<li data-id="<?php p($entry['id']); ?>">
135 135
 							<a href="<?php print_unescaped($entry['href']); ?>"
136
-								<?php if( $entry["active"] ): ?> class="active"<?php endif; ?>>
137
-								<img alt="" src="<?php print_unescaped($entry['icon'] . '?v=' . $_['versionHash']); ?>">
136
+								<?php if ($entry["active"]): ?> class="active"<?php endif; ?>>
137
+								<img alt="" src="<?php print_unescaped($entry['icon'].'?v='.$_['versionHash']); ?>">
138 138
 								<?php p($entry['name']) ?>
139 139
 							</a>
140 140
 						</li>
Please login to merge, or discard this patch.