|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* WebHemi. |
|
4
|
|
|
* |
|
5
|
|
|
* PHP version 7.1 |
|
6
|
|
|
* |
|
7
|
|
|
* @copyright 2012 - 2017 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
|
|
|
declare(strict_types = 1); |
|
13
|
|
|
|
|
14
|
|
|
namespace WebHemi\Application\ServiceAdapter; |
|
15
|
|
|
|
|
16
|
|
|
use Throwable; |
|
17
|
|
|
use WebHemi\Application\ServiceInterface; |
|
18
|
|
|
use WebHemi\DependencyInjection\ServiceInterface as DependencyInjectionInterface; |
|
19
|
|
|
use WebHemi\Http\ResponseInterface; |
|
20
|
|
|
use WebHemi\Http\ServerRequestInterface; |
|
21
|
|
|
use WebHemi\Middleware\Common as CommonMiddleware; |
|
22
|
|
|
use WebHemi\Middleware\MiddlewareInterface; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* Class AbstractAdapter |
|
26
|
|
|
*/ |
|
27
|
|
|
abstract class AbstractAdapter implements ServiceInterface |
|
28
|
|
|
{ |
|
29
|
|
|
/** @var DependencyInjectionInterface */ |
|
30
|
|
|
protected $container; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* ServiceAdapter constructor. |
|
34
|
|
|
* |
|
35
|
|
|
* @param DependencyInjectionInterface $container |
|
36
|
|
|
*/ |
|
37
|
6 |
|
public function __construct(DependencyInjectionInterface $container) |
|
38
|
|
|
{ |
|
39
|
6 |
|
$this->container = $container; |
|
40
|
6 |
|
} |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* Runs the application. This is where the magic happens. |
|
44
|
|
|
* According tho the environment settings this must build up the middleware pipeline and execute it. |
|
45
|
|
|
* |
|
46
|
|
|
* a Pre-Routing Middleware can be; priority < 0: |
|
47
|
|
|
* - LockCheck - check if the client IP is banned > S102|S403 |
|
48
|
|
|
* - Auth - if the user is not logged in, but there's a "Remember me" cookie, then logs in > S102 |
|
49
|
|
|
* |
|
50
|
|
|
* Routing Middleware is fixed (RoutingMiddleware::class); priority = 0: |
|
51
|
|
|
* - A middleware that routes the incoming Request and delegates to the matched middleware. > S102|S404|S405 |
|
52
|
|
|
* The RouteResult should be attached to the Request. |
|
53
|
|
|
* If the Routing is not defined explicitly in the pipeline, then it will be injected with priority 0. |
|
54
|
|
|
* |
|
55
|
|
|
* a Post-Routing Middleware can be; priority between 0 and 100: |
|
56
|
|
|
* - Acl - checks if the given route is available for the client. Also checks the auth > S102|S401|S403 |
|
57
|
|
|
* - CacheReader - checks if a suitable response body is cached. > S102|S200 |
|
58
|
|
|
* |
|
59
|
|
|
* Dispatcher Middleware is fixed (DispatcherMiddleware::class); priority = 100: |
|
60
|
|
|
* - A middleware which gets the corresponding Action middleware and applies it > S102 |
|
61
|
|
|
* If the Dispatcher is not defined explicitly in the pipeline, then it will be injected with priority 100. |
|
62
|
|
|
* The Dispatcher should not set the response Status Code to 200 to let Post-Dispatchers to be called. |
|
63
|
|
|
* |
|
64
|
|
|
* a Post-Dispatch Middleware can be; priority > 100: |
|
65
|
|
|
* - CacheWriter - writes response body into DataStorage (DB, File etc.) > S102 |
|
66
|
|
|
* |
|
67
|
|
|
* Final Middleware is fixed (FinalMiddleware:class): |
|
68
|
|
|
* - This middleware behaves a bit differently. It cannot be ordered, it's always the last called middleware: |
|
69
|
|
|
* - when the middleware pipeline reached its end (typically when the Status Code is still 102) |
|
70
|
|
|
* - when one item of the middleware pipeline returns with return response (status code is set to 200|40*|500) |
|
71
|
|
|
* - when during the pipeline process an Exception is thrown. |
|
72
|
|
|
* |
|
73
|
|
|
* When the middleware pipeline is finished the application prints the header and the output. |
|
74
|
|
|
* |
|
75
|
|
|
* If a middleware other than the Routing, Dispatcher and Final Middleware has no priority set, it will be |
|
76
|
|
|
* considered to have priority = 50. |
|
77
|
|
|
* |
|
78
|
|
|
* @return void |
|
79
|
|
|
*/ |
|
80
|
|
|
abstract public function run() : void; |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* Gets the Request object. |
|
84
|
|
|
* |
|
85
|
|
|
* @return ServerRequestInterface |
|
86
|
|
|
*/ |
|
87
|
|
|
abstract protected function getRequest() : ServerRequestInterface; |
|
88
|
|
|
|
|
89
|
|
|
/** |
|
90
|
|
|
* Gets the Response object. |
|
91
|
|
|
* |
|
92
|
|
|
* @return ResponseInterface |
|
93
|
|
|
*/ |
|
94
|
|
|
abstract protected function getResponse() : ResponseInterface; |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Instantiates and invokes a middleware |
|
98
|
|
|
* |
|
99
|
|
|
* @param string $middlewareClass |
|
100
|
|
|
* @param ServerRequestInterface $request |
|
101
|
|
|
* @param ResponseInterface $response |
|
102
|
|
|
* @return void |
|
103
|
|
|
*/ |
|
104
|
5 |
|
protected function invokeMiddleware( |
|
105
|
|
|
string $middlewareClass, |
|
106
|
|
|
ServerRequestInterface&$request, |
|
107
|
|
|
ResponseInterface&$response |
|
108
|
|
|
) : void { |
|
109
|
|
|
try { |
|
110
|
|
|
/** @var MiddlewareInterface $middleware */ |
|
111
|
5 |
|
$middleware = $this->container->get($middlewareClass); |
|
112
|
5 |
|
$requestAttributes = $request->getAttributes(); |
|
113
|
|
|
|
|
114
|
|
|
// As an extra step if an action middleware is resolved, it should be invoked by the dispatcher. |
|
115
|
5 |
|
if (isset($requestAttributes[ServerRequestInterface::REQUEST_ATTR_RESOLVED_ACTION_CLASS]) |
|
116
|
|
|
&& ($middleware instanceof CommonMiddleware\DispatcherMiddleware |
|
117
|
5 |
|
|| $middleware instanceof CommonMiddleware\CliDispatcherMiddleware |
|
|
|
|
|
|
118
|
|
|
) |
|
119
|
|
|
) { |
|
120
|
|
|
/** @var MiddlewareInterface $actionMiddleware */ |
|
121
|
3 |
|
$actionMiddleware = $this->container |
|
122
|
3 |
|
->get($requestAttributes[ServerRequestInterface::REQUEST_ATTR_RESOLVED_ACTION_CLASS]); |
|
123
|
3 |
|
$request = $request->withAttribute( |
|
124
|
3 |
|
ServerRequestInterface::REQUEST_ATTR_ACTION_MIDDLEWARE, |
|
125
|
|
|
$actionMiddleware |
|
126
|
|
|
); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
5 |
|
$middleware($request, $response); |
|
130
|
4 |
|
} catch (Throwable $exception) { |
|
131
|
4 |
|
$code = ResponseInterface::STATUS_INTERNAL_SERVER_ERROR; |
|
132
|
|
|
|
|
133
|
4 |
|
if (in_array( |
|
134
|
4 |
|
$exception->getCode(), |
|
135
|
|
|
[ |
|
136
|
4 |
|
ResponseInterface::STATUS_FORBIDDEN, |
|
137
|
4 |
|
ResponseInterface::STATUS_NOT_FOUND, |
|
138
|
4 |
|
ResponseInterface::STATUS_BAD_METHOD, |
|
139
|
4 |
|
ResponseInterface::STATUS_NOT_IMPLEMENTED, |
|
140
|
|
|
] |
|
141
|
|
|
)) { |
|
142
|
3 |
|
$code = $exception->getCode(); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
4 |
|
$response = $response->withStatus($code); |
|
146
|
4 |
|
$request = $request->withAttribute( |
|
147
|
4 |
|
ServerRequestInterface::REQUEST_ATTR_MIDDLEWARE_EXCEPTION, |
|
148
|
|
|
$exception |
|
149
|
|
|
); |
|
150
|
|
|
} |
|
151
|
5 |
|
} |
|
152
|
|
|
} |
|
153
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.