Dispatcher::push()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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