diff --git a/system/libraries/Router.php b/system/libraries/Router.php
index b61dfb7..7839de2 100644
--- a/system/libraries/Router.php
+++ b/system/libraries/Router.php
@@ -34,6 +34,7 @@
var $routes = array();
var $class = '';
var $method = 'index';
+ var $directory = '';
var $uri_protocol = 'auto';
var $default_controller;
var $scaffolding_request = FALSE; // Must be set to FALSE
@@ -121,6 +122,7 @@
log_message('debug', "No URI present. Default controller set.");
return;
}
+ unset($this->routes['default_controller']);
// Do we need to remove the suffix specified in the config file?
if ($this->config->item('url_suffix') != "")
@@ -129,13 +131,20 @@
}
// Explode the URI Segments. The individual segments will
- // be stored in the $this->segments array.
- $this->_compile_segments(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)));
-
-
- // Remap the class/method if a route exists
- unset($this->routes['default_controller']);
+ // be stored in the $this->segments array.
+ $i = 1;
+ foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+ {
+ // Filter segments for security
+ $val = trim($this->_filter_uri($val));
+
+ if ($val != '')
+ $this->segments[$i++] = $val;
+ }
+ $this->_compile_segments($this->segments);
+
+ // Do we have any custom routing to deal with?
if (count($this->routes) > 0)
{
$this->_parse_routes();
@@ -157,19 +166,15 @@
* @param bool
* @return void
*/
- function _compile_segments($segs, $route = FALSE)
- {
- $segments = array();
-
- $i = 1;
- foreach($segs as $val)
- {
- $val = trim($this->_filter_uri($val));
-
- if ($val != '')
- $segments[$i++] = $val;
- }
+ function _compile_segments($segments = array())
+ {
+ $segments = $this->_validate_segments($segments);
+ if (count($segments) == 0)
+ {
+ return;
+ }
+
$this->set_class($segments['1']);
if (isset($segments['2']))
@@ -186,19 +191,58 @@
$this->set_method($segments['2']);
}
}
-
- if ($route == FALSE)
- {
- $this->segments = $segments;
- }
-
- unset($segments);
}
// END _compile_segments()
// --------------------------------------------------------------------
/**
+ * Validates the supplied segments. Attempts to determine the path to
+ * the controller.
+ *
+ * @access private
+ * @param array
+ * @return array
+ */
+ function _validate_segments($segments)
+ {
+ // Does the requested controller exist?
+ if ( ! file_exists(APPPATH.'controllers/'.$segments['1'].EXT))
+ {
+ // Is it a directory? No? Smite them!
+ if ( ! is_dir(APPPATH.'controllers/'.$segments['1']))
+ {
+ show_404();
+ }
+ else
+ {
+ $this->set_directory($segments['1']);
+ $segs = array_slice($segments, 1);
+
+ if (count($segs) == 0)
+ {
+ $this->set_class($this->default_controller);
+ $this->set_method('index');
+ $this->directory = '';
+ return array();
+ }
+
+ $i = 1;
+ $segments = array();
+ foreach ($segs as $val)
+ {
+ $segments[$i++] = $val;
+ }
+ }
+ }
+
+ return $segments;
+ }
+ // END _validate_segments()
+
+ // --------------------------------------------------------------------
+
+ /**
* Filter segments for malicious characters
*
* @access private
@@ -219,64 +263,6 @@
// --------------------------------------------------------------------
/**
- * Set the class name
- *
- * @access public
- * @param string
- * @return void
- */
- function set_class($class)
- {
- $this->class = $class;
- }
- // END _filter_uri()
-
- // --------------------------------------------------------------------
-
- /**
- * Fetch the current class
- *
- * @access public
- * @return string
- */
- function fetch_class()
- {
- return $this->class;
- }
- // END _filter_uri()
-
- // --------------------------------------------------------------------
-
- /**
- * Set the method name
- *
- * @access public
- * @param string
- * @return void
- */
- function set_method($method)
- {
- $this->method = $method;
- }
- // END set_method()
-
- // --------------------------------------------------------------------
-
- /**
- * Fetch the current method
- *
- * @access public
- * @return string
- */
- function fetch_method()
- {
- return $this->method;
- }
- // END set_method()
-
- // --------------------------------------------------------------------
-
- /**
* Parse Routes
*
* This function matches any routes that may exist in
@@ -295,7 +281,7 @@
// Is there a literal match? If so we're done
if (isset($this->routes[$uri]))
{
- $this->_compile_segments(explode('/', $this->routes[$uri]), TRUE);
+ $this->_compile_segments(explode('/', $this->routes[$uri]));
return;
}
@@ -308,22 +294,109 @@
// Convert wildcards to RegEx
$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
- // Does the regex match this URI ?
+ // Does the RegEx match?
if (preg_match('|^'.$key.'$|', $uri))
{
- // Do we have a replacemnt?
+ // Do we have a back-reference?
if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
{
$val = preg_replace('|^'.$key.'$|', $val, $uri);
}
- $this->_compile_segments(explode('/', $val), TRUE);
- break;
+ $this->_compile_segments(explode('/', $val));
+ return;
}
-
}
}
// END set_method()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set the class name
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function set_class($class)
+ {
+ $this->class = $class;
+ }
+ // END set_class()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch the current class
+ *
+ * @access public
+ * @return string
+ */
+ function fetch_class()
+ {
+ return $this->class;
+ }
+ // END fetch_class()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set the method name
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function set_method($method)
+ {
+ $this->method = $method;
+ }
+ // END set_method()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch the current method
+ *
+ * @access public
+ * @return string
+ */
+ function fetch_method()
+ {
+ return $this->method;
+ }
+ // END fetch_method()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set the directory name
+ *
+ * @access public
+ * @param string
+ * @return void
+ */
+ function set_directory($dir)
+ {
+ $this->directory = $dir.'/';
+ }
+ // END set_directory()
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch the sub-directory (if any) that contains the requested controller class
+ *
+ * @access public
+ * @return string
+ */
+ function fetch_directory()
+ {
+ return $this->directory;
+ }
+ // END fetch_directory()
+
}
// END Router Class
?>
\ No newline at end of file