Completed
Push — master ( 93ad8b...2e8905 )
by Mathieu
02:12
created

Router   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 11.65%

Importance

Changes 13
Bugs 0 Features 0
Metric Value
c 13
b 0
f 0
dl 0
loc 168
rs 10
ccs 12
cts 103
cp 0.1165
wmc 25
lcom 1
cbo 2

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A configure() 0 11 4
B buildRoute() 0 25 5
B buildRestRoutes() 0 42 4
A parseRequest() 0 5 1
A addRoute() 0 13 2
A addMiddleware() 0 6 1
A getMiddlewares() 0 4 1
A getResponse() 0 4 1
B doRouting() 0 24 5
1
<?php
2
namespace Suricate;
3
4
/**
5
// TODO : handle closure
6
**/
7
class Router extends Service
8
{
9
    private $requestUri;
10
    private $baseUri;
11
    private $routes;
12
    private $response;
13
    private $appMiddlewares = array(
14
        '\Suricate\Middleware\CheckMaintenance',
15
        );
16
17
18
19 1
    public function __construct()
20
    {
21 1
        $this->routes   = array();
22 1
        $this->response = Suricate::Response();
23 1
        $this->parseRequest();
24
25
        // Get app base URI, to transform real path before passing to route
26 1
        $this->baseUri = Suricate::App()->getParameter('base_uri');
27 1
    }
28
29
    public function configure($parameters = array())
30
    {
31
32
        foreach ($parameters as $routeName => $routeData) {
33
            if (isset($routeData['isRest']) && $routeData['isRest']) {
34
                $this->buildRestRoutes($routeName, $routeData);
35
            } else {
36
                $this->buildRoute($routeName, $routeData);
37
            }
38
        }
39
    }
40
41
    private function buildRoute($routeName, $routeData) {
42
        if (isset($routeData['target'])) {
43
            $routeTarget = explode('::', $routeData['target']);
44
        } else {
45
            $routeTarget = null;
46
        }
47
        $routeMethod    = isset($routeData['method']) ? $routeData['method'] : 'any';
48
        $parameters     = isset($routeData['parameters']) ? $routeData['parameters'] : array();
49
        
50
51
        if (isset($routeData['middleware'])) {
52
            $middleware = (array)$routeData['middleware'];
53
        } else {
54
            $middleware = array(); 
55
        }
56
57
        $this->addRoute(
58
            $routeName,
59
            $routeMethod,
60
            $routeData['path'],
61
            $routeTarget,
62
            $parameters,
63
            $middleware
64
        );
65
    }
66
67
    private function buildRestRoutes($routeBaseName, $routeBaseData)
68
    {
69
        // If route has a parameters array defined, take the first defined 
70
        // argument as ":id" parameter, and use key as parameter name
71
        // otherwise, default to id => [0-9]*
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
72
        if (isset($routeBaseData['parameters'])
73
            && is_array($routeBaseData['parameters'])) {
74
            reset($routeBaseData['parameters']);
75
            $primaryParameterName = key($routeBaseData['parameters']);
76
77
            $routeParameters = dataGet($routeBaseData, 'parameters', []);
78
        } else {
79
            $primaryParameterName       = 'id';
80
            $primaryParameterPattern    = '[0-9]*';
81
82
            $routeParameters = array_merge(
83
                [$primaryParameterName => $primaryParameterPattern],
84
                dataGet($routeBaseData, 'parameters', [])
85
            );
86
        }
87
        
88
        $resources = [
89
            'index'     => ['method' => 'GET',      'append' => ''],
90
            'create'    => ['method' => 'GET',      'append' => '/create'],
91
            'store'     => ['method' => 'POST',     'append' => ''],
92
            'show'      => ['method' => 'GET',      'append' => '/:' . $primaryParameterName],
93
            'edit'      => ['method' => 'GET',      'append' => '/:' . $primaryParameterName . '/edit'],
94
            'update'    => ['method' => 'PUT',      'append' => '/:' . $primaryParameterName],
95
            'destroy'   => ['method' => 'DELETE',   'append' => '/:' . $primaryParameterName],
96
        ];
97
98
        foreach ($resources as $name => $definition) {
99
            $routeName                  = $routeBaseName . '.' . $name;
100
            $routeData                  = $routeBaseData;
101
            $routeData['method']        = $definition['method'];
102
            $routeData['path']         .= $definition['append'];
103
            $routeData['target']       .= '::' . $name;
104
            $routeData['parameters']    = $routeParameters;
105
            
106
            $this->buildRoute($routeName, $routeData);
107
        }
108
    }
109
110 1
    private function parseRequest()
111
    {
112 1
        $this->requestUri = Suricate::Request()->getRequestUri();
113 1
        $this->response->setRequestUri($this->requestUri);
114 1
    }
115
116
    public function addRoute($routeName, $routeMethod, $routePath, $routeTarget, $parametersDefinitions, $middleware = null)
117
    {
118
        $computedRoutePath = ($this->baseUri != '/') ? $this->baseUri . $routePath : $routePath;
119
        $this->routes[$routeName] = new Route(
120
            $routeName,
121
            $routeMethod,
122
            $computedRoutePath,
123
            Suricate::Request(),
124
            $routeTarget,
125
            $parametersDefinitions,
126
            $middleware
127
        );
128
    }
129
130
    public function addMiddleware($middleware)
131
    {
132
        array_unshift($this->appMiddlewares, $middleware);
133
134
        return $this;
135
    }
136
137
    public function getMiddlewares()
138
    {
139
        return $this->appMiddlewares;
140
    }
141
142 1
    public function getResponse()
143
    {
144 1
        return $this->response;
145
    }
146
    /**
147
     * Loop through each defined routes, to find good one
148
     * @return null
149
     */
150
    public function doRouting()
151
    {
152
        $hasRoute = false;
153
154
        foreach ($this->routes as $route) {
155
            if ($route->isMatched) {
156
                $hasRoute = true;
157
158
                Suricate::Logger()->debug('Route "' . $route->getPath() . '" matched, target: ' . json_encode($route->target));
159
                $result = $route->dispatch($this->response, $this->appMiddlewares);
160
                if ($result === false) {
161
                    break;
162
                }
163
            }
164
        }
165
166
        // No route matched
167
        if (!$hasRoute) {
168
            Suricate::Logger()->debug('No route found');
169
            app()->abort('404');
170
        }
171
172
        $this->response->write();
173
    }
174
}
175