1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Tebe\Pvc; |
||||
6 | |||||
7 | use Psr\Http\Message\ResponseInterface; |
||||
8 | use Psr\Http\Message\ServerRequestInterface; |
||||
9 | use Psr\Http\Server\MiddlewareInterface; |
||||
10 | use Tebe\Pvc\Event\EventDispatcher; |
||||
11 | use Tebe\Pvc\Event\EventHandler; |
||||
12 | use Tebe\Pvc\Helper\UrlHelper; |
||||
13 | use Tebe\Pvc\Middleware\MiddlewarePipe; |
||||
14 | use Tebe\Pvc\Middleware\RequestHandler; |
||||
15 | use Tebe\Pvc\View\ViewExtension; |
||||
16 | use Tebe\Pvc\View\ViewHelpers; |
||||
17 | use Tebe\Pvc\View\View; |
||||
18 | |||||
19 | class Application |
||||
20 | { |
||||
21 | /** |
||||
22 | * @var static |
||||
23 | */ |
||||
24 | private static $instance; |
||||
25 | |||||
26 | /** |
||||
27 | * @var Config |
||||
28 | */ |
||||
29 | private $config; |
||||
30 | |||||
31 | /** |
||||
32 | * @var ServerRequestInterface |
||||
33 | */ |
||||
34 | private $request; |
||||
35 | |||||
36 | /** |
||||
37 | * @var View |
||||
38 | */ |
||||
39 | private $view; |
||||
40 | |||||
41 | /** |
||||
42 | * @var array |
||||
43 | */ |
||||
44 | private $viewExtensions; |
||||
45 | |||||
46 | /** |
||||
47 | * @var MiddlewareInterface[] |
||||
48 | */ |
||||
49 | private $middlewares; |
||||
50 | |||||
51 | /** |
||||
52 | * @var EventDispatcher |
||||
53 | */ |
||||
54 | private $eventDispatcher; |
||||
55 | |||||
56 | /** |
||||
57 | * Application constructor. |
||||
58 | */ |
||||
59 | private function __construct() |
||||
60 | { |
||||
61 | $this->setEventDispatcher(new EventDispatcher()); |
||||
62 | $this->setMiddlewares([]); |
||||
63 | } |
||||
64 | |||||
65 | /** |
||||
66 | * @return Application |
||||
67 | */ |
||||
68 | public static function instance(): Application |
||||
69 | { |
||||
70 | if (is_null(static::$instance)) { |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
71 | static::$instance = new static(); |
||||
72 | } |
||||
73 | return static::$instance; |
||||
74 | } |
||||
75 | |||||
76 | /** |
||||
77 | * @param array $config |
||||
78 | * @return Application |
||||
79 | */ |
||||
80 | public function setConfig(array $config) |
||||
81 | { |
||||
82 | $this->config = new Config($config); |
||||
83 | return $this; |
||||
84 | } |
||||
85 | |||||
86 | /** |
||||
87 | * @return Config |
||||
88 | */ |
||||
89 | public function getConfig(): Config |
||||
90 | { |
||||
91 | return $this->config; |
||||
92 | } |
||||
93 | |||||
94 | /** |
||||
95 | * @param ServerRequestInterface $request |
||||
96 | * @return Application |
||||
97 | */ |
||||
98 | public function setRequest(ServerRequestInterface $request) |
||||
99 | { |
||||
100 | $this->request = $request; |
||||
101 | return $this; |
||||
102 | } |
||||
103 | |||||
104 | /** |
||||
105 | * @return ServerRequestInterface |
||||
106 | */ |
||||
107 | public function getRequest(): ServerRequestInterface |
||||
108 | { |
||||
109 | return $this->request; |
||||
110 | } |
||||
111 | |||||
112 | /** |
||||
113 | * @param View $view |
||||
114 | * @return Application |
||||
115 | */ |
||||
116 | public function setView(View $view) |
||||
117 | { |
||||
118 | $this->view = $view; |
||||
119 | return $this; |
||||
120 | } |
||||
121 | |||||
122 | /** |
||||
123 | * @return View |
||||
124 | * @throws Exception\SystemException |
||||
125 | */ |
||||
126 | public function getView(): View |
||||
127 | { |
||||
128 | if (is_null($this->view)) { |
||||
129 | $viewsPath = $this->config->get('viewsPath'); |
||||
130 | $helpers = new ViewHelpers(); |
||||
131 | $view = new View($viewsPath, $helpers); |
||||
0 ignored issues
–
show
It seems like
$viewsPath can also be of type null ; however, parameter $viewsPath of Tebe\Pvc\View\View::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
132 | |||||
133 | // TODO move to own ViewExtension class |
||||
134 | $view->registerHelper('escape', function (string $string) { |
||||
135 | return htmlspecialchars($string); |
||||
136 | }); |
||||
137 | $view->registerHelper('url', function ($args) { |
||||
138 | return UrlHelper::to($args); |
||||
139 | }); |
||||
140 | |||||
141 | foreach ($this->viewExtensions as $viewExtension) { |
||||
142 | $view->registerExtension($viewExtension); |
||||
143 | } |
||||
144 | |||||
145 | $this->setView($view); |
||||
146 | } |
||||
147 | return $this->view; |
||||
148 | } |
||||
149 | |||||
150 | /** |
||||
151 | * @param MiddlewareInterface $middleware |
||||
152 | * @return $this |
||||
153 | */ |
||||
154 | public function addMiddleware(MiddlewareInterface $middleware): Application |
||||
155 | { |
||||
156 | $this->middlewares[] = $middleware; |
||||
157 | return $this; |
||||
158 | } |
||||
159 | |||||
160 | /** |
||||
161 | * @param MiddlewareInterface[] $middlewares |
||||
162 | * @return Application |
||||
163 | */ |
||||
164 | public function setMiddlewares(array $middlewares): Application |
||||
165 | { |
||||
166 | foreach ($middlewares as $middleware) { |
||||
167 | $this->addMiddleware($middleware); |
||||
168 | } |
||||
169 | return $this; |
||||
170 | } |
||||
171 | |||||
172 | /** |
||||
173 | * @param EventDispatcher $eventDispatcher |
||||
174 | * @return Application |
||||
175 | */ |
||||
176 | public function setEventDispatcher(EventDispatcher $eventDispatcher) |
||||
177 | { |
||||
178 | $this->eventDispatcher = $eventDispatcher; |
||||
179 | return $this; |
||||
180 | } |
||||
181 | |||||
182 | /** |
||||
183 | * @return EventDispatcher |
||||
184 | */ |
||||
185 | public function getEventDispatcher(): EventDispatcher |
||||
186 | { |
||||
187 | return $this->eventDispatcher; |
||||
188 | } |
||||
189 | |||||
190 | /** |
||||
191 | * @param string $eventName |
||||
192 | * @param EventHandler $eventHandler |
||||
193 | * @return $this |
||||
194 | */ |
||||
195 | public function addEventHandler(string $eventName, EventHandler $eventHandler): Application |
||||
196 | { |
||||
197 | $this->eventDispatcher->addHandler($eventName, $eventHandler); |
||||
198 | return $this; |
||||
199 | } |
||||
200 | |||||
201 | /** |
||||
202 | * @throws Exception\SystemException |
||||
203 | */ |
||||
204 | public function run(): void |
||||
205 | { |
||||
206 | $request = $this->getRequest(); |
||||
207 | $requestHandler = $this->getRequestHandler(); |
||||
208 | $middlewarePipe = $this->getMiddlewarePipe(); |
||||
209 | $response = $middlewarePipe->process($request, $requestHandler); |
||||
210 | $this->emit($response); |
||||
211 | } |
||||
212 | |||||
213 | /** |
||||
214 | * @param ResponseInterface $response |
||||
215 | */ |
||||
216 | private function emit(ResponseInterface $response): void |
||||
217 | { |
||||
218 | $statusCode = $response->getStatusCode(); |
||||
219 | |||||
220 | http_response_code($statusCode); |
||||
221 | |||||
222 | foreach ($response->getHeaders() as $k => $values) { |
||||
223 | foreach ($values as $v) { |
||||
224 | header(sprintf('%s: %s', $k, $v), false); |
||||
225 | } |
||||
226 | } |
||||
227 | |||||
228 | echo $response->getBody(); |
||||
229 | } |
||||
230 | |||||
231 | /** |
||||
232 | * @return RequestHandler |
||||
233 | * @throws Exception\SystemException |
||||
234 | */ |
||||
235 | private function getRequestHandler(): RequestHandler |
||||
236 | { |
||||
237 | $view = $this->getView(); |
||||
238 | $controllersPath = $this->getConfig()->get('controllersPath'); |
||||
239 | $requestHandler = new RequestHandler($view, $controllersPath); |
||||
0 ignored issues
–
show
It seems like
$controllersPath can also be of type null ; however, parameter $controllersPath of Tebe\Pvc\Middleware\RequestHandler::__construct() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
240 | return $requestHandler; |
||||
241 | } |
||||
242 | |||||
243 | /** |
||||
244 | * @return MiddlewarePipe |
||||
245 | */ |
||||
246 | private function getMiddlewarePipe(): MiddlewarePipe |
||||
247 | { |
||||
248 | $middlewarePipe = MiddlewarePipe::create($this->middlewares); |
||||
249 | return $middlewarePipe; |
||||
250 | } |
||||
251 | |||||
252 | /** |
||||
253 | * @param ViewExtension[] $viewExtensions |
||||
254 | * @return Application |
||||
255 | */ |
||||
256 | public function setViewExtensions(array $viewExtensions) |
||||
257 | { |
||||
258 | $this->viewExtensions = $viewExtensions; |
||||
259 | return $this; |
||||
260 | } |
||||
261 | } |
||||
262 |