From c5bd9bb424006a4cbce1c71806c323d9ca3328e1 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 14 Dec 2017 17:42:00 +1300 Subject: [PATCH] BUG Fix incorrect BASE_DIR inferred in CLI BUG Fix Director::mockRequest() mocking incorrect $url Fixes #7689 --- src/Control/Director.php | 2 +- src/Control/HTTPRequestBuilder.php | 16 ++++++++++------ src/includes/constants.php | 5 +++++ tests/php/Control/DirectorTest.php | 26 ++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/Control/Director.php b/src/Control/Director.php index 316148578..2f42c8c5c 100644 --- a/src/Control/Director.php +++ b/src/Control/Director.php @@ -263,7 +263,7 @@ class Director implements TemplateGlobalProvider $newVars = HTTPRequestBuilder::cleanEnvironment($newVars); // Create new request - $request = HTTPRequestBuilder::createFromVariables($newVars, $body); + $request = HTTPRequestBuilder::createFromVariables($newVars, $body, ltrim($url, '/')); if ($headers) { foreach ($headers as $k => $v) { $request->addHeader($k, $v); diff --git a/src/Control/HTTPRequestBuilder.php b/src/Control/HTTPRequestBuilder.php index 378ea3b10..0e81fc712 100644 --- a/src/Control/HTTPRequestBuilder.php +++ b/src/Control/HTTPRequestBuilder.php @@ -28,16 +28,20 @@ class HTTPRequestBuilder * * @param array $variables * @param string $input Request body + * @param string|null $url Provide specific url (relative to base) * @return HTTPRequest */ - public static function createFromVariables(array $variables, $input) + public static function createFromVariables(array $variables, $input, $url = null) { - // Remove query parameters (they're retained separately through $server['_GET'] - $url = parse_url($variables['_SERVER']['REQUEST_URI'], PHP_URL_PATH); + // Infer URL from REQUEST_URI unless explicitly provided + if (!isset($url)) { + // Remove query parameters (they're retained separately through $server['_GET'] + $url = parse_url($variables['_SERVER']['REQUEST_URI'], PHP_URL_PATH); - // Remove base folders from the URL if webroot is hosted in a subfolder - if (substr(strtolower($url), 0, strlen(BASE_URL)) === strtolower(BASE_URL)) { - $url = substr($url, strlen(BASE_URL)); + // Remove base folders from the URL if webroot is hosted in a subfolder + if (substr(strtolower($url), 0, strlen(BASE_URL)) === strtolower(BASE_URL)) { + $url = substr($url, strlen(BASE_URL)); + } } // Build request diff --git a/src/includes/constants.php b/src/includes/constants.php index 61592cadf..a53ee8c0d 100644 --- a/src/includes/constants.php +++ b/src/includes/constants.php @@ -95,6 +95,11 @@ if (!defined('BASE_URL')) { return rtrim(parse_url($base, PHP_URL_PATH), '/'); } + // Unless specified, use empty string for base in CLI + if (in_array(php_sapi_name(), ['cli', 'phpdbg'])) { + return ""; + } + // Determine the base URL by comparing SCRIPT_NAME to SCRIPT_FILENAME and getting common elements // This tends not to work on CLI $path = realpath($_SERVER['SCRIPT_FILENAME']); diff --git a/tests/php/Control/DirectorTest.php b/tests/php/Control/DirectorTest.php index fa3237545..b629317ce 100644 --- a/tests/php/Control/DirectorTest.php +++ b/tests/php/Control/DirectorTest.php @@ -929,4 +929,30 @@ class DirectorTest extends SapphireTest { $this->assertTrue(Director::is_cli(), 'is_cli should be true for PHP CLI and phpdbg'); } + + public function testMockRequest() + { + Director::config()->set('alternate_base_url', 'http://www.mysite.com/some-subdir/'); + + // Can handle root-relative $url + Director::mockRequest(function (HTTPRequest $request) { + $this->assertEquals('some-page/nested', $request->getURL()); + $this->assertEquals(1, $request->getVar('query')); + $this->assertEquals('/some-subdir/some-page/nested', $_SERVER['REQUEST_URI']); + }, '/some-subdir/some-page/nested?query=1'); + + // Can handle absolute $url + Director::mockRequest(function (HTTPRequest $request) { + $this->assertEquals('some-page/nested', $request->getURL()); + $this->assertEquals(1, $request->getVar('query')); + $this->assertEquals('/some-subdir/some-page/nested', $_SERVER['REQUEST_URI']); + }, 'http://www.mysite.com/some-subdir/some-page/nested?query=1'); + + // Can handle relative $url + Director::mockRequest(function (HTTPRequest $request) { + $this->assertEquals('some-page/nested', $request->getURL()); + $this->assertEquals(1, $request->getVar('query')); + $this->assertEquals('/some-subdir/some-page/nested', $_SERVER['REQUEST_URI']); + }, 'some-page/nested?query=1'); + } }