Issue Details (XML | Word | Printable)

Key: ZF-6654
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Blocker Blocker
Assignee: Ben Scholzen
Reporter: Andrei Nikolov
Votes: 11
Watchers: 11
Operations

If you were logged in you would be able to see more operations.
Google issue summary
Zend Framework

Chaining routes with wildcard (*) does not work

Created: 14/May/09 08:29 AM   Updated: 17/Dec/09 05:41 PM   Resolved: 17/Dec/09 05:41 PM
Component/s: Zend_Controller
Affects Version/s: 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.9.0
Fix Version/s: 1.10.0

Time Tracking:
Not Specified

Issue Links:
Duplicate
 


 Description  « Hide

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...


Matthew Weier O'Phinney added a comment - 14/May/09 09:15 AM

Assigning to Ben to triage.


Andrei Nikolov added a comment - 15/May/09 04:09 AM

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


Andrei Nikolov added a comment - 20/Jul/09 03:16 PM

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..


Marc van de Geijn added a comment - 22/Jul/09 04:45 AM

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.


Marc van de Geijn added a comment - 22/Jul/09 04:52 AM

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?


Marc van de Geijn added a comment - 22/Jul/09 05:07 AM

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.


Jason Webster added a comment - 13/Aug/09 05:12 PM

Cleaned up formatting in report.


Stéphane added a comment - 18/Aug/09 06:22 AM

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.


Stéphane added a comment - 18/Aug/09 07:04 AM

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.


Michiel Thalen added a comment - 12/Oct/09 08:58 PM

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


Artur Bodera added a comment - 13/Oct/09 10:57 AM

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


Jeroen Weustink added a comment - 20/Oct/09 06:13 AM

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


Kevin Young added a comment - 28/Oct/09 01:58 PM

This issue still persists with 1.9.5.

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


Marc van de Geijn added a comment - 30/Nov/09 04:38 AM

This issue still persists with 1.9.6.


Sune Kibsgaard Pedersen added a comment - 10/Dec/09 05:04 AM

Will this be fixed in 1.9.7?


chaoshu sha added a comment - 10/Dec/09 05:34 AM

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;


Cristian Bichis added a comment - 17/Dec/09 08:33 AM

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

Lot of unfixed bugs on core ZF components


Andrei Nikolov added a comment - 17/Dec/09 08:45 AM

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


Cristian Bichis added a comment - 17/Dec/09 09:31 AM

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...


Cristian Bichis added a comment - 17/Dec/09 09:46 AM

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...


Artur Bodera added a comment - 17/Dec/09 11:29 AM

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