Passed
Push — master ( 022aa2...8d4f2f )
by Henri
04:23 queued 47s
created

RunInTrait::executeBefore()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace HnrAzevedo\Router;
6
7
trait RunInTrait
8
{
9
    use Helper, 
10
        CheckTrait, 
11
        CurrentTrait;
12
13
    protected array $beforeExcepts = [];
14
    protected array $afterExcepts = [];
15
    protected \Closure $beforeAll;
16
    protected \Closure $afterAll;
17
18
    protected function getState(string $state, bool $except = false)
19
    {
20
        if($state === 'before'){
21
            return ($except) ? $this->beforeExcepts : $this->beforeAll;
22
        }
23
24
        return ($except) ? $this->afterExcepts : $this->afterAll;
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($except){
40
            $this->afterExcepts = $settable;
41
            return true;
42
        }
43
            
44
        $this->afterAll = $settable;
45
        return true;
46
    }
47
48
    public static function before($closure): RouterInterface
49
    {
50
        return self::addInRoute('before',$closure);
51
    }
52
53
    public static function after($closure): RouterInterface
54
    {
55
        return self::addInRoute('after',$closure);
56
    }
57
58
    public static function beforeAll($closure, $excepts): RouterInterface
59
    {
60
        self::getInstance()->setState('before', (is_array($excepts)) ? $excepts : [ $excepts ] ,true);
61
        self::getInstance()->setState('before', $closure, false);
62
        return self::getInstance();
63
    }
64
65
    public static function afterAll($closure, $excepts): RouterInterface
66
    {
67
        self::getInstance()->setState('after', (is_array($excepts)) ? $excepts : [ $excepts ] ,true);
68
        self::getInstance()->setState('after', $closure, false);
69
        return self::getInstance();
70
    }
71
72
    public static function beforeGroup($closure, $excepts): RouterInterface
73
    {
74
        return self::addInRoutes('before', $closure, $excepts);
75
    }
76
77
    public static function afterGroup($closure, $excepts): RouterInterface
78
    {
79
        return self::addInRoutes('after', $closure, $excepts);
80
    }
81
82
    protected function executeRouteAction($action): bool
83
    {
84
        if(is_callable($action)){        
85
            call_user_func_array($action, $_REQUEST);
86
            return true;
87
        }
88
89
        $this->executeController($action);
90
        return true;
91
    }
92
93
    private static function addInRoutes(string $state, $closure, $excepts): RouterInterface
94
    {
95
        self::getInstance()->isInPseudGroup();
96
        $excepts = (is_array($excepts)) ? $excepts : [ $excepts ];
97
        $group = self::getInstance()->inSave()['group'];
98
99
        foreach(self::getInstance()->getRoutes() as $r => $route){
100
            if($route['group'] === $group && !in_array($r,$excepts)){
101
                self::getInstance()->getRoutes()[$r][$state] = (is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]); 
102
            }
103
        }
104
105
        return self::getInstance();
106
    }
107
108
    private static function addInRoute(string $state, $closure): RouterInterface
109
    {
110
        $route = self::getInstance()->inSave();
111
        $route[$state] = (!is_null($route[$state])) ? [ $closure ] : array_merge($route[$state], [ $closure ]);
112
        self::updateRoute($route,array_key_last(self::getInstance()->getRoutes()));
113
        return self::getInstance();
114
    }
115
116
    protected function executeBefore(): void
117
    {
118
        if(!in_array($this->currentName(), (array) $this->getState('before', true))){
119
            ($this->getState('before', false))();
120
        }
121
122
        $this->executeState('before');
123
    }
124
125
    protected function executeAfter(): void
126
    {
127
        $this->executeState('after');
128
129
        if(!in_array($this->currentName(), (array) $this->getState('after', true))){
130
            ($this->getState('after', false))();
131
        }
132
    }
133
134
    private function executeState(string $stage): void
135
    {
136
        foreach($this->current()[$stage] as $state){
137
            if(is_callable($state)){
138
                $state();
139
                continue;
140
            }
141
142
            $this->executeController($state);
143
        }
144
    }
145
146
    private function executeController(string $controllerMeth): void
147
    {
148
        if(count(explode('@',$controllerMeth)) !== 2){
149
            $path = urldecode($this->current()['uri']->getPath());
150
            throw new \RuntimeException("Misconfigured route action ({$path})");
151
        }
152
153
        $controller = (string) explode('@',$controllerMeth)[0];
154
        $method = (string) explode('@',$controllerMeth)[1];
155
156
        $this->checkControllerMeth($controllerMeth);
157
158
        call_user_func_array([(new $controller()),$method], $_REQUEST);
159
    }
160
161
    private function checkControllerMeth(string $controllerMeth): void
162
    {
163
        $routeURI = str_replace(['{:','{','}'],'',urldecode($this->current()['uri']->getPath()));
164
165
        $controller = (string) explode('@',$controllerMeth)[0];
166
        $method = (string) explode('@',$controllerMeth)[1];
167
168
        if(!class_exists($controller)){
169
            throw new \RuntimeException("Controller not found in route URI {$routeURI}");
170
        }
171
172
        if(!method_exists($controller, $method)){
173
            throw new \RuntimeException("Method {$method} not found in controller {$controller} in route URI {$routeURI}");
174
        }
175
        
176
    }
177
178
}
179