Completed
Push — 2.0 ( f77154...0b6a7d )
by Vermeulen
02:19
created

Router::sendNotifyRouteFindToOthers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
 * Class for the router system
4
 * @author Vermeulen Maxime <[email protected]>
5
 * @version 2.0
6
 */
7
8
namespace BfwFastRoute;
9
10
use \Exception;
11
use \stdClass;
12
use \FastRoute;
13
14
/**
15
 * Permet de gérer la vue et de savoir vers quel page envoyer
16
 * @package bfw-fastroute
17
 */
18
class Router
19
{
20
    /**
21
     * @var \BFW\Module $module The bfw module instance for this module
22
     */
23
    protected $module;
24
    
25
    /**
26
     * @var \BFW\Config $config The bfw config instance for this module
27
     */
28
    protected $config;
29
    
30
    /**
31
     * @var \BFW\ControllerRouterLink $routerLinker Linker between
32
     *  controller and router instance
33
     */
34
    protected $routerLinker;
35
    
36
    /**
37
     * @var \FastRoute\Dispatcher $dispatcher FastRoute dispatcher
38
     */
39
    protected $dispatcher;
40
    
41
    /**
42
     * Constructor
43
     * Get config and linker instance
44
     * Call fastRoute dispatcher
45
     * 
46
     * @param \BFW\Module $module
47
     */
48
    public function __construct(\BFW\Module $module)
49
    {
50
        $this->module = $module;
51
        $this->config = $module->getConfig();
52
        
53
        $this->routerLinker = \BFW\ControllerRouterLink::getInstance();
54
        
55
        $this->dispatcher = FastRoute\simpleDispatcher([$this, 'addRoutesToCollector']);
56
    }
57
    
58
    /**
59
     * Call by dispatcher; Add route in config to fastRoute router
60
     * 
61
     * @param FastRoute\RouteCollector $router FastRoute router
62
     * 
63
     * @return void
64
     */
65
    public function addRoutesToCollector(FastRoute\RouteCollector $router)
66
    {
67
        $routes = $this->config->getConfig('routes');
68
        
69
        foreach ($routes as $slug => $infos) {
70
            $slug = trim($slug);
71
72
            //Défault method
73
            $method = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];
74
            
75
            //If method is declared for the route
76
            if (isset($infos['httpMethod'])) {
77
                //Get the method ans remove it from httpMethod array
78
                $method = $infos['httpMethod'];
79
                unset($infos['httpMethod']);
80
            }
81
82
            $router->addRoute($method, $slug, $infos);
83
        }
84
    }
85
    
86
    /**
87
     * Obtain informations about the current route from fastRoute dispatcher
88
     * 
89
     * @return void
90
     */
91
    public function obtainCurrentRoute()
92
    {
93
        //Get current request informations
94
        $bfwRequest = \BFW\Request::getInstance();
95
        $request    = $bfwRequest->getRequest()->path;
96
        $method     = $bfwRequest->getMethod();
97
        
98
        //If request is index
99
        if ($request === '') {
100
            $request = '/';
101
        }
102
103
        //Get route information from dispatcher
104
        $routeInfo   = $this->dispatcher->dispatch($method, $request);
105
        $routeStatus = $routeInfo[0];
106
        
107
        //Get and send request http status to the controller/router linker
108
        $httpStatus = $this->checkStatus($routeStatus);
109
        
110
        http_response_code($httpStatus);
111
        if ($httpStatus !== 200) {
112
            return;
113
        }
114
115
        //Obtains datas for route from config file and send to linker
116
        $this->sendInfosForRouteToLinker($routeInfo[1]);
117
        
118
        //Add gets datas in route to $_GET var
119
        $this->addDatasToGetAndPostVar($routeInfo[1]);
120
        $this->addToSuperglobalVar('GET', $routeInfo[2]);
121
        
122
        $this->sendNotifyRouteFindToOthers();
123
    }
124
    
125
    /**
126
     * Get http status for response from dispatcher
127
     * 
128
     * @param int $routeStatus : Route status send by dispatcher for request
129
     * 
130
     * @return int
131
     */
132
    protected function checkStatus($routeStatus)
133
    {
134
        $httpStatus = 200;
135
        
136
        if ($routeStatus === FastRoute\Dispatcher::METHOD_NOT_ALLOWED) {
137
            $httpStatus = 405;
138
        } elseif ($routeStatus === FastRoute\Dispatcher::NOT_FOUND) {
139
            $httpStatus = 404;
140
        }
141
        
142
        return $httpStatus;
143
    }
144
    
145
    /**
146
     * Obtains route informations from config file and send this informations
147
     * to the controller/router linker
148
     * 
149
     * @param array $routeInfos : Route information from config file
150
     * 
151
     * @return void
152
     * 
153
     * @throws \Exception If target not define in config file
154
     */
155
    protected function sendInfosForRouteToLinker(array $routeInfos)
156
    {
157
        if (!isset($routeInfos['target'])) {
158
            throw new Exception('Router : target not defined');
159
        }
160
        
161
        $this->routerLinker->setTarget($routeInfos['target']);
162
    }
163
    
164
    /**
165
     * Add datas into a superglobal var
166
     * 
167
     * @param string $globalVarName : Name of the superglobal var
168
     * @param array $datasToAdd : Datas to add to $_GET var
169
     * 
170
     * @return void
171
     */
172
    protected function addToSuperglobalVar($globalVarName, array $datasToAdd)
173
    {
174
        global ${'_'.$globalVarName};
175
        ${'_'.$globalVarName} = array_merge(${'_'.$globalVarName}, $datasToAdd);
176
    }
177
    
178
    /**
179
     * If property 'get' has been declared into current route config, add
180
     * them into superglobal $_GET .
181
     * 
182
     * @param array $routeInfos route informations declared in config
183
     * 
184
     * @return void
185
     */
186
    protected function addDatasToGetAndPostVar(array $routeInfos)
187
    {
188
        if (isset($routeInfos['get'])) {
189
            $this->addToSuperglobalVar('GET', $routeInfos['get']);
190
        }
191
    }
192
    
193
    /**
194
     * Send to all observer of Application a notify who contains the message
195
     * "request_route_find" to say the route for the current request has been
196
     * found by us.
197
     * 
198
     * @return void
199
     */
200
    protected function sendNotifyRouteFindToOthers()
201
    {
202
        $app = \BFW\Application::getInstance();
203
        $app->notifyAction('request_route_find');
204
    }
205
}
206