Passed
Branch v2-dev (d50d65)
by Henri
01:22
created

RunInTrait::getState()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 4
nc 5
nop 2
dl 0
loc 8
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace HnrAzevedo\Router;
4
5
trait RunInTrait
6
{
7
    use Helper, 
8
        CheckTrait, 
9
        CurrentTrait;
10
11
    protected array $beforeExcepts = [];
12
    protected array $afterExcepts = [];
13
    protected \Closure $beforeAll;
14
    protected \Closure $afterAll;
15
16
    protected function getState(string $state, bool $except = false)
17
    {
18
        if($state === 'before'){
19
            return ($except) ? $this->beforeExcepts : $this->beforeAll;
20
        }
21
22
        if($state === 'after'){
23
            return ($except) ? $this->afterExcepts : $this->afterAll;
24
        }
25
    }
26
27
    protected function setState(string $state, $settable, bool $except = false): bool
28
    {
29
        if($state === 'before'){
30
            if($except){
31
                $this->beforeExcepts = $settable;
32
                return true;
33
            }
34
35
            $this->beforeAll = $settable;
36
            return true;
37
        }
38
39
        if($state === 'after'){
40
            if($except){
41
                $this->afterExcepts = $settable;
42
                return true;
43
            }
44
            
45
            $this->afterAll = $settable;
46
            return true;
47
        }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 39 is false. This is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
48
    }
49
50
    public static function before($closure): RouterInterface
51
    {
52
        return self::addInRoute('before',$closure);
53
    }
54
55
    public static function after($closure): RouterInterface
56
    {
57
        return self::addInRoute('after',$closure);
58
    }
59
60
    public static function beforeAll($closure, $excepts): RouterInterface
61
    {
62
        self::getInstance()->setState('before', (is_array($excepts)) ? $excepts : [ $excepts ] ,true);
63
        self::getInstance()->setState('before', $closure, false);
64
        return self::getInstance();
65
    }
66
67
    public static function afterAll($closure, $excepts): RouterInterface
68
    {
69
        self::getInstance()->setState('after', (is_array($excepts)) ? $excepts : [ $excepts ] ,true);
70
        self::getInstance()->setState('after', $closure, false);
71
        return self::getInstance();
72
    }
73
74
    public static function beforeGroup($closure, $excepts): RouterInterface
75
    {
76
        return self::addInRoutes('before', $closure, $excepts);
77
    }
78
79
    public static function afterGroup($closure, $excepts): RouterInterface
80
    {
81
        return self::addInRoutes('after', $closure, $excepts);
82
    }
83
84
    protected function executeRouteAction(): bool
85
    {
86
        if(is_callable($this->current()['action'])){        
87
            call_user_func_array($this->current()['action'], $_REQUEST);
88
            return true;
89
        }
90
91
        $this->executeController($this->current()['action']);
92
        return true;
93
    }
94
95
    private static function addInRoutes(string $state, $closure, $excepts): RouterInterface
96
    {
97
        self::getInstance()->isInPseudGroup();
98
        $excepts = (is_array($excepts)) ? $excepts : [ $excepts ];
99
        $group = self::getInstance()->inSave()['group'];
100
101
        foreach(self::getInstance()->getRoutes() as $r => $route){
102
            if($route['group'] === $group && !in_array($r,$excepts)){
103
                self::getInstance()->getRoutes()[$r][$state] = (is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]); 
104
            }
105
        }
106
107
        return self::getInstance();
108
    }
109
110
    private static function addInRoute(string $state, $closure): RouterInterface
111
    {
112
        $route = self::getInstance()->inSave();
113
        $route[$state] = (!is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]);
114
        self::updateRoute($route,array_key_last(self::getInstance()->getRoutes()));
115
        return self::getInstance();
116
    }
117
118
    protected function executeBefore(): void
119
    {
120
        if(!in_array($this->currentName(),$this->getState('before', true))){
121
            ($this->getState('before', false))();
122
        }
123
124
        $this->executeState('before');
125
    }
126
127
    protected function executeAfter(): void
128
    {
129
        if(!in_array($this->currentName(),$this->getState('after', true))){
0 ignored issues
show
Bug introduced by
It seems like $this->getState('after', true) can also be of type null; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

129
        if(!in_array($this->currentName(),/** @scrutinizer ignore-type */ $this->getState('after', true))){
Loading history...
130
            ($this->getState('after', false))();
131
        }
132
133
        $this->executeState('after');
134
    }
135
136
    private function executeState(string $stage): void
137
    {
138
        foreach($this->current()[$stage] as $state){
139
            if(is_callable($state)){
140
                $state();
141
                continue;
142
            }
143
144
            $this->executeController($state);
145
        }
146
    }
147
148
    private function executeController(string $controllerMeth): void
149
    {
150
        if(count(explode('@',$controllerMeth)) !== 2){
151
            $path = urldecode($this->current()['uri']->getPath());
152
            throw new \RuntimeException("Misconfigured route action ({$path})");
153
        }
154
155
        $controller = (string) explode('@',$controllerMeth)[0];
156
        $method = (string) explode('@',$controllerMeth)[1];
157
158
        $this->checkControllerMeth($controllerMeth);
159
160
        call_user_func_array([(new $controller()),$method], $_REQUEST);
161
    }
162
163
    private function checkControllerMeth(string $controllerMeth): void
164
    {
165
        $routeURI = str_replace(['{:','{','}'],'',urldecode($this->current()['uri']->getPath()));
166
167
        $controller = (string) explode('@',$controllerMeth)[0];
168
        $method = (string) explode('@',$controllerMeth)[1];
169
170
        if(!class_exists($controller)){
171
            throw new \RuntimeException("Controller not found in route URI {$routeURI}");
172
        }
173
174
        if(!method_exists($controller, $method)){
175
            throw new \RuntimeException("Method {$method} not found in controller {$controller} in route URI {$routeURI}");
176
        }
177
        
178
    }
179
180
}
181