-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbstractMiddlewareChainItem.php
128 lines (104 loc) · 3.45 KB
/
AbstractMiddlewareChainItem.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
declare(strict_types=1);
namespace Delvesoft\Psr15\Middleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
abstract class AbstractMiddlewareChainItem implements MiddlewareInterface
{
/** @var ServerRequestFactoryInterface */
private $serverRequestFactory;
/** @var ResponseFactoryInterface */
private $responseFactory;
/** @var AbstractMiddlewareChainItem|null */
private $next = null;
public function __construct(ServerRequestFactoryInterface $serverRequestFactory, ResponseFactoryInterface $responseFactory)
{
$this->serverRequestFactory = $serverRequestFactory;
$this->responseFactory = $responseFactory;
}
public function prepend(AbstractMiddlewareChainItem $first): self
{
$first->setNext($this);
return $first;
}
public function append(AbstractMiddlewareChainItem $newLast): self
{
$last = $this;
for ($actual = $this; $actual !== null; $actual = $actual->getNext()) {
$last = $actual;
}
$last->setNext($newLast);
return $this;
}
public function setNext(AbstractMiddlewareChainItem $next): self
{
$this->next = $next;
return $this;
}
/**
* @return string[]
*/
public function listChainClassNames(): array
{
$names = [
get_class($this)
];
$current = $this;
while (($next = $current->getNext()) !== null) {
$names[] = get_class($next);
$current = $next;
}
return $names;
}
public function hasNext(): bool
{
return ($this->next !== null);
}
protected function processNext(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if ($this->next === null) {
return $handler->handle($request);
}
return $this->next->process($request, $handler);
}
/**
* @param string $method
* @param UriInterface $uri
* @param string[] $serverParams
* @param string[][] $headers
*
* @return ServerRequestInterface
*/
protected function createServerRequest(string $method, UriInterface $uri, array $serverParams = [], array $headers = []): ServerRequestInterface
{
$serverRequest = $this->serverRequestFactory->createServerRequest($method, $uri, $serverParams);
foreach ($headers as $headerName => $headerValue) {
$serverRequest = $serverRequest->withHeader($headerName, $headerValue);
}
return $serverRequest;
}
/**
* @param int $code
* @param string $reasonPhrase
* @param string[][] $headers
*
* @return ResponseInterface
*/
protected function createResponse(int $code = 200, string $reasonPhrase = '', array $headers = []): ResponseInterface
{
$response = $this->responseFactory->createResponse($code, $reasonPhrase);
foreach ($headers as $headerName => $headerValue) {
$response = $response->withHeader($headerName, $headerValue);
}
return $response;
}
private function getNext(): ?AbstractMiddlewareChainItem
{
return $this->next;
}
}