Completed
Push — master ( be05e4...11542d )
by Taosikai
13:50
created

Dispatcher::decorateCallableMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/*
3
 * This file is part of the slince/middleware package.
4
 *
5
 * (c) Slince <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Slince\Middleware;
12
13
use Interop\Http\Server\MiddlewareInterface;
14
use Interop\Http\Server\RequestHandlerInterface;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Slince\Middleware\Exception\MissingResponseException;
18
19
class Dispatcher
20
{
21
    /**
22
     * @var \SplQueue
23
     */
24
    public $middlewares;
25
26
    public function __construct($middlewares = [])
27
    {
28
        $this->middlewares = new \SplQueue();
29
        foreach ((array) $middlewares as $middleware) {
30
            $this->push($middleware);
31
        }
32
    }
33
34
    /**
35
     * Add a middleware to the queue.
36
     *
37
     * @param callable|MiddlewareInterface $middleware
38
     */
39
    public function push($middleware)
40
    {
41
        if (is_callable($middleware)) {
42
            $middleware = static::decorateCallableMiddleware($middleware);
43
        }
44
        $this->middlewares->enqueue($middleware);
45
    }
46
47
    /**
48
     * Get all middlewares.
49
     *
50
     * @return MiddlewareInterface[]
51
     */
52
    public function all()
53
    {
54
        $middlewares = [];
55
        foreach ($this->middlewares as $middleware) {
56
            $middlewares[] = $middleware;
57
        }
58
59
        return $middlewares;
60
    }
61
62
    /**
63
     * Dispatch the request to the middlewares and get psr7 response.
64
     *
65
     * @param ServerRequestInterface $request
66
     *
67
     * @throws MissingResponseException
68
     *
69
     * @return ResponseInterface
70
     */
71
    public function process(ServerRequestInterface $request): ResponseInterface
72
    {
73
        $response = $this->resolve()->handle($request);
74
        if (!$response instanceof ResponseInterface) {
75
            throw new MissingResponseException('Last middleware executed did not return a response.');
76
        }
77
78
        return $response;
79
    }
80
81
    /**
82
     * @return Delegate
83
     */
84
    protected function resolve(): RequestHandlerInterface
85
    {
86
        return new Delegate(function($request){
87
            if (!$this->middlewares->isEmpty()) {
88
                $middleware = $this->middlewares->dequeue();
89
                $response = $middleware->process($request, $this->resolve());
90
                if (!$response instanceof ResponseInterface) {
91
                    throw new MissingResponseException(sprintf('Unexpected middleware result: %s', gettype($response)));
92
                }
93
94
                return $response;
95
            } else {
96
                throw new MissingResponseException( 'The queue was exhausted, with no response returned');
97
            }
98
        });
99
    }
100
101
    protected static function decorateCallableMiddleware(callable $middleware): CallableMiddleware
102
    {
103
        return new CallableMiddleware($middleware);
104
    }
105
}