Completed
Push — master ( 6fd9b2...303fc6 )
by Rasmus
02:00
created

Dispatcher   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 96%

Importance

Changes 5
Bugs 0 Features 2
Metric Value
wmc 8
c 5
b 0
f 2
lcom 1
cbo 0
dl 0
loc 80
ccs 24
cts 25
cp 0.96
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
     */
33 1
    public function __construct(array $stack, callable $resolver = null)
34
    {
35 1
        $this->stack = $stack;
36 1
        $this->resolver = $resolver;
37 1
    }
38
39
    /**
40
     * @param RequestInterface  $request
41
     * @param ResponseInterface $response
42
     *
43
     * @return ResponseInterface
44
     */
45 1
    public function dispatch(RequestInterface $request, ResponseInterface $response)
46
    {
47 1
        $resolved = $this->resolve(0);
48
49 1
        return $resolved($request, $response);
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55 1
    public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
56
    {
57 1
        return $next($request, $this->dispatch($request, $response));
58
    }
59
60
    /**
61
     * @param int $index middleware stack index
62
     *
63
     * @return callable function (RequestInterface $request, ResponseInterface $response): ResponseInterface
64
     */
65 1
    private function resolve($index)
66
    {
67 1
        if (isset($this->stack[$index])) {
68
            return function (RequestInterface $request, ResponseInterface $response) use ($index) {
69 1
                if (!isset($this->resolved[$index])) {
70 1
                    $this->resolved[$index] = $this->resolver
71 1
                        ? call_user_func($this->resolver, $this->stack[$index])
72 1
                        : $this->stack[$index]; // as-is
73 1
                }
74
75 1
                $middleware = $this->resolved[$index];
76
77 1
                $result = $middleware($request, $response, $this->resolve($index + 1));
78
79 1
                if (!$result instanceof ResponseInterface) {
80
                    throw new LogicException("unexpected middleware result");
81
                }
82
83 1
                return $result;
84 1
            };
85
        }
86
87 1
        return function (RequestInterface $request, ResponseInterface $response) {
88 1
            return $response;
89 1
        };
90
    }
91
}
92