Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
Manager
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
11 / 11
20
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 addHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 removeHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasHandlers
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 handle
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 terminate
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3 * Pop PHP Framework (https://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@noladev.com>
7 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
8 * @license    https://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Middleware;
15
16use Pop\AbstractManager;
17
18/**
19 * Middleware manager class
20 *
21 * @category   Pop
22 * @package    Pop\Middleware
23 * @author     Nick Sagona, III <dev@noladev.com>
24 * @copyright  Copyright (c) 2009-2026 NOLA Interactive, LLC.
25 * @license    https://www.popphp.org/license     New BSD License
26 * @version    4.4.0
27 */
28class Manager extends AbstractManager
29{
30
31    /**
32     * Handlers
33     * @var array
34     */
35    protected static array $handlers = [];
36
37    /**
38     * Constructor
39     *
40     * Instantiate the middleware manager object.
41     *
42     * @param ?array $handlers
43     */
44    public function __construct(?array $handlers = null)
45    {
46        if (!empty($handlers)) {
47            parent::addItems($handlers);
48        }
49    }
50
51    /**
52     * Add handlers
53     *
54     * @param  array $handlers
55     * @return static
56     */
57    public function addHandlers(array $handlers): static
58    {
59        return parent::addItems($handlers);
60    }
61
62    /**
63     * Add a handler
64     *
65     * @param  mixed $handler
66     * @param  mixed $name
67     * @return static
68     */
69    public function addHandler(mixed $handler, mixed $name = null): static
70    {
71        return parent::addItem($handler, $name);
72    }
73
74    /**
75     * Remove a handler
76     *
77     * @param  mixed $name
78     * @return static
79     */
80    public function removeHandler(mixed $name): static
81    {
82        return parent::removeItem($name);
83    }
84
85    /**
86     * Get a handler
87     *
88     * @param  mixed $name
89     * @return mixed
90     */
91    public function getHandler(mixed $name): mixed
92    {
93        return parent::getItem($name);
94    }
95
96    /**
97     * Get handlers
98     *
99     * @return array
100     */
101    public function getHandlers(): array
102    {
103        return parent::getItems();
104    }
105
106    /**
107     * Determine whether the manager has a handler
108     *
109     * @param  string $name
110     * @return bool
111     */
112    public function hasHandler(string $name): bool
113    {
114        return parent::hasItem($name);
115    }
116
117    /**
118     * Determine whether the manager has handlers
119     *
120     * @return bool
121     */
122    public function hasHandlers(): bool
123    {
124        return parent::hasItems();
125    }
126
127    /**
128     * Process all middleware
129     *
130     * @param  mixed    $request
131     * @param  \Closure $dispatch
132     * @param  mixed    $dispatchParams
133     * @return static
134     */
135    public function process(mixed $request, \Closure $dispatch, mixed $dispatchParams = null): static
136    {
137        self::$handlers = $this->items;
138        $response = self::handle($request, $dispatch, $dispatchParams);
139
140        self::terminate($this->items, $request, $response);
141
142        return $this;
143    }
144
145    /**
146     * Recursive method to execute all middleware handlers
147     *
148     * @param  mixed    $request
149     * @param  \Closure $dispatch
150     * @param  mixed    $dispatchParams
151     * @return mixed
152     */
153    public static function handle(mixed $request, \Closure $dispatch, mixed $dispatchParams = null): mixed
154    {
155        $next = array_shift(self::$handlers);
156
157        if ($next === null) {
158            return (null !== $dispatchParams) ? call_user_func_array($dispatch, $dispatchParams) : $dispatch();
159        } else if (is_string($next) && class_exists($next)) {
160            $next = new $next();
161        }
162
163        return $next->handle($request, function ($req) use ($dispatch, $dispatchParams) {
164            return self::handle($req, $dispatch, $dispatchParams);
165        });
166    }
167
168    /**
169     * Execute all middleware handlers terminate methods
170     *
171     * @param  array $handlers
172     * @param  mixed $request
173     * @param  mixed $response
174     * @return void
175     */
176    public static function terminate(array $handlers, mixed $request = null, mixed $response = null): void
177    {
178        foreach ($handlers as $handler) {
179            if (is_string($handler) && class_exists($handler)) {
180                $handler = new $handler();
181            }
182            if ($handler instanceof TerminableInterface) {
183                $handler->terminate($request, $response);
184            }
185        }
186    }
187
188}