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

Dispatcher::resolve()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0061

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 26
ccs 15
cts 16
cp 0.9375
rs 8.439
cc 5
eloc 14
nc 2
nop 1
crap 5.0061
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