Passed
Push — master ( 1f40d1...402cf9 )
by Alexander
02:17
created

MiddlewareDispatcher   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 18
c 1
b 0
f 0
dl 0
loc 69
ccs 20
cts 20
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A hasMiddlewares() 0 3 1
A __construct() 0 4 1
A dispatch() 0 7 2
A withMiddlewares() 0 7 1
A buildMiddlewares() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Middleware\Dispatcher;
6
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
12
final class MiddlewareDispatcher
13
{
14
    /**
15
     * Contains a stack of middleware handler.
16
     *
17
     * @var MiddlewareStackInterface stack of middleware
18
     */
19
    private MiddlewareStackInterface $stack;
20
21
    private MiddlewareFactoryInterface $middlewareFactory;
22
23
    /**
24
     * @var array[]|callable[]|string[]
25
     */
26
    private array $middlewareDefinitions = [];
27
28 11
    public function __construct(MiddlewareFactoryInterface $middlewareFactory, MiddlewareStackInterface $stack)
29
    {
30 11
        $this->middlewareFactory = $middlewareFactory;
31 11
        $this->stack = $stack;
32 11
    }
33
34 8
    public function dispatch(ServerRequestInterface $request, RequestHandlerInterface $fallbackHandler): ResponseInterface
35
    {
36 8
        if ($this->stack->isEmpty()) {
37 8
            $this->stack = $this->stack->build($this->buildMiddlewares(), $fallbackHandler);
38
        }
39
40 8
        return $this->stack->handle($request);
41
    }
42
43
    /**
44
     * Returns new instance with middleware handlers replaced.
45
     * Last specified handler will be executed first.
46
     *
47
     * @param array[]|callable[]|string[] $middlewareDefinitions Each array element is a name of PSR-15 middleware,
48
     * a callable with `function(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface`
49
     * signature or a handler action (an array of [handlerClass, handlerMethod]). For handler action and callable
50
     * typed parameters are automatically injected using dependency injection container passed to the route.
51
     * Current request and handler could be obtained by type-hinting for {@see ServerRequestInterface}
52
     * and {@see RequestHandlerInterface}.
53
     *
54
     * @return self
55
     */
56 11
    public function withMiddlewares(array $middlewareDefinitions): self
57
    {
58 11
        $clone = clone $this;
59 11
        $clone->middlewareDefinitions = $middlewareDefinitions;
60 11
        $clone->stack->reset();
61
62 11
        return $clone;
63
    }
64
65 2
    public function hasMiddlewares(): bool
66
    {
67 2
        return $this->middlewareDefinitions !== [];
68
    }
69
70
    /**
71
     * @return MiddlewareInterface[]
72
     */
73 8
    private function buildMiddlewares(): array
74
    {
75 8
        $middlewares = [];
76 8
        foreach ($this->middlewareDefinitions as $middlewareDefinition) {
77 8
            $middlewares[] = $this->middlewareFactory->create($middlewareDefinition);
78
        }
79
80 8
        return $middlewares;
81
    }
82
}
83