1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Mouf\Mvc\Splash\Controllers; |
4
|
|
|
|
5
|
|
|
use Mouf\Html\HtmlElement\Scopable; |
6
|
|
|
use Mouf\Html\HtmlElement\HtmlBlock; |
7
|
|
|
use Mouf\Html\Template\TemplateInterface; |
8
|
|
|
use Mouf\Html\HtmlElement\HtmlElementInterface; |
9
|
|
|
use Mouf\Mvc\Splash\Exception\BadRequestException; |
10
|
|
|
use Mouf\Mvc\Splash\HtmlResponse; |
11
|
|
|
use Psr\Http\Message\ResponseInterface; |
12
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
13
|
|
|
use Zend\Diactoros\Response\JsonResponse; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* This class provides the default Splash behaviour when a HTTP 404 and HTTP 500 error is triggered. |
17
|
|
|
* Fill free to configure/override/replace this controller with your own if you want to provide |
18
|
|
|
* a customized HTTP 400/404/500 page. |
19
|
|
|
* |
20
|
|
|
* @author David Négrier |
21
|
|
|
*/ |
22
|
|
|
class HttpErrorsController implements Http400HandlerInterface, Http404HandlerInterface, Http500HandlerInterface, Scopable |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* The template used by Splash for displaying error pages (HTTP 400, 404 and 500). |
26
|
|
|
* |
27
|
|
|
* @var TemplateInterface |
28
|
|
|
*/ |
29
|
|
|
private $template; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* The content block the template will be written into. |
33
|
|
|
* |
34
|
|
|
* @var HtmlBlock |
35
|
|
|
*/ |
36
|
|
|
private $contentBlock; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Whether we should display exception stacktrace or not in HTTP 500. |
40
|
|
|
* |
41
|
|
|
* @var bool |
42
|
|
|
*/ |
43
|
|
|
private $debugMode = true; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Content block displayed in case of a 400 error. |
47
|
|
|
* If not set, a default block will be used instead. |
48
|
|
|
* |
49
|
|
|
* @var HtmlElementInterface |
50
|
|
|
*/ |
51
|
|
|
protected $contentFor400; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Content block displayed in case of a 404 error. |
55
|
|
|
* If not set, a default block will be used instead. |
56
|
|
|
* |
57
|
|
|
* @var HtmlElementInterface |
58
|
|
|
*/ |
59
|
|
|
protected $contentFor404; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Content block displayed in case of a 500 error. |
63
|
|
|
* If not set, a default block will be used instead. |
64
|
|
|
* |
65
|
|
|
* @var HtmlElementInterface |
66
|
|
|
*/ |
67
|
|
|
protected $contentFor500; |
68
|
|
|
|
69
|
|
|
protected $exception; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @param TemplateInterface $template The template used by Splash for displaying error pages (HTTP 400, 404 and 500). |
73
|
|
|
* @param HtmlBlock $contentBlock The content block the template will be written into. |
74
|
|
|
* @param bool $debugMode Whether we should display exception stacktrace or not in HTTP 500. |
75
|
|
|
*/ |
76
|
|
|
public function __construct(TemplateInterface $template, HtmlBlock $contentBlock, bool $debugMode = true) |
77
|
|
|
{ |
78
|
|
|
$this->template = $template; |
79
|
|
|
$this->contentBlock = $contentBlock; |
80
|
|
|
$this->debugMode = $debugMode; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Creates a default controller. |
85
|
|
|
* |
86
|
|
|
* @param bool $debugMode |
87
|
|
|
* |
88
|
|
|
* @return HttpErrorsController |
89
|
|
|
*/ |
90
|
|
|
public static function createDefault(bool $debugMode = true) |
91
|
|
|
{ |
92
|
|
|
$block = new HtmlBlock(); |
93
|
|
|
$template = new DefaultSplashTemplate($block); |
94
|
|
|
|
95
|
|
|
return new self($template, $block, $debugMode); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* This function is called when a HTTP 400 error is triggered by the user. |
100
|
|
|
* |
101
|
|
|
* @param ServerRequestInterface $request |
102
|
|
|
* |
103
|
|
|
* @return ResponseInterface |
104
|
|
|
*/ |
105
|
|
View Code Duplication |
public function badRequest(BadRequestException $exception, ServerRequestInterface $request) : ResponseInterface |
|
|
|
|
106
|
|
|
{ |
107
|
|
|
$this->exception = $exception; |
108
|
|
|
|
109
|
|
|
$acceptType = $request->getHeader('Accept'); |
110
|
|
|
if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) { |
111
|
|
|
return new JsonResponse(['error' => ['message' => 'Bad request sent', 'type' => 'bad_request']], 400); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
if ($this->contentFor400) { |
115
|
|
|
$this->contentBlock = $this->contentFor400; |
|
|
|
|
116
|
|
|
} else { |
117
|
|
|
$this->contentBlock->addFile(__DIR__.'/../../../../views/400.php', $this); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return HtmlResponse::create($this->template, 400); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* This function is called when a HTTP 404 error is triggered by the user. |
125
|
|
|
* |
126
|
|
|
* @param ServerRequestInterface $request |
127
|
|
|
* |
128
|
|
|
* @return ResponseInterface |
129
|
|
|
*/ |
130
|
|
View Code Duplication |
public function pageNotFound(ServerRequestInterface $request) : ResponseInterface |
|
|
|
|
131
|
|
|
{ |
132
|
|
|
$acceptType = $request->getHeader('Accept'); |
133
|
|
|
if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) { |
134
|
|
|
return new JsonResponse(['error' => ['message' => 'Page not found', 'type' => 'page_not_found']], 404); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
if ($this->contentFor404) { |
138
|
|
|
$this->contentBlock->addHtmlElement($this->contentFor404); |
139
|
|
|
} else { |
140
|
|
|
$this->contentBlock->addFile(__DIR__.'/../../../../views/404.php', $this); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return HtmlResponse::create($this->template, 404); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* (non-PHPdoc). |
148
|
|
|
* |
149
|
|
|
* @see Mouf\Mvc\Splash\Controllers.Http500HandlerInterface::serverError() |
150
|
|
|
*/ |
151
|
|
|
public function serverError(\Throwable $exception, ServerRequestInterface $request) : ResponseInterface |
152
|
|
|
{ |
153
|
|
|
$this->exception = $exception; |
154
|
|
|
|
155
|
|
|
$acceptType = $request->getHeader('Accept'); |
156
|
|
|
if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) { |
157
|
|
|
return new JsonResponse(['error' => ['message' => $exception->getMessage(), 'type' => 'Exception', 'trace' => $this->debugMode ? $exception->getTraceAsString() : '']], 500); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
if ($this->contentFor500) { |
161
|
|
|
$this->contentBlock->addHtmlElement($this->contentFor500); |
162
|
|
|
} else { |
163
|
|
|
$this->contentBlock->addFile(__DIR__.'/../../../../views/500.php', $this); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
return HtmlResponse::create($this->template, 500); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Includes the file (useful to load a view inside the Controllers scope). |
171
|
|
|
* |
172
|
|
|
* @param string $file |
173
|
|
|
*/ |
174
|
|
|
public function loadFile($file) |
175
|
|
|
{ |
176
|
|
|
include $file; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Content block displayed in case of a 400 error. |
181
|
|
|
* If not set, a default block will be used instead. |
182
|
|
|
* |
183
|
|
|
* @param HtmlElementInterface $contentFor400 |
184
|
|
|
* |
185
|
|
|
* @return $this |
186
|
|
|
*/ |
187
|
|
|
public function setContentFor400(HtmlElementInterface $contentFor400) |
188
|
|
|
{ |
189
|
|
|
$this->contentFor400 = $contentFor400; |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Content block displayed in case of a 404 error. |
196
|
|
|
* If not set, a default block will be used instead. |
197
|
|
|
* |
198
|
|
|
* @param HtmlElementInterface $contentFor404 |
199
|
|
|
* |
200
|
|
|
* @return $this |
201
|
|
|
*/ |
202
|
|
|
public function setContentFor404(HtmlElementInterface $contentFor404) |
203
|
|
|
{ |
204
|
|
|
$this->contentFor404 = $contentFor404; |
205
|
|
|
|
206
|
|
|
return $this; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Content block displayed in case of a 500 error. |
211
|
|
|
* If not set, a default block will be used instead. |
212
|
|
|
* |
213
|
|
|
* @param HtmlElementInterface $contentFor500 |
214
|
|
|
* |
215
|
|
|
* @return $this |
216
|
|
|
*/ |
217
|
|
|
public function setContentFor500(HtmlElementInterface $contentFor500) |
218
|
|
|
{ |
219
|
|
|
$this->contentFor500 = $contentFor500; |
220
|
|
|
|
221
|
|
|
return $this; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.