Unable to get parameters using Zend Routing Chain - php

In my bootstrap file, I have the following routing chain. The desired behaviour is to send any request through /usa/:controller/:action to the local module.
For instance, when http://{hostname}/usa/index/index is called, the request goes through the local module, index controller, index action.
The problem I am having is adding parameters. For instance, when I request http://{hostname}/usa/index/index/id/5 to try to get the id parameter, I get the following error message:
An Error occurred. Page not found. Exception information: Message: Invalid controller specified (usa) with the following request params:
array (
'controller' => 'usa',
'action' => 'index',
'id' => '5',
'module' => 'default',
)
How can I set up the chain routing in order to still utilize other parameters?
Here is my code in the application bootstrap:
protected function _initRouting(){
$router = Zend_Controller_Front::getInstance()->getRouter(); // Get the main router from the front controller.
$router->addDefaultRoutes(); // Don't forget default routes!
//get default local route (directs to the local module)
$defaultLocalRoute = new Zend_Controller_Router_Route(
'/:controller/:action',
array(
'module' => 'local',
'controller' => 'index',
'action' => 'index'
)
);
$regionRoute = new Zend_Controller_Router_Route(
'/usa/',
array('region' => 'usa')
);
//chain this region route to the default local route that directs to the local module
$fullRegionRoute = $regionRoute->chain($defaultLocalRoute);
//add the full route to the router (ie. hamiltonRoute, atlanticcaRoute)
$regionRouteName = 'usaRoute';
$router->addRoute($regionRouteName, $fullRegionRoute);
}

Adding a * to the end of the $defaultLocalRoute was able to fix this issue for me.
//get default local route (directs to the local module)
$defaultLocalRoute = new Zend_Controller_Router_Route(
'/:controller/:action/*',
array(
'module' => 'local',
'controller' => 'index',
'action' => 'index'
)
);
Now when going to http://{hostname}/usa/product/view/id/5, the request goes to the desired location ->
module: 'local',
controller: 'product',
action: 'view',
params: array('id'=>5)

Related

Zend Framework - Param not specified

I got a little problem here. I'm currently trying to use the Zend Router Rewrite but I got this error:
Fatal error: Uncaught exception 'Zend_Controller_Router_Exception' with message 'alias is not specified'
Here's my code for the route:
// BLOG -> CATEGORIES -> LIST ARTICLES
$route = new Zend_Controller_Router_Route(
'/blog/categories/:alias',
array(
'module' => 'blog',
'controller' => 'categories',
'action' => 'list'
)
);
$router->addRoute('blog-categories-list', $route);
The URL i'm trying to access is: /blog/categories/general/.
Why am I getting this error?
P.S.: I didn't specify a default value for :alias 'cause I have this route also:
// BLOG -> CATEGORIES
$route = new Zend_Controller_Router_Route(
'blog/categories/',
array(
'module' => 'blog',
'controller' => 'categories',
'action' => 'index'
)
);
$router->addRoute('blog-categories', $route);
This error is probably coming from somewhere where you are trying to output a link using the route, such as the URL helper:
$this->url(array(), 'blog-categories-list')
It's telling you that you need to pass 'alias' to this as well.

Zend Framework 2 - Why i can't override MvcEvent's MatchRoute?

i would like to match all requests where user is unlogged to controller Admin\Controller\Sign and action in. I wrote this code in onBootstrap() method in Module.php file :
if (!$authService->hasIdentity()) {
$routeMatch = new RouteMatch(
array(
'controller' => 'Admin\Controller\Sign',
'action' => 'in'
)
);
$event->setRouteMatch($routeMatch);
}
I don't get any errors, but code doesn't work, why?
The problem here is that the application route event (MvcEvent::EVENT_ROUTE) is triggered after the (MvcEvent::EVENT_BOOTSTRAP).
Which means even if you're setting the route match at the bootstrap level, the application is going to override it with the route match of the request after the MvcEvent::EVENT_ROUTE.
If you want to avoid this overriding you need to add a listener for the route event with a very low priority to make sure it will not be overridden:
$e->getApplication()->getEventManager()->attach(MvcEvent::EVENT_ROUTE, array($this, 'onRouteEvent'), -1000000);
Note : the onRouteEvent would be the method of your Module class that handles the route event (similar to your code).
If you want to short-circuit your application running at the bootstrap level, what you can do is to send the headers with redirection code to the client:
//get the url of the login page (assuming it has route name 'login')
$url = $e->getRouter()->assemble(array(), array('name' => 'login'));
$response=$e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
$response->sendHeaders();
add a route entry sign_in as below in the routes section of the module.config.php under admin module
'sign_in' => array(
'type' => 'Segment',
'options' => array(
'route' => '/admin/sign/in',
'defaults' => array(
'controller' => 'sign',
'action' => 'in',
),
),
),
and call the route in the controller like this
$this->redirect()->toRoute('sign_in');

Zend Url View Helper not working with Regex Routes

I'm using Zend Framework 1.12 and have this route:
$router->addRoute('item_start',
new Zend_Controller_Router_Route_Regex(
'(foo|bar|baz)',
array(
'module' => 'default',
'controller' => 'item',
'action' => 'start'
),
array(
1 => 'area'
),
'%s'
)
);
Problem is, when I call '/foo' and use the Url Helper in the View, it doesn't give me any parameters:
$this->url(array("page"=>1));
// returns '/foo' (expected '/foo/page/1')
$this->url(array("page"=>1), "item_start", true);
// also returns '/foo'
Any idea how to get the page-parameter into the URL? I can't use the wildcard like in the standard route, can't I?
In addition to David's suggestions, you could change this route to use the standard route class, and then keep the wildcard option:
$router->addRoute('item_start',
new Zend_Controller_Router_Route(
':area/*',
array(
'module' => 'default',
'controller' => 'item',
'action' => 'start'
),
array(
'area' => '(foo|bar|baz)'
)
)
);
// in your view:
echo $this->url(array('area' => 'foo', 'page' => 1), 'item_start');
Your Regex route doesn't have a page parameter, so when the url view-helper ends up calling Route::assemble() with the parameters you feed it, it ignores your page value.
The two choices that come to mind are:
Modify your regex to include a (probably optional with default value) page parameter
Manage the page parameter outside of your route in the query string.

Zend Regex Route > Track the api version

i am building a web service with zend and i am using modules to separate my api versions. Ex: "applications/modules/v1/controllers", "applications/modules/v2/controllers" have different set of actions and functionality.
I have made "v1" as the default module in "application.ini" file:
resources.modules = ""
resources.frontController.defaultModule = "v1"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectoryName = "controllers"
I have written the following in my bootstrap file:
$router = $front->getRouter();
$r1 = new Zend_Controller_Router_Route_Regex('api/v1/tags.xml',
array('module' => 'v1', 'controller' => 'tags', 'action' => 'index'));
$router->addRoute('route1', $r1);
Suppose, if this is my url: http://localhost/api/v1/tags.xml
then it belongs to version 1 (v1).
But i dont want to write many routes like this one, so i want to know how can i track the version from the regex url and dynamically determine the api version to be used (1 or 2).
try to use
$r1->addRoute(
'json_request',
new Zend_Controller_Router_Route_Regex(
'([^-]*)/([^-]*)/([^-]*)\.xml',
array(
'controller' => 'index',
'action' => 'index',
'request_type' => 'xml'),
array(
1 => 'module',
2 => 'controller',
3 => 'action'
)
));
Try this:
$r1 = new Zend_Controller_Router_Route_Regex('api/(v.*)/tags.xml',
array('module' => 'v1', 'controller' => 'tags', 'action' => 'index'),
array(1 => 'module')
);
This will automatically overwrite the module param, and should therefor automatically route to the right module. No need to use a plug-in with the preDispatch method anymore.
So far, i tried like this:
$r1 = new Zend_Controller_Router_Route_Regex('api/v(.*)/tags.xml',
array('module' => 'v1', 'controller' => 'tags', 'action' => 'index'),
array(1 => 'version')
);
$router->addRoute('route1', $r1);
And I could get an idea from here:
So now i used a front controller and in preDispatch method, i am setting the module name based on the value i get in the "version" parameter value, like
if($request->getParam('version') == 2 { $request->setModuleName('v2') }
But after changing the version in url to v2, it still goes to the action of controller in v1 module.

Zend Framework subdomain problem

I am using .ini file to add routes in my application.
resources.router.routes.username.type = "Zend_Controller_Router_Route_Hostname"
resources.router.routes.username.route = ":username.example.com"
resources.router.routes.username.defaults.module = "userinfo"
resources.router.routes.username.chains.index.type = "Zend_Controller_Router_Route"
resources.router.routes.username.chains.index.route = ":language/:controller/:action/*"
resources.router.routes.username.chains.index.defaults.controller = "index"
resources.router.routes.username.chains.index.defaults.action = "index"
1) http://john.example.com/fr/controller/action
2) http://john.example.com/fr/controller/action/id/10
#1 url it's work. Request parameter here
Request Parameters:
array (
'language' => 'fr',
'controller' => 'controller',
'action' => 'action',
'username' => 'john',
'module' => 'userinfo',
)
#2 url it's not work. Request parameter here
Request Parameters:
array (
'controller' => 'fr',
'action' => 'controller',
'module' => 'default',
)
Can anyone suggest a solution for this.
did you set a default language for the route? by saying it doesn't work could you provide more details?
I ran into some similar problem with Zend_navigation not taking in the language param and always switch to the default lang that i defined.
Eventually i have to hack it by manually setting default language in the routshutdown in a custom plugin please see my post if it helps
Zend Framework: Zend_translate and routing related issue
resources.router.routes.username.type = "Zend_Controller_Router_Route_Hostname"
resources.router.routes.username.route = ":username.example.com"
resources.router.routes.username.defaults.module = "userinfo"
resources.router.routes.username.chains.index.type = "Zend_Controller_Router_Route"
resources.router.routes.username.chains.index.route = ":language/:controller/:action/*"
resources.router.routes.username.chains.index.defaults.controller = "index"
resources.router.routes.username.chains.index.defaults.action = "index"
resources.router.routes.username.chains.index.defaults.language = "en"
I add to default language parameter in route. But this url not work
http://john.example.com/fr/controller/action/id/10
Request Parameters:
array (
'controller' => 'fr',
'action' => 'controller',
'module' => 'default',
)
Looks like the route has been reset to default. I run into that before
create a plugin and register to the front controller. Define dispatchLoopStartup() in there try set the language parameter or module name using
$router = $fc->getRouter();
$router->setGlobalParam('lang','somelanguage');
$router->setGlobalParam('module','somemodule');
see if you can bring back the correct route.

Categories