Passed
Pull Request — master (#10)
by Dmitriy
01:59
created

MiddlewareStack::__construct()   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 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
eloc 1
cc 1
crap 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Middleware\Dispatcher;
6
7
use Psr\EventDispatcher\EventDispatcherInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\MiddlewareInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Yiisoft\Middleware\Dispatcher\Event\AfterMiddleware;
13
use Yiisoft\Middleware\Dispatcher\Event\BeforeMiddleware;
14
15
final class MiddlewareStack implements MiddlewareStackInterface
16
{
17
    /**
18
     * Contains a stack of middleware wrapped in handlers.
19
     * Each handler points to the handler of middleware that will be processed next.
20
     *
21
     * @var RequestHandlerInterface|null stack of middleware
22
     */
23
    private ?RequestHandlerInterface $stack = null;
24
25
    private EventDispatcherInterface $eventDispatcher;
26
27 6
    public function __construct(EventDispatcherInterface $eventDispatcher)
28
    {
29 6
        $this->eventDispatcher = $eventDispatcher;
30 6
    }
31
32 6
    public function build(array $middlewares, RequestHandlerInterface $fallbackHandler): MiddlewareStackInterface
33
    {
34 6
        $handler = $fallbackHandler;
35 6
        foreach ($middlewares as $middleware) {
36 6
            $handler = $this->wrap($middleware, $handler);
37
        }
38
39 6
        $new = clone $this;
40 6
        $new->stack = $handler;
41
42 6
        return $new;
43
    }
44
45 6
    public function handle(ServerRequestInterface $request): ResponseInterface
46
    {
47 6
        if ($this->isEmpty()) {
48
            throw new \RuntimeException('Stack is empty.');
49
        }
50
51 6
        return $this->stack->handle($request);
52
    }
53
54 6
    public function reset(): void
55
    {
56 6
        $this->stack = null;
57 6
    }
58
59 6
    public function isEmpty(): bool
60
    {
61 6
        return $this->stack === null;
62
    }
63
64
    /**
65
     * Wraps handler by middlewares
66
     */
67 6
    private function wrap(MiddlewareInterface $middleware, RequestHandlerInterface $handler): RequestHandlerInterface
68
    {
69 6
        return new class($middleware, $handler, $this->eventDispatcher) implements RequestHandlerInterface {
70
            private MiddlewareInterface $middleware;
71
            private RequestHandlerInterface $handler;
72
            private EventDispatcherInterface $eventDispatcher;
73
74
            public function __construct(MiddlewareInterface $middleware, RequestHandlerInterface $handler, EventDispatcherInterface $eventDispatcher)
75
            {
76 6
                $this->middleware = $middleware;
77 6
                $this->handler = $handler;
78 6
                $this->eventDispatcher = $eventDispatcher;
79 6
            }
80
81
            public function handle(ServerRequestInterface $request): ResponseInterface
82
            {
83 6
                $this->eventDispatcher->dispatch(new BeforeMiddleware($this->middleware, $request));
84
85 6
                $response = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
86
                try {
87 6
                    return $response = $this->middleware->process($request, $this->handler);
88
                } finally {
89 6
                    $this->eventDispatcher->dispatch(new AfterMiddleware($this->middleware, $response));
90
                }
91
            }
92
        };
93
    }
94
}
95