Zend Project with multiple modules and every modules have its own routes.ini defined inside it. and every routes.ini file is being loaded using following script in module based bootstrap files.
protected function _initRoutes() {
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$routerDir = realpath(dirname(__FILE__)). "/configs/routes/moduleRoutes.ini";
$config = new Zend_Config_Ini($routerDir,'production');
$router->addConfig($config,'routes');
}
and All routes are being loaded without order. because Routes are checked in reverse order of loaded sequence and it check/execute those routes first which it should check/execute later.
Is there a way that I can add a orderBy bit (1,2,3,4...) with every route in routes.ini file of each module and load them in specific order so that It will check the routes in sequence I define.
typical routes.ini file of modules looks like this.
routes.frontindex.type = "Zend_Controller_Router_Route_Regex"
routes.frontindex.route = "/?(?!login/)([a-zA-Z0-9_-]+)?/?([a-zA-Z0-9_-]+)?/?([0-9_-]+)?"
routes.frontindex.defaults.module = mymodule1
routes.frontindex.defaults.controller = mycontroller1
routes.frontindex.map.page = 1
routes.siteimage.type = "Zend_Controller_Router_Route_Regex"
routes.siteimage.route = "siteimage/?([a-zA-Z0-9_-]+)?/?(jpg|png|gif)?"
routes.siteimage.defaults.module = mymodule1
routes.siteimage.defaults.controller = mycontroller2
routes.siteimage.defaults.action = getimage
routes.siteimage.map.imageid = 1
routes.sitemapseo.type = "Zend_Controller_Router_Route_Static"
routes.sitemapseo.route = "sitemap.xml"
routes.sitemapseo.defaults.module = mymodule1
routes.sitemapseo.defaults.controller = mycontroller3
routes.sitemapseo.defaults.action = sitemap
It can be done, but it will take some work and you'll need to be fairly comfortable with ZF.
You'll need to extend Zend_Controller_Router_Rewrite
to make your own router class (which you will need to set using the front controller's setRouter() method in the bootstrap). In your router class, you'll want to:
Extend the addRoute
method to add a third parameter indicating priority. (This could be a constant like Your_Router::HIGH_PRIORITY
, Your_Router::MEDIUM_PRIORITY
etc. or simply a number). You'll see that the existing method stores routes in an array called _routes
. You could instead store routes in different array depending on the priority param ($this->_highPriorityRoutes
, $this->_lowPriorityRoutes
etc.)
Extend the route()
method. Most of that unfortunately will be cut and paste. But you'll see that it calls array_reverse
on $this->_routes
and then loops though these to do the matching. You'll want to merge together your route arrays so that the end result is an array with your highest priority routes first. So you might end up with something like:
$routes = array_merge($this->_lowPriorityRoutes, $this->_highPriorityRoutes);
$routes = array_reverse($routes, true);
foreach ($routes as $name => $route) {
(...as before)
Update your ini files to add a parameter to your routes indicating the priority. Then extend the addConfig()
method in the router class so it passes this parameter to the addRoute()
method.
Good luck!