diff --git a/core/Url.php b/core/Url.php index 1ed77f5fa5033a9e38f449fffbad36d16f867b26..c27805305d7d660e1efa6490d24366e0f66bd880 100644 --- a/core/Url.php +++ b/core/Url.php @@ -67,6 +67,7 @@ class Url return self::getCurrentScheme() . '://' . self::getCurrentHost() . self::getCurrentScriptName() + . self::getCurrentPathInfo() . self::getCurrentQueryString(); } @@ -83,7 +84,8 @@ class Url { return self::getCurrentScheme() . '://' . self::getCurrentHost($default = 'unknown', $checkTrustedHost) - . self::getCurrentScriptName(); + . self::getCurrentScriptName() + . self::getCurrentPathInfo(); } /** @@ -173,6 +175,24 @@ class Url return $url; } + /** + * Returns the current PATH_INFO from the request. + * + * Contains any client-provided pathname information trailing the actual + * script filename but preceding the query string, if available. + * + * For instance, if the current script was accessed via the URL + * http://www.example.com/php/path_info.php/some/stuff?foo=bar + * then getCurrentPathInfo() would return "/some/stuff". + * + * @return string + * @api + */ + public static function getCurrentPathInfo() + { + return isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; + } + /** * Returns the current URL's protocol. * diff --git a/tests/PHPUnit/Unit/UrlTest.php b/tests/PHPUnit/Unit/UrlTest.php index c77907ee046d0a10cc6a43f3013f5cfcd367c0bc..888e6c8c9d71cc64f1d44d30b64c73083fca8e0b 100644 --- a/tests/PHPUnit/Unit/UrlTest.php +++ b/tests/PHPUnit/Unit/UrlTest.php @@ -159,11 +159,7 @@ class UrlTest extends PHPUnit_Framework_TestCase */ public function testGetCurrentUrlWithoutFilename($expected, $https, $host, $path) { - $names = array('PATH_INFO', 'REQUEST_URI', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'argv', 'HTTPS', 'HTTP_HOST', 'QUERY_STRING', 'HTTP_REFERER'); - - foreach ($names as $name) { - unset($_SERVER[$name]); - } + $this->resetGlobalVariables(); if ($https) { $_SERVER['HTTPS'] = $https; @@ -185,11 +181,7 @@ class UrlTest extends PHPUnit_Framework_TestCase */ public function test_getCurrentScriptName() { - $names = array('PATH_INFO', 'REQUEST_URI', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'argv', 'HTTPS', 'HTTP_HOST', 'QUERY_STRING', 'HTTP_REFERER'); - - foreach ($names as $name) { - unset($_SERVER[$name]); - } + $this->resetGlobalVariables(); $tests = array( array('/', 'http://example.com/', null), @@ -335,4 +327,85 @@ class UrlTest extends PHPUnit_Framework_TestCase ); } + public function urlProvider() + { + return array( + array('http://example.com/'), + array('https://example.com/'), + array('http://example.com/piwik/'), + array('http://example.com/index.php'), + array('http://example.com/index.php?foo=bar'), + array('http://example.com/index.php/.html?foo=bar', '/.html'), + ); + } + + /** + * @dataProvider urlProvider + */ + public function testGetCurrentUrl($url, $pathInfo = null) + { + $this->resetGlobalVariables(); + $this->setGlobalVariablesFromUrl($url, $pathInfo); + + $this->assertEquals($url, Url::getCurrentUrl()); + } + + public function urlWithoutQueryStringProvider() + { + return array( + array('http://example.com/', 'http://example.com/'), + array('https://example.com/', 'https://example.com/'), + array('http://example.com/piwik/', 'http://example.com/piwik/'), + array('http://example.com/index.php', 'http://example.com/index.php'), + array('http://example.com/index.php?foo=bar', 'http://example.com/index.php'), + array('http://example.com/index.php/.html?foo=bar', 'http://example.com/index.php/.html', '/.html'), + ); + } + + /** + * @dataProvider urlWithoutQueryStringProvider + */ + public function testGetCurrentUrlWithoutQueryString($url, $expected, $pathInfo = null) + { + $this->resetGlobalVariables(); + $this->setGlobalVariablesFromUrl($url, $pathInfo); + + $this->assertEquals($expected, Url::getCurrentUrlWithoutQueryString()); + } + + private function resetGlobalVariables() + { + $names = array('PATH_INFO', 'REQUEST_URI', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'argv', 'HTTPS', + 'HTTP_HOST', 'QUERY_STRING', 'HTTP_REFERER'); + + foreach ($names as $name) { + unset($_SERVER[$name]); + } + + Config::getInstance()->General['enable_trusted_host_check'] = 0; + } + + /** + * @param string $url + * @param string $pathInfo The PATH_INFO has to be provided because parse_url() doesn't parse that + */ + private function setGlobalVariablesFromUrl($url, $pathInfo) + { + if (parse_url($url, PHP_URL_SCHEME) === 'https') { + $_SERVER['HTTPS'] = true; + } + + $_SERVER['HTTP_HOST'] = parse_url($url, PHP_URL_HOST); + $_SERVER['REQUEST_URI'] = parse_url($url, PHP_URL_PATH); + + $queryString = parse_url($url, PHP_URL_QUERY); + if ($queryString) { + $_SERVER['REQUEST_URI'] .= '?' . $queryString; + $_SERVER['QUERY_STRING'] = $queryString; + } + + if ($pathInfo) { + $_SERVER['PATH_INFO'] = $pathInfo; + } + } }