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 3c0846b019ed533852a148eb68c62a02c03d27a8 Mon Sep 17 00:00:00 2001 From: bigCat Date: Tue, 21 Aug 2012 00:20:20 +0800 Subject: China's biggest ICP China Telecom will hijack user and leave a cookie contains | . such as "1345466626|7601294|43373|0|0|0" it's impossible to fix this shit... --- system/core/Input.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index 968a42a9a..d7bfed3f8 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -620,7 +620,7 @@ class CI_Input { */ protected function _clean_input_keys($str) { - if ( ! preg_match('/^[a-z0-9:_\/-]+$/i', $str)) + if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str)) { set_status_header(503); exit('Disallowed Key Characters.'); -- 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 From d4516e3562b1c412d7c3edea874eaa6e6922ad0e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 14:44:38 +0200 Subject: CI_URI::_detect_uri() to accept absolute URIs (thanks to @sourcejedi, PR #1326) For HTTP/1.1 compliance, RFC2616 specifies that both relative and absolute URI formats must be accepted: - http://localhost/path/ (absolute) - /path/ (relative) --- system/core/URI.php | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index d67a35d4b..3d942eda7 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -185,37 +185,39 @@ class CI_URI { return ''; } - if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) - { - $uri = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); - } - elseif (strpos($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])) === 0) + $uri = parse_url($_SERVER['REQUEST_URI']); + $query = isset($uri['query']) ? $uri['query'] : ''; + $uri = isset($uri['path']) ? $uri['path'] : ''; + + if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) { - $uri = substr($_SERVER['REQUEST_URI'], strlen(dirname($_SERVER['SCRIPT_NAME']))); + $uri = (string) substr($uri, strlen($_SERVER['SCRIPT_NAME'])); } - else + elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) { - $uri = $_SERVER['REQUEST_URI']; + $uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); } - // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - if (strpos($uri, '?/') === 0) + + if ($uri === '' && strncmp($query, '/', 1) === 0) + { + $query = explode('?', $query, 2); + $uri = $query[0]; + $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; + } + else { - $uri = substr($uri, 2); + $_SERVER['QUERY_STRING'] = $query; } - $parts = explode('?', $uri, 2); - $uri = $parts[0]; - if (isset($parts[1])) + if ($_SERVER['QUERY_STRING'] === '') { - $_SERVER['QUERY_STRING'] = $parts[1]; - parse_str($_SERVER['QUERY_STRING'], $_GET); + $_GET = array(); } else { - $_SERVER['QUERY_STRING'] = ''; - $_GET = array(); + parse_str($_SERVER['QUERY_STRING'], $_GET); } if ($uri === '/' OR $uri === '') @@ -223,8 +225,6 @@ class CI_URI { return '/'; } - $uri = parse_url('pseudo://hostname/'.$uri, PHP_URL_PATH); - // Do some final cleaning of the URI and return it return str_replace(array('//', '../'), '/', trim($uri, '/')); } -- cgit v1.2.3-24-g4f1b From f2b19fee7876708c7a7bb5cba6b7df682a9d2a53 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 16:16:24 +0200 Subject: Multiple improvements to the URI class (thanks to @sourcejedi, PR #1326 for most of the ideas) - Renamed _detect_uri() and _parse_cli_args() to _parse_request_uri() and _parse_argv() respectively. - Added _parse_query_string() which allows us to detect the URI path from QUERY_STRING much like it is done in _parse_request_uri(). (the above changes also allow for a simpler logic in the case where the *uri_protocol* setting is not set to 'AUTO') - Updated application/config/config.php with a better list of the *uri_protocol* options. - Added _reset_query_string() to aid in re-processing from the QUERY_STRING (utilized in _parse_request_uri() and _parse_query_string()). --- system/core/URI.php | 103 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 28 deletions(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 3d942eda7..6692d07a6 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -98,12 +98,12 @@ class CI_URI { // Is the request coming from the command line? if ($this->_is_cli_request()) { - $this->_set_uri_string($this->_parse_cli_args()); + $this->_set_uri_string($this->_parse_argv()); return; } // Let's try the REQUEST_URI first, this will work in most situations - if ($uri = $this->_detect_uri()) + if (($uri = $this->_parse_request_uri()) !== '') { $this->_set_uri_string($uri); return; @@ -111,18 +111,17 @@ class CI_URI { // Is there a PATH_INFO variable? // Note: some servers seem to have trouble with getenv() so we'll test it two ways - $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); - if (trim($path, '/') !== '' && $path !== '/'.SELF) + $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); + if (trim($uri, '/') !== '' && $uri !== '/'.SELF) { $this->_set_uri_string($path); return; } // No PATH_INFO?... What about QUERY_STRING? - $path = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); - if (trim($path, '/') !== '') + if (($uri = $this->_parse_query_string()) !== '') { - $this->_set_uri_string($path); + $this->_set_uri_string($uri); return; } @@ -140,19 +139,19 @@ class CI_URI { $uri = strtoupper($this->config->item('uri_protocol')); - if ($uri === 'REQUEST_URI') + if ($uri === 'CLI') { - $this->_set_uri_string($this->_detect_uri()); + $this->_set_uri_string($this->_parse_argv()); return; } - elseif ($uri === 'CLI') + elseif (method_exists($this, ($method = '_parse_'.strtolower($uri)))) { - $this->_set_uri_string($this->_parse_cli_args()); + $this->_set_uri_string($this->$method()); return; } - $path = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri); - $this->_set_uri_string($path); + $uri = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri); + $this->_set_uri_string($uri); } // -------------------------------------------------------------------- @@ -172,13 +171,15 @@ class CI_URI { // -------------------------------------------------------------------- /** - * Detects URI + * Parse REQUEST_URI * - * Will detect the URI automatically and fix the query string if necessary. + * Will parse REQUEST_URI and automatically detect the URI from it, + * while fixing the query string if necessary. * + * @used-by CI_URI::_fetch_uri_string() * @return string */ - protected function _detect_uri() + protected function _parse_request_uri() { if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME'])) { @@ -197,10 +198,10 @@ class CI_URI { { $uri = (string) substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); } + // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct // URI is found, and also fixes the QUERY_STRING server var and $_GET array. - - if ($uri === '' && strncmp($query, '/', 1) === 0) + if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) { $query = explode('?', $query, 2); $uri = $query[0]; @@ -211,14 +212,7 @@ class CI_URI { $_SERVER['QUERY_STRING'] = $query; } - if ($_SERVER['QUERY_STRING'] === '') - { - $_GET = array(); - } - else - { - parse_str($_SERVER['QUERY_STRING'], $_GET); - } + $this->_reset_query_string(); if ($uri === '/' OR $uri === '') { @@ -231,6 +225,59 @@ class CI_URI { // -------------------------------------------------------------------- + /** + * Parse QUERY_STRING + * + * Will parse QUERY_STRING and automatically detect the URI from it. + * + * @used-by CI_URI::_fetch_uri_string() + * @return string + */ + protected function _parse_query_string() + { + $uri = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); + + if (trim($uri, '/') === '') + { + return ''; + } + elseif (strncmp($uri, '/', 1) === 0) + { + $uri = explode('?', $uri, 2); + $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : ''; + $uri = $uri[0]; + } + $this->_reset_query_string(); + + return str_replace(array('//', '../'), '/', trim($uri, '/')); + } + + // -------------------------------------------------------------------- + + /** + * Reset QUERY_STRING + * + * Re-processes QUERY_STRING to and fetches the real GET values from it. + * Useful for cases where we got the URI path from it's query string. + * + * @used-by CI_URI::_parse_request_uri() + * @used-by CI_URI::_parse_query_string() + * @return void + */ + protected function _reset_query_string() + { + if ($_SERVER['QUERY_STRING'] === '') + { + $_GET = array(); + } + else + { + parse_str($_SERVER['QUERY_STRING']); + } + } + + // -------------------------------------------------------------------- + /** * Is CLI Request? * @@ -255,10 +302,10 @@ class CI_URI { * * @return string */ - protected function _parse_cli_args() + protected function _parse_argv() { $args = array_slice($_SERVER['argv'], 1); - return $args ? '/'.implode('/', $args) : ''; + return $args ? implode('/', $args) : ''; } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From 704f3f5223637dd6008106b1d04a68668458590e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 16:50:13 +0200 Subject: Fix an erroneous variable name --- system/core/URI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 6692d07a6..407a6ce88 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -114,7 +114,7 @@ class CI_URI { $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); if (trim($uri, '/') !== '' && $uri !== '/'.SELF) { - $this->_set_uri_string($path); + $this->_set_uri_string($uri); return; } -- cgit v1.2.3-24-g4f1b From 9dd2dbb8b9a3edecddcb3907b65a402fd1ae71b4 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 17:54:56 +0200 Subject: Fix issues #388 & #705 (thanks to @sourcejedi, PR #1326 for pointing inconsistencies with RFC2616 --- system/core/URI.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 407a6ce88..4a8d33e88 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -188,7 +188,7 @@ class CI_URI { $uri = parse_url($_SERVER['REQUEST_URI']); $query = isset($uri['query']) ? $uri['query'] : ''; - $uri = isset($uri['path']) ? $uri['path'] : ''; + $uri = isset($uri['path']) ? rawurldecode($uri['path']) : ''; if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) { @@ -204,7 +204,7 @@ class CI_URI { if (trim($uri, '/') === '' && strncmp($query, '/', 1) === 0) { $query = explode('?', $query, 2); - $uri = $query[0]; + $uri = rawurldecode($query[0]); $_SERVER['QUERY_STRING'] = isset($query[1]) ? $query[1] : ''; } else @@ -245,8 +245,9 @@ class CI_URI { { $uri = explode('?', $uri, 2); $_SERVER['QUERY_STRING'] = isset($uri[1]) ? $uri[1] : ''; - $uri = $uri[0]; + $uri = rawurldecode($uri[0]); } + $this->_reset_query_string(); return str_replace(array('//', '../'), '/', trim($uri, '/')); @@ -325,7 +326,7 @@ class CI_URI { { // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', urldecode($str))) + if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '|')).']+$|i', $str)) { show_error('The URI you submitted has disallowed characters.', 400); } -- cgit v1.2.3-24-g4f1b From ea6688b3b9a7a208d1c44439c4f01801fd3b8c65 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 31 Oct 2012 21:52:11 +0200 Subject: Fix issue in resetting QUERY_STRING, GET vars introduced in f2b19fee7876708c7a7bb5cba6b7df682a9d2a53 --- system/core/URI.php | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 4a8d33e88..3b7718fff 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -212,7 +212,7 @@ class CI_URI { $_SERVER['QUERY_STRING'] = $query; } - $this->_reset_query_string(); + parse_str($_SERVER['QUERY_STRING'], $_GET); if ($uri === '/' OR $uri === '') { @@ -248,37 +248,13 @@ class CI_URI { $uri = rawurldecode($uri[0]); } - $this->_reset_query_string(); + parse_str($_SERVER['QUERY_STRING'], $_GET); return str_replace(array('//', '../'), '/', trim($uri, '/')); } // -------------------------------------------------------------------- - /** - * Reset QUERY_STRING - * - * Re-processes QUERY_STRING to and fetches the real GET values from it. - * Useful for cases where we got the URI path from it's query string. - * - * @used-by CI_URI::_parse_request_uri() - * @used-by CI_URI::_parse_query_string() - * @return void - */ - protected function _reset_query_string() - { - if ($_SERVER['QUERY_STRING'] === '') - { - $_GET = array(); - } - else - { - parse_str($_SERVER['QUERY_STRING']); - } - } - - // -------------------------------------------------------------------- - /** * Is CLI Request? * -- cgit v1.2.3-24-g4f1b From 3b72eb58e61581b7e92012a322be48e216491d7c Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 00:45:26 +0200 Subject: Changed URI auto-detection to try PATH_INFO first (thanks to @sourcejedi, PR #1326) Up until PHP 5.2.4 (which is our new lowest requirement), there was a bug related to PATH_INFO which made REQUEST_URI a more reliable choice. This is now no longer the case, see https://bugs.php.net/bug.php?id=31892 for more details. Also removed ORIG_PATH_INFO from the suggested alternatives for uri_protocol in application/config/config.php as it will not exist in most of PHP's recent versions and is pointless when you can use PATH_INFO anyway. --- system/core/URI.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 3b7718fff..309c77630 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -102,23 +102,21 @@ class CI_URI { return; } - // Let's try the REQUEST_URI first, this will work in most situations - if (($uri = $this->_parse_request_uri()) !== '') + // Is there a PATH_INFO variable? This should be the easiest solution. + if (isset($_SERVER['PATH_INFO'])) { - $this->_set_uri_string($uri); + $this->_set_uri_string($_SERVER['PATH_INFO']); return; } - // Is there a PATH_INFO variable? - // Note: some servers seem to have trouble with getenv() so we'll test it two ways - $uri = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); - if (trim($uri, '/') !== '' && $uri !== '/'.SELF) + // Let's try REQUEST_URI then, this will work in most situations + if (($uri = $this->_parse_request_uri()) !== '') { $this->_set_uri_string($uri); return; } - // No PATH_INFO?... What about QUERY_STRING? + // No REQUEST_URI either?... What about QUERY_STRING? if (($uri = $this->_parse_query_string()) !== '') { $this->_set_uri_string($uri); -- cgit v1.2.3-24-g4f1b From c5536aac5752054f7f76e448d58b86407d8f574e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 17:33:58 +0200 Subject: Manually apply PR #1594 (fixing phpdoc page-level generation/warnings) Also partially fixes issue #1295, fixes inconsistencies in some page-level docblocks and adds include checks in language files. --- system/core/Benchmark.php | 3 ++- system/core/CodeIgniter.php | 3 ++- system/core/Common.php | 3 ++- system/core/Config.php | 3 ++- system/core/Controller.php | 3 ++- system/core/Exceptions.php | 3 ++- system/core/Hooks.php | 3 ++- system/core/Input.php | 3 ++- system/core/Lang.php | 3 ++- system/core/Loader.php | 3 ++- system/core/Model.php | 3 ++- system/core/Output.php | 3 ++- system/core/Router.php | 3 ++- system/core/Security.php | 3 ++- system/core/URI.php | 3 ++- system/core/Utf8.php | 3 ++- 16 files changed, 32 insertions(+), 16 deletions(-) (limited to 'system/core') diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php index f94db2721..e80ee54dd 100644 --- a/system/core/Benchmark.php +++ b/system/core/Benchmark.php @@ -1,4 +1,4 @@ - Date: Thu, 1 Nov 2012 19:55:42 +0200 Subject: Allow use of dashes in controller/method URI segments Supersedes PR #642 --- system/core/Router.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 87f3e9e63..89fb74f2f 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -190,6 +190,7 @@ class CI_Router { { 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) { @@ -268,9 +269,13 @@ class CI_Router { return $segments; } + $temp = str_replace('-', '_', $segments[0]); + // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$segments[0].'.php')) + if (file_exists(APPPATH.'controllers/'.$temp.'.php')) { + $segments[0] = $temp; + empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]); return $segments; } @@ -283,6 +288,9 @@ class CI_Router { if (count($segments) > 0) { + $segments[0] = str_replace('-', '_', $segments[0]); + empty($segments[1]) OR $segments[1] = str_replace('-', '_', $segments[1]); + // Does the requested controller exist in the sub-folder? if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php')) { -- cgit v1.2.3-24-g4f1b From 254735ee011d99f5c7fe3825849d7ec0b54bd4e1 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 1 Nov 2012 21:21:20 +0200 Subject: Fix issue #122 --- system/core/URI.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index 2f6cade34..e2cac8d89 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -696,7 +696,14 @@ class CI_URI { */ public function ruri_string() { - return implode('/', $this->rsegment_array()); + global $RTR; + + if (($dir = $RTR->fetch_directory()) === '/') + { + $dir = ''; + } + + return $dir.implode('/', $this->rsegment_array()); } } -- cgit v1.2.3-24-g4f1b From 7d394f8cc75dff27324279bfbaffb1a487ea6dc7 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 04:37:34 +0200 Subject: Router-related optimizations An improved version of changes suggesed in PR #1352, and more specifically: https://github.com/sourcejedi/CodeIgniter/commit/8f7d2dfe42bd8543981c0f295e391e433d82fd42 https://github.com/sourcejedi/CodeIgniter/commit/d2de251c092d9d822fc4898e3681b64e9c74dd2a (thanks again @sourcejedi) --- system/core/CodeIgniter.php | 13 ++++--------- system/core/Router.php | 7 ------- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'system/core') diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index ee1e9b9c9..633be7fab 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -256,17 +256,14 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * Security check * ------------------------------------------------------ * - * None of the functions in the app controller or the + * None of the methods in the app controller or the * loader class can be called via the URI, nor can - * controller functions that begin with an underscore + * controller functions that begin with an underscore. */ $class = $RTR->fetch_class(); $method = $RTR->fetch_method(); - if ( ! class_exists($class) - OR strpos($method, '_') === 0 - OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller'))) - ) + if ( ! class_exists($class) OR $method[0] === '_' OR method_exists('CI_Controller', $method)) { if ( ! empty($RTR->routes['404_override'])) { @@ -325,9 +322,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); } else { - // is_callable() returns TRUE on some versions of PHP 5 for private and protected - // methods, so we'll use this workaround for consistent behavior - if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI)))) + if ( ! is_callable(array($CI, $method))) { // Check and see if we are using a 404 override and use it. if ( ! empty($RTR->routes['404_override'])) diff --git a/system/core/Router.php b/system/core/Router.php index 89fb74f2f..48c157f18 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -53,13 +53,6 @@ class CI_Router { */ public $routes = array(); - /** - * List of error routes - * - * @var array - */ - public $error_routes = array(); - /** * Current class name * -- cgit v1.2.3-24-g4f1b From c3751f843e9e4f646f3da2617df25cae6660f3af Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 16:50:00 +0200 Subject: Fix #1956 --- system/core/URI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/URI.php b/system/core/URI.php index e2cac8d89..91740254c 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -301,7 +301,7 @@ class CI_URI { { // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '|')).']+$|i', $str)) + if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str)) { show_error('The URI you submitted has disallowed characters.', 400); } -- cgit v1.2.3-24-g4f1b From 533bf2dd5f36e277a9ee6629ccd667a32b05d154 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 22:44:29 +0200 Subject: Fix a directory/404_override bug and some routing-related optimizations --- system/core/CodeIgniter.php | 16 ++++++---- system/core/Router.php | 76 +++++++++++++-------------------------------- 2 files changed, 31 insertions(+), 61 deletions(-) (limited to 'system/core') diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 633be7fab..12747c5d9 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -267,9 +267,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); { if ( ! empty($RTR->routes['404_override'])) { - $x = explode('/', $RTR->routes['404_override'], 2); - $class = $x[0]; - $method = isset($x[1]) ? $x[1] : 'index'; + if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + { + $method = 'index'; + } + if ( ! class_exists($class)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) @@ -327,9 +329,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); // Check and see if we are using a 404 override and use it. if ( ! empty($RTR->routes['404_override'])) { - $x = explode('/', $RTR->routes['404_override'], 2); - $class = $x[0]; - $method = isset($x[1]) ? $x[1] : 'index'; + if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + { + $method = 'index'; + } + if ( ! class_exists($class)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) diff --git a/system/core/Router.php b/system/core/Router.php index 48c157f18..67e9b300d 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -142,7 +142,7 @@ class CI_Router { include(APPPATH.'config/routes.php'); } - $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route; + $this->routes = (isset($route) && is_array($route)) ? $route : array(); unset($route); // Set the default controller so we can display it in the event @@ -179,26 +179,21 @@ class CI_Router { */ protected function _set_default_controller() { - if ($this->default_controller === FALSE) + 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 (strpos($this->default_controller, '/') !== FALSE) + if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) { - $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')); + $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 $this->uri->_reindex_segments(); @@ -227,17 +222,8 @@ class CI_Router { $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'; - } + isset($segments[1]) OR $segments[1] = 'index'; + $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 @@ -276,9 +262,7 @@ class CI_Router { 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); - + $this->set_directory(array_shift($segments)); if (count($segments) > 0) { $segments[0] = str_replace('-', '_', $segments[0]); @@ -289,12 +273,8 @@ class CI_Router { { 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; + $this->directory = ''; + return explode('/', $this->routes['404_override'], 2); } else { @@ -305,40 +285,26 @@ class CI_Router { 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')) + $segments = explode('/', $this->default_controller); + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.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 override if ( ! 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'); + if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + { + $method = 'index'; + } - return $x; + return array($class, $method); } // Nothing else to do at this point but show a 404 @@ -533,7 +499,7 @@ class CI_Router { if (isset($routing['function'])) { - $routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function']; + $routing['function'] = empty($routing['function']) ? 'index' : $routing['function']; $this->set_method($routing['function']); } } -- cgit v1.2.3-24-g4f1b From e24eed7e4e410fabf7479a67d3a27e2596444505 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 2 Nov 2012 23:33:45 +0200 Subject: Some micro-optimizations --- system/core/Input.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index c6063a280..142e2b434 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -356,11 +356,7 @@ class CI_Input { // Some proxies typically list the whole chain of IP // addresses through which the client has reached us. // e.g. client_ip, proxy_ip1, proxy_ip2, etc. - if (strpos($spoof, ',') !== FALSE) - { - $spoof = explode(',', $spoof, 2); - $spoof = $spoof[0]; - } + sscanf($spoof, '%[^,]', $spoof); if ( ! $this->valid_ip($spoof)) { @@ -430,7 +426,7 @@ class CI_Input { } // Split the netmask length off the network address - list($netaddr, $masklen) = explode('/', $proxy_ips[$i], 2); + sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen); // Again, an IPv6 address is most likely in a compressed form if ($separator === ':') -- cgit v1.2.3-24-g4f1b From 38e32f643492a7bf0233bb9848138d183fbdfcd4 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 3 Nov 2012 00:16:47 +0200 Subject: Bootstrap improvements - Don't instantiate the CI singleton twice. - General clean-up. - Fix issue #953. --- system/core/CodeIgniter.php | 72 +++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 39 deletions(-) (limited to 'system/core') diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 12747c5d9..1cd6403bf 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -288,6 +288,38 @@ defined('BASEPATH') OR exit('No direct script access allowed'); } } + if (method_exists($class, '_remap')) + { + $params = array($method, array_slice($URI->rsegments, 2)); + $method = '_remap'; + } + else + { + if ( ! is_callable(array($class, $method))) + { + if (empty($RTR->routes['404_override'])) + { + show_404($class.'/'.$method); + } + elseif (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) + { + $method = 'index'; + } + + if ( ! class_exists($class)) + { + if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) + { + show_404($class.'/'.$method); + } + + include_once(APPPATH.'controllers/'.$class.'.php'); + } + } + + $params = array_slice($URI->rsegments, 2); + } + /* * ------------------------------------------------------ * Is there a "pre_controller" hook? @@ -317,45 +349,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); * Call the requested method * ------------------------------------------------------ */ - // Is there a "remap" function? If so, we call it instead - if (method_exists($CI, '_remap')) - { - $CI->_remap($method, array_slice($URI->rsegments, 2)); - } - else - { - if ( ! is_callable(array($CI, $method))) - { - // Check and see if we are using a 404 override and use it. - if ( ! empty($RTR->routes['404_override'])) - { - if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2) - { - $method = 'index'; - } - - if ( ! class_exists($class)) - { - if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) - { - show_404($class.'/'.$method); - } - - include_once(APPPATH.'controllers/'.$class.'.php'); - unset($CI); - $CI = new $class(); - } - } - else - { - show_404($class.'/'.$method); - } - } - - // Call the requested method. - // Any URI segments present (besides the class/function) will be passed to the method for convenience - call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); - } + call_user_func_array(array(&$CI, $method), $params); // Mark a benchmark end point $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); -- cgit v1.2.3-24-g4f1b From 679525d0237ac2e0a94d7b05377eb31eb3398f19 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 3 Nov 2012 00:35:48 +0200 Subject: Removed CI_Loader::initialize() and moved its logic to the constructor. That method used to be called by the CI_Controller constructor and was required because of the possibility to instantiate the Controller class twice due to 404_override, and so some properties needed to be reset. Following the last commit - this is no longer the case. --- system/core/Controller.php | 1 - system/core/Loader.php | 28 ++++++---------------------- 2 files changed, 6 insertions(+), 23 deletions(-) (limited to 'system/core') diff --git a/system/core/Controller.php b/system/core/Controller.php index ee6fec8d5..cbdf0515f 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -65,7 +65,6 @@ class CI_Controller { } $this->load =& load_class('Loader', 'core'); - $this->load->initialize(); log_message('debug', 'Controller Class Initialized'); } diff --git a/system/core/Loader.php b/system/core/Loader.php index e9d03482f..2a78f4153 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -130,8 +130,10 @@ class CI_Loader { /** * Class constructor * - * Sets component load paths gets the initial output buffering level. + * Sets component load paths, gets the initial output buffering level + * and calls the autoloader. * + * @uses CI_Loader::_ci_autoloader() * @return void */ public function __construct() @@ -141,28 +143,10 @@ class CI_Loader { $this->_ci_helper_paths = array(APPPATH, BASEPATH); $this->_ci_model_paths = array(APPPATH); $this->_ci_view_paths = array(VIEWPATH => TRUE); - - log_message('debug', 'Loader Class Initialized'); - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Loader - * - * @used-by CI_Controller - * @uses CI_Loader::_ci_autoloader() - * @return object $this - */ - public function initialize() - { - $this->_ci_classes = array(); - $this->_ci_loaded_files = array(); - $this->_ci_models = array(); $this->_base_classes =& is_loaded(); - $this->_ci_autoloader(); - return $this; + + log_message('debug', 'Loader Class Initialized'); } // -------------------------------------------------------------------- @@ -1150,7 +1134,7 @@ class CI_Loader { * * Loads component listed in the config/autoload.php file. * - * @used-by CI_Loader::initialize() + * @used-by CI_Loader::__construct() * @return void */ protected function _ci_autoloader() -- cgit v1.2.3-24-g4f1b From cdac248e9cf7a8ea3ed426f189bb52254800bc2a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 3 Nov 2012 18:09:01 +0200 Subject: Revert 679525d0237ac2e0a94d7b05377eb31eb3398f19 It appears to break get_instance()->*_package_path*() usage which is very common. Need to figure out how to resolve this. --- system/core/Controller.php | 1 + system/core/Loader.php | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Controller.php b/system/core/Controller.php index cbdf0515f..ee6fec8d5 100644 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -65,6 +65,7 @@ class CI_Controller { } $this->load =& load_class('Loader', 'core'); + $this->load->initialize(); log_message('debug', 'Controller Class Initialized'); } diff --git a/system/core/Loader.php b/system/core/Loader.php index 2a78f4153..88fbdb6e1 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -130,10 +130,8 @@ class CI_Loader { /** * Class constructor * - * Sets component load paths, gets the initial output buffering level - * and calls the autoloader. + * Sets component load paths, gets the initial output buffering level. * - * @uses CI_Loader::_ci_autoloader() * @return void */ public function __construct() @@ -143,14 +141,29 @@ class CI_Loader { $this->_ci_helper_paths = array(APPPATH, BASEPATH); $this->_ci_model_paths = array(APPPATH); $this->_ci_view_paths = array(VIEWPATH => TRUE); - $this->_base_classes =& is_loaded(); - $this->_ci_autoloader(); log_message('debug', 'Loader Class Initialized'); } // -------------------------------------------------------------------- + /** + * Initializer + * + * @todo Figure out a way to move this to the constructor + * without breaking *package_path*() methods. + * @uses CI_Loader::_ci_autoloader() + * @used-by CI_Controller::__construct() + * @return void + */ + public function initialize() + { + $this->_base_classes =& is_loaded(); + $this->_ci_autoloader(); + } + + // -------------------------------------------------------------------- + /** * Is Loaded * @@ -1134,7 +1147,7 @@ class CI_Loader { * * Loads component listed in the config/autoload.php file. * - * @used-by CI_Loader::__construct() + * @used-by CI_Loader::initialize() * @return void */ protected function _ci_autoloader() -- cgit v1.2.3-24-g4f1b From a3f5c5c78f6172565e3264764e1de7dcad894b0a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sun, 4 Nov 2012 20:08:42 +0200 Subject: Fix #98 --- 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 67e9b300d..30bf39657 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -147,7 +147,7 @@ class CI_Router { // 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 : strtolower($this->routes['default_controller']); + $this->default_controller = empty($this->routes['default_controller']) ? FALSE : $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) -- cgit v1.2.3-24-g4f1b From 522c73623b46afc9082ac7c8af5c34bf1b4f47f4 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 5 Nov 2012 16:40:32 +0200 Subject: Revert usage of is_callable() in system/core/CodeIgniter.php Seems to be causing issues (see #1970). Also updated the Controller docs, mainly to include an important note related to #1967. --- system/core/CodeIgniter.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 1cd6403bf..89081b572 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -295,7 +295,11 @@ defined('BASEPATH') OR exit('No direct script access allowed'); } else { - if ( ! is_callable(array($class, $method))) + // WARNING: It appears that there are issues with is_callable() even in PHP 5.2! + // Furthermore, there are bug reports and feature/change requests related to it + // that make it unreliable to use in this context. Please, DO NOT change this + // work-around until a better alternative is available. + if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($class)), TRUE)) { if (empty($RTR->routes['404_override'])) { -- cgit v1.2.3-24-g4f1b From a287a34c215903d3452023d74149eb5880125715 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 5 Nov 2012 23:19:59 +0200 Subject: Refactored DB Forge - PDO subdrivers are isolated from each other now. - Added compatibility for pretty much all of the features, for every DB platform. - Unified the way that stuff works in general. - Fixes issue #1005. --- system/core/Loader.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Loader.php b/system/core/Loader.php index 88fbdb6e1..808fa80df 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -392,7 +392,20 @@ class CI_Loader { require_once(BASEPATH.'database/DB_forge.php'); require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php'); - $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; + + if ( ! empty($CI->db->subdriver)) + { + $driver_path = BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/subdrivers/'.$CI->db->dbdriver.'_'.$CI->db->subdriver.'_forge.php'; + if (file_exists($driver_path)) + { + require_once($driver_path); + $class = 'CI_DB_'.$CI->db->dbdriver.'_'.$CI->db->subdriver.'_forge'; + } + } + else + { + $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; + } $CI->dbforge = new $class(); } -- cgit v1.2.3-24-g4f1b From eaa60c71082c1e49f8a48d633347c98b68a387c0 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 6 Nov 2012 01:11:22 +0200 Subject: Added possibility to pass custom database objects to DB Forge and DB Utilities Also, their property is no longer public and the utility class no longer extends CI_DB_forge. --- system/core/Loader.php | 61 +++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 25 deletions(-) (limited to 'system/core') diff --git a/system/core/Loader.php b/system/core/Loader.php index 808fa80df..9525f35d0 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -352,26 +352,30 @@ class CI_Loader { /** * Load the Database Utilities Class * - * @return void + * @param object $db Database object + * @param bool $return Whether to return the DB Forge class object or not + * @return void|object */ - public function dbutil() + public function dbutil($db = NULL, $return = FALSE) { - if ( ! class_exists('CI_DB')) - { - $this->database(); - } - $CI =& get_instance(); - // for backwards compatibility, load dbforge so we can extend dbutils off it - // this use is deprecated and strongly discouraged - $CI->load->dbforge(); + if ( ! is_object($db) OR ! ($db instanceof CI_DB)) + { + class_exists('CI_DB', FALSE) OR $this->database(); + $db =& $CI->db; + } require_once(BASEPATH.'database/DB_utility.php'); - require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php'); - $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; + require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php'); + $class = 'CI_DB_'.$db->dbdriver.'_utility'; + + if ($return === TRUE) + { + return new $class($db); + } - $CI->dbutil = new $class(); + $CI->dbutil = new $class($db); } // -------------------------------------------------------------------- @@ -379,35 +383,42 @@ class CI_Loader { /** * Load the Database Forge Class * - * @return void + * @param object $db Database object + * @param bool $return Whether to return the DB Forge class object or not + * @return void|object */ - public function dbforge() + public function dbforge($db = NULL, $return = FALSE) { - if ( ! class_exists('CI_DB')) + $CI =& get_instance(); + if ( ! is_object($db) OR ! ($db instanceof CI_DB)) { - $this->database(); + class_exists('CI_DB', FALSE) OR $this->database(); + $db =& $CI->db; } - $CI =& get_instance(); - require_once(BASEPATH.'database/DB_forge.php'); - require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php'); + require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php'); - if ( ! empty($CI->db->subdriver)) + if ( ! empty($db->subdriver)) { - $driver_path = BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/subdrivers/'.$CI->db->dbdriver.'_'.$CI->db->subdriver.'_forge.php'; + $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php'; if (file_exists($driver_path)) { require_once($driver_path); - $class = 'CI_DB_'.$CI->db->dbdriver.'_'.$CI->db->subdriver.'_forge'; + $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge'; } } else { - $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; + $class = 'CI_DB_'.$db->dbdriver.'_forge'; + } + + if ($return === TRUE) + { + return new $class($db); } - $CI->dbforge = new $class(); + $CI->dbforge = new $class($db); } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From 303eef056b7317a1e4f06feb26fdb452a59c3a51 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Tue, 6 Nov 2012 14:55:48 +0200 Subject: Added CI_Input::input_stream() Helps in reading php://input stream data by caching it when accessed for the first time. (supersedes PR #1684) --- system/core/Input.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index c0158df99..adc5f7ac0 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -99,6 +99,16 @@ class CI_Input { */ protected $headers = array(); + /** + * Input stream data + * + * Parsed from php://input at runtime + * + * @see CI_Input::input_stream() + * @var array + */ + protected $_input_stream = NULL; + /** * Class constructor * @@ -256,6 +266,37 @@ class CI_Input { // ------------------------------------------------------------------------ + /** + * Fetch an item from the php://input stream + * + * Useful when you need to access PUT, DELETE or PATCH request data. + * + * @param string $index Index for item to be fetched + * @param bool $xss_clean Whether to apply XSS filtering + * @return mixed + */ + public function input_stream($index = '', $xss_clean = FALSE) + { + // The input stream can only be read once, so we'll need to check + // if we have already done that first. + if (is_array($this->_input_stream)) + { + return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); + } + + // Parse the input stream in our cache var + parse_str(file_get_contents('php://input'), $this->_input_stream); + if ( ! is_array($this->_input_stream)) + { + $this->_input_stream = array(); + return NULL; + } + + return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean); + } + + // ------------------------------------------------------------------------ + /** * Set cookie * -- cgit v1.2.3-24-g4f1b From e9d2dc85b9cb255aae235635576972e4b7dbd5a8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 7 Nov 2012 14:23:29 +0200 Subject: Added function_usable() to common functions It is now used to check whether dangerous functions like eval() and exec() are available. It appears that the Suhosin extension (which is becoming popular) terminates script execution instead of returning e.g. FALSE when it has a function blacklisted. function_exists() checks are insufficient and our only option is to check the ini settings here. Filed an issue here: https://github.com/stefanesser/suhosin/issues/18 ... hopefully we'll be able to deal with this in a more elegant way in the future. (this commit supersedes PR #1809) --- system/core/Common.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ system/core/Loader.php | 4 +++- 2 files changed, 50 insertions(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Common.php b/system/core/Common.php index 3b7ea6ad4..aea5f1808 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -651,5 +651,52 @@ if ( ! function_exists('_stringify_attributes')) } } +// ------------------------------------------------------------------------ + +if ( ! function_exists('function_usable')) +{ + /** + * Function usable + * + * Executes a function_exists() check, and if the Suhosin PHP + * extension is loaded - checks whether the function that is + * checked might be disabled in there as well. + * + * This is useful as function_exists() will return FALSE for + * functions disabled via the *disable_functions* php.ini + * setting, but not for *suhosin.executor.func.blacklist* and + * *suhosin.executor.disable_eval*. These settings will just + * terminate script execution if a disabled function is executed. + * + * @link http://www.hardened-php.net/suhosin/ + * @param string $function_name Function to check for + * @return bool TRUE if the function exists and is safe to call, + * FALSE otherwise. + */ + function function_usable($function_name) + { + static $_suhosin_func_blacklist; + + if (function_exists($function_name)) + { + if ( ! isset($_suhosin_func_blacklist)) + { + $_suhosin_func_blacklist = extension_loaded('suhosin') + ? array() + : explode(',', trim(@ini_get('suhosin.executor.func.blacklist'))); + + if ( ! in_array('eval', $_suhosin_func_blacklist, TRUE) && @ini_get('suhosin.executor.disable_eval')) + { + $_suhosin_func_blacklist[] = 'eval'; + } + } + + return in_array($function_name, $_suhosin_func_blacklist, TRUE); + } + + return FALSE; + } +} + /* End of file Common.php */ /* Location: ./system/core/Common.php */ \ No newline at end of file diff --git a/system/core/Loader.php b/system/core/Loader.php index 9525f35d0..a9eec396c 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -871,7 +871,9 @@ class CI_Loader { // If the PHP installation does not support short tags we'll // do a little string replacement, changing the short tags // to standard PHP echo statements. - if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') === TRUE) + if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE + && config_item('rewrite_short_tags') === TRUE && function_usable('eval') + ) { echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace(' Date: Thu, 8 Nov 2012 11:34:00 +0200 Subject: Change route type checks priorities --- system/core/Router.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 30bf39657..3ef55cee2 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -341,8 +341,13 @@ class CI_Router { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri, $matches)) { + // Are we using the default routing method for back-references? + if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) + { + $val = preg_replace('#^'.$key.'$#', $val, $uri); + } // Are we using callbacks to process back-references? - if ( ! is_string($val) && is_callable($val)) + elseif ( ! is_string($val) && is_callable($val)) { // Remove the original string from the matches array. array_shift($matches); @@ -379,11 +384,6 @@ class CI_Router { // 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? - elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) - { - $val = preg_replace('#^'.$key.'$#', $val, $uri); - } return $this->_set_request(explode('/', $val)); } -- cgit v1.2.3-24-g4f1b From da5562a4bd87ad8ea827298dbe60e850225cfe34 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 8 Nov 2012 12:34:38 +0200 Subject: Revert 96ea52894aea85b86d75f59fee35f90676735060 --- system/core/Router.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'system/core') diff --git a/system/core/Router.php b/system/core/Router.php index 3ef55cee2..30bf39657 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -341,13 +341,8 @@ class CI_Router { // Does the RegEx match? if (preg_match('#^'.$key.'$#', $uri, $matches)) { - // Are we using the default routing method for back-references? - if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) - { - $val = preg_replace('#^'.$key.'$#', $val, $uri); - } // Are we using callbacks to process back-references? - elseif ( ! is_string($val) && is_callable($val)) + if ( ! is_string($val) && is_callable($val)) { // Remove the original string from the matches array. array_shift($matches); @@ -384,6 +379,11 @@ class CI_Router { // 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? + elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE) + { + $val = preg_replace('#^'.$key.'$#', $val, $uri); + } return $this->_set_request(explode('/', $val)); } -- cgit v1.2.3-24-g4f1b From e2b0754c4ea3fe227bc80a546f4d5cbd88a1e24e Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 8 Nov 2012 12:37:40 +0200 Subject: Another router fix for the dumbest usage of callbacks ever --- 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 30bf39657..01f44bc83 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -327,7 +327,7 @@ class CI_Router { $uri = implode('/', $this->uri->segments); // Is there a literal match? If so we're done - if (isset($this->routes[$uri])) + if (isset($this->routes[$uri]) && is_string($this->routes[$uri])) { return $this->_set_request(explode('/', $this->routes[$uri])); } -- cgit v1.2.3-24-g4f1b From 0aeee85b5164e31e2a76c05caa97bd898c1a776d Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 9 Nov 2012 17:43:11 +0200 Subject: Move the Log class to system/core/ It is a core class after all, I guess somebody forgot it when the rest of them were moved. --- system/core/Common.php | 2 +- system/core/Log.php | 181 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 system/core/Log.php (limited to 'system/core') diff --git a/system/core/Common.php b/system/core/Common.php index aea5f1808..7feb16bfd 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -420,7 +420,7 @@ if ( ! function_exists('log_message')) return; } - $_log =& load_class('Log'); + $_log =& load_class('Log', 'core'); $_log->write_log($level, $message, $php_error); } } diff --git a/system/core/Log.php b/system/core/Log.php new file mode 100644 index 000000000..e66270840 --- /dev/null +++ b/system/core/Log.php @@ -0,0 +1,181 @@ + 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4); + + /** + * Initialize Logging class + * + * @return void + */ + public function __construct() + { + $config =& get_config(); + + $this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/'; + + if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path)) + { + $this->_enabled = FALSE; + } + + if (is_numeric($config['log_threshold'])) + { + $this->_threshold = (int) $config['log_threshold']; + } + elseif (is_array($config['log_threshold'])) + { + $this->_threshold = $this->_threshold_max; + $this->_threshold_array = array_flip($config['log_threshold']); + } + + if ($config['log_date_format'] !== '') + { + $this->_date_fmt = $config['log_date_format']; + } + } + + // -------------------------------------------------------------------- + + /** + * Write Log File + * + * Generally this function will be called using the global log_message() function + * + * @param string the error level + * @param string the error message + * @param bool whether the error is a native PHP error + * @return bool + */ + public function write_log($level = 'error', $msg, $php_error = FALSE) + { + if ($this->_enabled === FALSE) + { + return FALSE; + } + + $level = strtoupper($level); + + if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) + && ! isset($this->_threshold_array[$this->_levels[$level]])) + { + return FALSE; + } + + + $filepath = $this->_log_path.'log-'.date('Y-m-d').'.php'; + $message = ''; + + if ( ! file_exists($filepath)) + { + $newfile = TRUE; + $message .= '<'."?php defined('BASEPATH') OR exit('No direct script access allowed'); ?".">\n\n"; + } + + if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE)) + { + return FALSE; + } + + $message .= $level.' '.($level === 'INFO' ? ' -' : '-').' '.date($this->_date_fmt).' --> '.$msg."\n"; + + flock($fp, LOCK_EX); + fwrite($fp, $message); + flock($fp, LOCK_UN); + fclose($fp); + + if (isset($newfile) && $newfile === TRUE) + { + @chmod($filepath, FILE_WRITE_MODE); + } + + return TRUE; + } + +} + +/* End of file Log.php */ +/* Location: ./system/libraries/Log.php */ \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 12d7b468d907c73abac3e3711b2f53c2fce25199 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 12 Nov 2012 13:42:09 +0200 Subject: Fix issue #777 --- system/core/Loader.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'system/core') diff --git a/system/core/Loader.php b/system/core/Loader.php index a9eec396c..1e6eafe8a 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -532,27 +532,34 @@ class CI_Loader { continue; } - $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php'; - // Is this a helper extension request? - if (file_exists($ext_helper)) + $ext_helper = config_item('subclass_prefix').$helper; + $ext_loaded = FALSE; + foreach ($this->_ci_helper_paths as $path) { - $base_helper = BASEPATH.'helpers/'.$helper.'.php'; + if (file_exists($path.'helpers/'.$ext_helper.'.php')) + { + include_once($path.'helpers/'.$ext_helper.'.php'); + $ext_loaded = TRUE; + } + } + // If we have loaded extensions - check if the base one is here + if ($ext_loaded === TRUE) + { + $base_helper = BASEPATH.'helpers/'.$helper.'.php'; if ( ! file_exists($base_helper)) { show_error('Unable to load the requested file: helpers/'.$helper.'.php'); } - include_once($ext_helper); include_once($base_helper); - $this->_ci_helpers[$helper] = TRUE; log_message('debug', 'Helper loaded: '.$helper); continue; } - // Try to load the helper + // No extensions found ... try loading regular helpers and/or overrides foreach ($this->_ci_helper_paths as $path) { if (file_exists($path.'helpers/'.$helper.'.php')) -- cgit v1.2.3-24-g4f1b