diff --git a/src/Routing/Router.php b/src/Routing/Router.php index 6617298c7dc..5cdba9f34bf 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -616,23 +616,21 @@ public static function url($url = null, $full = false) 'action' => 'index', '_ext' => null, ]; - $here = $base = $output = $frag = null; + $here = $output = $frag = null; + $context = static::$_requestContext; // In 4.x this should be replaced with state injected via setRequestContext $request = static::getRequest(true); if ($request) { $params = $request->getAttribute('params'); $here = $request->getRequestTarget(); - $base = $request->getAttribute('base'); - } else { - $base = Configure::read('App.base'); - if (isset(static::$_requestContext['_base'])) { - $base = static::$_requestContext['_base']; - } + $context['_base'] = $request->getAttribute('base'); + } elseif (!isset($context['_base'])) { + $context['_base'] = Configure::read('App.base'); } if (empty($url)) { - $output = $base . (isset($here) ? $here : '/'); + $output = $context['_base'] . (isset($here) ? $here : '/'); if ($full) { $output = static::fullBaseUrl() . $output; } @@ -680,8 +678,9 @@ public static function url($url = null, $full = false) if ($full && isset($url['_scheme']) && !isset($url['_host'])) { $url['_host'] = parse_url(static::fullBaseUrl(), PHP_URL_HOST); } + $context['params'] = $params; - $output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]); + $output = static::$_collection->match($url, $context); } else { $plainString = ( strpos($url, 'javascript:') === 0 || @@ -697,7 +696,7 @@ public static function url($url = null, $full = false) if ($plainString) { return $url; } - $output = $base . $url; + $output = $context['_base'] . $url; } $protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output); if ($protocol === 0) { diff --git a/tests/TestCase/Routing/RouterTest.php b/tests/TestCase/Routing/RouterTest.php index a01b06b6287..df4b7ee1db0 100644 --- a/tests/TestCase/Routing/RouterTest.php +++ b/tests/TestCase/Routing/RouterTest.php @@ -96,6 +96,34 @@ public function testBaseUrlWithBasePath() $this->assertEquals('http://example.com/cakephp/tasks', Router::url('/tasks', true)); } + /** + * Test that Router uses App.base to build URL's when there are no stored + * request objects. + * + * @return void + */ + public function testBaseUrlWithBasePathArrayUrl() + { + Configure::write('App.base', '/cakephp'); + Router::fullBaseUrl('http://example.com'); + Router::scope('/', function ($routes) { + $routes->get('/:controller/:action', []); + }); + + $out = Router::url([ + 'controller' => 'tasks', + 'action' => 'index' + ], true); + $this->assertEquals('http://example.com/cakephp/tasks', $out); + + $out = Router::url([ + 'controller' => 'tasks', + 'action' => 'index', + '_base' => false + ], true); + $this->assertEquals('http://example.com/tasks', $out); + } + /** * Test that Router uses the correct url including base path for requesting the current actions. *