From a101c93b93b43ac98370bb0a1378a82ff44e4e1a Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Fri, 20 Jul 2012 12:23:43 +0200 Subject: allow for routes that can be processed with php, ex: $route['([^/]+)/([^/]+)(/:any)?'] = 'php:"$1" . "/do" . ucfirst("$2") . "$3"'; --- system/core/Router.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 5bc053045..cb7df5320 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -86,6 +86,13 @@ class CI_Router { * @var string */ public $default_controller; + + /** + * Prepend used in php processed routes + * + * @var string + */ + public $route_prepend = 'php:'; /** * Constructor @@ -373,10 +380,16 @@ class CI_Router { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri)) { + // Are we using php functions to process matches? + $modifier = strpos($val, $this->route_prepend) === 0? 'e': ''; + + // If we have the 'e' modifier, remove the prepend from the route value. + $val = $modifier === 'e'? substr($val, strlen($this->route_prepend)): $val; + // Do we have a back-reference? if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) { - $val = preg_replace('#^'.$key.'$#', $val, $uri); + $val = preg_replace('#^'.$key.'$#'.$modifier, $val, $uri); } return $this->_set_request(explode('/', $val)); -- cgit v1.2.3-24-g4f1b From 80275c7ee050ed42678d68a752e0c282f0240752 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Wed, 1 Aug 2012 19:15:48 +0200 Subject: Added possibility of using callbacks. --- system/core/Router.php | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index cb7df5320..727e85f7e 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -380,16 +380,35 @@ class CI_Router { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri)) { - // Are we using php functions to process matches? - $modifier = strpos($val, $this->route_prepend) === 0? 'e': ''; + // Are we using a callback? + $callable = is_callable($val); + + // Determine the appropriate preg_replace to use. + $preg_replace_type = $callable? 'preg_replace_callback': 'preg_replace'; + + // Are we using the route_prepend to change how we process the matches? + $modifier = (is_string($val) AND strpos($val, $this->route_prepend) === 0)? 'e': ''; - // If we have the 'e' modifier, remove the prepend from the route value. - $val = $modifier === 'e'? substr($val, strlen($this->route_prepend)): $val; + // Are we using callbacks to process the matches? + if($callable){ + $val = function($matches)use($val){ + // Remove the string we are matching against from the matches array. + array_shift($matches); + + // Distribute the matches to the arguments of the user's callback. + return call_user_func_array($val, $matches); + }; + } + else + { + // Remove the "php:" portion of the string if it exists. + $val = $modifier === 'e'? substr($val, strlen($this->route_prepend)): $val; + } // Do we have a back-reference? - if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) + if ($callable OR (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)) { - $val = preg_replace('#^'.$key.'$#'.$modifier, $val, $uri); + $val = call_user_func($preg_replace_type, '#^'.$key.'$#'.$modifier, $val, $uri); } return $this->_set_request(explode('/', $val)); -- cgit v1.2.3-24-g4f1b From 0af2d4ffd1735e24dd4f5ee9b17ac6a90508c1e9 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Mon, 6 Aug 2012 13:05:15 +0200 Subject: revert changes to routing system - part 1 --- system/core/Router.php | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 727e85f7e..5bc053045 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -86,13 +86,6 @@ class CI_Router { * @var string */ public $default_controller; - - /** - * Prepend used in php processed routes - * - * @var string - */ - public $route_prepend = 'php:'; /** * Constructor @@ -380,35 +373,10 @@ class CI_Router { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri)) { - // Are we using a callback? - $callable = is_callable($val); - - // Determine the appropriate preg_replace to use. - $preg_replace_type = $callable? 'preg_replace_callback': 'preg_replace'; - - // Are we using the route_prepend to change how we process the matches? - $modifier = (is_string($val) AND strpos($val, $this->route_prepend) === 0)? 'e': ''; - - // Are we using callbacks to process the matches? - if($callable){ - $val = function($matches)use($val){ - // Remove the string we are matching against from the matches array. - array_shift($matches); - - // Distribute the matches to the arguments of the user's callback. - return call_user_func_array($val, $matches); - }; - } - else - { - // Remove the "php:" portion of the string if it exists. - $val = $modifier === 'e'? substr($val, strlen($this->route_prepend)): $val; - } - // Do we have a back-reference? - if ($callable OR (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)) + if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) { - $val = call_user_func($preg_replace_type, '#^'.$key.'$#'.$modifier, $val, $uri); + $val = preg_replace('#^'.$key.'$#', $val, $uri); } return $this->_set_request(explode('/', $val)); -- cgit v1.2.3-24-g4f1b From c0d98b296186e6206dfa88476199559e630d06d0 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Mon, 6 Aug 2012 15:42:50 +0100 Subject: New optional routing system, v3 --- system/core/Router.php | 90 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 33 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 5bc053045..a5d01b1ee 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -354,39 +354,63 @@ class CI_Router { * @return void */ protected 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 done - if (isset($this->routes[$uri])) - { - return $this->_set_request(explode('/', $this->routes[$uri])); - } - - // Loop through the route array looking for wild-cards - foreach ($this->routes as $key => $val) - { - // Convert wild-cards to RegEx - $key = str_replace(array(':any', ':num'), array('.+', '[0-9]+'), $key); - - // Does the RegEx match? - if (preg_match('#^'.$key.'$#', $uri)) - { - // Do we have a back-reference? - if (strpos($val, '$') !== FALSE && 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); - } + { + // Turn the segment array into a URI string + $uri = implode('/', $this->uri->segments); + + // Is there a literal match? If so we're done + if (isset($this->routes[$uri])) + { + return $this->_set_request(explode('/', $this->routes[$uri])); + } + + // Loop through the route array looking for wild-cards + foreach ($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, $matches)) + { + // Are we using a callback? + $callable = is_callable($val); + + // Are we using callbacks to process back-references? + if($callable){ + // Remove the original string from the matches array. + array_shift($matches); + + // Get the match count. + $matchCount = count($matches); + + // Determine how many parameters the callback has. + $reflection = new ReflectionFunction($val); + $paramCount = count($reflection->getParameters()); + + // Are there more parameters than matches? + if($paramCount > $matchCount){ + // Set any extra params to empty string. + $matches = array_merge($matches, array_fill($matchCount, $paramCount - $matchCount, '')); + } + + // execute callback using matches as its parameters. + $val = call_user_func_array($val, $matches); + } + // Are we using the default routing method for back-references? + else 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); + } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From 3b45cf62bec6684f35207a1bfb2193f1adc9cd2b Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Mon, 6 Aug 2012 15:47:24 +0100 Subject: Fixed a bug when detecting if the user used a callback. --- system/core/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index a5d01b1ee..d6788c314 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -374,7 +374,7 @@ class CI_Router { if (preg_match('#^'.$key.'$#', $uri, $matches)) { // Are we using a callback? - $callable = is_callable($val); + $callable = ! is_string($val) && is_callable($val); // Are we using callbacks to process back-references? if($callable){ -- cgit v1.2.3-24-g4f1b From 07264381020d730ebba9ae95688b73c25e523e54 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Mon, 6 Aug 2012 16:37:26 +0100 Subject: Corrected code style to be inline with project conventions. --- system/core/Router.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index d6788c314..081468944 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -377,24 +377,26 @@ class CI_Router { $callable = ! is_string($val) && is_callable($val); // Are we using callbacks to process back-references? - if($callable){ + if($callable) + { // Remove the original string from the matches array. array_shift($matches); // Get the match count. - $matchCount = count($matches); + $match_count = count($matches); // Determine how many parameters the callback has. $reflection = new ReflectionFunction($val); - $paramCount = count($reflection->getParameters()); + $param_count = count($reflection->getParameters()); // Are there more parameters than matches? - if($paramCount > $matchCount){ - // Set any extra params to empty string. - $matches = array_merge($matches, array_fill($matchCount, $paramCount - $matchCount, '')); + if($param_count > $match_count) + { + // Any params without matches will be set to an empty string. + $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, '')); } - // execute callback using matches as its parameters. + // Execute the callback using the values in matches as its parameters. $val = call_user_func_array($val, $matches); } // Are we using the default routing method for back-references? -- cgit v1.2.3-24-g4f1b From cf168303ead21d1c8ad89af01458806e6be197fd Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Mon, 6 Aug 2012 17:10:17 +0100 Subject: Updated documentation --- system/core/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 081468944..b11aa9ba5 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -387,7 +387,7 @@ class CI_Router { // Determine how many parameters the callback has. $reflection = new ReflectionFunction($val); - $param_count = count($reflection->getParameters()); + $param_count = $reflection->getNumberOfParameters(); // Are there more parameters than matches? if($param_count > $match_count) -- cgit v1.2.3-24-g4f1b From 59dbe859ffea8159932f6d28b765de615d430cf4 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Tue, 7 Aug 2012 12:13:32 +0100 Subject: Changed spaces to tabs where necessary. --- system/core/Router.php | 118 ++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index b11aa9ba5..1d566c56f 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -354,65 +354,65 @@ class CI_Router { * @return void */ protected 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 done - if (isset($this->routes[$uri])) - { - return $this->_set_request(explode('/', $this->routes[$uri])); - } - - // Loop through the route array looking for wild-cards - foreach ($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, $matches)) - { - // Are we using a callback? - $callable = ! is_string($val) && is_callable($val); - - // Are we using callbacks to process back-references? - if($callable) - { - // Remove the original string from the matches array. - array_shift($matches); - - // Get the match count. - $match_count = count($matches); - - // Determine how many parameters the callback has. - $reflection = new ReflectionFunction($val); - $param_count = $reflection->getNumberOfParameters(); - - // Are there more parameters than matches? - if($param_count > $match_count) - { - // Any params without matches will be set to an empty string. - $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, '')); - } - - // Execute the callback using the values in matches as its parameters. - $val = call_user_func_array($val, $matches); - } - // Are we using the default routing method for back-references? - else 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); - } + { + // Turn the segment array into a URI string + $uri = implode('/', $this->uri->segments); + + // Is there a literal match? If so we're done + if (isset($this->routes[$uri])) + { + return $this->_set_request(explode('/', $this->routes[$uri])); + } + + // Loop through the route array looking for wild-cards + foreach ($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, $matches)) + { + // Are we using a callback? + $callable = ! is_string($val) && is_callable($val); + + // Are we using callbacks to process back-references? + if($callable) + { + // Remove the original string from the matches array. + array_shift($matches); + + // Get the match count. + $match_count = count($matches); + + // Determine how many parameters the callback has. + $reflection = new ReflectionFunction($val); + $param_count = $reflection->getNumberOfParameters(); + + // Are there more parameters than matches? + if($param_count > $match_count) + { + // Any params without matches will be set to an empty string. + $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, '')); + } + + // Execute the callback using the values in matches as its parameters. + $val = call_user_func_array($val, $matches); + } + // Are we using the default routing method for back-references? + else 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); + } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From f950e5c18d7a36408e33cb11bb67a254362607cc Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Thu, 27 Sep 2012 11:39:33 +0100 Subject: made some corrections to the code --- system/core/Router.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 1d566c56f..0e915521d 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -368,16 +368,13 @@ class CI_Router { foreach ($this->routes as $key => $val) { // Convert wild-cards to RegEx - $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); + $key = str_replace(array(':any', ':num'), array('.+', '[0-9]+'), $key); // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri, $matches)) { - // Are we using a callback? - $callable = ! is_string($val) && is_callable($val); - // Are we using callbacks to process back-references? - if($callable) + if(! is_string($val) && is_callable($val)) { // Remove the original string from the matches array. array_shift($matches); @@ -400,7 +397,7 @@ class CI_Router { $val = call_user_func_array($val, $matches); } // Are we using the default routing method for back-references? - else if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) + elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) { $val = preg_replace('#^'.$key.'$#', $val, $uri); } -- cgit v1.2.3-24-g4f1b From 24296ca1e940ac32841cc24a5fdc2f49a0f8ec8a Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Thu, 27 Sep 2012 12:10:01 +0100 Subject: corrected a few more style problems --- system/core/Router.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 0e915521d..3428ff07b 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -374,7 +374,7 @@ class CI_Router { if (preg_match('#^'.$key.'$#', $uri, $matches)) { // Are we using callbacks to process back-references? - if(! is_string($val) && is_callable($val)) + if ( ! is_string($val) && is_callable($val)) { // Remove the original string from the matches array. array_shift($matches); @@ -387,7 +387,7 @@ class CI_Router { $param_count = $reflection->getNumberOfParameters(); // Are there more parameters than matches? - if($param_count > $match_count) + if ($param_count > $match_count) { // Any params without matches will be set to an empty string. $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, '')); -- cgit v1.2.3-24-g4f1b From efb81669b8f90352fdabd109e14fdec25bbce8fe Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Tue, 23 Oct 2012 19:52:46 +0100 Subject: users' default values are now respected in callback routes --- system/core/Router.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 3428ff07b..e8addf962 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -391,6 +391,21 @@ class CI_Router { { // Any params without matches will be set to an empty string. $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, '')); + + $match_count = $param_count; + } + + // Get the parameters so we can use their default values. + $params = $reflection->getParameters(); + + for ($m = 0; $m < $match_count; $m++) + { + // Is the match empty and does a default value exist? + if (empty($matches[$m]) && $params[$m]->isDefaultValueAvailable()) + { + // Substitute the empty match for the default value. + $matches[$m] = $params[$m]->getDefaultValue(); + } } // Execute the callback using the values in matches as its parameters. -- cgit v1.2.3-24-g4f1b