Passed
Branch v2-dev (ac4b1e)
by Henri
01:33
created

MiddlewareTrait::groupMiddlewares()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace HnrAzevedo\Router;
6
7
use HnrAzevedo\Http\Factory;
8
use HnrAzevedo\Http\ServerRequest;
9
use Psr\Http\Server\RequestHandlerInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Psr\Http\Message\ResponseInterface;
12
13
trait MiddlewareTrait
14
{
15
    use Helper, CurrentTrait, RunInTrait;
16
17
    protected array $globalMiddlewares = [];
18
    protected ServerRequest $serverRequest;
19
    protected array $currentMiddlewares = [];
20
21
    public static function globalMiddlewares(array $middlewares): RouterInterface
22
    {
23
        foreach($middlewares as $middleware){
24
            if(!class_exists($middleware)){
25
                throw new \RuntimeException("Middleware class {$middleware} not exists");
26
            }
27
        }
28
        self::getInstance()->setGlobalMiddlewares($middlewares);
29
        return self::getInstance();
30
    }
31
32
    protected function setGlobalMiddlewares(array $middlewares): void
33
    {
34
        $this->globalMiddlewares = $middlewares;
35
    }
36
37
    public static function middleware(array $middlewares): RouterInterface
38
    {
39
        $route = self::getInstance()->inSave();
40
        $route['middlewares'] = (is_array($route['middlewares'])) ? array_merge($route['middlewares'],$middlewares) : $middlewares;
41
        self::getInstance()->updateRoute($route,array_key_last(self::getInstance()->getRoutes()));
42
        return self::getInstance();
43
    }
44
45
    public static function groupMiddlewares(array $middlewares, array $excepts): RouterInterface
0 ignored issues
show
Unused Code introduced by
The parameter $excepts is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

45
    public static function groupMiddlewares(array $middlewares, /** @scrutinizer ignore-unused */ array $excepts): RouterInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
46
    {
47
        $middlewares = (is_array($middlewares)) ? $middlewares : [ $middlewares ];
0 ignored issues
show
introduced by
The condition is_array($middlewares) is always true.
Loading history...
48
49
50
        $route = self::getInstance()->inSave();
51
        $route['middlewares'] = (is_array($route['middlewares'])) ? array_merge($route['middlewares'],$middlewares) : $middlewares;
52
        self::getInstance()->updateRoute($route,array_key_last(self::getInstance()->getRoutes()));
53
        return self::getInstance();
54
    }
55
56
    private static function existMiddleware(string $name): void
57
    {
58
        if(!class_exists($name) && !array_key_exists($name,self::$globalMiddlewares)){
59
            throw new \RuntimeException("Middleware {$name} does not exist");
60
        }
61
    }
62
63
    protected function handleMiddlewares(): void
64
    {
65
        $factory = new Factory();
66
67
        $this->serverRequest = (!isset($this->serverRequest)) ? $factory->createServerRequest($_SERVER['REQUEST_METHOD'], $this->current()['uri'],['route' => $this->current()]) : $this->serverRequest;
68
        
69
        foreach ($this->current()['middlewares'] as $middleware){
70
            $this->currentMiddlewares[] = (class_exists($middleware)) ? new $middleware() : new $this->globalMiddlewares[$middleware]();
71
        }
72
73
        $this->process($this->serverRequest, new class implements RequestHandlerInterface {
74
            public function handle(ServerRequestInterface $request): ResponseInterface
75
            {
76
                return (new Factory())->createResponse(200);
77
            }
78
        });
79
80
    }
81
82
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
83
    {
84
        if(!$this->getInstance()->loaded){
0 ignored issues
show
Bug introduced by
The property loaded is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
85
            $this->getInstance()->load();
86
        }
87
88
        $route = $this->getInstance()->current();
89
        if(!empty($route)){
90
            $route['action'] = function(){
91
                $this->getInstance()->executeBefore();
92
                $this->getInstance()->executeRouteAction($this->getInstance()->current()['action']);
93
                $this->getInstance()->executeAfter();
94
            };
95
        }
96
97
        return $this->next($handler)->handle($request->withAttribute('route',$route));
98
    }
99
100
    private function next(RequestHandlerInterface $defaultHandler): RequestHandlerInterface
101
    {
102
        return new class ($this->currentMiddlewares, $defaultHandler) implements RequestHandlerInterface {
103
            private RequestHandlerInterface $handler;
104
            private array $pipeline;
105
106
            public function __construct(array $pipeline, RequestHandlerInterface $handler)
107
            {
108
                $this->handler = $handler;
109
                $this->pipeline = $pipeline;
110
            }
111
112
            public function handle(ServerRequestInterface $request): ResponseInterface
113
            {
114
                if (!$middleware = array_shift($this->pipeline)) {
115
                    return $this->handler->handle($request);
116
                }
117
118
                $next = clone $this;
119
                $this->pipeline = [];
120
121
                return $middleware->process($request, $next);
122
            }
123
        };
124
    }
125
    
126
}
127