Bamboo   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 1
dl 0
loc 83
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A push() 0 4 1
A dispatch() 0 6 1
A __invoke() 0 4 1
B processMiddleware() 0 24 4
1
<?php
2
3
namespace Cormy\Server;
4
5
use Generator;
6
use Throwable;
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
10
/**
11
 * Bamboo style PSR-7 middleware pipe.
12
 */
13
class Bamboo implements MiddlewareInterface
14
{
15
    /**
16
     * @var (callable|MiddlewareInterface)[]
17
     */
18
    protected $nodes = [];
19
20
    /**
21
     * Bamboo style PSR-7 middleware pipe.
22
     *
23
     * @param (callable|MiddlewareInterface)[] $nodes the middlewares, which requests pass through
24
     */
25
    public function __construct(array $nodes)
26
    {
27
        array_map([$this, 'push'], $nodes);
28
    }
29
30
    /**
31
     * Push a middleware onto the end of $nodes type safe.
32
     *
33
     * @param callable|MiddlewareInterface $middleware
34
     */
35
    private function push(callable $middleware)
36
    {
37
        $this->nodes[] = $middleware;
38
    }
39
40
    /**
41
     * Process an incoming server request and return the response.
42
     *
43
     * @param ServerRequestInterface           $request
44
     * @param callable|RequestHandlerInterface $finalHandler
45
     *
46
     * @return ResponseInterface
47
     */
48
    public function dispatch(ServerRequestInterface $request, callable $finalHandler):ResponseInterface
49
    {
50
        $dispatcher = new MiddlewareDispatcher($this, $finalHandler);
51
52
        return $dispatcher($request);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function __invoke(ServerRequestInterface $request):Generator
59
    {
60
        return $this->processMiddleware(0, $request);
61
    }
62
63
    /**
64
     * Process an incoming server request by delegating it to the middleware specified by $index.
65
     *
66
     * @param int                    $index   the $nodes index
67
     * @param ServerRequestInterface $request
68
     *
69
     * @return Generator
70
     */
71
    protected function processMiddleware(int $index, ServerRequestInterface $request):Generator
72
    {
73
        if (!array_key_exists($index, $this->nodes)) {
74
            $response = (yield $request);
75
76
            return $response;
77
        }
78
79
        $current = $this->nodes[$index]($request);
80
        $nextIndex = $index + 1;
81
82
        while ($current->valid()) {
83
            $nextRequest = $current->current();
84
85
            try {
86
                $nextResponse = yield from $this->processMiddleware($nextIndex, $nextRequest);
87
                $current->send($nextResponse);
88
            } catch (Throwable $exception) {
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
89
                $current->throw($exception);
90
            }
91
        }
92
93
        return $current->getReturn();
94
    }
95
}
96