Lines 100.00% 8 / 8
Methods 100.00% 2 / 2
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 2 / 2 100.00% 1 / 1 1
 handle 100.00% 6 / 6 100.00% 1 / 1 2
17class MiddlewarePipeline implements RequestHandlerInterface
18{
19    /** @var array<int, \Psr\Http\Server\MiddlewareInterface> */
20    private array $middleware = [];
21
22    private RequestHandlerInterface $fallbackHandler;
23
24    /**
25     * Cursor into $middleware. Using an index instead of array_shift() keeps
26     * the pipeline's middleware list intact, so a pipeline instance can be
27     * reused (e.g. a fresh clone per dispatch) without losing entries.
28     */
29    private int $position = 0;
30
31    /**
32     * @param \Psr\Http\Server\MiddlewareInterface[] $middleware
33     */
34    public function __construct(array $middleware, RequestHandlerInterface $fallbackHandler)
35    {
36        $this->middleware = array_values($middleware);
37        $this->fallbackHandler = $fallbackHandler;
38    }
39
40    public function handle(ServerRequestInterface $request): ResponseInterface
41    {
42        if (!isset($this->middleware[$this->position])) {
43            return $this->fallbackHandler->handle($request);
44        }
45
46        $middleware = $this->middleware[$this->position];
47
48        // Advance a clone so nested handle() calls (from middleware calling
49        // $handler->handle()) each get their own cursor — the pipeline
50        // instance itself is not mutated.
51        $next = clone $this;
52        $next->position++;
53
54        return $middleware->process($request, $next);
55    }
56}