Zend_Router parameter exceptions - zend-framework

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'

Related

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 :) )

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.

Zend Route Overwriting each other

Edit, Slight problem caused by the fix in the respond below:
Now these rules clash:
$router->addRoute('view-category', new Zend_Controller_Router_Route(':id/category/:page', array('module' => 'default', 'controller' => 'category', 'action' => 'view', 'page' => null)));
$router->addRoute('management/category', new Zend_Controller_Router_Route('management/category/', array('module' => 'management', 'controller' => 'category', 'action' => 'index')));
So basically /management/category/reset gets captured by the view-category rule, even if I switch there order. This never used to be an issue.
Ideally if anything caught /management or /administration it would ignore the :name/category rule. Is it possible to make /management and /administration ignore previous rules and route to its controller action as there are no specific rules otherwise in those areas.
OLD QUESTION:
$router->addRoute('view-category', new Zend_Controller_Router_Route(':id/category', array('module' => 'default', 'controller' => 'category', 'action' => 'view')));
$router->addRoute('view-category-page', new Zend_Controller_Router_Route(':id/category/:page', array('module' => 'default', 'controller' => 'category', 'action' => 'view')));
These rules clash which stops paginator working on the /category-name/category URL.
Is there away to combine them?
Try add default value for "page" param.
$router->addRoute('view-category',
new Zend_Controller_Router_Route(':id/category/:page',
array('module' => 'default',
'controller' => 'category',
'action' => 'view',
'page' => null)
)
);

Zend Framework Change parameter in route on the same spot?

I'm not sure how to fix this, or wat is the best way to approach this. Also couldn't find enough information to get me on the right way (could be that my searching sucks..)
Anyway, this is my problem:
I defined a route in my bootstrap file:
protected function _initRoutes()
{
$router = $this->frontController->getRouter();
$router->removeDefaultRoutes();
$router->addRoute(
'delete',
new Zend_Controller_Router_Route('/:controller/:action/:id/',
array('controller' => ':controller',
'action' => ':action',
'id' => ':id',
)
)
);
}
This works perfectly for my update and delete actions.
Now I've added the pagination to the indexpage. The pagination expects the page parameter. Because I haven't set this in my route, it cannot pass it, so my pagination doesn't work (as in switching between results).
I understand this. But what I want is that on the index page the id parameter isn't necessary and replace this with the page parameter.
Trying another route replacing id with page didn't work.
Is there a good way to solve this in the bootstrap or is it the best way to check for the action, and depending on the action, index or update/delete, define the route. The best place would than be a plugin?
Any advice or tips are greatly appreciated!
While working on another aspect of the application I came back to the same problem. I solved it, by specifying the routes much more.
First I deleted the $router->removeDefaultRoutes(); rule.
And then instead of (which didn't work):
$router->addRoute(
'crud',
new Zend_Controller_Router_Route('/:controller/:action/:id', array('controller' => ':controller', 'action' => ':action', 'id' => ':id'))
);
$router->addRoute(
'pagination',
new Zend_Controller_Router_Route('/:controller/:action/:page', array('controller' => ':controller', 'action' => ':action', 'page' => ':page'))
);
I now use this:
$router->addRoute(
'crud',
new Zend_Controller_Router_Route('/:controller/:action/:id', array('controller' => ':controller', 'action' => ':action', 'id' => ':id'))
);
$router->addRoute(
'pagination',
new Zend_Controller_Router_Route('/:controller/index/:page', array('controller' => ':controller', 'action' => 'index', 'page' => ':page'))
);

Add Page Parameter in Zend Framework Doesn't Work

I've been trying to figure this out these days. I got a problem when I want to add 'page' parameter in my URL for my pagination.
This is my router
->addRoute('budi',new Zend_Controller_Router_Route(':lang/budi',array('controller' => 'budi', 'action' => 'index', 'page' => 1), array('lang'=>$s, 'page' => '\d+')))
->addRoute('budi1',new Zend_Controller_Router_Route(':lang/budi/page/:page',array('controller' => 'budi', 'action' => 'index', 'page' => 1), array('lang'=>$s, 'page' => '\d+')))
Then I access my URL
http://localhost/learningsystem/en/budi
but when I hover on my pagination links, the page parameter doesn't appear. The URL is still
http://localhost/learningsystem/en/budi
but if I enter same URL with index in the end like this one
http://localhost/learningsystem/en/budi/index
or like this one
http://localhost/learningsystem/en/budi/page/1
the page parameter appears perfectly when I click the page 2 link http://localhost/learningsystem/en/budi/index/page/2
Actually, I don't want include 'index' or 'page' at first in my URL. Anyway, I use default pagination.phtml template from Zend. Anyone please help me to solve this problem?
Thank you very much
How about something like these?
$router->addRoute(
'budi',
new Zend_Controller_Router_Route_Regex(
'(.*)/budi',
array('controller' => 'budi', 'action' => 'index', 'page' => 1),
array(1 => 'lang', 2 => 'page'),
'%s/budi/page/%d'
)
);
$router->addRoute(
'budi1',
new Zend_Controller_Router_Route_Regex(
'(.*)/budi/page/(\d*)',
array('controller' => 'budi', 'action' => 'index'),
array(1=>'lang', 2=>'page'),
'%s/budi/page/%d'
)
);