Blame | Last modification | View Log | RSS feed
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');/*** CodeIgniter** An open source application development framework for PHP 5.1.6 or newer** @package CodeIgniter* @author ExpressionEngine Dev Team* @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.* @license http://codeigniter.com/user_guide/license.html* @link http://codeigniter.com* @since Version 1.0* @filesource*/// ------------------------------------------------------------------------/*** Router Class** Parses URIs and determines routing** @package CodeIgniter* @subpackage Libraries* @author ExpressionEngine Dev Team* @category Libraries* @link http://codeigniter.com/user_guide/general/routing.html*/class CI_Router {/*** Config class** @var object* @access public*/var $config;/*** List of routes** @var array* @access public*/var $routes = array();/*** List of error routes** @var array* @access public*/var $error_routes = array();/*** Current class name** @var string* @access public*/var $class = '';/*** Current method name** @var string* @access public*/var $method = 'index';/*** Sub-directory that contains the requested controller class** @var string* @access public*/var $directory = '';/*** Default controller (and method if specific)** @var string* @access public*/var $default_controller;/*** Constructor** Runs the route mapping function.*/function __construct(){$this->config =& load_class('Config', 'core');$this->uri =& load_class('URI', 'core');log_message('debug', "Router Class Initialized");}// --------------------------------------------------------------------/*** Set the route mapping** This function determines what should be served based on the URI request,* as well as any "routes" that have been set in the routing config file.** @access private* @return void*/function _set_routing(){// 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 AND isset($_GET[$this->config->item('controller_trigger')])){if (isset($_GET[$this->config->item('directory_trigger')])){$this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));$segments[] = $this->fetch_directory();}if (isset($_GET[$this->config->item('controller_trigger')])){$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));$segments[] = $this->fetch_class();}if (isset($_GET[$this->config->item('function_trigger')])){$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));$segments[] = $this->fetch_method();}}// Load the routes.php file.if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php')){include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');}elseif (is_file(APPPATH.'config/routes.php')){include(APPPATH.'config/routes.php');}$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;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 = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($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){return $this->_validate_request($segments);}// 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 == ''){return $this->_set_default_controller();}// Do we need to remove the URL suffix?$this->uri->_remove_url_suffix();// Compile the segments into an array$this->uri->_explode_segments();// Parse any custom routing that may exist$this->_parse_routes();// Re-index the segment array so that it starts with 1 rather than 0$this->uri->_reindex_segments();}// --------------------------------------------------------------------/*** Set the default controller** @access private* @return void*/function _set_default_controller(){if ($this->default_controller === FALSE){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{$this->set_class($this->default_controller);$this->set_method('index');$this->_set_request(array($this->default_controller, 'index'));}// 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.");}// --------------------------------------------------------------------/*** Set the Route** This function takes an array of URI segments as* input, and sets the current class/method** @access private* @param array* @param bool* @return void*/function _set_request($segments = array()){$segments = $this->_validate_request($segments);if (count($segments) == 0){return $this->_set_default_controller();}$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';}// 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$this->uri->rsegments = $segments;}// --------------------------------------------------------------------/*** Validates the supplied segments. Attempts to determine the path to* the controller.** @access private* @param array* @return array*/function _validate_request($segments){if (count($segments) == 0){return $segments;}// Does the requested controller exist in the root folder?if (file_exists(APPPATH.'controllers/'.$segments[0].'.php')){return $segments;}// Is the controller in a sub-folder?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);if (count($segments) > 0){// 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;}else{show_404($this->fetch_directory().$segments[0]);}}}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')){$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 overrideif ( ! 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');return $x;}// Nothing else to do at this point but show a 404show_404($segments[0]);}// --------------------------------------------------------------------/*** 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->uri->segments);// Is there a literal match? If so we're doneif (isset($this->routes[$uri])){return $this->_set_request(explode('/', $this->routes[$uri]));}// Loop through the route array looking for wild-cardsforeach ($this->routes as $key => $val){// Convert wild-cards 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);}return $this->_set_request(explode('/', $val));}}// If we got this far it means we didn't encounter a// matching route so we'll set the site default route$this->_set_request($this->uri->segments);}// --------------------------------------------------------------------/*** Set the class name** @access public* @param string* @return void*/function set_class($class){$this->class = str_replace(array('/', '.'), '', $class);}// --------------------------------------------------------------------/*** Fetch the current class** @access public* @return string*/function fetch_class(){return $this->class;}// --------------------------------------------------------------------/*** Set the method name** @access public* @param string* @return void*/function set_method($method){$this->method = $method;}// --------------------------------------------------------------------/*** Fetch the current method** @access public* @return string*/function fetch_method(){if ($this->method == $this->fetch_class()){return 'index';}return $this->method;}// --------------------------------------------------------------------/*** Set the directory name** @access public* @param string* @return void*/function set_directory($dir){$this->directory = str_replace(array('/', '.'), '', $dir).'/';}// --------------------------------------------------------------------/*** Fetch the sub-directory (if any) that contains the requested controller class** @access public* @return string*/function fetch_directory(){return $this->directory;}// --------------------------------------------------------------------/*** Set the controller overrides** @access public* @param array* @return null*/function _set_overrides($routing){if ( ! is_array($routing)){return;}if (isset($routing['directory'])){$this->set_directory($routing['directory']);}if (isset($routing['controller']) AND $routing['controller'] != ''){$this->set_class($routing['controller']);}if (isset($routing['function'])){$routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];$this->set_method($routing['function']);}}}// END Router Class/* End of file Router.php *//* Location: ./system/core/Router.php */