Completed
Push — master ( fe5d3a...cf3b4c )
by Mathieu
05:11
created

Router   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 11.54%

Importance

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