From 08fec7bdf846daa3dfa4114310f065294ac092fc Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 19 Jul 2013 16:25:51 +0300 Subject: Router improvements - Make dashes-to-underscores URI segment replacement configurable via ['translate_uri_dashes']. - Make _set_routing() protected and move the call to the class constructor. - Remove redudant calls to set_class() and set_method(). - Clean-up/optimize the routes loading procedure. (fixes issue #2503) --- application/config/routes.php | 14 ++++++-- system/core/CodeIgniter.php | 1 - system/core/Router.php | 56 +++++++++++++++++++++---------- user_guide_src/source/changelog.rst | 4 +-- user_guide_src/source/general/routing.rst | 14 +++++++- 5 files changed, 65 insertions(+), 24 deletions(-) diff --git a/application/config/routes.php b/application/config/routes.php index a5047a14e..3078c3c76 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -49,7 +49,7 @@ | RESERVED ROUTES | ------------------------------------------------------------------------- | -| There are two reserved routes: +| There are three reserved routes: | | $route['default_controller'] = 'welcome'; | @@ -62,10 +62,20 @@ | This route will tell the Router which controller/method to use if those | provided in the URL cannot be matched to a valid route. | +| $route['translate_uri_dashes'] = FALSE; +| +| This is not exactly a route, but allows you to automatically route +| controller and method names that contain dashes. '-' isn't a valid +| class or method name character, so it requires translation. +| When you set this option to TRUE, it will replace ALL dashes in the +| controller and method URI segments. +| +| Examples: my-controller/index -> my_controller/index +| my-controller/my-method -> my_controller/my_method */ - $route['default_controller'] = 'welcome'; $route['404_override'] = ''; +$route['translate_uri_dashes'] = FALSE; /* End of file routes.php */ /* Location: ./application/config/routes.php */ \ No newline at end of file diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 3fe5c0648..c68266408 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -165,7 +165,6 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * ------------------------------------------------------ */ $RTR =& load_class('Router', 'core'); - $RTR->_set_routing(); // Set any routing overrides that may exist in the main index file if (isset($routing)) diff --git a/system/core/Router.php b/system/core/Router.php index c86ab9c20..cc3916f86 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -81,6 +81,18 @@ class CI_Router { */ public $default_controller; + /** + * Translate URI dashes + * + * Determines whether dashes in controller & method segments + * should be automatically replaced by underscores. + * + * @var bool + */ + public $translate_uri_dashes = FALSE; + + // -------------------------------------------------------------------- + /** * Class constructor * @@ -92,6 +104,7 @@ class CI_Router { { $this->config =& load_class('Config', 'core'); $this->uri =& load_class('URI', 'core'); + $this->_set_routing(); log_message('debug', 'Router Class Initialized'); } @@ -105,7 +118,7 @@ class CI_Router { * * @return void */ - public function _set_routing() + protected 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. @@ -143,12 +156,14 @@ class CI_Router { include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); } - $this->routes = (empty($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 = empty($this->routes['default_controller']) ? FALSE : $this->routes['default_controller']; + // Validate & get reserved routes + if (isset($route) && is_array($route)) + { + isset($route['default_controller']) && $this->default_controller = $route['default_controller']; + isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes']; + unset($route['default_controller'], $route['translate_uri_dashes']); + $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) @@ -191,8 +206,6 @@ class CI_Router { $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 @@ -221,8 +234,16 @@ class CI_Router { return $this->_set_default_controller(); } - $this->set_class($segments[0]); + if ($this->translate_uri_dashes === TRUE) + { + $segments[0] = str_replace('-', '_', $segments[0]); + if (isset($segments[1])) + { + $segments[1] = str_replace('-', '_', $segments[1]); + } + } + $this->set_class($segments[0]); isset($segments[1]) OR $segments[1] = 'index'; $this->set_method($segments[1]); @@ -249,13 +270,12 @@ class CI_Router { return $segments; } - $temp = str_replace('-', '_', $segments[0]); + $test = ($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/'.$temp.'.php')) + if (file_exists(APPPATH.'controllers/'.$test.'.php')) { - $segments[0] = $temp; - empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]); return $segments; } @@ -266,11 +286,11 @@ class CI_Router { $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]); + $test = ($this->translate_uri_dashes === TRUE) + ? str_replace('-', '_', $segments[0]) : $segments[0]; - // Does the requested controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$segments[0].'.php')) + // Does the requested controller exist in the sub-directory? + if ( ! file_exists(APPPATH.'controllers/'.$this->directory.$test.'.php')) { if ( ! empty($this->routes['404_override'])) { diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst index 0beffb568..efbe86069 100644 --- a/user_guide_src/source/changelog.rst +++ b/user_guide_src/source/changelog.rst @@ -414,7 +414,7 @@ Release Date: Not Released - :doc:`URI Routing ` changes include: - Added possibility to route requests using callbacks. - - Added possibility to use dashes in the controller and method URI segments (translated to underscores). + - Added a new reserved route (*translate_uri_dashes*) to allow usage of dashes in the controller and method URI segments. - Deprecated methods ``fetch_directory()``, ``fetch_class()`` and ``fetch_method()`` in favor of their respective public properties. - :doc:`Language Library ` changes include: @@ -483,7 +483,7 @@ Bug fixes for 3.0 - Fixed a bug (#23, #1238) - delete_all() in the `Database Caching Library ` used to delete .htaccess and index.html files, which is a potential security risk. - Fixed a bug in :doc:`Trackback Library ` method validate_url() where it didn't actually do anything, due to input not being passed by reference. - Fixed a bug (#11, #183, #863) - CI_Form_validation::_execute() silently continued to the next rule, if a rule method/function is not found. -- Fixed a bug (#122) Where routed uri string was being reported incorrectly in sub-directories. +- Fixed a bug (#122) - routed URI string was being reported incorrectly in sub-directories. - Fixed a bug (#1242) - read_dir() in the :doc:`Zip Library ` wasn't compatible with Windows. - Fixed a bug (#306) - ODBC driver didn't have an _insert_batch() method, which resulted in fatal error being triggered when insert_batch() is used with it. - Fixed a bug in MSSQL and SQLSrv's _truncate() where the TABLE keyword was missing. diff --git a/user_guide_src/source/general/routing.rst b/user_guide_src/source/general/routing.rst index 123257fc8..5520f59fe 100644 --- a/user_guide_src/source/general/routing.rst +++ b/user_guide_src/source/general/routing.rst @@ -145,7 +145,7 @@ routing rules to process the back-references. Example:: Reserved Routes =============== -There are two reserved routes:: +There are three reserved routes:: $route['default_controller'] = 'welcome'; @@ -165,5 +165,17 @@ error page. It won't affect to the ``show_404()`` function, which will continue loading the default *error_404.php* file at *application/views/errors/error_404.php*. + +:: + + $route['translate_uri_dashes'] = FALSE; + +As evident by the boolean value, this is not exactly a route. This +option enables you to automatically replace dashes ('-') with +underscores in the controller and method URI segments, thus saving you +additional route entries if you need to do that. +This is required, because the dash isn't a valid class or method name +character and would cause a fatal error if you try to use it. + .. important:: The reserved routes must come before any wildcard or regular expression routes. \ No newline at end of file -- cgit v1.2.3-24-g4f1b