ZF-6065: Zend_Controller_Router_Route_Regexp does not honor $reset parameter

Issue Type: Bug Created: 2009-03-19T08:53:35.000+0000 Last Updated: 2011-03-16T03:14:13.000+0000 Status: Open Fix version(s): Reporter: Colin Guthrie (coling) Assignee: Ben Scholzen (dasprid) Tags: - Zend_Controller

Related issues: Attachments: - regex.patch



I posted this message to the mailing list but got no feedback so I am going to proceed under the assumption that this is infact a real bone-fide bug!…

In Zend_View_Helper_Url the reset parameter is documented as: "Whether or not to reset the route defaults with those provided".

I've always taken this to mean that if the route being assembled is the same as the one matched on the current request, do not use the values extracted from the current request when assembling if this argument is true.

Assuming I am correct, when I look at the assemble() method of Zend_Controller_Router_Route_Regex it's clearly evident that the $reset parameter is completely ignored and $this->_values is always used.

So under this logic, it is impossible to e.g. link to the same route as currently matched but with different values for some params, but leaving others to be filled in by their default values when said missing params were actually supplied in the currently matched route!

Phew, that last sentence was a hard one to follow, so I'll do an example.

Say I have a route:

new Zend_Route_Regex( 'foo(?:/([\w-]+)(?:/([0-9]+))?)?', array('module' => 'blah', 'controller' => 'blah', 'action' => 'blah', 'arg1' => bar, 'arg2' => 1), array(1 => 'arg1', 2 => 'arg2') );

If the following URL is matched /foo/bar/42

And I use a view helper to create a new link on that page via: $this->url(array('arg1' => 'oink'), null, true);

Then I'd expect a route of: /foo/oink to be produced (because null will match the current route, and true says the current values should be ignored.

However this actually produces a route: /foo/oink/42

As the value matched in the current route is not reset as you would expect.

This is the same regardless of the $reset parameter so: $this->url(array('arg1' => 'oink'), null, false); will also produce the same result: /foo/oink/42


Posted by Colin Guthrie (coling) on 2009-03-19T08:56:30.000+0000

Here is a patch that causes the route to honour the $reset argument.

Posted by Ben Scholzen (dasprid) on 2009-03-19T12:58:52.000+0000

Is the regexp route the only one with this problem, or does it apply to other route types as well?

Posted by Colin Guthrie (coling) on 2009-03-19T13:10:18.000+0000

A quick look at the code seems to suggest that only Regex.php is affected.

Hostname and Module both use it and Chain passes it on, Static doesn't but that's expected.

I've not tested the above, just a quick glance at the code. I only personally use Regex in my app as we have fairly locked down routes and use forward() quite a lot and the forwarded locations often assume that the ACL checks have been done etc. so things like module routing (the default) are unsafe for me :)

Posted by Raphael Dehousse (thymus) on 2010-02-03T04:33:16.000+0000

I use this patch and it works for me. It's used in company-level projects.

Posted by Denis Novikov (denisnovikov) on 2011-02-01T10:09:41.000+0000

Don't want to be noisy, but is it really should take 2 year to change from:

<pre class="highlight">
        $matchedValuesMapped  = $this->_getMappedValues($this->_values, true, false);


<pre class="highlight">
        $matchedValuesMapped  = $reset ? array() : $this->_getMappedValues($this->_values, true, false);


Posted by Colin Guthrie (coling) on 2011-02-02T02:51:11.000+0000

Yeah, I've been carrying this patch in my local copy since I reported it. Getting it committed would be one less hassle. Are you still around Ben, or should we try and reassign this bug?

Posted by Ryan Lange (ryan.lange) on 2011-02-09T07:31:58.000+0000

This fix is especially necessary for any regular expressions that contain subpatterns that don't get used during assembly.

Consider this route...

<pre class="highlight">
$router->addRoute( 'admin_client', new Zend_Controller_Router_Route_Regex(

    // route

    // defaults
        'module'     => 'admin',
        'controller' => 'clients',
        'action'     => 'view'

    // subpattern map
        1 => 'id',
        3 => 'action'

    // reverse
) );

If the user has navigated to /admin/client/123/edit, the matched values are as follows:

<pre class="highlight">
"id"     => "123"
2        => "/edit"
"action" => "edit"

Now, if we try to assemble a URL based on this route...

<pre class="highlight">
$this->_helper->getHelper( 'Url' )->url( array( 'id' => 123, 'action' => 'view' ), 'admin_client', true );
$this->_helper->getHelper( 'Url' )->url( array( 'id' => 123, 'action' => 'delete' ), 'admin_client', true );

...these both result in /admin/client/123/%2Fedit.

In this situation, without this fix, the action key is essentially ignored and the second matched subpattern ("/edit") is encoded and inserted, resulting in an incorrect URL.

Posted by Gabriel Schuster (g.schuster) on 2011-03-16T03:14:12.000+0000

upvote This needs to be fixed as it makes regex-assembly completely useless.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.