Browse Source

Merge pull request #12377 from cakephp/issue-12375

Ensure base path is always part of URL context.
Mark Story 7 years ago
parent
commit
11b055635a
2 changed files with 37 additions and 10 deletions
  1. 9 10
      src/Routing/Router.php
  2. 28 0
      tests/TestCase/Routing/RouterTest.php

+ 9 - 10
src/Routing/Router.php

@@ -616,23 +616,21 @@ class Router
             '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 @@ class Router
             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 @@ class Router
             if ($plainString) {
                 return $url;
             }
-            $output = $base . $url;
+            $output = $context['_base'] . $url;
         }
         $protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output);
         if ($protocol === 0) {

+ 28 - 0
tests/TestCase/Routing/RouterTest.php

@@ -97,6 +97,34 @@ class RouterTest extends TestCase
     }
 
     /**
+     * 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.
      *
      * @return void