Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Close #671 #693

Closed
wants to merge 1 commit into from

1 participant

@jails
Collaborator

A possible solution for #671.

  • If not null, default route params must respect its regular expression to be considered as "optionnal":
  • You can use ':.*' to have the same behavior as args :
Router::connect('/{:controller}/{:action}/{:args}');
Router::connect('/{:controller}/{:action}/{:category:.*}');

maybe a "BC break" : the following syntax won't match on '/site' anymore:

Router::connect('/site/{:action:home}', array('Site::index'));

But I don't think such syntax really make sense.

@jails jails closed this
@jails jails reopened this
@jails jails closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 23, 2012
  1. @jails

    Close #671

    jails authored
This page is out of date. Refresh to see the latest.
Showing with 79 additions and 1 deletion.
  1. +8 −1 net/http/Route.php
  2. +71 −0 tests/cases/net/http/RouterTest.php
View
9 net/http/Route.php
@@ -464,7 +464,14 @@ protected function _regex($regex, $param, $token, $prefix) {
} else {
$regex = '[^\/]+';
}
- $req = $param === 'args' || array_key_exists($param, $this->_params) ? '?' : '';
+
+ $optionnal = false;
+ if (isset($this->_params[$param])) {
+ $optionnal = preg_match("@{$regex}@", $this->_params[$param]);
+ } elseif (array_key_exists($param, $this->_params)) {
+ $optionnal = true;
+ }
+ $req = $regex === '.*' || $optionnal ? '?' : '';
if ($prefix === '/') {
$pattern = "(?:/(?P<{$param}>{$regex}){$req}){$req}";
View
71 tests/cases/net/http/RouterTest.php
@@ -142,6 +142,77 @@ public function testRouteMatchingWithDefaultParameters() {
$this->assertNull(Router::parse($this->request));
}
+ public function testRouteMatchingWithRegExAction() {
+ Router::connect(
+ '/products/{:action:add|edit|remove}/{:category}',
+ array('controller' => 'Products')
+ );
+ Router::connect('/products/{:category}', array('Products::category'));
+
+ $this->request = new Request();
+ $this->request->url = '/products/add/computer';
+ $result = Router::parse($this->request);
+ $expected = array(
+ 'controller' => 'Products',
+ 'action' => 'add',
+ 'category' => 'computer'
+ );
+ $this->assertEqual($expected, $result->params);
+
+ $this->request = new Request();
+ $this->request->url = '/products/add';
+ $result = Router::parse($this->request);
+ $expected = array(
+ 'controller' => 'Products',
+ 'action' => 'category',
+ 'category' => 'add'
+ );
+ $this->assertEqual($expected, $result->params);
+
+ $this->request = new Request();
+ $this->request->url = '/products/computer';
+ $result = Router::parse($this->request);
+ $expected = array(
+ 'controller' => 'Products',
+ 'action' => 'category',
+ 'category' => 'computer'
+ );
+ $this->assertEqual($expected, $result->params);
+
+ Router::reset();
+ Router::connect(
+ '/products/{:action:add|edit|remove}/{:category:.*}',
+ array('controller' => 'Products')
+ );
+ Router::connect('/products/{:category}', array('Products::category'));
+
+ $this->request = new Request();
+ $this->request->url = '/products/add';
+ $result = Router::parse($this->request);
+ $expected = array(
+ 'controller' => 'Products',
+ 'action' => 'add'
+ );
+ $this->assertEqual($expected, $result->params);
+
+ Router::reset();
+ Router::connect(
+ '/products/{:action:add|edit|remove}/{:category:.*}',
+ array('controller' => 'Products', 'category' => 'default')
+ );
+ Router::connect('/products/{:category}', array('Products::category'));
+
+ $this->request = new Request();
+ $this->request->url = '/products/add';
+ $result = Router::parse($this->request);
+ $expected = array(
+ 'controller' => 'Products',
+ 'action' => 'add',
+ 'category' => 'default'
+ );
+ $this->assertEqual($expected, $result->params);
+ }
+
/**
* Tests that URLs specified as "Controller::action" are interpreted properly.
*/
Something went wrong with that request. Please try again.