Completed
Push — master ( 238e2d...c71ea9 )
by Gabor
03:17
created

FinalMiddleware::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 5.6
6
 *
7
 * @copyright 2012 - 2016 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
namespace WebHemi\Middleware;
13
14
use RuntimeException;
15
use WebHemi\Adapter\Http\ResponseInterface;
16
use WebHemi\Adapter\Http\ServerRequestInterface;
17
use WebHemi\Adapter\Renderer\RendererAdapterInterface;
18
19
/**
20
 * Class FinalMiddleware.
21
 */
22
class FinalMiddleware implements MiddlewareInterface
23
{
24
    /** @var RendererAdapterInterface */
25
    private $templateRenderer;
26
27
    /**
28
     * FinalMiddleware constructor.
29
     *
30
     * @param RendererAdapterInterface $templateRenderer
31
     */
32 7
    public function __construct(RendererAdapterInterface $templateRenderer)
33
    {
34 7
        $this->templateRenderer = $templateRenderer;
35 7
    }
36
37
    /**
38
     * Sends out the headers and prints the response body to the output.
39
     *
40
     * @param ServerRequestInterface $request
41
     * @param ResponseInterface      $response
42
     *
43
     * @return ResponseInterface
44
     */
45 2
    public function __invoke(ServerRequestInterface &$request, ResponseInterface $response)
46
    {
47
        // @codeCoverageIgnoreStart
48
        if (!defined('PHPUNIT_WEBHEMI_TESTSUITE') && headers_sent()) {
49
            throw new RuntimeException('Unable to emit response; headers already sent');
50
        }
51
        // @codeCoverageIgnoreEnd
52
53 2
        $content = $response->getBody();
54
55
        // Handle errors here.
56 2
        if ($response->getStatusCode() !== ResponseInterface::STATUS_OK) {
57 1
            $errorTemplate = 'error-'.$response->getStatusCode();
58 1
            $exception = $request->getAttribute(ServerRequestInterface::REQUEST_ATTR_MIDDLEWARE_EXCEPTION);
59 1
            $content = $this->templateRenderer->render($errorTemplate, ['exception' => $exception]);
60 1
        }
61
62 2
        $response = $this->injectContentLength($response);
63
64
        // Skip sending output when PHP Unit is running.
65
        // @codeCoverageIgnoreStart
66
        if (!defined('PHPUNIT_WEBHEMI_TESTSUITE')) {
67
            $reasonPhrase = $response->getReasonPhrase();
68
            header(sprintf(
69
                'HTTP/%s %d%s',
70
                $response->getProtocolVersion(),
71
                $response->getStatusCode(),
72
                ($reasonPhrase ? ' '.$reasonPhrase : '')
73
            ));
74
75
            foreach ($response->getHeaders() as $headerName => $values) {
76
                $name  = $this->filterHeaderName($headerName);
77
                $first = true;
78
                foreach ($values as $value) {
79
                    header(sprintf('%s: %s', $name, $value), $first);
80
                    $first = false;
81
                }
82
            }
83
84
            echo $content;
85
        }
86
        // @codeCoverageIgnoreEnd
87
88 2
        return $response;
89
    }
90
91
    /**
92
     * Inject the Content-Length header if is not already present.
93
     *
94
     * @param ResponseInterface $response
95
     *
96
     * @return ResponseInterface
97
     */
98 2
    private function injectContentLength(ResponseInterface $response)
99
    {
100 2
        if (!$response->hasHeader('Content-Length')&& !is_null($response->getBody()->getSize())) {
101 2
            $response = $response->withHeader('Content-Length', (string) $response->getBody()->getSize());
102 2
        }
103
104 2
        return $response;
105
    }
106
107
    /**
108
     * Filter a header name to word case.
109
     *
110
     * @param string $headerName
111
     *
112
     * @return string
113
     */
114 5
    private function filterHeaderName($headerName)
115
    {
116 5
        $filtered = str_replace('-', ' ', $headerName);
117 5
        $filtered = ucwords($filtered);
118 5
        return str_replace(' ', '-', $filtered);
119
    }
120
}
121