Passed
Branch v2-dev (a5bfb7)
by Henri
01:26
created

RunInTrait::executeState()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace HnrAzevedo\Router;
4
5
trait RunInTrait
6
{
7
    use Helper, CheckTrait;
8
9
    protected array $beforeExcepts = [];
10
    protected array $afterExcepts = [];
11
    protected \Closure $beforeAll;
12
    protected \Closure $afterAll;
13
14
    public static function before($closure): RouterInterface
15
    {
16
        return self::addInRoute('before',$closure);
17
    }
18
19
    public static function after($closure): RouterInterface
20
    {
21
        return self::addInRoute('after',$closure);
22
    }
23
24
    public static function beforeAll($closure, $excepts): RouterInterface
25
    {
26
        self::getInstance()->beforeExcepts = (is_array($excepts)) ? $excepts : [ $excepts ];
0 ignored issues
show
Bug introduced by
The property beforeExcepts is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
27
        self::getInstance()->beforeAll = $closure;
0 ignored issues
show
Bug introduced by
The property beforeAll is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
28
        return self::getInstance();
29
    }
30
31
    public static function afterAll($closure, $excepts): RouterInterface
32
    {
33
        self::getInstance()->afterExcepts = (is_array($excepts)) ? $excepts : [ $excepts ];
0 ignored issues
show
Bug introduced by
The property afterExcepts is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
34
        self::getInstance()->afterAll = $closure;
0 ignored issues
show
Bug introduced by
The property afterAll is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
35
        return self::getInstance();
36
    }
37
38
    public static function beforeGroup($closure, $excepts): RouterInterface
39
    {
40
        return self::addInRoutes('before', $closure, $excepts);
41
    }
42
43
    public static function afterGroup($closure, $excepts): RouterInterface
44
    {
45
        return self::addInRoutes('after', $closure, $excepts);
46
    }
47
48
    protected function executeRouteAction(): bool
49
    {
50
        if(is_callable($this->current()['action'])){        
0 ignored issues
show
Bug introduced by
It seems like current() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

50
        if(is_callable($this->/** @scrutinizer ignore-call */ current()['action'])){        
Loading history...
51
            call_user_func_array($this->current()['action'], $_REQUEST);
52
            return true;
53
        }
54
55
        $this->executeController($this->current()['action']);
56
        return true;
57
    }
58
59
    private static function addInRoutes(string $state, $closure, $excepts): RouterInterface
60
    {
61
        self::getInstance()->isInPseudGroup();
62
        $excepts = (is_array($excepts)) ? $excepts : [ $excepts ];
63
        $group = self::getInstance()->inSave()['group'];
64
65
        foreach(self::getInstance()->routes as $r => $route){
66
            if($route['group'] === $group && !in_array($r,$excepts)){
67
                self::getInstance()->routes[$r][$state] = (is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]); 
0 ignored issues
show
Bug introduced by
The property routes is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
68
            }
69
        }
70
71
        return self::getInstance();
72
    }
73
74
    private static function addInRoute(string $state, $closure): RouterInterface
75
    {
76
        $route = self::getInstance()->inSave();
77
        $route[$state] = (!is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]);
78
        self::updateRoute($route,array_key_last(self::getInstance()->routes));
0 ignored issues
show
Bug introduced by
The property routes is declared protected in HnrAzevedo\Router\Router and cannot be accessed from this context.
Loading history...
79
        return self::getInstance();
80
    }
81
82
    protected function executeBefore(): void
83
    {
84
        if(!in_array($this->currentName(),$this->beforeExcepts)){
0 ignored issues
show
Bug introduced by
It seems like currentName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

84
        if(!in_array($this->/** @scrutinizer ignore-call */ currentName(),$this->beforeExcepts)){
Loading history...
85
            ($this->beforeAll)();
86
        }
87
88
        $this->executeState('before');
89
    }
90
91
    protected function executeAfter(): void
92
    {
93
        if(!in_array($this->currentName(),$this->afterExcepts)){
94
            ($this->afterAll)();
95
        }
96
97
        $this->executeState('after');
98
    }
99
100
    private function executeState(string $stage): void
101
    {
102
        foreach($this->current()[$stage] as $state){
103
            if(is_callable($state)){
104
                $state();
105
                continue;
106
            }
107
108
            $this->executeController($state);
109
        }
110
    }
111
112
    private function executeController(string $controllerMeth): void
113
    {
114
        if(count(explode('@',$controllerMeth)) !== 2){
115
            throw new \RuntimeException('Misconfigured route action');
116
        }
117
118
        $controller = (string) explode('@',$controllerMeth)[0];
119
        $method = (string) explode('@',$controllerMeth)[1];
120
121
        $this->checkControllerMeth($controllerMeth);
122
123
        call_user_func_array([(new $controller()),$method], $_REQUEST);
124
    }
125
126
    private function checkControllerMeth(string $controllerMeth): void
127
    {
128
        $routeURI = str_replace(['{:','{','}'],'',urldecode($this->current()['uri']->getPath()));
129
130
        $controller = (string) explode('@',$controllerMeth)[0];
131
        $method = (string) explode('@',$controllerMeth)[1];
132
133
        if(!class_exists($controller)){
134
            throw new \RuntimeException("Controller not found in route URI {$routeURI}");
135
        }
136
137
        if(!method_exists($controller, $method)){
138
            throw new \RuntimeException("Method {$method} not found in controller {$controller} in route URI {$routeURI}");
139
        }
140
        
141
    }
142
143
}
144