Completed
Push — fetcher_factories ( ec83ea...40fc6e )
by David
08:11
created

HttpErrorsController::setContentFor400()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
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 404 and 500).
26
     *
27
     * @Property
28
     * @Compulsory
29
     *
30
     * @var TemplateInterface
31
     */
32
    private $template;
33
34
    /**
35
     * The content block the template will be written into.
36
     *
37
     * @Property
38
     * @Compulsory
39
     *
40
     * @var HtmlBlock
41
     */
42
    private $contentBlock;
43
44
    /**
45
     * Whether we should display exception stacktrace or not in HTTP 500.
46
     *
47
     * @Property
48
     *
49
     * @var bool
50
     */
51
    private $debugMode = true;
52
53
    /**
54
     * Content block displayed in case of a 400 error.
55
     * If not set, a default block will be used instead.
56
     *
57
     * @var HtmlElementInterface
58
     */
59
    protected $contentFor400;
60
61
    /**
62
     * Content block displayed in case of a 404 error.
63
     * If not set, a default block will be used instead.
64
     *
65
     * @var HtmlElementInterface
66
     */
67
    protected $contentFor404;
68
69
    /**
70
     * Content block displayed in case of a 500 error.
71
     * If not set, a default block will be used instead.
72
     *
73
     * @var HtmlElementInterface
74
     */
75
    protected $contentFor500;
76
77
    protected $exception;
78
79
    public function __construct(TemplateInterface $template, HtmlBlock $contentBlock, bool $debugMode = true)
80
    {
81
        $this->template = $template;
82
        $this->contentBlock = $contentBlock;
83
        $this->debugMode = $debugMode;
84
    }
85
86
    /**
87
     * Creates a default controller.
88
     *
89
     * @param bool $debugMode
90
     *
91
     * @return HttpErrorsController
92
     */
93
    public static function createDefault(bool $debugMode = true)
94
    {
95
        $block = new HtmlBlock();
96
        $template = new DefaultSplashTemplate($block);
97
98
        return new self($template, $block, $debugMode);
99
    }
100
101
    /**
102
     * This function is called when a HTTP 400 error is triggered by the user.
103
     *
104
     * @param ServerRequestInterface $request
105
     *
106
     * @return ResponseInterface
107
     */
108 View Code Duplication
    public function badRequest(BadRequestException $exception, ServerRequestInterface $request) : ResponseInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
109
    {
110
        $this->exception = $exception;
111
112
        $acceptType = $request->getHeader('Accept');
113
        if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) {
114
            return new JsonResponse(['error' => ['message' => 'Bad request sent', 'type' => 'bad_request']], 400);
115
        }
116
117
        if ($this->contentFor400) {
118
            $this->contentBlock = $this->contentFor400;
0 ignored issues
show
Documentation Bug introduced by
$this->contentFor400 is of type object<Mouf\Html\HtmlEle...t\HtmlElementInterface>, but the property $contentBlock was declared to be of type object<Mouf\Html\HtmlElement\HtmlBlock>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
119
        } else {
120
            $this->contentBlock->addFile(__DIR__.'/../../../../views/400.php', $this);
121
        }
122
123
        return HtmlResponse::create($this->template, 400);
124
    }
125
126
    /**
127
     * This function is called when a HTTP 404 error is triggered by the user.
128
     *
129
     * @param ServerRequestInterface $request
130
     *
131
     * @return ResponseInterface
132
     */
133 View Code Duplication
    public function pageNotFound(ServerRequestInterface $request) : ResponseInterface
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
134
    {
135
        $acceptType = $request->getHeader('Accept');
136
        if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) {
137
            return new JsonResponse(['error' => ['message' => 'Page not found', 'type' => 'page_not_found']], 404);
138
        }
139
140
        if ($this->contentFor404) {
141
            $this->contentBlock->addHtmlElement($this->contentFor404);
142
        } else {
143
            $this->contentBlock->addFile(__DIR__.'/../../../../views/404.php', $this);
144
        }
145
146
        return HtmlResponse::create($this->template, 404);
147
    }
148
149
    /**
150
     * (non-PHPdoc).
151
     *
152
     * @see Mouf\Mvc\Splash\Controllers.Http500HandlerInterface::serverError()
153
     */
154
    public function serverError(\Throwable $exception, ServerRequestInterface $request) : ResponseInterface
155
    {
156
        $this->exception = $exception;
157
158
        $acceptType = $request->getHeader('Accept');
159
        if (is_array($acceptType) && count($acceptType) > 0 && strpos($acceptType[0], 'json') !== false) {
160
            return new JsonResponse(['error' => ['message' => $exception->getMessage(), 'type' => 'Exception', 'trace' => $this->debugMode ? $exception->getTraceAsString() : '']], 500);
161
        }
162
163
        if ($this->contentFor500) {
164
            $this->contentBlock = $this->contentFor500;
0 ignored issues
show
Documentation Bug introduced by
$this->contentFor500 is of type object<Mouf\Html\HtmlEle...t\HtmlElementInterface>, but the property $contentBlock was declared to be of type object<Mouf\Html\HtmlElement\HtmlBlock>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
165
        } else {
166
            $this->contentBlock->addFile(__DIR__.'/../../../../views/500.php', $this);
167
        }
168
169
        return HtmlResponse::create($this->template, 500);
170
    }
171
172
    /**
173
     * Includes the file (useful to load a view inside the Controllers scope).
174
     *
175
     * @param string $file
176
     */
177
    public function loadFile($file)
178
    {
179
        include $file;
180
    }
181
182
    /**
183
     * Content block displayed in case of a 400 error.
184
     * If not set, a default block will be used instead.
185
     *
186
     * @param HtmlElementInterface $contentFor400
187
     */
188
    public function setContentFor400(HtmlElementInterface $contentFor400)
189
    {
190
        $this->contentFor400 = $contentFor400;
191
192
        return $this;
193
    }
194
195
    /**
196
     * Content block displayed in case of a 404 error.
197
     * If not set, a default block will be used instead.
198
     *
199
     * @param HtmlElementInterface $contentFor404
200
     */
201
    public function setContentFor404(HtmlElementInterface $contentFor404)
202
    {
203
        $this->contentFor404 = $contentFor404;
204
205
        return $this;
206
    }
207
208
    /**
209
     * Content block displayed in case of a 500 error.
210
     * If not set, a default block will be used instead.
211
     *
212
     * @param HtmlElementInterface $contentFor500
213
     */
214
    public function setContentFor500(HtmlElementInterface $contentFor500)
215
    {
216
        $this->contentFor500 = $contentFor500;
217
218
        return $this;
219
    }
220
}
221