Router_Core::setup()   F
last analyzed

Complexity

Conditions 21
Paths 3460

Size

Total Lines 119
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 21
eloc 46
c 2
b 1
f 0
nc 3460
nop 0
dl 0
loc 119
rs 2

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 defined('SYSPATH') or die('No direct access allowed.');
2
/**
3
 * Router
4
 *
5
 * $Id: Router.php 4391 2009-06-04 03:10:12Z zombor $
6
 *
7
 * @package    Core
8
 * @author     Kohana Team
9
 * @copyright  (c) 2007-2008 Kohana Team
10
 * @license    http://kohanaphp.com/license.html
11
 */
12
class Router_Core
13
{
14
    protected static $routes;
15
16
    public static $current_uri  = '';
17
    public static $query_string = '';
18
    public static $complete_uri = '';
19
    public static $routed_uri   = '';
20
    public static $url_suffix   = '';
21
22
    public static $segments;
23
    public static $rsegments;
24
25
    public static $controller;
26
    public static $controller_path;
27
28
    public static $method    = 'index';
29
    public static $arguments = array();
30
31
    /**
32
     * Router setup routine. Automatically called during Kohana setup process.
33
     *
34
     * @return  void
35
     */
36
    public static function setup()
0 ignored issues
show
Coding Style introduced by
setup uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
37
    {
38
        if (! empty($_SERVER['QUERY_STRING'])) {
39
            // Set the query string to the current query string
40
            Router::$query_string = '?'.trim($_SERVER['QUERY_STRING'], '&/');
41
        }
42
43
        if (Router::$routes === null) {
44
            // Load routes
45
            Router::$routes = Kohana::config('routes');
46
        }
47
48
        // Default route status
49
        $default_route = false;
50
51
        if (Router::$current_uri === '') {
52
            // Make sure the default route is set
53
            if (! isset(Router::$routes['_default'])) {
54
                throw new Kohana_Exception('core.no_default_route');
55
            }
56
57
            // Use the default route when no segments exist
58
            Router::$current_uri = Router::$routes['_default'];
59
60
            // Default route is in use
61
            $default_route = true;
62
        }
63
64
        // Make sure the URL is not tainted with HTML characters
65
        Router::$current_uri = html::specialchars(Router::$current_uri, false);
66
67
        // Remove all dot-paths from the URI, they are not valid
68
        Router::$current_uri = preg_replace('#\.[\s./]*/#', '', Router::$current_uri);
69
70
        // At this point segments, rsegments, and current URI are all the same
71
        Router::$segments = Router::$rsegments = Router::$current_uri = trim(Router::$current_uri, '/');
72
73
        // Set the complete URI
74
        Router::$complete_uri = Router::$current_uri.Router::$query_string;
75
76
        // Explode the segments by slashes
77
        Router::$segments = ($default_route === true or Router::$segments === '') ? array() : explode('/', Router::$segments);
78
79
        if ($default_route === false and count(Router::$routes) > 1) {
80
            // Custom routing
81
            Router::$rsegments = Router::routed_uri(Router::$current_uri);
82
        }
83
84
        // The routed URI is now complete
85
        Router::$routed_uri = Router::$rsegments;
86
87
        // Routed segments will never be empty
88
        Router::$rsegments = explode('/', Router::$rsegments);
89
90
        // Prepare to find the controller
91
        $controller_path = '';
92
        $method_segment  = null;
93
94
        // Paths to search
95
        $paths = Kohana::include_paths();
96
97
        foreach (Router::$rsegments as $key => $segment) {
98
            // Add the segment to the search path
99
            $controller_path .= $segment;
100
101
            $found = false;
102
            foreach ($paths as $dir) {
103
                // Search within controllers only
104
                $dir .= 'controllers/';
105
106
                if (is_dir($dir.$controller_path) or is_file($dir.$controller_path.EXT)) {
107
                    // Valid path
108
                    $found = true;
109
110
                    // The controller must be a file that exists with the search path
111
                    if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT))
112
                        and is_file($c) and strpos($c, $dir) === 0) {
113
                        // Set controller name
114
                        Router::$controller = $segment;
115
116
                        // Change controller path
117
                        Router::$controller_path = $c;
118
119
                        // Set the method segment
120
                        $method_segment = $key + 1;
121
122
                        // Stop searching
123
                        break;
124
                    }
125
                }
126
            }
127
128
            if ($found === false) {
129
                // Maximum depth has been reached, stop searching
130
                break;
131
            }
132
133
            // Add another slash
134
            $controller_path .= '/';
135
        }
136
137
        if ($method_segment !== null and isset(Router::$rsegments[$method_segment])) {
138
            // Set method
139
            Router::$method = Router::$rsegments[$method_segment];
140
141
            if (isset(Router::$rsegments[$method_segment + 1])) {
142
                // Set arguments
143
                Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1);
144
            }
145
        }
146
147
        // Last chance to set routing before a 404 is triggered
148
        Event::run('system.post_routing');
149
150
        if (Router::$controller === null) {
151
            // No controller was found, so no page can be rendered
152
            Event::run('system.404');
153
        }
154
    }
155
156
    /**
157
     * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF.
158
     *
159
     * @return  void
160
     */
161
    public static function find_uri()
0 ignored issues
show
Coding Style introduced by
find_uri uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
find_uri uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
162
    {
163
        if (PHP_SAPI === 'cli') {
164
            // Command line requires a bit of hacking
165
            if (isset($_SERVER['argv'][1])) {
166
                Router::$current_uri = $_SERVER['argv'][1];
167
168
                // Remove GET string from segments
169
                if (($query = strpos(Router::$current_uri, '?')) !== false) {
170
                    list(Router::$current_uri, $query) = explode('?', Router::$current_uri, 2);
171
172
                    // Parse the query string into $_GET
173
                    parse_str($query, $_GET);
174
175
                    // Convert $_GET to UTF-8
176
                    $_GET = utf8::clean($_GET);
177
                }
178
            }
179
        } elseif (isset($_GET['kohana_uri'])) {
180
            // Use the URI defined in the query string
181
            Router::$current_uri = $_GET['kohana_uri'];
182
183
            // Remove the URI from $_GET
184
            unset($_GET['kohana_uri']);
185
186
            // Remove the URI from $_SERVER['QUERY_STRING']
187
            $_SERVER['QUERY_STRING'] = preg_replace('~\bkohana_uri\b[^&]*+&?~', '', $_SERVER['QUERY_STRING']);
188
        } elseif (isset($_SERVER['PATH_INFO']) and $_SERVER['PATH_INFO']) {
189
            Router::$current_uri = $_SERVER['PATH_INFO'];
190
        } elseif (isset($_SERVER['ORIG_PATH_INFO']) and $_SERVER['ORIG_PATH_INFO']) {
191
            Router::$current_uri = $_SERVER['ORIG_PATH_INFO'];
192
        } elseif (isset($_SERVER['PHP_SELF']) and $_SERVER['PHP_SELF']) {
193
            Router::$current_uri = $_SERVER['PHP_SELF'];
194
        }
195
        
196
        if (($strpos_fc = strpos(Router::$current_uri, KOHANA)) !== false) {
197
            // Remove the front controller from the current uri
198
            Router::$current_uri = (string) substr(Router::$current_uri, $strpos_fc + strlen(KOHANA));
199
        }
200
        
201
        // Remove slashes from the start and end of the URI
202
        Router::$current_uri = trim(Router::$current_uri, '/');
203
        
204
        if (Router::$current_uri !== '') {
205
            if ($suffix = Kohana::config('core.url_suffix') and strpos(Router::$current_uri, $suffix) !== false) {
206
                // Remove the URL suffix
207
                Router::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', Router::$current_uri);
208
209
                // Set the URL suffix
210
                Router::$url_suffix = $suffix;
211
            }
212
213
            // Reduce multiple slashes into single slashes
214
            Router::$current_uri = preg_replace('#//+#', '/', Router::$current_uri);
215
        }
216
    }
217
218
    /**
219
     * Generates routed URI from given URI.
220
     *
221
     * @param  string  URI to convert
222
     * @return string  Routed uri
223
     */
224
    public static function routed_uri($uri)
225
    {
226
        if (Router::$routes === null) {
227
            // Load routes
228
            Router::$routes = Kohana::config('routes');
229
        }
230
231
        // Prepare variables
232
        $routed_uri = $uri = trim($uri, '/');
233
234
        if (isset(Router::$routes[$uri])) {
235
            // Literal match, no need for regex
236
            $routed_uri = Router::$routes[$uri];
237
        } else {
238
            // Loop through the routes and see if anything matches
239
            foreach (Router::$routes as $key => $val) {
240
                if ($key === '_default') {
241
                    continue;
242
                }
243
244
                // Trim slashes
245
                $key = trim($key, '/');
246
                $val = trim($val, '/');
247
248
                if (preg_match('#^'.$key.'$#u', $uri)) {
249
                    if (strpos($val, '$') !== false) {
250
                        // Use regex routing
251
                        $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri);
252
                    } else {
253
                        // Standard routing
254
                        $routed_uri = $val;
255
                    }
256
257
                    // A valid route has been found
258
                    break;
259
                }
260
            }
261
        }
262
263
        if (isset(Router::$routes[$routed_uri])) {
264
            // Check for double routing (without regex)
265
            $routed_uri = Router::$routes[$routed_uri];
266
        }
267
268
        return trim($routed_uri, '/');
269
    }
270
} // End Router
271