From 45c872b0ac215d590e785fe393241a06facd7e05 Mon Sep 17 00:00:00 2001 From: admin Date: Sat, 26 Aug 2006 04:51:38 +0000 Subject: --- system/libraries/Router.php | 211 +++++++++++++++++++++++++++++--------------- 1 file changed, 142 insertions(+), 69 deletions(-) (limited to 'system/libraries/Router.php') diff --git a/system/libraries/Router.php b/system/libraries/Router.php index b61dfb79c..7839de2d9 100644 --- a/system/libraries/Router.php +++ b/system/libraries/Router.php @@ -34,6 +34,7 @@ class CI_Router { 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 @@ class CI_Router { 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 @@ class CI_Router { } // 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 @@ class CI_Router { * @param bool * @return void */ - function _compile_segments($segs, $route = FALSE) - { - $segments = array(); - - $i = 1; - foreach($segs as $val) + function _compile_segments($segments = array()) + { + $segments = $this->_validate_segments($segments); + + if (count($segments) == 0) { - $val = trim($this->_filter_uri($val)); - - if ($val != '') - $segments[$i++] = $val; + return; } - + $this->set_class($segments['1']); if (isset($segments['2'])) @@ -186,15 +191,54 @@ class CI_Router { $this->set_method($segments['2']); } } - - if ($route == FALSE) + } + // 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)) { - $this->segments = $segments; + // 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; + } + } } - unset($segments); + return $segments; } - // END _compile_segments() + // END _validate_segments() // -------------------------------------------------------------------- @@ -218,6 +262,56 @@ class CI_Router { // -------------------------------------------------------------------- + /** + * Parse Routes + * + * This function matches any routes that may exist in + * the config/routes.php file against the URI to + * determine if the class/method need to be remapped. + * + * @access private + * @return void + */ + function _parse_routes() + { + // Turn the segment array into a URI string + $uri = implode('/', $this->segments); + $num = count($this->segments); + + // Is there a literal match? If so we're done + if (isset($this->routes[$uri])) + { + $this->_compile_segments(explode('/', $this->routes[$uri])); + return; + } + + // Loop through the route array looking for wildcards + foreach (array_slice($this->routes, 1) as $key => $val) + { + if (count(explode('/', $key)) != $num) + continue; + + // Convert wildcards to RegEx + $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); + + // Does the RegEx match? + if (preg_match('|^'.$key.'$|', $uri)) + { + // 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)); + return; + } + } + } + // END set_method() + + // -------------------------------------------------------------------- + /** * Set the class name * @@ -229,7 +323,7 @@ class CI_Router { { $this->class = $class; } - // END _filter_uri() + // END set_class() // -------------------------------------------------------------------- @@ -243,7 +337,7 @@ class CI_Router { { return $this->class; } - // END _filter_uri() + // END fetch_class() // -------------------------------------------------------------------- @@ -259,7 +353,7 @@ class CI_Router { $this->method = $method; } // END set_method() - + // -------------------------------------------------------------------- /** @@ -272,58 +366,37 @@ class CI_Router { { return $this->method; } - // END set_method() - + // END fetch_method() + // -------------------------------------------------------------------- /** - * Parse Routes + * Set the directory name * - * This function matches any routes that may exist in - * the config/routes.php file against the URI to - * determine if the class/method need to be remapped. - * - * @access private + * @access public + * @param string * @return void - */ - function _parse_routes() + */ + function set_directory($dir) { - // Turn the segment array into a URI string - $uri = implode('/', $this->segments); - $num = count($this->segments); + $this->directory = $dir.'/'; + } + // END set_directory() - // Is there a literal match? If so we're done - if (isset($this->routes[$uri])) - { - $this->_compile_segments(explode('/', $this->routes[$uri]), TRUE); - return; - } - - // Loop through the route array looking for wildcards - foreach (array_slice($this->routes, 1) as $key => $val) - { - if (count(explode('/', $key)) != $num) - continue; - - // Convert wildcards to RegEx - $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); - - // Does the regex match this URI ? - if (preg_match('|^'.$key.'$|', $uri)) - { - // Do we have a replacemnt? - if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) - { - $val = preg_replace('|^'.$key.'$|', $val, $uri); - } - - $this->_compile_segments(explode('/', $val), TRUE); - break; - } - - } + // -------------------------------------------------------------------- + + /** + * Fetch the sub-directory (if any) that contains the requested controller class + * + * @access public + * @return string + */ + function fetch_directory() + { + return $this->directory; } - // END set_method() + // END fetch_directory() + } // END Router Class ?> \ No newline at end of file -- cgit v1.2.3-24-g4f1b