Completed
Pull Request — master (#28)
by Dennis
02:49
created

CRouterBasic::handle()   F

Complexity

Conditions 14
Paths 735

Size

Total Lines 82
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 0 Features 0
Metric Value
cc 14
eloc 39
c 9
b 0
f 0
nc 735
nop 0
dl 0
loc 82
rs 2.439

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Anax\Route;
4
5
/**
6
 * A container for routes.
7
 *
8
 */
9
class CRouterBasic implements \Anax\DI\IInjectionAware
10
{
11
    use \Anax\DI\TInjectionAware;
12
13
14
15
    /**
16
     * Properties
17
     *
18
     */
19
    private $routes         = [];    // All the routes
20
    private $internalRoutes = [];    // All internal routes
21
    private $defaultRoute   = null;  // A default rout to catch all
22
23
24
25
    /**
26
     * Get all routes.
27
     *
28
     * @return array with all routes.
29
     */
30
    public function getAll()
31
    {
32
        return $this->routes;
33
    }
34
35
36
37
    /**
38
     * Get all internal routes.
39
     *
40
     * @return array with internal routes.
41
     */
42
    public function getInternal()
43
    {
44
        return $this->internalRoutes;
45
    }
46
47
48
49
    /**
50
     * Add a route to the router.
51
     *
52
     * @param string $rule   for this route
53
     * @param mixed  $action null, string or callable to implement a controller for the route
54
     *
55
     * @return object as new route
56
     */
57
    public function add($rule, $action = null)
58
    {
59
        $route = $this->di->get('route');
60
        $route->set($rule, $action);
61
        $this->routes[] = $route;
62
63
        // Set as default route
64
        if ($rule == "*") {
65
            $this->defaultRoute = $route;
66
        }
67
        
68
        return $route;
69
    }
70
71
72
73
    /**
74
     * Add an internal (not exposed to url-matching) route to the router.
75
     *
76
     * @param string $rule   for this route
77
     * @param mixed  $action null, string or callable to implement a controller for the route
78
     *
79
     * @return object as new route
80
     */
81
    public function addInternal($rule, $action = null)
82
    {
83
        $route = $this->di->get('route');
84
        $route->set($rule, $action);
85
        $this->internalRoutes[$rule] = $route;
86
        return $route;
87
    }
88
89
90
    /**
91
     * Add an internal (not exposed to url-matching) route to the router.
92
     *
93
     * @param string $rule for this route
94
     *
95
     * @return object as new route
96
     * @throws \Anax\Exception\NotFoundException
97
     */
98
    public function handleInternal($rule)
99
    {
100
        if (isset($this->internalRoutes[$rule])) {
101
            $route = $this->internalRoutes[$rule];
102
            $route->handle();
103
        } else {
104
            throw new \Anax\Exception\NotFoundException("No internal route to handle: " . $rule);
105
        }
106
    }
107
108
109
    /**
110
     * Handle the routes and match them towards the request, dispatch them when a match is made.
111
     *
112
     * @return $this
113
     * @throws \Anax\Exception\NotFoundException
114
     * @throws \Exception
115
     */
116
    public function handle()
117
    {
118
        try {
119
120
            $query = $this->di->request->getRoute();
121
            $parts = $this->di->request->getRouteParts();
122
123
            // Match predefined routes
124
            foreach ($this->routes as $route) {
125
                if ($route->match($query)) {
126
                    return $route->handle();
127
                }
128
            }
129
130
            // Default handling route as :controller/:action/:params using the dispatcher
131
            $dispatcher = $this->di->dispatcher;
132
133
            $dispatcher->setControllerName();
134
135
            // Checks if the first part is a valid controller.
136
            if (isset($parts[0])) {
137
                $dispatcher->setControllerName($parts[0]);
138
139
                // If not valid then ignore the first param and sets the default.
140
                if ($dispatcher->isValidController()) {
141
                    array_shift($parts);
142
                } else {
143
                    $dispatcher->setControllerName();
144
                }
145
            }
146
147
            if ($dispatcher->isValidController()) {
148
149
                // Checks if a action is set. If not then will use index action.
150
                $dispatcher->setActionName();
151
152
                if (isset($parts[0])) {
153
                    $dispatcher->setActionName($parts[0]);
154
155
                    if ($dispatcher->isCallable()) {
156
                        array_shift($parts);
157
                    } else {
158
                        $dispatcher->setActionName();
159
                    }
160
                }
161
162
                if ($dispatcher->isCallable()) {
163
164
                    $parts = !empty($parts) ? $parts : [];
165
                    $dispatcher->setParams($parts);
166
167
                    // Checks if the are correct number of params that the action accepts
168
                    if ($dispatcher->isParamsValid()) {
169
                        return $dispatcher->dispatch();
170
                    }
171
                }
172
173
            }
174
175
            // Use the "catch-all" route
176
            if ($this->defaultRoute) {
177
                return $this->defaultRoute->handle();
178
            }
179
180
            // No route was matched
181
            $this->handleInternal('404');
182
        
183
        } catch (\Exception $e) {
184
185
            // Exception codes can match a route for a http status code
186
            $code = $e->getCode();
187
            $statusCodes = [403, 404, 500];
188
            if (in_array($code, $statusCodes)) {
189
190
                $this->di->flash->setMessage($e->getMessage());
191
                $this->handleInternal($code);
192
            
193
            } else {
194
                throw $e;
195
            }
196
        }
197
    }
198
}
199