ZF2-486: Individual segments in a route are not filled when using url view helper and url controller plugin
Description
I have this application module config file in /module/Application/config/module.config.php
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application',
'action' => 'index',
),
),
),
'application' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:locale][/:controller][/:action][/:id]',
'constraints' => array(
'locale' => '[a-z]{2}',
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Application',
'action' => 'index',
'locale' => 'de',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Wildcard',
'options' => array(
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Application' => 'Application\Controller\IndexController',
),
),
);
The routing itself works perfectly. But when I want to create an Url with the url view helper or the url controller plugin I don't get the expected result. Here is an example from a view script:
<?php echo $this->url('application', array('locale' => 'de', 'action'=>'add', 'controller' => 'application')); ?>
And here from a controller:
echo $this->url()->fromRoute('application', array('action' => 'add', 'controller' => 'application', 'locale' => 'de'));
Both output
/application/add
and not the expected
/de/application/add
Renaming the locale segment or changing the order of the segments does not help. But when I clear the default for the locale then it does work.
Comments
Posted by Ralf Eggert (ralf) on 2012-08-22T08:11:58.000+0000
corrected code blocks
Posted by Ralf Eggert (ralf) on 2012-08-22T12:03:22.000+0000
Assigned to Shavar Evron by mistake
Posted by Matthew Weier O'Phinney (matthew) on 2012-08-22T18:42:42.000+0000
I've confirmed the reproduce case a this time, and will see if I can fix it.
Posted by Matthew Weier O'Phinney (matthew) on 2012-08-22T19:10:56.000+0000
Actually, in looking at it, the problem is with your route.
Because you have multiple optional segments that are not encapsulated, the router is getting confused about what is truly optional, and what is required. Couple this with a wildcard route, and it's really anybody's guess as to how this should be assembled.
If you rewrite the segment route string as follows, it works fine:
Based on the use cases you've presented so far, it appears this is what you really want -- the locale should always be the first segment, and it will be optionally followed by the controller, optionally followed by the action, and finally optionally followed by the identifier.
Posted by Ralf Eggert (ralf) on 2012-08-22T20:07:42.000+0000
Thanks for your effort. Works now. And sorry for stuffing the issue tracker with this.
Posted by Matthew Weier O'Phinney (matthew) on 2012-08-22T20:09:17.000+0000
No worries -- it looked like a legitimate bug. It was only when I was tracing execution that I realized what was happening, and why.