Completed
Push — master ( 303fc6...bad7bd )
by Rasmus
01:48
created

Dispatcher   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 88
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 0 Features 2
Metric Value
wmc 8
c 6
b 0
f 2
lcom 1
cbo 0
dl 0
loc 88
ccs 25
cts 25
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A dispatch() 0 6 1
A __invoke() 0 4 1
B resolve() 0 26 5
1
<?php
2
3
namespace mindplay\middleman;
4
5
use LogicException;
6
use Psr\Http\Message\RequestInterface;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * PSR-7 middleware dispatcher
11
 */
12
class Dispatcher implements MiddlewareInterface
13
{
14
    /**
15
     * @var callable middleware resolver
16
     */
17
    private $resolver;
18
19
    /**
20
     * @var mixed[] unresolved middleware stack
21
     */
22
    private $stack;
23
24
    /**
25
     * @var (callable|MiddlewareInterface)[] resolved middleware stack
26
     */
27
    private $resolved = [];
28
29
    /**
30
     * @param (callable|MiddlewareInterface|mixed)[] $stack middleware stack
31
     * @param callable|null $resolver optional middleware resolver:
32
     *                                function (string $name): MiddlewareInterface
33
     */
34 1
    public function __construct(array $stack, callable $resolver = null)
35
    {
36 1
        $this->stack = $stack;
37 1
        $this->resolver = $resolver;
38 1
    }
39
40
    /**
41
     * Dispatches the middleware stack and returns the resulting `ResponseInterface`.
42
     *
43
     * @param RequestInterface  $request
44
     * @param ResponseInterface $response
45
     *
46
     * @return ResponseInterface
47
     * 
48
     * @throws LogicException on unexpected result from any middleware on the stack
49
     */
50 1
    public function dispatch(RequestInterface $request, ResponseInterface $response)
51
    {
52 1
        $resolved = $this->resolve(0);
53
54 1
        return $resolved($request, $response);
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60 1
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
61
    {
62 1
        return $next($request, $this->dispatch($request, $response));
63
    }
64
65
    /**
66
     * @param int $index middleware stack index
67
     *
68
     * @return callable middleware delegate:
69
     *         function (RequestInterface $request, ResponseInterface $response): ResponseInterface
70
     *                  
71
     * @throws LogicException on unexpected middleware result
72
     */
73 1
    private function resolve($index)
74
    {
75 1
        if (isset($this->stack[$index])) {
76
            return function (RequestInterface $request, ResponseInterface $response) use ($index) {
77 1
                if (!isset($this->resolved[$index])) {
78 1
                    $this->resolved[$index] = $this->resolver
79 1
                        ? call_user_func($this->resolver, $this->stack[$index])
80 1
                        : $this->stack[$index]; // as-is
81 1
                }
82
83 1
                $middleware = $this->resolved[$index];
84
85 1
                $result = $middleware($request, $response, $this->resolve($index + 1));
86
87 1
                if (!$result instanceof ResponseInterface) {
88 1
                    throw new LogicException("unexpected middleware result");
89
                }
90
91 1
                return $result;
92 1
            };
93
        }
94
95 1
        return function (RequestInterface $request, ResponseInterface $response) {
96 1
            return $response;
97 1
        };
98
    }
99
}
100