Completed
Push — master ( bcfd56...80724d )
by Michael
01:39
created

Onion::processMiddleware()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 13
nc 5
nop 2
1
<?php
2
3
namespace Cormy\Server;
4
5
use Throwable;
6
use Psr\Http\Message\ResponseInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
9
/**
10
 * Onion style PSR-7 middleware stack.
11
 */
12
class Onion implements RequestHandlerInterface
13
{
14
    /**
15
     * @var callable|RequestHandlerInterface
16
     */
17
    protected $core;
18
19
    /**
20
     * @var callable[]|MiddlewareInterface[]
21
     */
22
    protected $scales;
23
24
    /**
25
     * Constructs an onion style PSR-7 middleware stack.
26
     *
27
     * @param callable|RequestHandlerInterface $core   the innermost request handler
28
     * @param callable[]|MiddlewareInterface[] $scales the middlewares to wrap around the core
29
     */
30
    public function __construct(callable $core, callable ...$scales)
31
    {
32
        $this->core = $core;
33
        $this->scales = $scales;
34
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function __invoke(ServerRequestInterface $request):ResponseInterface
40
    {
41
        $topIndex = count($this->scales) - 1;
42
43
        return $this->processMiddleware($topIndex, $request);
44
    }
45
46
    /**
47
     * Process an incoming server request by delegating it to the middleware specified by $index.
48
     *
49
     * @param int                    $index   the $scales index
50
     * @param ServerRequestInterface $request
51
     *
52
     * @return ResponseInterface
53
     */
54
    protected function processMiddleware(int $index, ServerRequestInterface $request):ResponseInterface
55
    {
56
        if ($index < 0) {
57
            return ($this->core)($request);
58
        }
59
60
        $current = $this->scales[$index]($request);
61
        $nextIndex = $index - 1;
62
63
        while ($current->valid()) {
64
            $nextRequest = $current->current();
65
66
            try {
67
                $nextResponse = $this->processMiddleware($nextIndex, $nextRequest);
68
                $current->send($nextResponse);
69
            } 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...
70
                $current->throw($exception);
71
            }
72
        }
73
74
        return $current->getReturn();
75
    }
76
}
77