Issues

ZF-6654: Chaining routes with wildcard (*) does not work

Description

Reproduce code:


$userRoute = new Zend_Controller_Router_Route_Hostname(':nickname..'.$configuration->general->domain,
                    array('controller'=>'profile', 'action'=>'view'));

$userActionsRoute = new  Zend_Controller_Router_Route(':action/*',
                    array('action'=>'view'));
$router->addRoute('uActionsRoute', $userRoute->chain($userActionsRoute));

This have the simple purpose to have URLs like: username.domain.com/action/*, for example john.domain.com/image/id/76

but in ZF 1.8.1 the above route 'uActionsRoute' does not match such URLs. This is because in Controller/Router/Route.php there is a bug in match() method - when matching wildcard variables, $matchedPath is not updated.

Proposed fix:


                // Path is longer than a route, it's not a match
                if (!array_key_exists($pos, $this->_parts)) {
                    if ($partial) {
                        break;
                    } else {
                        return false;
                    }
                }                               
                
                // If it's a wildcard, get the rest of URL as wildcard data and stop matching
                if ($this->_parts[$pos] == '*') {
                    $count = count($path);
                    for($i = $pos; $i < $count; $i+=2) {
                        $var = urldecode($path[$i]);                        
                        //start fix:
                        $matchedPath .= $path[$i] . $this->_urlDelimiter;
                        if (isset ($path[$i+1]))
                        {
                            $matchedPath .= $path[$i+1] . $this->_urlDelimiter;
                        }
                        //end fix

                        if (!isset($this->_wildcardData[$var]) && !isset($this->_defaults[$var]) && !isset($values[$var])) {
                            $this->_wildcardData[$var] = (isset($path[$i+1])) ? urldecode($path[$i+1]) : null;
                        }
                    }
                    break;
                }

                //fix: moved this after the above IF block
                $matchedPath .= $pathPart . $this->_urlDelimiter;
                //end fix

                $name     = isset($this->_variables[$pos]) ? $this->_variables[$pos] : null;
                $pathPart = urldecode($pathPart);
// and so on...

Comments

Assigning to Ben to triage.

Sorry, wrong fix.. here is fix of the fix :)

//start fix: $matchedPath .= $path[$i] . $this->_urlDelimiter; if (isset ($path[$i+1])) { $matchedPath .= $path[$i+1] . $this->_urlDelimiter; } //end fix

Whats going on with this issue? Reported 2 months ago, provided you with the patch code, and still not fixed.. This is just not serious attention..

I ran into this issue also and it took me a day to find the problem. It would be very nice if this is fixed in the next release of the Framework.

I checked, but this issue is still present in the 1.9 preview release.

Unfortunatly I'm not allowed to change the affected versions for this issue. Is it an option to clone this issue and change the affected version?

Last comment from me on this issue. I've fixed it another way:

            // If it's a wildcard, get the rest of URL as wildcard data and stop matching
            if ($this->_parts[$pos] == '*') {
                $count = count($path);
                for($i = $pos; $i < $count; $i+=2) {
                    $var = urldecode($path[$i]);
                    if (!isset($this->_wildcardData[$var]) && !isset($this->_defaults[$var]) && !isset($values[$var])) {
                        $this->_wildcardData[$var] = (isset($path[$i+1])) ? urldecode($path[$i+1]) : null;
                    }
                }
                $matchedPath = implode( $this->_urlDelimiter, $path );
                break;
            }

I think it's safe to implode the $path array and assign it to $matchedPath, as the wildcard for loop is processing the full path.

Cleaned up formatting in report.

Well, I also encountered this issue today and lost quite some time. Hopefully, the fix proposed by Andrei just did it. I hope this patch will make its way to the next minor release.

Just a little update. I finally had to use Marc's fix as there was a variable scope issue with the one provided by Andrei. I am using ZF 1.9.1.

About time this gets fixed, very annoying this does not work and you are trying to figure out how the routing works.

It is a close one to the one I've stumbled upon when using chains and ``'' (empty) static routes: ZF-7848

Just updated to 1.9.4 and issue still isn't fixed..?????

This issue still persists with 1.9.5.

Marc van de Geijn's fix solved the problem for me.

This issue still persists with 1.9.6.

Will this be fixed in 1.9.7?

this below maybe another fix,

Index: Route.php

--- Route.php (revision 1324) +++ Route.php (working copy) @@ -239,6 +239,7 @@ $var = urldecode($path[$i]); if (!isset($this->_wildcardData[$var]) && !isset($this->_defaults[$var]) && !isset($values[$var])) { $this->_wildcardData[$var] = (isset($path[$i+1])) ? urldecode($path[$i+1]) : null; + $matchedPath .= $this->_wildcardData[$var] . $this->_urlDelimiter; } } break;

This doesn't seems to get fixed even now, on 1.9.7...

Lot of unfixed bugs on core ZF components :(

well, why fixing this bug, when we can just go and manually fix it every time when we upgrade ZF version.. really no need to fix it

I have made my own route class based on your fix, but of course, this is also a problem at any Route.php update, we loose the updates to the match function...

Actually i don't understand why there is planned a 2.0 release if doesn't seems to be 1.x branch usable without lot of manual fixes. I have quite lot of "fix" classes taken from the Jira, just to cleanup the bugs from framework...

I guess for a very small project - newbies like - is possible that you won't find any bugs, but even for small-medium projects is impossible to develop without tons of classes to fix the bugs...

I concur. I've got a pack of diff/patches to fix the holes, but it's ridiculous.

For example, the bug reported by me (ZF-7848) and related to static routes has a test scenario taken directly from ZF documentation examples! So something that is given in docs as an example is broken dead.

What is even more puzzling is that I've already devised a fix and posted it here, but none cares to use it :-)