Browse Source

Merge pull request #16132 from cakephp/fix-16130

3.x Fix Router::reverse() not being compatible with setPass()
Mark Story 4 years ago
parent
commit
719354efe2
2 changed files with 26 additions and 1 deletions
  1. 7 1
      src/Routing/Router.php
  2. 19 0
      tests/TestCase/Routing/RouterTest.php

+ 7 - 1
src/Routing/Router.php

@@ -859,7 +859,13 @@ class Router
             $params['_matchedRoute'],
             $params['_name']
         );
-        $params = array_merge($params, $pass);
+        foreach ($pass as $i => $passedValue) {
+            // Remove passed values that are also route keys
+            if (in_array($passedValue, $params, true)) {
+                unset($pass[$i]);
+            }
+        }
+        $params = array_merge($params, array_values($pass));
         if (!empty($url)) {
             $params['?'] = $url;
         }

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

@@ -2802,6 +2802,25 @@ class RouterTest extends TestCase
         $this->assertEquals('/eng/posts/view/1', $result);
     }
 
+    public function testReverseRouteKeyAndPass()
+    {
+        Router::reload();
+        $routes = Router::createRouteBuilder('/');
+        $routes->connect('/articles/{slug}', ['controller' => 'Articles', 'action' => 'view'])->setPass(['slug']);
+
+        $request = new ServerRequest([
+            'url' => '/articles/first-post',
+            'params' => [
+                'controller' => 'Articles',
+                'action' => 'view',
+                'pass' => ['first-post'],
+                'slug' => 'first-post',
+            ],
+        ]);
+        $result = Router::reverse($request);
+        $this->assertSame('/articles/first-post', $result);
+    }
+
     public function testReverseArrayQuery()
     {
         Router::connect('/:lang/:controller/:action/*', [], ['lang' => '[a-z]{3}']);