From c3f647217d305a2ffc4dc63c01f3ec5692b3d4fa Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 23 Oct 2011 21:23:06 -0400 Subject: [PATCH] Implement trailing greedy star star. Trailing args grabs all trailing arguments as a single passed parameter. This is useful when you want to have trailing arguments that contain / in them. --- lib/Cake/Routing/Route/CakeRoute.php | 10 ++++++- .../Test/Case/Routing/Route/CakeRouteTest.php | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index 0af11e339..872b96c8b 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -148,7 +148,10 @@ class CakeRoute { } $names[] = $name; } - if (preg_match('#\/\*$#', $route)) { + if (preg_match('#\/\*\*$#', $route)) { + $parsed = preg_replace('#/\\\\\*\\\\\*$#', '(?:/(?P<_trailing_>.*))?', $parsed); + $this->_greedy = true; + } elseif (preg_match('#\/\*$#', $route)) { $parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed); $this->_greedy = true; } @@ -226,6 +229,11 @@ class CakeRoute { unset($route['_args_']); } + if (isset($route['_trailing_'])) { + $route['pass'][] = $route['_trailing_']; + unset($route['_trailing_']); + } + // restructure 'pass' key route params if (isset($this->options['pass'])) { $j = count($this->options['pass']); diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index 004b58d34..c72d9034a 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -718,4 +718,30 @@ class CakeRouteTest extends CakeTestCase { ); $this->assertEquals($expected, $result, 'Slug should have moved'); } + +/** + * Test the /** special type on parsing. + * + * @return void + */ + public function testParseTrailing() { + $route = new CakeRoute('/:controller/:action/**'); + $result = $route->parse('/posts/index/1/2/3/foo:bar'); + $expected = array( + 'controller' => 'posts', + 'action' => 'index', + 'pass' => array('1/2/3/foo:bar'), + 'named' => array() + ); + $this->assertEquals($expected, $result); + + $result = $route->parse('/posts/index/http://example.com'); + $expected = array( + 'controller' => 'posts', + 'action' => 'index', + 'pass' => array('http://example.com'), + 'named' => array() + ); + $this->assertEquals($expected, $result); + } }