ErrorPageContent::process()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
c 0
b 0
f 0
rs 8.439
cc 5
eloc 17
nc 4
nop 2
1
<?php
2
3
namespace Nofw\Foundation\Http\Middleware;
4
5
use Interop\Http\Factory\StreamFactoryInterface;
6
use Interop\Http\ServerMiddleware\DelegateInterface;
7
use Interop\Http\ServerMiddleware\MiddlewareInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
11
/**
12
 * @author Márk Sági-Kazár <[email protected]>
13
 */
14
final class ErrorPageContent implements MiddlewareInterface
15
{
16
    /**
17
     * @var \Twig_Environment
18
     */
19
    private $twig;
20
21
    /**
22
     * @var StreamFactoryInterface
23
     */
24
    private $streamFactory;
25
26
    public function __construct(\Twig_Environment $twig, StreamFactoryInterface $streamFactory)
27
    {
28
        $this->twig = $twig;
29
        $this->streamFactory = $streamFactory;
30
    }
31
32
    public function process(ServerRequestInterface $request, DelegateInterface $delegate): ResponseInterface
33
    {
34
        $response = $delegate->process($request);
35
36
        // If there is an error, but there is no body
37
        if ($this->isError($response) && $response->getBody()->getSize() < 1) {
38
            if ($this->isHtml($request, $response)) {
39
                switch ($response->getStatusCode()) {
40
                    case 404:
41
                        $html = $this->twig->render('error/error404.html.twig');
42
                        break;
43
44
                    default:
45
                        $html = $this->twig->render('error/error.html.twig', [
46
                            'status_code' => $response->getStatusCode(),
47
                            'reason_phrase' => $response->getReasonPhrase(),
48
                        ]);
49
                        break;
50
                }
51
52
                $body = $this->streamFactory->createStream($html);
53
                $body->rewind();
54
55
                return $response->withBody($body);
56
            }
57
        }
58
59
        return $response;
60
    }
61
62
    /**
63
     * Checks if the response is an error one based on the status code.
64
     */
65
    private function isError(ResponseInterface $response): bool
66
    {
67
        return $response->getStatusCode() >= 400 && $response->getStatusCode() < 600;
68
    }
69
70
    /**
71
     * Checks if HTML response is expected by the client.
72
     */
73
    private function isHtml(ServerRequestInterface $request, ResponseInterface $response): bool
74
    {
75
        $accept = $request->getHeaderLine('Accept');
76
        $contentType = $response->getHeaderLine('Content-Type');
77
78
        // TODO: improve negotiation
79
        return empty($accept) ||
80
            stripos($accept, '*') !== false ||
81
            stripos($accept, 'text/html') !== false ||
82
            stripos($contentType, 'text/html') !== false
83
        ;
84
    }
85
}
86