Passed
Push — master ( ad31bb...824b59 )
by Mikael
02:28 queued 17s
created

RouterInjectable   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 86.44%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 23
c 2
b 0
f 1
lcom 1
cbo 2
dl 0
loc 248
ccs 51
cts 59
cp 0.8644
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
C handle() 0 25 7
A handleInternal() 0 9 2
A any() 0 14 4
A add() 0 4 1
A all() 0 4 1
A get() 0 4 1
A post() 0 4 1
A put() 0 4 1
A delete() 0 4 1
A addInternal() 0 7 1
A getLastRoute() 0 4 1
A getAll() 0 4 1
A getInternal() 0 4 1
1
<?php
2
3
namespace Anax\Route;
4
5
/**
6
 * A container for routes.
7
 */
8
class RouterInjectable
9
{
10
    /**
11
     * @var array       $routes         all the routes.
12
     * @var array       $internalRoutes all internal routes.
13
     * @var null|string $lastRoute      last route that was matched and called.
14
     */
15
    private $routes         = [];
16
    private $internalRoutes = [];
17
    private $lastRoute      = null;
18
19
20
21
    /**
22
     * Handle the routes and match them towards the request, dispatch them
23
     * when a match is made. Each route handler may throw exceptions that
24
     * may redirect to an internal route for error handling.
25
     * Several routes can match and if the routehandler does not break
26
     * execution flow, the route matching will carry on.
27
     * Only the last routehandler will get its return value returned further.
28
     *
29
     * @param string $path    the path to find a matching handler for.
30
     * @param string $method  the request method to match.
31
     *
32
     * @return mixed content returned from route.
33
     */
34 13
    public function handle($path, $method = null)
35
    {
36
        try {
37 13
            $match = false;
38 13
            foreach ($this->routes as $route) {
39 12
                if ($route->match($path, $method)) {
40 12
                    $this->lastRoute = $route->getRule();
41 12
                    $match = true;
42 12
                    $results = $route->handle();
43 9
                }
44 10
            }
45
46 10
            if ($match) {
47 9
                return $results;
0 ignored issues
show
Bug introduced by
The variable $results does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
48
            }
49
50 1
            $this->handleInternal("404");
51 4
        } catch (ForbiddenException $e) {
52 1
            $this->handleInternal("403");
53 3
        } catch (NotFoundException $e) {
54 2
            $this->handleInternal("404");
55 1
        } catch (InternalErrorException $e) {
56 1
            $this->handleInternal("500");
57
        }
58
    }
59
60
61
62
    /**
63
     * Handle an internal route, the internal routes are not exposed to the
64
     * end user.
65
     *
66
     * @param string $rule for this route.
67
     *
68
     * @return void
69
     *
70
     * @throws \Anax\Route\NotFoundException
71
     */
72 4
    public function handleInternal($rule)
73
    {
74 4
        if (!isset($this->internalRoutes[$rule])) {
75 1
            throw new NotFoundException("No internal route to handle: " . $rule);
76
        }
77 3
        $route = $this->internalRoutes[$rule];
78 3
        $this->lastRoute = $rule;
79 3
        $route->handle();
80
    }
81
82
83
84
    /**
85
     * Add a route with a request method, a path rule to match and an action
86
     * as the callback. Adding several path rules (array) results in several
87
     * routes being created.
88
     *
89
     * @param null|string|array    $method as a valid request method.
90
     * @param null|string|array    $rule   path rule for this route.
91
     * @param null|string|callable $action to implement a handler for the route.
92
     *
93
     * @return class|array as new route(s), class if one added, else array.
94
     */
95 13
    public function any($method, $rule, $action)
96
    {
97 13
        $rules = is_array($rule) ? $rule : [$rule];
98
99 13
        $routes = [];
100 13
        foreach ($rules as $val) {
101 13
            $route = new Route();
102 13
            $route->set($val, $action, $method);
103 13
            $routes[] = $route;
104 13
            $this->routes[] = $route;
105 13
        }
106
107 13
        return count($routes) === 1 ? $routes[0] : $routes;
108
    }
109
110
111
112
    /**
113
     * Add a route to the router by rule(s) and a callback.
114
     *
115
     * @param null|string|array    $rule   for this route.
116
     * @param null|string|callable $action a callback handler for the route.
117
     *
118
     * @return class|array as new route(s), class if one added, else array.
119
     */
120 10
    public function add($rule, $action)
121
    {
122 10
        return $this->any(null, $rule, $action);
123
    }
124
125
126
127
    /**
128
     * Add a default route which will be applied for any path, if the choosen
129
     * request method is matching.
130
     *
131
     * @param null|string|array    $method as request methods
132
     * @param null|string|callable $action a callback handler for the route.
133
     *
134
     * @return class|array as new route(s), class if one added, else array.
135
     */
136 1
    public function all($method, $action)
137
    {
138 1
        return $this->any($method, null, $action);
139
    }
140
141
142
143
    /**
144
     * Shortcut to add a GET route.
145
     *
146
     * @param null|string|array    $method as request methods
0 ignored issues
show
Bug introduced by
There is no parameter named $method. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
147
     * @param null|string|callable $action a callback handler for the route.
148
     *
149
     * @return class|array as new route(s), class if one added, else array.
150
     */
151 1
    public function get($rule, $action)
152
    {
153 1
        return $this->any(["GET"], $rule, $action);
154
    }
155
156
157
158
    /**
159
    * Shortcut to add a POST route.
160
     *
161
     * @param null|string|array    $method as request methods
0 ignored issues
show
Bug introduced by
There is no parameter named $method. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
162
     * @param null|string|callable $action a callback handler for the route.
163
     *
164
     * @return class|array as new route(s), class if one added, else array.
165
     */
166 1
    public function post($rule, $action)
167
    {
168 1
        return $this->any(["POST"], $rule, $action);
169
    }
170
171
172
173
    /**
174
    * Shortcut to add a PUT route.
175
     *
176
     * @param null|string|array    $method as request methods
0 ignored issues
show
Bug introduced by
There is no parameter named $method. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
177
     * @param null|string|callable $action a callback handler for the route.
178
     *
179
     * @return class|array as new route(s), class if one added, else array.
180
     */
181 1
    public function put($rule, $action)
182
    {
183 1
        return $this->any(["PUT"], $rule, $action);
184
    }
185
186
187
188
    /**
189
    * Shortcut to add a DELETE route.
190
     *
191
     * @param null|string|array    $method as request methods
0 ignored issues
show
Bug introduced by
There is no parameter named $method. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
192
     * @param null|string|callable $action a callback handler for the route.
193
     *
194
     * @return class|array as new route(s), class if one added, else array.
195
     */
196 1
    public function delete($rule, $action)
197
    {
198 1
        return $this->any(["DELETE"], $rule, $action);
199
    }
200
201
202
203
    /**
204
     * Add an internal route to the router, this route is not exposed to the
205
     * browser and the end user.
206
     *
207
     * @param string               $rule   for this route
208
     * @param null|string|callable $action a callback handler for the route.
209
     *
210
     * @return class|array as new route(s), class if one added, else array.
211
     */
212 3
    public function addInternal($rule, $action)
213
    {
214 3
        $route = new Route();
215 3
        $route->set($rule, $action);
216 3
        $this->internalRoutes[$rule] = $route;
217 3
        return $route;
218
    }
219
220
221
222
    /**
223
     * Get the route for the last route that was handled.
224
     *
225
     * @return mixed
226
     */
227
    public function getLastRoute()
228
    {
229
        return $this->lastRoute;
230
    }
231
232
233
234
    /**
235
     * Get all routes.
236
     *
237
     * @return array with all routes.
238
     */
239
    public function getAll()
240
    {
241
        return $this->routes;
242
    }
243
244
245
246
    /**
247
     * Get all internal routes.
248
     *
249
     * @return array with internal routes.
250
     */
251
    public function getInternal()
252
    {
253
        return $this->internalRoutes;
254
    }
255
}
256