Skip to content
Permalink
Browse files

Use the `pass` option when matching routes.

Routes are much easier to refactor if the `pass` option is honoured
when matching routes. When the pass option is defined, positional
arguments will be rekeyed to their matching route element should the
route element be undefined.

Fixes #4359
  • Loading branch information...
markstory committed Aug 25, 2014
1 parent f11629f commit 82a94ab10a741dce48f2bd2df50b210167eb2124
Showing with 92 additions and 1 deletion.
  1. +11 −0 src/Routing/Route/Route.php
  2. +81 −1 tests/TestCase/Routing/Route/RouteTest.php
@@ -430,6 +430,17 @@ public function match(array $url, array $context = []) {
return false;
}
// If this route uses pass option, and the passed elements are
// not set, rekey elements.
if (isset($this->options['pass'])) {
foreach ($this->options['pass'] as $i => $name) {
if (isset($url[$i]) && !isset($url[$name])) {
$url[$name] = $url[$i];
unset($url[$i]);
}
}
}
// check that all the key names are in the url
$keyNames = array_flip($this->keys);
if (array_intersect_key($keyNames, $url) !== $keyNames) {
@@ -393,7 +393,7 @@ public function testMatchWithHostKeys() {
*
* @return void
*/
public function testGreedyRouteFailurePassedArg() {
public function testMatchGreedyRouteFailurePassedArg() {
$route = new Route('/:controller/:action', array('plugin' => null));
$result = $route->match(array('controller' => 'posts', 'action' => 'view', '0'));
$this->assertFalse($result);
@@ -447,6 +447,86 @@ public function testMatchWithPassedArgs() {
$this->assertFalse($result);
}
/**
* Test that the pass option lets you use positional arguments for the
* route elements that were named.
*
* @return void
*/
public function testMatchWithPassOption() {
$route = new Route(
'/blog/:id-:slug',
['controller' => 'Blog', 'action' => 'view'],
['pass' => ['id', 'slug']]
);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
'id' => 1,
'slug' => 'second'
]);
$this->assertEquals('/blog/1-second', $result);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
1,
'second'
]);
$this->assertEquals('/blog/1-second', $result);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
1,
'second',
'query' => 'string'
]);
$this->assertEquals('/blog/1-second?query=string', $result);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
1 => 2,
2 => 'second'
]);
$this->assertFalse($result, 'Positional args must match exactly.');
}
/**
* Test that match() with pass and greedy routes.
*
* @return void
*/
public function testMatchWithPassOptionGreedy() {
$route = new Route(
'/blog/:id-:slug/*',
['controller' => 'Blog', 'action' => 'view'],
['pass' => ['id', 'slug']]
);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
'id' => 1,
'slug' => 'second',
'third',
'fourth',
'query' => 'string'
]);
$this->assertEquals('/blog/1-second/third/fourth?query=string', $result);
$result = $route->match([
'controller' => 'Blog',
'action' => 'view',
1,
'second',
'third',
'fourth',
'query' => 'string'
]);
$this->assertEquals('/blog/1-second/third/fourth?query=string', $result);
}
/**
* Test that extensions work.
*

0 comments on commit 82a94ab

Please sign in to comment.
You can’t perform that action at this time.