Zend_Router requirements mismatch - zend-framework

I have two routes that match a url with the same apparent pattern, the difference lies in the $actionRoute, this should only be matched if the variable :action on it equals 'myaction'.
If I go to /en/mypage/whatever/myaction it goes as expected through $actionRoute.
If I go to /en/mypage/whatever/blahblah it gets rejected by $actionRoute and matched by $genRoute.
If I go to /en/mypage/whatever it should be matched by $genRoute but it gets matched by $actionRoute instead throwing and exception because the action noactionAction() does not exist.
Don't know what I'm doing wrong, I'd appreciate your help.
$genRoute = new Zend_Controller_Router_Route(
':lang/mypage/:var1/:var2',
array(
'lang' => '',
'module' => 'mymodule',
'controller' => 'index',
'action' => 'index',
'var1' => 'noone',
'var2' => 'no'
),
array(
'var1' => '[a-z\-]+?',
'lang' => '(es|en|fr|de){1}'
)
);
$actionRoute = new Zend_Controller_Router_Route(
':lang/mypage/:var1/:action',
array(
'lang' => '',
'module' => 'mymodule',
'controller' => 'index',
'action' => 'noaction',
'var1' => 'noone',
),
array(
'action' => '(myaction)+?',
'var' => '[a-z\-]+?',
'lang' => '(es|en|fr|de){1}',
)
);
$router->addRoute('genroute',$genRoute);
$router->addRoute('actionroute',$actionRoute);

By providing a default value ('noaction') for action in your $actionRoute, you are making that variable optional. If you remove this it should all work fine. Also the 'var' key in the regexp patterns in your second route should probably be 'var1' as it is in your first.
So, you probably want your second route to be:
$actionRoute = new Zend_Controller_Router_Route(
':lang/mypage/:var1/:action',
array(
'lang' => '',
'module' => 'mymodule',
'controller' => 'index',
'var1' => 'noone',
),
array(
'action' => '(myaction)+?',
'var1' => '[a-z\-]+?',
'lang' => '(es|en|fr|de){1}',
)
);

Related

How to redirect with GET query in Zend 2?

I can redirect to matchable routes like $this->redirect()->toRoute('controller', array('action' => 'something', 'foo' => 'bar')), but how can I append a get query? I'm using it for a filter for a table. The filter can either be submitted on the page (form get method), or linked from another page (need to add get query).
try this :
'course' => array(
'type' => 'Segment',
'options' => array(
'route' => '/course[/:action[/:id]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '\d+'
),
'defaults' => array(
'__NAMESPACE__' => 'Home\Controller',
'controller' => 'course',
'action' => 'index',
'id' => 0
),
),
'may_terminate' => true,
'child_routes' => array(
'query' => array(
'type' => 'Query',
'options' => array(
'route' => '?[:filterByDepartment]'
),
),
),
),
make sure the route is met your need in the view :
echo $this->url('course/query', array('controller'=>'course', 'action'=>'index', 'id'=>0, 'filterByDepartment'=>'depA'));
if this is right, let's try the following in the controller action :
$this->redirect()->toRoute('course/query', array('controller'=>'course', 'action'=>'index', 'id'=>0, 'filterByDepartment'=>'depA'));

Zend_Controller_Router_Route_Regex Optional Parameters with Reverse

I've successfully created my Route using Regex. I have Several Optional Parameters in my route that I don't want displayed in the URL Helper unless the user has specified them. How can I accomplish this?
This is what I currently have
$route = new Zend_Controller_Router_Route_Regex(
'([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
array(
'controller' => 'widget',
'action' => 'list',
),
array(
1 => 'color',
2 => 'page',
3 => 'limit'
),
'%s-Widgets/'
);
$router->addRoute('color_widgets', $route);
I then call the URL Helper with following code
echo $this->url(array('page' => $page), 'color_widgets', false);
This results in /Blue-Widgets/ and does not send the Page to the URL. I can fix this by changing the reverse in the Router
$route = new Zend_Controller_Router_Route_Regex(
'([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
array(
'controller' => 'widget',
'action' => 'list',
'page' => 1
),
array(
1 => 'color',
2 => 'page',
3 => 'limit'
),
'%s-Widgets/page/%d'
);
However this doesn't solve my problem say I have a Url
/Blue-Widgets/page/1/limit/10 The limit doesn't show, again I can fix that with the following
$route = new Zend_Controller_Router_Route_Regex(
'([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
array(
'controller' => 'widget',
'action' => 'list',
'page' => 1,
'limit' => 10
),
array(
1 => 'color',
2 => 'page',
3 => 'limit'
),
'%s-Widgets/page/%d/limit/%d'
);
The problem with this is the user is at
/Blue-Widgets/ and I want to take them to the next page of Blue Widgets with following code
echo $this->url(array('page' => $page), 'color_widgets', false);
They are actually taken to
/Blue-Widgets/page/2/limit/10
When I actually want to take them to
/Blue-Widgets/page/2
How can I accomplish this with the Zend Framework.
It is not possible to use a regex reverse route with a variable number of values.
You could:
Write a different route for every optional parameter (not recommended)
Use a different route structure
You could, for instance change your route to:
$route = new Zend_Controller_Router_Route(
'widgets/:color/*',
array(
'controller' => 'widget',
'action' => 'list',
'page' => 1,
'limit' => 10
),
array(
'color' => '[a-zA-Z-_0-9-]+',
'page' => '\d+',
'limit' => '\d+',
)
);
Another option would be to create your own custom route class, which can parse and build the correct uri.
You've give wrong Regex match variable indexes, that's why you get weird results. Your code should look like this:
$route = new Zend_Controller_Router_Route_Regex(
'([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
array(
'controller' => 'widget',
'action' => 'list',
),
array(
1 => 'color',
3 => 'page',
5 => 'limit'
),
'%s-Widgets/'
);
$router->addRoute('color_widgets', $route);

Zend_Controller_Router_Route dynamic route

Assuming the following router:
$router->addRoute('listOfFacilities',
new Zend_Controller_Router_Route('/:lang/:type/',
array('module' => 'default',
'controller' => 'search',
'action' => 'index',
'lang' => 'de',
'type' => ':type'
)));
Result will be:
http://example/en/Hotels/
lang == en
type == Hotels
It's possible to do in such way that for only one language, for example the german, the result is http://example/Hotels/ and not http://example/de/Hotels/?
Tanks,
From a route point of view, just ditch the lang parameter to just have the "type" one.
$router->addRoute('listOfFacilities',
new Zend_Controller_Router_Route('/:lang/:type/',
array('module' => 'default',
'controller' => 'search',
'action' => 'index',
'lang' => 'de',
'type' => ':type'
)));
$router->addRoute('listOfFacilities_default',
new Zend_Controller_Router_Route('/:type',
array('module' => 'default',
'controller' => 'search',
'action' => 'index',
'type' => ':type'
)));
And from a controller point of view, just look for an empty lang parameter to define the default one (in your case, de).
If your page is already redirecting to /de/Hotels, then in our controller test for this :
if($lang == 'de' && $type == 'Hotels') {
$this->_redirect('/Hotels');
}

Zend_Router_Regex and additional parameter

I have no idea how realize it.
I have this router
$route = new Zend_Controller_Router_Route_Regex(
'category/([-\w]+)(?:/(\d+))?',
array('module' => 'dynamic', 'controller' => 'index', 'action' => 'show-category'),
array(1 => 'category', 2 => 'pageNumber'),
'category/%s/%d'
);
$router->addRoute('dynamic-categories', $route);
Assembled url in view will be /category/news/1 by using $this->url(...) helper. I want that my first page of news will be /category/news. Should I use other route to do it or use router chaining. I'm frustrated. Thank you for help.
You can use Zend_Controller_Router_Route for straight forward mapping:
new Zend_Controller_Router_Route(
'/category/:category/:page',
array(
'module' => 'dynamic',
'controller' => 'index',
'action' => 'show-category',
'category' => 'news',
'page' => 1
)
)
Will match /category/, /category/news/, /category/othercategory or /category/news/4 (examples only of course).

problem with Zend URL helper $this->url

I have situation with Zend route & $this->url method
IN my bootstrap.php I have few routes as
$route = new Zend_Controller_Router_Route(
'dashboard',
array(
'action' => 'index',
'controller' => 'index',
'module' => 'dashboard',
'isAdmin' => true
)
);
$router->addRoute('dashboard', $route);
$route = new Zend_Controller_Router_Route(
'logout',
array(
'action' => 'logout',
'controller' => 'index',
'module' => 'main',
'isAdmin' => true
)
);
$router->addRoute('logout', $route);
$route = new Zend_Controller_Router_Route(
'manage-users',
array(
'action' => 'list',
'controller' => 'index',
'module' => 'main',
'isAdmin' => true
)
);
$router->addRoute('manage-users', $route);
$route = new Zend_Controller_Router_Route(
'edit-user/:id',
array(
'action' => 'edit',
'controller' => 'index',
'module' => 'main',
),
array('id' => '[0-9]+')
);
$router->addRoute('edit-user', $route);
$route = new Zend_Controller_Router_Route(
'/manage-subcat/:ident',
array(
'action' => 'index',
'controller' => 'subcategory',
'module' => 'category',
'ident' => '',
array(
'ident' => '[a-zA-Z-_0-9]+',
)
)
);
$router->addRoute('manage-subcat', $route);
take a case of last route
in my view when I write
<?php echo $cat->CategoryName ?>
I get url as http://127.0.0.10/manage-subcat
& when I disable the last route in bootstrap & then I write in my view file
<?php echo $cat->CategoryName ?>
I get Url as same http://127.0.0.10/category/subcategory
Ideally I should get http://127.0.0.10/category/subcategory/ident/some-category for this one
& for previous one it should be http://127.0.0.10/manage-subcat/ident/some-category
This code sample is not working with custom routes as well as traditional routes, and I am trying to determine why this sample is not working correctly.
Besides the route declaration formatting error noted by zerocrates, could it be simply a typo in your code?
I notice you use $cat->CategoryName (singular $cat) in one place and $cats->catident (plural $cats) in another.
If passed a null parameter value, the router will omit that parameter from the generated URL.