]> jfr.im git - z_archive/KronOS.git/blob - video/system/core/Router.php
Merge branch 'master' of https://github.com/Mustis/WebOsProject
[z_archive/KronOS.git] / video / system / core / Router.php
1 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2 /**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package CodeIgniter
8 * @author ExpressionEngine Dev Team
9 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
10 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16 // ------------------------------------------------------------------------
17
18 /**
19 * Router Class
20 *
21 * Parses URIs and determines routing
22 *
23 * @package CodeIgniter
24 * @subpackage Libraries
25 * @author ExpressionEngine Dev Team
26 * @category Libraries
27 * @link http://codeigniter.com/user_guide/general/routing.html
28 */
29 class CI_Router {
30
31 /**
32 * Config class
33 *
34 * @var object
35 * @access public
36 */
37 var $config;
38 /**
39 * List of routes
40 *
41 * @var array
42 * @access public
43 */
44 var $routes = array();
45 /**
46 * List of error routes
47 *
48 * @var array
49 * @access public
50 */
51 var $error_routes = array();
52 /**
53 * Current class name
54 *
55 * @var string
56 * @access public
57 */
58 var $class = '';
59 /**
60 * Current method name
61 *
62 * @var string
63 * @access public
64 */
65 var $method = 'index';
66 /**
67 * Sub-directory that contains the requested controller class
68 *
69 * @var string
70 * @access public
71 */
72 var $directory = '';
73 /**
74 * Default controller (and method if specific)
75 *
76 * @var string
77 * @access public
78 */
79 var $default_controller;
80
81 /**
82 * Constructor
83 *
84 * Runs the route mapping function.
85 */
86 function __construct()
87 {
88 $this->config =& load_class('Config', 'core');
89 $this->uri =& load_class('URI', 'core');
90 log_message('debug', "Router Class Initialized");
91 }
92
93 // --------------------------------------------------------------------
94
95 /**
96 * Set the route mapping
97 *
98 * This function determines what should be served based on the URI request,
99 * as well as any "routes" that have been set in the routing config file.
100 *
101 * @access private
102 * @return void
103 */
104 function _set_routing()
105 {
106 // Are query strings enabled in the config file? Normally CI doesn't utilize query strings
107 // since URI segments are more search-engine friendly, but they can optionally be used.
108 // If this feature is enabled, we will gather the directory/class/method a little differently
109 $segments = array();
110 if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
111 {
112 if (isset($_GET[$this->config->item('directory_trigger')]))
113 {
114 $this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
115 $segments[] = $this->fetch_directory();
116 }
117
118 if (isset($_GET[$this->config->item('controller_trigger')]))
119 {
120 $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
121 $segments[] = $this->fetch_class();
122 }
123
124 if (isset($_GET[$this->config->item('function_trigger')]))
125 {
126 $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
127 $segments[] = $this->fetch_method();
128 }
129 }
130
131 // Load the routes.php file.
132 if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
133 {
134 include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
135 }
136 elseif (is_file(APPPATH.'config/routes.php'))
137 {
138 include(APPPATH.'config/routes.php');
139 }
140
141 $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
142 unset($route);
143
144 // Set the default controller so we can display it in the event
145 // the URI doesn't correlated to a valid controller.
146 $this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);
147
148 // Were there any query string segments? If so, we'll validate them and bail out since we're done.
149 if (count($segments) > 0)
150 {
151 return $this->_validate_request($segments);
152 }
153
154 // Fetch the complete URI string
155 $this->uri->_fetch_uri_string();
156
157 // Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
158 if ($this->uri->uri_string == '')
159 {
160 return $this->_set_default_controller();
161 }
162
163 // Do we need to remove the URL suffix?
164 $this->uri->_remove_url_suffix();
165
166 // Compile the segments into an array
167 $this->uri->_explode_segments();
168
169 // Parse any custom routing that may exist
170 $this->_parse_routes();
171
172 // Re-index the segment array so that it starts with 1 rather than 0
173 $this->uri->_reindex_segments();
174 }
175
176 // --------------------------------------------------------------------
177
178 /**
179 * Set the default controller
180 *
181 * @access private
182 * @return void
183 */
184 function _set_default_controller()
185 {
186 if ($this->default_controller === FALSE)
187 {
188 show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
189 }
190 // Is the method being specified?
191 if (strpos($this->default_controller, '/') !== FALSE)
192 {
193 $x = explode('/', $this->default_controller);
194
195 $this->set_class($x[0]);
196 $this->set_method($x[1]);
197 $this->_set_request($x);
198 }
199 else
200 {
201 $this->set_class($this->default_controller);
202 $this->set_method('index');
203 $this->_set_request(array($this->default_controller, 'index'));
204 }
205
206 // re-index the routed segments array so it starts with 1 rather than 0
207 $this->uri->_reindex_segments();
208
209 log_message('debug', "No URI present. Default controller set.");
210 }
211
212 // --------------------------------------------------------------------
213
214 /**
215 * Set the Route
216 *
217 * This function takes an array of URI segments as
218 * input, and sets the current class/method
219 *
220 * @access private
221 * @param array
222 * @param bool
223 * @return void
224 */
225 function _set_request($segments = array())
226 {
227 $segments = $this->_validate_request($segments);
228
229 if (count($segments) == 0)
230 {
231 return $this->_set_default_controller();
232 }
233
234 $this->set_class($segments[0]);
235
236 if (isset($segments[1]))
237 {
238 // A standard method request
239 $this->set_method($segments[1]);
240 }
241 else
242 {
243 // This lets the "routed" segment array identify that the default
244 // index method is being used.
245 $segments[1] = 'index';
246 }
247
248 // Update our "routed" segment array to contain the segments.
249 // Note: If there is no custom routing, this array will be
250 // identical to $this->uri->segments
251 $this->uri->rsegments = $segments;
252 }
253
254 // --------------------------------------------------------------------
255
256 /**
257 * Validates the supplied segments. Attempts to determine the path to
258 * the controller.
259 *
260 * @access private
261 * @param array
262 * @return array
263 */
264 function _validate_request($segments)
265 {
266 if (count($segments) == 0)
267 {
268 return $segments;
269 }
270
271 // Does the requested controller exist in the root folder?
272 if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
273 {
274 return $segments;
275 }
276
277 // Is the controller in a sub-folder?
278 if (is_dir(APPPATH.'controllers/'.$segments[0]))
279 {
280 // Set the directory and remove it from the segment array
281 $this->set_directory($segments[0]);
282 $segments = array_slice($segments, 1);
283
284 if (count($segments) > 0)
285 {
286 // Does the requested controller exist in the sub-folder?
287 if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
288 {
289 if ( ! empty($this->routes['404_override']))
290 {
291 $x = explode('/', $this->routes['404_override']);
292
293 $this->set_directory('');
294 $this->set_class($x[0]);
295 $this->set_method(isset($x[1]) ? $x[1] : 'index');
296
297 return $x;
298 }
299 else
300 {
301 show_404($this->fetch_directory().$segments[0]);
302 }
303 }
304 }
305 else
306 {
307 // Is the method being specified in the route?
308 if (strpos($this->default_controller, '/') !== FALSE)
309 {
310 $x = explode('/', $this->default_controller);
311
312 $this->set_class($x[0]);
313 $this->set_method($x[1]);
314 }
315 else
316 {
317 $this->set_class($this->default_controller);
318 $this->set_method('index');
319 }
320
321 // Does the default controller exist in the sub-folder?
322 if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
323 {
324 $this->directory = '';
325 return array();
326 }
327
328 }
329
330 return $segments;
331 }
332
333
334 // If we've gotten this far it means that the URI does not correlate to a valid
335 // controller class. We will now see if there is an override
336 if ( ! empty($this->routes['404_override']))
337 {
338 $x = explode('/', $this->routes['404_override']);
339
340 $this->set_class($x[0]);
341 $this->set_method(isset($x[1]) ? $x[1] : 'index');
342
343 return $x;
344 }
345
346
347 // Nothing else to do at this point but show a 404
348 show_404($segments[0]);
349 }
350
351 // --------------------------------------------------------------------
352
353 /**
354 * Parse Routes
355 *
356 * This function matches any routes that may exist in
357 * the config/routes.php file against the URI to
358 * determine if the class/method need to be remapped.
359 *
360 * @access private
361 * @return void
362 */
363 function _parse_routes()
364 {
365 // Turn the segment array into a URI string
366 $uri = implode('/', $this->uri->segments);
367
368 // Is there a literal match? If so we're done
369 if (isset($this->routes[$uri]))
370 {
371 return $this->_set_request(explode('/', $this->routes[$uri]));
372 }
373
374 // Loop through the route array looking for wild-cards
375 foreach ($this->routes as $key => $val)
376 {
377 // Convert wild-cards to RegEx
378 $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
379
380 // Does the RegEx match?
381 if (preg_match('#^'.$key.'$#', $uri))
382 {
383 // Do we have a back-reference?
384 if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
385 {
386 $val = preg_replace('#^'.$key.'$#', $val, $uri);
387 }
388
389 return $this->_set_request(explode('/', $val));
390 }
391 }
392
393 // If we got this far it means we didn't encounter a
394 // matching route so we'll set the site default route
395 $this->_set_request($this->uri->segments);
396 }
397
398 // --------------------------------------------------------------------
399
400 /**
401 * Set the class name
402 *
403 * @access public
404 * @param string
405 * @return void
406 */
407 function set_class($class)
408 {
409 $this->class = str_replace(array('/', '.'), '', $class);
410 }
411
412 // --------------------------------------------------------------------
413
414 /**
415 * Fetch the current class
416 *
417 * @access public
418 * @return string
419 */
420 function fetch_class()
421 {
422 return $this->class;
423 }
424
425 // --------------------------------------------------------------------
426
427 /**
428 * Set the method name
429 *
430 * @access public
431 * @param string
432 * @return void
433 */
434 function set_method($method)
435 {
436 $this->method = $method;
437 }
438
439 // --------------------------------------------------------------------
440
441 /**
442 * Fetch the current method
443 *
444 * @access public
445 * @return string
446 */
447 function fetch_method()
448 {
449 if ($this->method == $this->fetch_class())
450 {
451 return 'index';
452 }
453
454 return $this->method;
455 }
456
457 // --------------------------------------------------------------------
458
459 /**
460 * Set the directory name
461 *
462 * @access public
463 * @param string
464 * @return void
465 */
466 function set_directory($dir)
467 {
468 $this->directory = str_replace(array('/', '.'), '', $dir).'/';
469 }
470
471 // --------------------------------------------------------------------
472
473 /**
474 * Fetch the sub-directory (if any) that contains the requested controller class
475 *
476 * @access public
477 * @return string
478 */
479 function fetch_directory()
480 {
481 return $this->directory;
482 }
483
484 // --------------------------------------------------------------------
485
486 /**
487 * Set the controller overrides
488 *
489 * @access public
490 * @param array
491 * @return null
492 */
493 function _set_overrides($routing)
494 {
495 if ( ! is_array($routing))
496 {
497 return;
498 }
499
500 if (isset($routing['directory']))
501 {
502 $this->set_directory($routing['directory']);
503 }
504
505 if (isset($routing['controller']) AND $routing['controller'] != '')
506 {
507 $this->set_class($routing['controller']);
508 }
509
510 if (isset($routing['function']))
511 {
512 $routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
513 $this->set_method($routing['function']);
514 }
515 }
516
517
518 }
519 // END Router Class
520
521 /* End of file Router.php */
522 /* Location: ./system/core/Router.php */