Completed
Push — develop ( 64da83...d844ac )
by Mathieu
01:46
created

Router::getMiddlewares()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
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
        parent::__construct();
22
23 1
        $this->routes   = array();
24 1
        $this->response = Suricate::Response();
0 ignored issues
show
Bug introduced by
The method Response() does not exist on Suricate\Suricate. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

24
        /** @scrutinizer ignore-call */ 
25
        $this->response = Suricate::Response();
Loading history...
25 1
        $this->parseRequest();
26
27
        // Get app base URI, to transform real path before passing to route
28 1
        $this->baseUri = Suricate::App()->getParameter('base_uri');
0 ignored issues
show
Bug introduced by
The method App() does not exist on Suricate\Suricate. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

28
        $this->baseUri = Suricate::/** @scrutinizer ignore-call */ App()->getParameter('base_uri');
Loading history...
29 1
    }
30
31
    public function configure($parameters = array())
32
    {
33
34
        foreach ($parameters as $routeName => $routeData) {
35
            if (isset($routeData['isRest']) && $routeData['isRest']) {
36
                $this->buildRestRoutes($routeName, $routeData);
37
            } else {
38
                $this->buildRoute($routeName, $routeData);
39
            }
40
        }
41
    }
42
43
    private function buildRoute($routeName, $routeData)
44
    {
45
        $routeTarget = null;
46
        if (isset($routeData['target'])) {
47
            $routeTarget = explode('::', $routeData['target']);
48
        }
49
        
50
        $routeMethod    = isset($routeData['method']) ? $routeData['method'] : 'any';
51
        $parameters     = isset($routeData['parameters']) ? $routeData['parameters'] : array();
52
        
53
54
        $middleware = [];
55
        if (isset($routeData['middleware'])) {
56
            $middleware = (array)$routeData['middleware'];
57
        }
58
59
        $this->addRoute(
60
            $routeName,
61
            $routeMethod,
62
            $routeData['path'],
63
            $routeTarget,
64
            $parameters,
65
            $middleware
66
        );
67
    }
68
69
    private function buildRestRoutes($routeBaseName, $routeBaseData)
70
    {
71
        // If route has a parameters array defined, take the first defined
72
        // argument as ":id" parameter, and use key as parameter name
73
        // otherwise, default to id => [0-9]*
74
        if (isset($routeBaseData['parameters'])
75
            && is_array($routeBaseData['parameters'])) {
76
            reset($routeBaseData['parameters']);
77
            $primaryParameterName = key($routeBaseData['parameters']);
78
79
            $routeParameters = dataGet($routeBaseData, 'parameters', []);
80
        } else {
81
            $primaryParameterName       = 'id';
82
            $primaryParameterPattern    = '[0-9]*';
83
84
            $routeParameters = array_merge(
85
                [$primaryParameterName => $primaryParameterPattern],
86
                dataGet($routeBaseData, 'parameters', [])
87
            );
88
        }
89
        
90
        $resources = [
91
            'index'     => ['method' => ['GET'],                'append' => ''],
92
            'create'    => ['method' => ['GET'],                'append' => '/create'],
93
            'store'     => ['method' => ['POST', 'OPTIONS'],    'append' => ''],
94
            'show'      => ['method' => ['GET'],                'append' => '/:' . $primaryParameterName],
95
            'edit'      => ['method' => ['GET'],                'append' => '/:' . $primaryParameterName . '/edit'],
96
            'update'    => ['method' => ['PUT', 'OPTIONS'],     'append' => '/:' . $primaryParameterName],
97
            'destroy'   => ['method' => ['DELETE', 'OPTIONS'],  'append' => '/:' . $primaryParameterName],
98
        ];
99
100
        foreach ($resources as $name => $definition) {
101
            $routeName                  = $routeBaseName . '.' . $name;
102
            $routeData                  = $routeBaseData;
103
            $routeData['method']        = $definition['method'];
104
            $routeData['path']         .= $definition['append'];
105
            $routeData['target']       .= '::' . $name;
106
            $routeData['parameters']    = $routeParameters;
107
            
108
            $this->buildRoute($routeName, $routeData);
109
        }
110
    }
111
112 1
    private function parseRequest()
113
    {
114 1
        $this->requestUri = Suricate::Request()->getRequestUri();
0 ignored issues
show
Bug introduced by
The method Request() does not exist on Suricate\Suricate. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

114
        $this->requestUri = Suricate::/** @scrutinizer ignore-call */ Request()->getRequestUri();
Loading history...
115 1
        $this->response->setRequestUri($this->requestUri);
116 1
    }
117
118
    public function addRoute($routeName, $routeMethod, $routePath, $routeTarget, $parametersDefinitions, $middleware = null)
119
    {
120
        $computedRoutePath = ($this->baseUri != '/') ? $this->baseUri . $routePath : $routePath;
121
        $this->routes[$routeName] = new Route(
122
            $routeName,
123
            $routeMethod,
124
            $computedRoutePath,
125
            Suricate::Request(),
126
            $routeTarget,
127
            $parametersDefinitions,
128
            $middleware
129
        );
130
    }
131
132
    public function addMiddleware($middleware)
133
    {
134
        array_unshift($this->appMiddlewares, $middleware);
135
136
        return $this;
137
    }
138
139
    public function getMiddlewares()
140
    {
141
        return $this->appMiddlewares;
142
    }
143
144 1
    public function getResponse()
145
    {
146 1
        return $this->response;
147
    }
148
    /**
149
     * Loop through each defined routes, to find good one
150
     * @return null
151
     */
152
    public function doRouting()
153
    {
154
        $hasRoute = false;
155
156
        foreach ($this->routes as $route) {
157
            if ($route->isMatched) {
158
                $hasRoute = true;
159
160
                Suricate::Logger()->debug('Route "' . $route->getPath() . '" matched, target: ' . json_encode($route->target));
0 ignored issues
show
Bug introduced by
The method Logger() does not exist on Suricate\Suricate. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

160
                Suricate::/** @scrutinizer ignore-call */ 
161
                          Logger()->debug('Route "' . $route->getPath() . '" matched, target: ' . json_encode($route->target));
Loading history...
161
                $result = $route->dispatch($this->response, $this->appMiddlewares);
162
                if ($result === false) {
163
                    break;
164
                }
165
            }
166
        }
167
168
        // No route matched
169
        if (!$hasRoute) {
170
            Suricate::Logger()->debug('No route found');
171
            app()->abort('404');
172
        }
173
174
        $this->response->write();
175
    }
176
}
177