summaryrefslogtreecommitdiffstats
path: root/system/core/Router.php
diff options
context:
space:
mode:
Diffstat (limited to 'system/core/Router.php')
-rw-r--r--system/core/Router.php144
1 files changed, 75 insertions, 69 deletions
diff --git a/system/core/Router.php b/system/core/Router.php
index a5e29f1a3..01f44bc83 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Router Class
@@ -53,13 +54,6 @@ class CI_Router {
public $routes = array();
/**
- * List of error routes
- *
- * @var array
- */
- public $error_routes = array();
-
- /**
* Current class name
*
* @var string
@@ -148,12 +142,12 @@ class CI_Router {
include(APPPATH.'config/routes.php');
}
- $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
+ $this->routes = (isset($route) && is_array($route)) ? $route : array();
unset($route);
// Set the default controller so we can display it in the event
// the URI doesn't correlated to a valid controller.
- $this->default_controller = empty($this->routes['default_controller']) ? FALSE : strtolower($this->routes['default_controller']);
+ $this->default_controller = empty($this->routes['default_controller']) ? FALSE : $this->routes['default_controller'];
// Were there any query string segments? If so, we'll validate them and bail out since we're done.
if (count($segments) > 0)
@@ -185,25 +179,21 @@ class CI_Router {
*/
protected function _set_default_controller()
{
- if ($this->default_controller === FALSE)
+ if (empty($this->default_controller))
{
show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
}
+
// Is the method being specified?
- if (strpos($this->default_controller, '/') !== FALSE)
- {
- $x = explode('/', $this->default_controller);
- $this->set_class($x[0]);
- $this->set_method($x[1]);
- $this->_set_request($x);
- }
- else
+ if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
{
- $this->set_class($this->default_controller);
- $this->set_method('index');
- $this->_set_request(array($this->default_controller, 'index'));
+ $method = 'index';
}
+ $this->set_class($class);
+ $this->set_method($method);
+ $this->_set_request(array($class, $method));
+
// re-index the routed segments array so it starts with 1 rather than 0
$this->uri->_reindex_segments();
@@ -232,17 +222,8 @@ class CI_Router {
$this->set_class($segments[0]);
- if (isset($segments[1]))
- {
- // A standard method request
- $this->set_method($segments[1]);
- }
- else
- {
- // This lets the "routed" segment array identify that the default
- // index method is being used.
- $segments[1] = 'index';
- }
+ isset($segments[1]) OR $segments[1] = 'index';
+ $this->set_method($segments[1]);
// Update our "routed" segment array to contain the segments.
// Note: If there is no custom routing, this array will be
@@ -267,9 +248,13 @@ class CI_Router {
return $segments;
}
+ $temp = str_replace('-', '_', $segments[0]);
+
// Does the requested controller exist in the root folder?
- if (file_exists(APPPATH.'controllers/'.$segments[0].'.php'))
+ if (file_exists(APPPATH.'controllers/'.$temp.'.php'))
{
+ $segments[0] = $temp;
+ empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
return $segments;
}
@@ -277,22 +262,19 @@ class CI_Router {
if (is_dir(APPPATH.'controllers/'.$segments[0]))
{
// Set the directory and remove it from the segment array
- $this->set_directory($segments[0]);
- $segments = array_slice($segments, 1);
-
+ $this->set_directory(array_shift($segments));
if (count($segments) > 0)
{
+ $segments[0] = str_replace('-', '_', $segments[0]);
+ empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]);
+
// Does the requested controller exist in the sub-folder?
if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
{
if ( ! empty($this->routes['404_override']))
{
- $x = explode('/', $this->routes['404_override']);
- $this->set_directory('');
- $this->set_class($x[0]);
- $this->set_method(isset($x[1]) ? $x[1] : 'index');
-
- return $x;
+ $this->directory = '';
+ return explode('/', $this->routes['404_override'], 2);
}
else
{
@@ -303,40 +285,26 @@ class CI_Router {
else
{
// Is the method being specified in the route?
- if (strpos($this->default_controller, '/') !== FALSE)
- {
- $x = explode('/', $this->default_controller);
- $this->set_class($x[0]);
- $this->set_method($x[1]);
- }
- else
- {
- $this->set_class($this->default_controller);
- $this->set_method('index');
- }
-
- // Does the default controller exist in the sub-folder?
- if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
+ $segments = explode('/', $this->default_controller);
+ if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
{
$this->directory = '';
- return array();
}
-
}
return $segments;
}
-
// If we've gotten this far it means that the URI does not correlate to a valid
// controller class. We will now see if there is an override
if ( ! empty($this->routes['404_override']))
{
- $x = explode('/', $this->routes['404_override']);
- $this->set_class($x[0]);
- $this->set_method(isset($x[1]) ? $x[1] : 'index');
+ if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+ {
+ $method = 'index';
+ }
- return $x;
+ return array($class, $method);
}
// Nothing else to do at this point but show a 404
@@ -359,7 +327,7 @@ class CI_Router {
$uri = implode('/', $this->uri->segments);
// Is there a literal match? If so we're done
- if (isset($this->routes[$uri]))
+ if (isset($this->routes[$uri]) && is_string($this->routes[$uri]))
{
return $this->_set_request(explode('/', $this->routes[$uri]));
}
@@ -371,10 +339,48 @@ class CI_Router {
$key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
// Does the RegEx match?
- if (preg_match('#^'.$key.'$#', $uri))
+ if (preg_match('#^'.$key.'$#', $uri, $matches))
{
- // Do we have a back-reference?
- if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
+ // Are we using callbacks to process back-references?
+ if ( ! is_string($val) && is_callable($val))
+ {
+ // Remove the original string from the matches array.
+ array_shift($matches);
+
+ // Get the match count.
+ $match_count = count($matches);
+
+ // Determine how many parameters the callback has.
+ $reflection = new ReflectionFunction($val);
+ $param_count = $reflection->getNumberOfParameters();
+
+ // Are there more parameters than matches?
+ if ($param_count > $match_count)
+ {
+ // Any params without matches will be set to an empty string.
+ $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, ''));
+
+ $match_count = $param_count;
+ }
+
+ // Get the parameters so we can use their default values.
+ $params = $reflection->getParameters();
+
+ for ($m = 0; $m < $match_count; $m++)
+ {
+ // Is the match empty and does a default value exist?
+ if (empty($matches[$m]) && $params[$m]->isDefaultValueAvailable())
+ {
+ // Substitute the empty match for the default value.
+ $matches[$m] = $params[$m]->getDefaultValue();
+ }
+ }
+
+ // Execute the callback using the values in matches as its parameters.
+ $val = call_user_func_array($val, $matches);
+ }
+ // Are we using the default routing method for back-references?
+ elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
{
$val = preg_replace('#^'.$key.'$#', $val, $uri);
}
@@ -493,7 +499,7 @@ class CI_Router {
if (isset($routing['function']))
{
- $routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
+ $routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
$this->set_method($routing['function']);
}
}