diff options
author | Andrey Andreev <narf@devilix.net> | 2014-01-17 15:37:48 +0100 |
---|---|---|
committer | Andrey Andreev <narf@devilix.net> | 2014-01-17 15:37:48 +0100 |
commit | e17ccdb9cefa21df944b416a5461661419263ad0 (patch) | |
tree | feeefa322b042009ed389a2704ef694de0de5515 /system/core/Router.php | |
parent | 88cf55bd294e74c71e70406e3a48e722db224f7f (diff) | |
parent | 30d5324617ae136c7a91badb6ed8f7de418fd7f5 (diff) |
Merge branch 'feature/uri_routing_overhaul' into 'develop'
Diffstat (limited to 'system/core/Router.php')
-rw-r--r-- | system/core/Router.php | 240 |
1 files changed, 118 insertions, 122 deletions
diff --git a/system/core/Router.php b/system/core/Router.php index 71530ff07..e3c911511 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -91,6 +91,15 @@ class CI_Router { */ public $translate_uri_dashes = FALSE; + /** + * Enable query strings flag + * + * Determines wether to use GET parameters or segment URIs + * + * @var bool + */ + public $enable_query_strings = FALSE; + // -------------------------------------------------------------------- /** @@ -106,6 +115,8 @@ class CI_Router { $this->config =& load_class('Config', 'core'); $this->uri =& load_class('URI', 'core'); + + $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE); $this->_set_routing(); // Set any routing overrides that may exist in the main index file @@ -146,26 +157,39 @@ class CI_Router { // Are query strings enabled in the config file? Normally CI doesn't utilize query strings // since URI segments are more search-engine friendly, but they can optionally be used. // If this feature is enabled, we will gather the directory/class/method a little differently - $segments = array(); - if ($this->config->item('enable_query_strings') === TRUE - && ! empty($_GET[$this->config->item('controller_trigger')]) - && is_string($_GET[$this->config->item('controller_trigger')]) - ) + if ($this->enable_query_strings) { - if (isset($_GET[$this->config->item('directory_trigger')]) && is_string($_GET[$this->config->item('directory_trigger')])) + $_d = $this->config->item('directory_trigger'); + $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : ''; + if ($_d !== '') { - $this->set_directory(trim($this->uri->filter_uri($_GET[$this->config->item('directory_trigger')]))); - $segments[] = $this->directory; + $this->set_directory($this->uri->filter_uri($_d)); } - $this->set_class(trim($this->uri->filter_uri($_GET[$this->config->item('controller_trigger')]))); - $segments[] = $this->class; + $_c = $this->config->item('controller_trigger'); + if ( ! empty($_GET[$_c])) + { + $this->set_class(trim($this->uri->filter_uri(trim($_GET[$_c])))); + + $_f = $this->config->item('function_trigger'); + if ( ! empty($_GET[$_f])) + { + $this->set_method(trim($this->uri->filter_uri($_GET[$_f]))); + } - if ( ! empty($_GET[$this->config->item('function_trigger')]) && is_string($_GET[$this->config->item('function_trigger')])) + $this->uri->rsegments = array( + 1 => $this->class, + 2 => $this->method + ); + } + else { - $this->set_method(trim($this->uri->filter_uri($_GET[$this->config->item('function_trigger')]))); - $segments[] = $this->method; + $this->_set_default_controller(); } + + // Routing rules don't apply to query strings and we don't need to detect + // directories, so we're done here + return; } // Load the routes.php file. @@ -188,53 +212,15 @@ class CI_Router { $this->routes = $route; } - // Were there any query string segments? If so, we'll validate them and bail out since we're done. - if (count($segments) > 0) + // Is there anything to parse? + if ($this->uri->uri_string !== '') { - return $this->_validate_request($segments); + $this->_parse_routes(); } - - // Fetch the complete URI string - $this->uri->_fetch_uri_string(); - - // Is there a URI string? If not, the default controller specified in the "routes" file will be shown. - if ($this->uri->uri_string == '') + else { - return $this->_set_default_controller(); + $this->_set_default_controller(); } - - $this->uri->_remove_url_suffix(); // Remove the URL suffix - $this->uri->_explode_segments(); // Compile the segments into an array - $this->_parse_routes(); // Parse any custom routing that may exist - $this->uri->_reindex_segments(); // Re-index the segment array so that it starts with 1 rather than 0 - } - - // -------------------------------------------------------------------- - - /** - * Set default controller - * - * @return void - */ - protected function _set_default_controller() - { - 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 (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) - { - $method = 'index'; - } - - $this->_set_request(array($class, $method)); - - // re-index the routed segments array so it starts with 1 rather than 0 - $this->uri->_reindex_segments(); - - log_message('debug', 'No URI present. Default controller set.'); } // -------------------------------------------------------------------- @@ -245,16 +231,19 @@ class CI_Router { * Takes an array of URI segments as input and sets the class/method * to be called. * + * @used-by CI_Router::_parse_routes() * @param array $segments URI segments * @return void */ protected function _set_request($segments = array()) { $segments = $this->_validate_request($segments); - - if (count($segments) === 0) + // If we don't have any segments left - try the default controller; + // WARNING: Directories get shifted out of the segments array! + if (empty($segments)) { - return $this->_set_default_controller(); + $this->_set_default_controller(); + return; } if ($this->translate_uri_dashes === TRUE) @@ -267,90 +256,86 @@ class CI_Router { } $this->set_class($segments[0]); - isset($segments[1]) OR $segments[1] = 'index'; - $this->set_method($segments[1]); + if (isset($segments[1])) + { + $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 - // identical to $this->uri->segments + array_unshift($segments, NULL); + unset($segments[0]); $this->uri->rsegments = $segments; } // -------------------------------------------------------------------- /** - * Validate request - * - * Attempts validate the URI request and determine the controller path. + * Set default controller * - * @param array $segments URI segments - * @return array URI segments + * @return void */ - protected function _validate_request($segments) + protected function _set_default_controller() { - if (count($segments) === 0) + if (empty($this->default_controller)) { - return $segments; + show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.'); } - $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); - - // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$test.'.php')) + // Is the method being specified? + if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) { - return $segments; + $method = 'index'; } - // Is the controller in a sub-folder? - if (is_dir(APPPATH.'controllers/'.$segments[0])) + if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php')) { - // Set the directory and remove it from the segment array - $this->set_directory(array_shift($segments)); - if (count($segments) > 0) - { - $test = ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); + // This will trigger 404 later + return; + } - // Does the requested controller exist in the sub-directory? - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php')) - { - if ( ! empty($this->routes['404_override'])) - { - $this->directory = ''; - return explode('/', $this->routes['404_override'], 2); - } - else - { - show_404($this->directory.$segments[0]); - } - } - } - else - { - // Is the method being specified in the route? - $segments = explode('/', $this->default_controller); - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($segments[0]).'.php')) - { - $this->directory = ''; - } - } + $this->set_class($class); + $this->set_method($method); - return $segments; - } + // Assign routed segments, index starting from 1 + $this->uri->rsegments = array( + 1 => $class, + 2 => $method + ); + + log_message('debug', 'No URI present. Default controller set.'); + } + + // -------------------------------------------------------------------- - // 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'])) + /** + * Validate request + * + * Attempts validate the URI request and determine the controller path. + * + * @used-by CI_Router::_set_request() + * @param array $segments URI segments + * @return mixed URI segments + */ + protected function _validate_request($segments) + { + $c = count($segments); + // Loop through our segments and return as soon as a controller + // is found or when such a directory doesn't exist + while ($c-- > 0) { - if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + $test = $this->directory + .ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]); + + if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])) { - $method = 'index'; + $this->set_directory(array_shift($segments), TRUE); + continue; } - return array($class, $method); + return $segments; } - // Nothing else to do at this point but show a 404 - show_404($segments[0]); + // This means that all segments were actually directories + return $segments; } // -------------------------------------------------------------------- @@ -377,12 +362,14 @@ class CI_Router { // Check default routes format if (is_string($this->routes[$uri])) { - return $this->_set_request(explode('/', $this->routes[$uri])); + $this->_set_request(explode('/', $this->routes[$uri])); + return; } // Is there a matching http verb? elseif (is_array($this->routes[$uri]) && isset($this->routes[$uri][$http_verb])) { - return $this->_set_request(explode('/', $this->routes[$uri][$http_verb])); + $this->_set_request(explode('/', $this->routes[$uri][$http_verb])); + return; } } @@ -452,7 +439,8 @@ class CI_Router { $val = preg_replace('#^'.$key.'$#', $val, $uri); } - return $this->_set_request(explode('/', $val)); + $this->_set_request(explode('/', $val)); + return; } } @@ -519,11 +507,19 @@ class CI_Router { * Set directory name * * @param string $dir Directory name + * @param bool $appent Whether we're appending rather then setting the full value * @return void */ - public function set_directory($dir) + public function set_directory($dir, $append = FALSE) { - $this->directory = str_replace(array('/', '.'), '', $dir).'/'; + if ($append !== TRUE OR empty($this->directory)) + { + $this->directory = str_replace('.', '', trim($dir, '/')).'/'; + } + else + { + $this->directory .= str_replace('.', '', trim($dir, '/')).'/'; + } } // -------------------------------------------------------------------- |