Passed
Push — fix_bc_break ( 0db1fe )
by Koldo
03:23
created

ReactApplication::patch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\React;
6
7
use Antidot\Application\Http\Application;
8
use Antidot\Application\Http\Response\ErrorResponseGenerator;
9
use Antidot\Application\Http\RouteFactory;
10
use Antidot\Application\Http\Router;
11
use Antidot\Container\MiddlewareFactory;
12
use Psr\Http\Message\ResponseInterface;
13
use Psr\Http\Message\ServerRequestInterface;
14
use Psr\Http\Server\MiddlewareInterface;
15
use Psr\Http\Server\RequestHandlerInterface;
16
use Ramsey\Uuid\Uuid;
17
use React\Promise\PromiseInterface;
18
use RuntimeException;
19
use Throwable;
20
use function React\Promise\resolve;
21
22
class ReactApplication implements Application, RequestHandlerInterface, MiddlewareInterface
23
{
24
    private MiddlewarePipeline $pipeline;
25
    private Router $router;
26
    private MiddlewareFactory $middlewareFactory;
27
    private RouteFactory $routeFactory;
28
    private ErrorResponseGenerator $errorResponseGenerator;
29
30 13
    public function __construct(
31
        MiddlewarePipeline $pipeline,
32
        Router $router,
33
        MiddlewareFactory $middlewareFactory,
34
        RouteFactory $routeFactory,
35
        ErrorResponseGenerator $errorResponseGenerator
36
    ) {
37 13
        $this->routeFactory = $routeFactory;
38 13
        $this->middlewareFactory = $middlewareFactory;
39 13
        $this->router = $router;
40 13
        $this->pipeline = $pipeline;
41 13
        $this->errorResponseGenerator = $errorResponseGenerator;
42 13
    }
43
44 1
    public function pipe(string $middlewareName): void
45
    {
46 1
        $this->pipeline->pipe($this->middlewareFactory->create($middlewareName));
47 1
    }
48
49 1
    public function get(string $uri, array $middleware, string $name): void
50
    {
51 1
        $this->route($uri, $middleware, ['GET'], $name);
52 1
    }
53
54 1
    public function post(string $uri, array $middleware, string $name): void
55
    {
56 1
        $this->route($uri, $middleware, ['POST'], $name);
57 1
    }
58
59 1
    public function patch(string $uri, array $middleware, string $name): void
60
    {
61 1
        $this->route($uri, $middleware, ['PATCH'], $name);
62 1
    }
63
64 1
    public function put(string $uri, array $middleware, string $name): void
65
    {
66 1
        $this->route($uri, $middleware, ['PUT'], $name);
67 1
    }
68
69 1
    public function delete(string $uri, array $middleware, string $name): void
70
    {
71 1
        $this->route($uri, $middleware, ['DELETE'], $name);
72 1
    }
73
74 1
    public function options(string $uri, array $middleware, string $name): void
75
    {
76 1
        $this->route($uri, $middleware, ['OPTIONS'], $name);
77 1
    }
78
79 6
    public function route(string $uri, array $middleware, array $methods, string $name): void
80
    {
81 6
        $this->router->append(
82 6
            $this->routeFactory->create($methods, $middleware, $uri, $name)
83
        );
84 6
    }
85
86 2
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
87
    {
88 2
        return new PromiseResponse(resolve($request)
89 2
            ->then(
90 2
                function (ServerRequestInterface $request) use ($handler): PromiseInterface {
91 2
                    $response = new PromiseResponse(
92 2
                        resolve($request)
93 2
                            ->then(static function (ServerRequestInterface $request): ServerRequestInterface {
94 2
                                return $request->withAttribute('request_id', Uuid::uuid4()->toString());
95 2
                            })
96 2
                            ->then(function (ServerRequestInterface $request) use ($handler): ResponseInterface {
97
                                try {
98 2
                                    return $this->pipeline->process($request, $handler);
99 1
                                } catch (Throwable $exception) {
100 1
                                    return $this->errorResponseGenerator->__invoke($exception);
101
                                }
102 2
                            })
103
                    );
104
105 2
                    return resolve($response);
106 2
                }
107
            ));
108
    }
109
110 2
    public function handle(ServerRequestInterface $request): ResponseInterface
111
    {
112 2
        return new PromiseResponse(resolve($request)
113 2
            ->then(
114 2
                function (ServerRequestInterface $request): PromiseInterface {
115 2
                    $response = new PromiseResponse(
116 2
                        resolve($request)
117 2
                            ->then(static function (ServerRequestInterface $request): ServerRequestInterface {
118 2
                                return $request->withAttribute('request_id', Uuid::uuid4()->toString());
119 2
                            })
120 2
                            ->then(function (ServerRequestInterface $request): ResponseInterface {
121
                                try {
122 2
                                    return $this->pipeline->handle($request);
123 1
                                } catch (Throwable $exception) {
124 1
                                    return $this->errorResponseGenerator->__invoke($exception);
125
                                }
126 2
                            })
127
                    );
128
129 2
                    return resolve($response);
130 2
                }
131
            ));
132
    }
133
134 1
    public function run(): void
135
    {
136 1
        throw new RuntimeException('You can\'t run application out of React PHP server.');
137
    }
138
}
139