Completed
Branch master (740422)
by Mathieu
02:04
created

Router::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.125

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 9
ccs 3
cts 6
cp 0.5
crap 1.125
rs 9.6666
c 0
b 0
f 0
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
        $this->response = Suricate::Response();
23
        $this->parseRequest();
24
25
        // Get app base URI, to transform real path before passing to route
26
        $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
        $resources = array(
70
            'index'     => array('method' => 'GET', 'append' => ''),
71
            'create'    => array('method' => 'GET', 'append' => '/create'),
72
            'store'     => array('method' => 'POST', 'append' => ''),
73
            'show'      => array('method' => 'GET', 'append' => '/:id'),
74
            'edit'      => array('method' => 'GET', 'append' => '/:id/edit'),
75
            'update'    => array('method' => 'PUT', 'append' => '/:id'),
76
            'destroy'   => array('method' => 'DELETE', 'append' => '/:id'),
77
            );
78
79
        foreach ($resources as $name => $definition) {
80
            $routeName = $routeBaseName . '.' . $name;
81
            $routeData = $routeBaseData;
82
            $routeData['method'] = $definition['method'];
83
            $routeData['path'] .= $definition['append'];
84
            $routeData['target'] .= '::' . $name;
85
            $routeData['parameters'] = array_merge(
86
                array('id' => '[0-9]*'),
87
                dataGet($routeBaseData, 'parameters', array())
88
                );
89
90
            $this->buildRoute($routeName, $routeData);
91
        }
92
    }
93
94 1
    private function parseRequest()
95
    {
96
        $this->requestUri = Suricate::Request()->getRequestUri();
97
        $this->response->setRequestUri($this->requestUri);
98 1
    }
99
100
    public function addRoute($routeName, $routeMethod, $routePath, $routeTarget, $parametersDefinitions, $middleware = null)
101
    {
102
        $computedRoutePath = ($this->baseUri != '/') ? $this->baseUri . $routePath : $routePath;
103
        $this->routes[$routeName] = new Route(
104
            $routeName,
105
            $routeMethod,
106
            $computedRoutePath,
107
            Suricate::Request(),
108
            $routeTarget,
109
            $parametersDefinitions,
110
            $middleware
111
        );
112
    }
113
114
    public function addMiddleware($middleware)
115
    {
116
        array_unshift($this->appMiddlewares, $middleware);
117
118
        return $this;
119
    }
120
121
    public function getMiddlewares()
122
    {
123
        return $this->appMiddlewares;
124
    }
125
126 1
    public function getResponse()
127
    {
128 1
        return $this->response;
129
    }
130
    /**
131
     * Loop through each defined routes, to find good one
132
     * @return null
133
     */
134
    public function doRouting()
135
    {
136
        $hasRoute = false;
137
138
        foreach ($this->routes as $route) {
139
            if ($route->isMatched) {
140
                $hasRoute = true;
141
142
                Suricate::Logger()->debug('Route "' . $route->getPath() . '" matched, target: ' . json_encode($route->target));
143
                $result = $route->dispatch($this->response, $this->appMiddlewares);
144
                if ($result === false) {
145
                    break;
146
                }
147
            }
148
        }
149
150
        // No route matched
151
        if (!$hasRoute) {
152
            Suricate::Logger()->debug('No route found');
153
            app()->abort('404');
154
        }
155
156
        $this->response->write();
157
    }
158
}
159