]> git.mxchange.org Git - friendica.git/blob - src/Module/Special/HTTPException.php
Merge pull request #13128 from annando/owa
[friendica.git] / src / Module / Special / HTTPException.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Module\Special;
23
24 use Friendica\App\Arguments;
25 use Friendica\App\Request;
26 use Friendica\Core\L10n;
27 use Friendica\Core\Renderer;
28 use Friendica\Core\Session\Model\UserSession;
29 use Friendica\Core\System;
30 use Psr\Log\LoggerInterface;
31
32 /**
33  * This special module displays HTTPException when they are thrown in modules.
34  *
35  * @package Friendica\Module\Special
36  */
37 class HTTPException
38 {
39         /** @var L10n */
40         protected $l10n;
41         /** @var LoggerInterface */
42         protected $logger;
43         /** @var Arguments */
44         protected $args;
45         /** @var bool */
46         protected $isSiteAdmin;
47         /** @var array */
48         protected $server;
49         /** @var string */
50         protected $requestId;
51
52         public function __construct(L10n $l10n, LoggerInterface $logger, Arguments $args, UserSession $session, Request $request, array $server = [])
53         {
54                 $this->logger      = $logger;
55                 $this->l10n        = $l10n;
56                 $this->args        = $args;
57                 $this->isSiteAdmin = $session->isSiteAdmin();
58                 $this->server      = $server;
59                 $this->requestId   = $request->getRequestId();
60         }
61
62         /**
63          * Generates the necessary template variables from the caught HTTPException.
64          *
65          * Fills in the blanks if title or descriptions aren't provided by the exception.
66          *
67          * @param \Friendica\Network\HTTPException $e
68          *
69          * @return array ['$title' => ..., '$description' => ...]
70          */
71         private function getVars(\Friendica\Network\HTTPException $e)
72         {
73                 // Explanations are mostly taken from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
74                 $vars = [
75                         '$title'       => $e->getDescription() ?: 'Error ' . $e->getCode(),
76                         '$message'     => $e->getMessage() ?: $e->getExplanation(),
77                         '$back'        => $this->l10n->t('Go back'),
78                         '$stack_trace' => $this->l10n->t('Stack trace:'),
79                         '$request_id'  => $this->requestId,
80                 ];
81
82                 if ($this->isSiteAdmin) {
83                         $vars['$thrown'] = $this->l10n->t('Exception thrown in %s:%d', $e->getFile(), $e->getLine());
84                         $vars['$trace']  = $e->getTraceAsString();
85                 }
86
87                 return $vars;
88         }
89
90         /**
91          * Displays a bare message page with no theming at all.
92          *
93          * @param \Friendica\Network\HTTPException $e
94          *
95          * @throws \Exception
96          */
97         public function rawContent(\Friendica\Network\HTTPException $e)
98         {
99                 $content = '';
100
101                 if ($e->getCode() >= 400) {
102                         $vars = $this->getVars($e);
103                         try {
104                                 $tpl     = Renderer::getMarkupTemplate('http_status.tpl');
105                                 $content = Renderer::replaceMacros($tpl, $vars);
106                         } catch (\Exception $e) {
107                                 $vars = array_map('htmlentities', $vars);
108                                 $content = "<h1>{$vars['$title']}</h1><p>{$vars['$message']}</p>";
109                                 if ($this->isSiteAdmin) {
110                                         $content .= "<p>{$vars['$thrown']}</p>";
111                                         $content .= "<pre>{$vars['$trace']}</pre>";
112                                 }
113                         }
114                 }
115
116                 System::httpError($e->getCode(), $e->getDescription(), $content);
117         }
118
119         /**
120          * Returns a content string that can be integrated in the current theme.
121          *
122          * @param \Friendica\Network\HTTPException $e
123          *
124          * @return string
125          * @throws \Exception
126          */
127         public function content(\Friendica\Network\HTTPException $e): string
128         {
129                 header($this->server['SERVER_PROTOCOL'] ?? 'HTTP/1.0' . ' ' . $e->getCode() . ' ' . $e->getDescription());
130
131                 if ($e->getCode() >= 400) {
132                         $this->logger->debug('Exit with error',
133                                 [
134                                         'code'        => $e->getCode(),
135                                         'description' => $e->getDescription(),
136                                         'query'       => $this->args->getQueryString(),
137                                         'callstack'   => System::callstack(20),
138                                         'method'      => $this->args->getMethod(),
139                                         'agent'       => $this->server['HTTP_USER_AGENT'] ?? ''
140                                 ]);
141                 }
142
143                 $tpl = Renderer::getMarkupTemplate('exception.tpl');
144
145                 return Renderer::replaceMacros($tpl, $this->getVars($e));
146         }
147 }