Passed
Push — develop ( 71b03c...334703 )
by Brent
32:34 queued 24:49
created

Server::setRouter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Stitcher\Application;
4
5
use GuzzleHttp\Psr7\Request;
6
use GuzzleHttp\Psr7\Response;
7
use GuzzleHttp\Psr7\ServerRequest;
8
use Pageon\Http\HeaderContainer;
9
use Parsedown;
10
use Stitcher\Exception\Http;
11
use Stitcher\Exception\StitcherException;
12
13
abstract class Server
14
{
15
    /** @var Router */
16
    protected $router;
17
18
    /** @var Request */
19
    protected $request;
20
21
    /** @var Parsedown */
22
    protected $markdownParser;
23
24
    /** @var HeaderContainer */
25
    protected $headerContainer;
26
27
    abstract protected function handleStaticRoute(): ?Response;
28
29 3
    public function setRouter(Router $router): Server
30
    {
31 3
        $this->router = $router;
32
33 3
        return $this;
34
    }
35
36
    public function setHeaderContainer(HeaderContainer $headerContainer): Server
37
    {
38
        $this->headerContainer = $headerContainer;
39
40
        return $this;
41
    }
42
43 3
    public function setMarkdownParser(Parsedown $markdownParser): Server
44
    {
45 3
        $this->markdownParser = $markdownParser;
46
47 3
        return $this;
48
    }
49
50 4
    public function run(): string
51
    {
52 4
        $response = $this->createResponse();
53
54 4
        return $this->handleResponse($response);
55
    }
56
57 2
    protected function getRequest(): Request
58
    {
59 2
        if (! $this->request) {
60 2
            $this->request = ServerRequest::fromGlobals();
0 ignored issues
show
Documentation Bug introduced by
It seems like \GuzzleHttp\Psr7\ServerRequest::fromGlobals() of type object<Psr\Http\Message\ServerRequestInterface> is incompatible with the declared type object<GuzzleHttp\Psr7\Request> of property $request.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
61
        }
62
63 2
        return $this->request;
64
    }
65
66 2
    protected function getCurrentPath(): string
67
    {
68 2
        $path = $this->getRequest()->getUri()->getPath();
69
70 2
        return $path === '' ? '/' : $path;
71
    }
72
73
    protected function handleDynamicRoute(): ?Response
74
    {
75
        if (! $this->router) {
76
            return null;
77
        }
78
79
        return $this->router->dispatch($this->getRequest());
80
    }
81
82 4
    protected function createResponse(): Response
83
    {
84
        if (
85 4
            $this->router
86 4
            && $redirectTo = $this->router->getRedirectForUrl($this->getCurrentPath())
87
        ) {
88
            return $this->redirectResponse($redirectTo);
89
        }
90
91
        try {
92 4
            $response = $this->handleStaticRoute();
93
94 4
            if (! $response) {
95 4
                $response = $this->handleDynamicRoute();
96
            }
97
        } catch (StitcherException $e) {
98
            $response = $this->responseFromException($e);
99
        }
100
101 4
        return $response ?? $this->responseFromException(
102
                Http::notFound(
103 4
                    $this->getCurrentPath()
104
                )
105
            );
106
    }
107
108
    protected function redirectResponse(string $targetUrl): Response
109
    {
110
        return new Response(301, ["Location: {$targetUrl}"]);
111
    }
112
113
    protected function responseFromException(StitcherException $e): Response
114
    {
115
        $statusCode = $e instanceof Http ? $e->statusCode() : 500;
116
117
        $responseBody = file_get_contents(__DIR__ . '/../../static/exception.html');
118
119
        $responseBody = str_replace(
120
            '{{ title }}',
121
            $this->markdownParser->parse($e->title()),
122
            $responseBody
123
        );
124
125
        $responseBody = str_replace(
126
            '{{ body }}',
127
            $this->markdownParser->parse($e->body()),
128
            $responseBody
129
        );
130
131
        return new Response($statusCode, [], $responseBody);
132
    }
133
134 4
    protected function handleResponse(Response $response): string
135
    {
136 4
        foreach ($response->getHeaders() as $headers) {
137
            header(implode(', ', $headers));
138
        }
139
140 4
        if ($this->headerContainer) {
141
            foreach ($this->headerContainer as $header) {
142
                header((string) $header);
143
            }
144
        }
145
146 4
        http_response_code($response->getStatusCode());
147
148 4
        return $response->getBody()->getContents();
149
    }
150
}
151