Regex Routing - rule not being found - zend-framework

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.

Related

zend framework 1.11.11 routing

http://xxxxxx.xxx/man/pant/man-yellow-box-pant
$router = $ctrl->getRouter(); // returns a rewrite router by default
$router->addRoute(
'location',
new Zend_Controller_Router_Route(
':category/:subcategory/:productname',
array(
'module' => 'default',
'controller' => 'product',
'action' => 'index',
'id' => 'id',
'name' => 'p_name'
)
)
);
above this code is not working..
$routers = $ctrl->getRouter(); // returns a rewrite router by default
$routers->addRoute(
'location',
new Zend_Controller_Router_Route(
':uname',
array(
'module' => 'default',
'controller' => 'user',
'action' => 'index',
'id' => 'uid',
'name' => 'u_name'
)
)
);
above is working...........
please suggest me why not working when both code write on same page, same project..
Your routes need to have a unique name. By calling them both 'location', the second one you add replaces the first.
I know writing mistake, if we change location to other then also not working because i have more URL condition and condition is we not use on module/controller/function name on URL, according to category or function we use to name On URL.
I have 4 module and 15 controller with as per more function and need to all URL make to SEO friendly so i did, if i change to location with username, he not working,and
$routers = $ctrl->getRouter(); // returns a rewrite router by default
$routers->addRoute('category',
new Zend_Controller_Router_Route(
':category/:subcategory/:productname',
array(
'module' => 'default',
'controller' => 'product',
'action' => 'index',
'id' => 'id',
'name' => 'p_name')));
Category and Subcategory system is not working.
how to set right path way as per my condition and not through 404 error
URL get Like http://testing.com/man/pant/man-yellow-box-pant

Zend Framework: Page not found

I have developed a web application with Zend Framework which root is http://www.demo31.com/validacion/demo31/ but when I call that url I've got the next error:
Page not found
Request Parameters:
array (
'controller' => 'validacion',
'action' => 'demo31',
'module' => 'default',
)
I want that the values of array would be next:
array (
'controller' => 'index',
'action' => 'index',
'module' => 'default',
)
And my .htaccess is correct.
So, what do I have to do what I want?
Zend framework normally operates as per routes. If a particular URL is not reaching your code, then you have to configure routes to do that.
$router = $front -> getRouter();
$routePage = new Zend_Controller_Router_Route('/:controller/:action', array(
/* ^ Things to notice
Only two parameters are
asked from the route */
'controller' => 'default',
'action' => 'index',
'module' => 'default' //Predefine the module as `default
));
$router -> addRoute('default', $routePage);
By default, ZF assumes that the app is located in the root of the domain so that's why it treats validacion as a controller.
Zend Framework in a subfolder

Zend Framework: Router

That is my two routers:
->addRoute('viewTextMaterial', new Zend_Controller_Router_Route(':mCat/:mCatSub/:mId/:mTitle', array('controller' => 'index', 'action' => 'viewtextmaterial')))
->addRoute('viewNews', new Zend_Controller_Router_Route(':nCat/:nId/:nTitle/:page', array('controller' => 'index', 'action' => 'viewnews')))
In index.phtml file I add this:
Test
Exp. for viewnews URL:
some text
But why, when I click a href, it redirect me to 'viewnews'?
In my experience(which is not very great :) )
I think when you use the colon in front of a name, when you are defining a router
i.e like
'/:mCat/:mCatSub/:mId/:mTitle',
array(
'controller' => 'index',
'action' => 'viewtextmaterial'
)
What you are telling the router to do is to route any url, which follows the above format('/:mCat/:mCatSub/:mId/:mTitle'), to be routed to the controller/action you mentioned there. eg.
someController/action/x/y
or
anoCont/act/a/b
would be routed to the same controller/action.
So in your case what you are doing is you are defining two routers with same options(which creates ambiguity), and by default the second defined route is used(Bottom to top matching).
you can use something like this
'/test/:mCatSub/:mId/:mTitle',
array(
'controller' => 'index',
'action' => 'viewtextmaterial'
)
so anything that starts with 'test' as controller(in the url) would now be routed to your desired controller/view.
Hope it works.. :) (If it doesn't please enlighten me :) )

ZF Frontend and backend routing

I want something that sounds fairly simple to me but appears not to be.
My problem is that I need 2 routes voor my application:
Whenever the module is admin apply the following route:
$router->addRoute(
'backend',
new Zend_Controller_Router_Route('/:module/:controller/:action/:id/:value', array('module' => 'admin', 'controller' => 'dashboard', 'action' => 'index', 'id' => ':id', 'value' => ':value'))
);
Which works great. An example url could be: http://localhost/server/domains/demo/admin/images/album/3 where admin is the module, images the controller and so on.
All I want is that when a user goes to http://localhost/server/domains/demo he is redirected to the default module, index controller and index action. Everything after demo/ should be considered a single parameter (with unknown / possible).
I tried several things, from using Route_Regex, trying (.*) or (\d+), things I found all around online. Tried switching values, making them static, turning on/off removeDefaultRouter, but nothing worked. Below you can see my current bootstrap. Any ideas?
$router = $this->frontController->getRouter();
$router->removeDefaultRoutes();
$router->addRoute(
'backend',
new Zend_Controller_Router_Route('/admin/:controller/:action/:id/:value', array('module' => 'admin', 'controller' => 'dashboard', 'action' => 'index', 'id' => ':id', 'value' => ':value'))
);
$router->addRoute(
'frontend',
new Zend_Controller_Router_Route('/default/:controller/:action/(.*)', array('module' => 'default', 'controller' => 'index', 'action' => 'index'))
);
Backend works fine, but whenon the http://localhost/server/domains/demo/ I get the following error: No route matched the request
When given an answer, please explain why, because Zend_Route has always been a little vague for me. Thanks in advance!
Temp fix
Below the temporary fix that I use. It works exactly how I want, but I still believe that the same is achievable with Zend_Route without checking if the module is admin.
$router = $this->frontController->getRouter();
$uri = explode('demo/', $_SERVER['REQUEST_URI']);
$uri = (isset($uri[1])) ? explode('/', $uri[1]) : $uri[0];
if($uri[0] == 'admin')
{
$route = new Zend_Controller_Router_Route('/:module/:controller/:action/:id/:value', array('module' => 'admin', 'controller' => 'dashboard', 'action' => 'index', 'id' => null, 'value' => null));
$router->addRoute('router', $route);
}
else
{
$route = new Zend_Controller_Router_Route('/*', array('module' => 'default', 'controller' => 'index', 'action' => 'index'));
$router->addRoute('router', $route);
}
It is worth doing if you really have to use this routes. For normal usage you can just generate links by
Zend_Layout::getMvcInstance()->getView()->Url(array('module' => 'admin'));
Zend_Layout::getMvcInstance()->getView()->Url(array('module' => 'default'));
and so on.
If you are not ok with this, try routes chaining:
$router = Zend_Controller_Front::getInstance()->getRouter();
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
$request = Zend_Controller_Front::getInstance()->getRequest();
$frontRoute = new Zend_Controller_Router_Route_Module(array(), $dispatcher, $request);
$backRoute = new Zend_Controller_Router_Route_Module(array('module' => 'admin'), $dispatcher, $request);
$route = new Zend_Controller_Router_Route('admin');
$router->addRoute('backend', $route->chain($backRoute));
$route = new Zend_Controller_Router_Route('default');
$router->addRoute('frontend', $route->chain($frontRoute));
Explenation:
Zend_Controller_Router_Route_Module is for definining modules routes for the application. By chaining it to normal route like new Zend_Controller_Router_Route('admin') you made links like /admin/[your_module_route] where [your_module_route] have defined defaults array('module' => 'admin') and can take other parameters too.
new Zend_Controller_Router_Route_Module(array(), $dispatcher, $request); is defined as an default route on the standard router.

Zend_Router parameter exceptions

My problem is I want some parameter values, passed through URL, don't trigger the Zend routing but lead to defaul controller/action pair.
Right now I have following in my index.php:
// *** routing info ***
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('showpage', new Zend_Controller_Router_Route('/show/:title',
array('controller' => 'Show',
'action' => 'page')));
// annoying exceptions :(
$router->addRoute('addshow', new Zend_Controller_Router_Route('/show/add',
array('controller' => 'Show',
'action' => 'add')));
$router->addRoute('saveshow', new Zend_Controller_Router_Route('/show/save',
array('controller' => 'Show',
'action' => 'save')));
$router->addRoute('addepisode', new Zend_Controller_Router_Route('/show/addEpisode',
array('controller' => 'Show',
'action' => 'addEpisode')));
$router->addRoute('saveepisode', new Zend_Controller_Router_Route('/show/saveEpisode',
array('controller' => 'Show',
'action' => 'saveEpisode')));
without last 4 routers, URL /show/add leads to show/page, carrying title == 'add'.
Please, every help will be much appreciated.
You can use a regular expression to reject add, save, addEpisode and saveEpisode
$router->addRoute(
'showpage',
new Zend_Controller_Router_Route(
'/show/:title',
array(
'controller' => 'show',
'action' => 'page'
),
array(
'title' => '(?:(?!add)(?!save)(?!addEpisode)(?!saveEpisode).)+'
)
)
)
First, use Zend_Controller_Router_Route_Static for the static routes.
Secondly, I'm pretty sure you don't need to include the leading forward slash, though I'm not sure if this is an issue.
As routes are matched in reverse order, yours should work (I think). For anything not matching "saveEpisode", "addEpisode", "save" or "add", it should fall through to the "showpage" route.
The only other thing I could think of would be to make the "showpage" route more specific, something like
'show/page/:title'