MiddlewareCollection::destroyMiddleware()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 15
rs 10
1
<?php
2
3
namespace MinasRouter\Router\Middlewares;
4
5
use MinasRouter\Http\Request;
6
use MinasRouter\Router\Middlewares\MiddlewareRoute;
7
8
class MiddlewareCollection
9
{
10
    /** @var array */
11
    protected $queue;
12
13
    /** @var array|string */
14
    protected $middlewares;
15
16
    /** @var object */
17
    protected $currentRequest;
18
19
    /** @var int = 0 */
20
    protected $currentQueueNumber = 0;
21
22
    public function __construct($middlewares)
23
    {
24
        $this->middlewares = $middlewares;
25
    }
26
27
    /**
28
     * Return all middlewares of this route.
29
     * 
30
     * @param string $middleware = null
31
     * 
32
     * @return string|array
33
     */
34
    public function get(String $middleware = null)
35
    {
36
        if ($middleware && is_array($this->middlewares) && isset($this->middlewares[$middleware])) {
37
            return $this->middlewares[$middleware];
38
        }
39
40
        return $this->middlewares;
41
    }
42
43
    /**
44
     * Method responsible for setting the Route's Request
45
     * 
46
     * @param \MinasRouter\Http\Request $request
47
     * 
48
     * @return void
49
     */
50
    public function setRequest(Request $request)
51
    {
52
        $this->currentRequest = $request;
53
    }
54
55
    /**
56
     * Method responsible for setting the
57
     * middlewares of the route.
58
     * 
59
     * @var array $middlewares
60
     * 
61
     * @return void
62
     */
63
    public function setMiddlewares(array $middlewares)
64
    {
65
        $this->middlewares = $middlewares;
66
    }
67
68
    /**
69
     * Store a new middleware and return
70
     * all middlewares of route.
71
     * 
72
     * @param string|array $middleware
73
     * 
74
     * @return string|array
75
     */
76
    public function storeMiddleware($middleware)
77
    {
78
        if (is_string($middleware)) {
79
            $middleware = explode(",", $middleware);
80
        }
81
82
        return $this->resolveLaterMiddleware($middleware);
83
    }
84
85
    /**
86
     * Remove a middleware of the middleware queue.
87
     * 
88
     * @param string|array $middleware
89
     * 
90
     * @return string|array
91
     */
92
    public function removeMiddleware($middleware)
93
    {
94
        if (is_string($middleware)) {
95
            $middleware = explode(",", $middleware);
96
        }
97
98
        return $this->destroyMiddleware($middleware);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->destroyMiddleware($middleware) targeting MinasRouter\Router\Middl...on::destroyMiddleware() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug Best Practice introduced by
The expression return $this->destroyMiddleware($middleware) returns the type void which is incompatible with the documented return type array|string.
Loading history...
99
    }
100
101
    /**
102
     * Destroy the middlewares of individual route.
103
     * 
104
     * @param array $middleware
105
     * 
106
     */
107
    private function destroyMiddleware(Array $middleware): void
108
    {
109
        $currentMiddleware = $this->middlewares;
110
111
        foreach ($middleware as $mid) {
112
            $mid = trim(rtrim($mid));
113
            
114
            if (is_string($currentMiddleware)) {
115
                $currentMiddleware = rtrim(trim(preg_replace("/\s?".$mid."\,?/", "", $currentMiddleware), ' '), ',');
116
            } else {
117
                $currentMiddleware = array_values(array_filter($currentMiddleware, fn($middleware) => $middleware != $mid));
118
            }
119
        }
120
121
        $this->middlewares = $currentMiddleware;
122
    }
123
124
    /**
125
     * Resolve the middlewares of individual route.
126
     * 
127
     * @param array $middleware
128
     * 
129
     * @return string|array
130
     */
131
    private function resolveLaterMiddleware(Array $middleware)
132
    {
133
        $currentMiddleware = $this->middlewares;
134
135
        foreach ($middleware as $mid) {
136
            $mid = trim(rtrim($mid));
137
            
138
            if (is_string($currentMiddleware)) {
139
                $currentMiddleware .= ", {$mid}";
140
            } else {
141
                $currentMiddleware[] = $mid;
142
            }
143
        }
144
145
        return $currentMiddleware;
146
    }
147
148
    /**
149
     * Alias for execute the middlewares.
150
     * 
151
     * @return mixed|bool
152
     */
153
    public function execute()
154
    {
155
        return $this->executeMiddleware();
156
    }
157
158
    /**
159
     * Execute the middlewares.
160
     * 
161
     * @return mixed|bool
162
     */
163
    protected function executeMiddleware()
164
    {
165
        $middlewares = $this->middlewares;
166
167
        if(is_string($middlewares)) {
168
            $middlewares = explode(',', $middlewares);
169
        }
170
171
        $this->resolveNestedMiddleware($middlewares);
172
173
        return $this->callMiddlewares();
174
    }
175
176
    /**
177
     * Method responsible for identifying
178
     * middlewares and instantiating them.
179
     * 
180
     * @param array $middlewares
181
     * 
182
     * @return void
183
     */
184
    protected function resolveNestedMiddleware(Array $middlewares): void
185
    {
186
        $this->queue = array_map(function ($middleware) {
187
            $middleware = trim(rtrim($middleware));
188
189
            return $this->instanceMiddleware($middleware);
190
        }, $middlewares);
191
    }
192
193
    /**
194
     * Method responsible for instantiating middlewares.
195
     * 
196
     * @param string
197
     * 
198
     * @return null|object
199
     */
200
    protected function instanceMiddleware($middleware)
201
    {
202
        if (!preg_match("/\\\/", $middleware)) {
203
            if (!$middlewareClass = $this->getByAlias($middleware)) return;
204
205
            return new $middlewareClass();
206
        }
207
208
        if (class_exists($middleware)) {
209
            return new $middleware();
210
        }
211
212
        return;
213
    }
214
215
    /**
216
     * Method responsible for identifying 
217
     * a middleware by alias.
218
     * 
219
     * @param string $alias
220
     * 
221
     * @return null|string
222
     */
223
    protected function getByAlias(String $alias)
224
    {
225
        $middlewares = MiddlewareRoute::getGlobalMiddlewares();
226
227
        if (!array_key_exists($alias, $middlewares)) {
228
            return;
229
        }
230
231
        if (class_exists($middlewares[$alias])) {
232
            return $middlewares[$alias];
233
        }
234
235
        return;
236
    }
237
238
    /**
239
     * Method responsible for 
240
     * calling the next middleware.
241
     * 
242
     * @return mixed|bool
243
     */
244
    protected function next()
245
    {
246
        $this->currentQueueNumber++;
247
248
        return $this->callMiddlewares();
249
    }
250
251
    /**
252
     * Method responsible for resetting 
253
     * the middleware queue.
254
     * 
255
     * @return void
256
     */
257
    protected function reset()
258
    {
259
        $this->currentQueueNumber = 0;
260
    }
261
262
    /**
263
     * Method responsible for calling
264
     * middlewares and class handle.
265
     * 
266
     * @return mixed|bool
267
     */
268
    protected function callMiddlewares()
269
    {
270
        if (!isset($this->queue[$this->currentQueueNumber])) {
271
            $this->reset();
272
            return true;
273
        }
274
275
        $currentMiddleware = $this->queue[$this->currentQueueNumber];
276
277
        if (is_null($currentMiddleware) || empty($currentMiddleware)) {
278
            return $this->next();
279
        }
280
281
        return $currentMiddleware->handle(
282
            $this->currentRequest,
283
            fn () => $this->next()
284
        );
285
    }
286
}
287