Skip to content

Commit 793ff89

Browse files
committed
Ensure base path is always part of URL context.
In scenarios where there is no active request (CLI tools) the current request context was missing the base path. By setting the request context earlier in the method we can add the base path when necessary. Refs #12375
1 parent 9c81344 commit 793ff89

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

src/Routing/Router.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -616,23 +616,21 @@ public static function url($url = null, $full = false)
616616
'action' => 'index',
617617
'_ext' => null,
618618
];
619-
$here = $base = $output = $frag = null;
619+
$here = $output = $frag = null;
620620

621+
$context = static::$_requestContext;
621622
// In 4.x this should be replaced with state injected via setRequestContext
622623
$request = static::getRequest(true);
623624
if ($request) {
624625
$params = $request->getAttribute('params');
625626
$here = $request->getRequestTarget();
626-
$base = $request->getAttribute('base');
627-
} else {
628-
$base = Configure::read('App.base');
629-
if (isset(static::$_requestContext['_base'])) {
630-
$base = static::$_requestContext['_base'];
631-
}
627+
$context['_base'] = $request->getAttribute('base');
628+
} elseif (!isset($context['_base'])) {
629+
$context['_base'] = Configure::read('App.base');
632630
}
633631

634632
if (empty($url)) {
635-
$output = $base . (isset($here) ? $here : '/');
633+
$output = $context['_base'] . (isset($here) ? $here : '/');
636634
if ($full) {
637635
$output = static::fullBaseUrl() . $output;
638636
}
@@ -680,8 +678,9 @@ public static function url($url = null, $full = false)
680678
if ($full && isset($url['_scheme']) && !isset($url['_host'])) {
681679
$url['_host'] = parse_url(static::fullBaseUrl(), PHP_URL_HOST);
682680
}
681+
$context['params'] = $params;
683682

684-
$output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]);
683+
$output = static::$_collection->match($url, $context);
685684
} else {
686685
$plainString = (
687686
strpos($url, 'javascript:') === 0 ||
@@ -697,7 +696,7 @@ public static function url($url = null, $full = false)
697696
if ($plainString) {
698697
return $url;
699698
}
700-
$output = $base . $url;
699+
$output = $context['_base'] . $url;
701700
}
702701
$protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output);
703702
if ($protocol === 0) {

tests/TestCase/Routing/RouterTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,34 @@ public function testBaseUrlWithBasePath()
9696
$this->assertEquals('http://example.com/cakephp/tasks', Router::url('/tasks', true));
9797
}
9898

99+
/**
100+
* Test that Router uses App.base to build URL's when there are no stored
101+
* request objects.
102+
*
103+
* @return void
104+
*/
105+
public function testBaseUrlWithBasePathArrayUrl()
106+
{
107+
Configure::write('App.base', '/cakephp');
108+
Router::fullBaseUrl('http://example.com');
109+
Router::scope('/', function ($routes) {
110+
$routes->get('/:controller/:action', []);
111+
});
112+
113+
$out = Router::url([
114+
'controller' => 'tasks',
115+
'action' => 'index'
116+
], true);
117+
$this->assertEquals('http://example.com/cakephp/tasks', $out);
118+
119+
$out = Router::url([
120+
'controller' => 'tasks',
121+
'action' => 'index',
122+
'_base' => false
123+
], true);
124+
$this->assertEquals('http://example.com/tasks', $out);
125+
}
126+
99127
/**
100128
* Test that Router uses the correct url including base path for requesting the current actions.
101129
*

0 commit comments

Comments
 (0)