Passed
Push — master ( a14261...5f8bab )
by Gabor
05:22
created

AbstractAdapter::__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 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
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
0 ignored issues
show
Bug introduced by
The class WebHemi\Middleware\Common\CliDispatcherMiddleware does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to 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 require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
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