Zend routes two routes need same count of params - zend-framework

I don´t know what I do wrong. I got two named Zend route:
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:productIdent/',
array(
'action' => 'viewproduct',
'controller' => 'catalog',
'module' => 'eshop',
'categoryIdent' => '',
'productIdent' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+',
'productIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category_product', $route);
// catalog category route
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:page/',
array(
'action' => 'viewcategory',
'controller' => 'category',
'module' => 'eshop',
'categoryIdent' => '',
'page' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category', $route);
When I call catalog_category its all fine but when I try call to catalog_category_product is used viewcategory action from second route. It means its problem with :page variable in url, resp. same count of arguments in URL? I think that itsn´t nessesary I would like to get two different but similar routes - for example:
For category - catalog/category1/1
For product - catalog/category1/product1 (without number of page)
when I change form of route catalog_category_product to catalog/:categoryIdent/something/:productIdent/ so its working
here is route calls
$this->url(array('categoryIdent' => categoryIdent, 'productIdent' => productIdent), 'catalog_category_product', true);
$this->url(array('categoryIdent' => 'cerveny-cedr', 'page' => 'pageNumber'), 'catalog_category', true);
Thanks for any help

Keep in mind that routes are checked in reverse order, so the ZF router will check the catalog_category route before the catalog_category_product route when matching URLs. So, the number of arguments is not a problem, but since you've not put any sort of restriction on the 'page' parameter, all URLs that would normally match your catalog_category_product URL will be matched by catalog_category instead.
It sounds like 'page' should be numeric, so adding that restriction to your second route should fix the problem.

Related

Stopping zend route default paramaters 'key' displaying in the URL

I have a route defined as below.
$route['manage-vehicles'] = new Zend_Controller_Router_Route(
'vehicles/manage/page/:page',
array(
'controller' => 'vehicles',
'action' => 'manage',
'page' => '1'
)
);
When the 'page' parameter is not specifically defined (e.g. in a menu constructed using the navigation component), the resultant URL is
/vehicles/manage/page
I would much prefer or the URL not to to display the default paramater key in this scenario
i.e. /vehicles/manage
Any ideas how to accomplish this would be appreciated?
Thanks.
EDIT: For clarity, I would like vehicles/manage/page/1 etc to display when the 'page' parameter is defined
The 'page' string you have in your route is not required for the page parameter to work, so all you need to do is change your route to:
$route['manage-vehicles'] = new Zend_Controller_Router_Route(
'vehicles/manage/:page',
array(
'controller' => 'vehicles',
'action' => 'manage',
'page' => '1'
)
);
you've told it which thing in the URL is 'page', so you don't need the prefix there. That's just part of the default route where the parameters are not predefined.

Zend Framework: Route assemble and GET parameters

In my Bootstrap I have
$route = new Zend_Controller_Router_Route(
':language/:country/:controller/:action/*',
array(
'language' => 'en',
'country' => 'us',
'controller' => 'bicycle',
'action' => 'index'
),
array(
'language' => '[a-z][a-z]',
'country' => '[a-z][a-z]'
)
);
Somewhere in my view I have
echo $this->url(array('page'=>2));
//actually this translated to $route->assemble(array('page' => 2), null, false);
The problem, is when I have some GET parameters: they won't be considered in the building of the link, and this is what I actually want.
Example:
I access the URL (in the browser)
http://localhost/myproject/en/us/controller/action/?get1=gval1&get2=gval2&get3=gval3
and the assembled URL is
http://localhost/myproject/en/us/controller/action/page/2
INSTEAD of
http://localhost/myproject/en/us/controller/action/page/2/get1/gval1/get2/gval2/get3/gval3/
or (I would prefer the next one)
http://localhost/myproject/en/us/controller/action/page/2/?get1=gval1&get2=gval2&get3=gval3
Any ideas?
Of course one solution (with Apache) would be to call this in my view:
$this->url(array(page=>2)) . ($_SERVER['QUERY_STRING']?$_SERVER['QUERY_STRING']:"")
but you cannot be sure this will always be included in the $_SERVER variable.

Regex Routing - rule not being found

I'm defining regex routes for cleaning up my URLS. The idea is that all pages added by the user will be use the URL www.example.com/page-slug rather than using the actual controller, www.example.com/userpages/page-slug. Other pages will follow the standard module:controller:action routing scheme.
I'm trying to aceive this using router precedence.
I have defined the scheme below..
class Default_Bootstrap extends Zend_Application_Module_Bootstrap{
protected function _initRoute() {
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter(); // returns a rewrite router by default
$route['index'] = new Zend_Controller_Router_Route_Regex(
'/',
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)
);
$route['contact'] = new Zend_Controller_Router_Route_Regex(
'contact/(\d+)',
array(
'module' => 'default',
'controller' => 'contact',
'action' => 'index'
)
);
$route['research'] = new Zend_Controller_Router_Route_Regex(
'research/(\d+)',
array(
'module' => 'default',
'controller' => 'research',
'action' => 'index'
)
);
$route['account'] = new Zend_Controller_Router_Route_Regex(
'account/(\d+)',
array(
'module' => 'default',
'controller' => 'account',
'action' => 'index'
)
);
$route['userpages'] = new Zend_Controller_Router_Route_Regex(
'/(.+)',
array(
'module' => 'default',
'controller' => 'userpages',
'action' => 'index'
),
array(
'slug' => 1
),
'%s'
);
$router->addRoute('userpages', $route['userpages']);
$router->addRoute('contact', $route['contact']);
$router->addRoute('research', $route['research']);
$router->addRoute('account', $route['account']);
$router->addRoute('index', $route['index']);
}
}
Things are generally working OK with the router precedence ensuring that index/account/research/contact pages are picking up the correct controller. However, when attempting to go to a URL covered by the "userpages" route e.g. "about-us", final catch all route is not being found resulting in...
Message: Invalid controller specified (about-us)
.
.
.
Request Parameters:
array (
'controller' => 'about-us',
'action' => 'index',
'module' => 'default',
)
Any idea where I'm going wrong here? It seems to me that the regex is correct "/(.+)" should be catching eveything that is not the index page.
EDIT: #phatfingers, OK you're right, I've edited "\d+" to ".+" to catch one or more of any character. The problem persists. In fact before changing the regex, I tried the URL www.example.com/52, and got the same error - "Invalid controller specified (52)". After the change - with code as per the edited snippet above, the rule is still failing to find any matches.
Drop the forward slash in the 'userpages' regex, i.e. just ('.+)
The quote is straight from the manual Zend Router and Router_Regex but afaik it also applies to all the routes.
Note: Leading and trailing slashes are trimmed from the URL in the
Router prior to a match. As a result, matching the URL
http://domain.com/foo/bar/, would involve a regex of foo/bar, and not
/foo/bar.

Custom route with parameters

I want to make customer route for url which have parameters.
<a href='javascript:void(0)' onclick="window.location='<?php echo
$this->url(array('module' => 'courses', 'controller' => 'course', 'action' => 'add',
'std_id' => $entry['std_id']), 'coursesadd', TRUE); ?>'">add course</a>
and here what I make routing
$route = new Zend_Controller_Router_Route('courses/std_id/:std_id',
array('module' => 'courses', 'controller' => 'course', 'action' => 'add'));
$routesArray = array('coursesadd' => $route );
$router->addRoutes($routesArray);
But It doesn't route correctly!
Your code looks fine, except what RockyFord sad - You should only pass these parameters to url() helper which are required by designated route (when 'default' route is used indeed it requires module, controller, action, but Your 'coursesadd' route requires only std_id parameter). Moreover You should improve Your route a little bit to:
$route = new Zend_Controller_Router_Route('courses/:std_id', array(
'module' => 'main',
'controller' => 'product',
'action' => 'add',
'std_id' => null //default value if param is not passed
));
The param_name/:param_value construction in Your route is redundant because You already named the parameter, so by using above route You'll get std_id param in controller using
$this->_getParam('std_id')
Default value in route definition would save from throwing Zend_Controller_Router_Exception: std_id is not specified but it looks like $entry['std_id'] is not set.

Zend Framework Router Getting /module/VALUE/controller/action

I've been googling around and I can't seem to find anything which explains the use of ZF router well. I've read the documentation on the site, which seems to only talk about re-routing.
I am trying to make the format:
/module/value/controller/action give /module/controller/action passing on value as a parameter
e.g.
/store/johnsmithbigsale/home/newstuff would route to /store/home/newstuff passing on johnsmithbigsale as the value to a parameter with a hidden namespace e.g. storeName.
Some help would be greatful!
You can use Zend_Controller_Router_Route to map your url parts to modules, controllers, actions, and parameters that can be used in the controller by $this->_getParam('varName'). You can define these routes in the application.ini file or in the application bootstrap.
// custom city route
$route = new Zend_Controller_Router_Route(
'cities/:city',
array(
'controller' => 'city',
'action' => 'view'
)
);
$this->addRoute('city', $route);
// custom buy widgets route
$route = new Zend_Controller_Router_Route_Regex(
'buy_(.+)_widgets/([0-9]+)(.*)',
array(
'controller' => 'widgets',
'action' => 'view'
),
array(
1 => 'nothing',
2 => 'widget_id',
3 => 'vars'
)
);
$this->addRoute('widgets', $route);
The regex route is kind of specific to my app, but you can see that each match can get mapped to a parameter.