Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Pipeline
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 process
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Http\Client\Middleware;
16
17use Psr\Http\Message\RequestInterface;
18use Psr\Http\Message\ResponseInterface;
19
20/**
21 * Builds and runs a middleware chain. Registration order is wrap order: the
22 * first-registered middleware ends up outermost (runs first going in, last
23 * coming out) - the standard onion convention.
24 *
25 * @category   Pop
26 * @package    Pop\Http
27 * @author     Nick Sagona, III <nick@popphp.org>
28 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
29 * @license    https://www.popphp.org/license     New BSD License
30 * @version    6.0.0
31 */
32class Pipeline
33{
34
35    /**
36     * Registered middleware, in registration order
37     * @var array
38     */
39    protected array $middleware;
40
41    /**
42     * Constructor
43     *
44     * @param  array $middleware  MiddlewareInterface instances, in registration order
45     * @throws \InvalidArgumentException if any element is not a MiddlewareInterface
46     */
47    public function __construct(array $middleware = [])
48    {
49        foreach ($middleware as $i => $entry) {
50            if (!($entry instanceof MiddlewareInterface)) {
51                throw new \InvalidArgumentException(
52                    'Error: Middleware at index ' . $i . ' must be an instance of ' .
53                    MiddlewareInterface::class . ', got ' .
54                    (is_object($entry) ? get_class($entry) : gettype($entry)) . '.'
55                );
56            }
57        }
58
59        $this->middleware = $middleware;
60    }
61
62    /**
63     * Build the chain (terminal innermost, first-registered middleware outermost)
64     * and run it against the given request
65     *
66     * @param  RequestInterface $request
67     * @param  callable         $terminal  callable(RequestInterface $request): ResponseInterface
68     * @return ResponseInterface
69     */
70    public function process(RequestInterface $request, callable $terminal): ResponseInterface
71    {
72        $handler = new CallableRequestHandler($terminal);
73
74        foreach (array_reverse($this->middleware) as $middleware) {
75            $handler = new CallableRequestHandler(
76                fn(RequestInterface $req) => $middleware->process($req, $handler)
77            );
78        }
79
80        return $handler->handle($request);
81    }
82
83}