zend framework this->url get different url on the same page but different url - zend-framework

in application\modules\admin\layouts\scripts\layout.phtml
<?php echo $this->url(array('action'=>'logout','controller'=>'user','module'=>'admin'),null,true);?>
when I visited zfmul/public/admin-cate/ , It return
/zfmul/public/admin-cate/logout
but when I visited zfmul/public/admin/categories, It return
/zfmul/public/admin/user/logout
and the two url is render to the same module, same controller, same action, I wonder why it retrun different result?
I didi some configs in application.ini,
resources.router.routes.admincategories.route = "admin-cate/:action/:id"
resources.router.routes.admincategories.defaults.module = "admin"
resources.router.routes.admincategories.defaults.controller = "categories"
resources.router.routes.admincategories.defaults.action = "index"
resources.router.routes.admincategories.reqs.action = "save|edit|index|new"
resources.router.routes.admincategories.defaults.id = "1"
resources.router.routes.admincategories.reqs.id = "\d+"

When you use $this->url, you're in fact using function url from library/Zend/View/Helper/Url.php, whose 1st line is:
$router = Zend_Controller_Front::getInstance()->getRouter();
Since you declared a custom admincategories route, you now have 2 to access those particular module/controller/actions:
Default - accessible via zfmul/public/admin/categories;
Custom - accessible via zfmul/public/admin-cate/.
Depending on the URL you use to access, the $router variable value will change accordingly and so will the result of the $this->url call as you're experiencing.
Here are a few references to questions on SO that might help you work around that behaviour:
Zend Framework: How to disable default routing?;
Zend framework: Removing default routes.

Related

how do you get a variable from a post address in zendframework 1

I am still new to Zend Framework and confused about a few concepts.
I have built a POST form and attached a unique Id to the URL at the end of the form. I now want to collect that Id when the form is submitted but I am unclear how to do that
I will show you want I have done:
Below is the function that renders the form from my controller page to the view. You will note that I have fed into the parameter, for the form, a return Action address with the ID
$action = "{$this->view->baseUrl()}/sample-manager/process-price/{$sampleId}";
$this->view->Form = $model= $this->_model->createForm($action);
The function to receive the post is below. However, I want to collect the Id that should have come back with the post return values, but I have no idea where to find it or how to attach it.
public function processPriceAction()
{
$this->requirePost();
if($this->_model->processTieredPriceForm($this->view->form, $this->getRequest()->getPost()))
{
$this->_helper->FlashMessenger('Changes saved');
return $this->_redirect("/product-ecommerce/{$this->_model->getProduct()->id}");
}
else
{
return $this->render('index');
}
}
In summary, when a post is returned, does the return address come with the post in Zend Framework?
Could you not supply the id into the construction of the form and assign it to a hidden element? For example, in your controller:
$action = "{$this->view->baseUrl()}/sample-manager/process-price";
$this->view->Form = $model= $this->_model->createForm($action, $sampleId);
In your form model (not provided so best guess here):
$sampleId = new Zend_Form_Element_Hidden('sampleId');
$sampleId->setValue($sampleId);
$form->addElement($sampleId);
Then once the form is posted, you should be able to get the sample id in your controller in the standard way:
$sampleId = $this->getParam('sampleId');
The answer depends a bit on how your routing is setup. If you're using the default setup, after the action name the default route allows for key/value pairs of additional data. So, you might have more luck with a URL like this:
{$this->view->baseUrl()}/sample-manager/process-price/id/{$sampleId}
That'll put your sampleId in a named parameter called 'id', which you can access in your controller action with $this->_getParam('id').

zend routes ini load routes by order according to priority.

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!
I don't believe you can specify an order. You'd have to write your own code to do this. I'm sure there's multiple ways, but have you considered writing a custom Zend Controller Plugin? You could make one and assemble your routes inside the routeStartup() method.
I also tried to set a priority to the routes in application.ini.
For it I readed the code of Zend_Controller_Router_Rewrite. The important functions are addRoute() and route(). My conclusion is very simple : The routes are evaluated in the oposit order compare the order in application.ini.
Example :
If I write in application.ini
routeA
routeB
routeC
routeC will be checked first, and routeB after and routeA the last.
priority routeC > priority routeB > priority routeA

Zend url : get parameter always stay in the url

I have some trouble using the Zend url helper with get parameter.
In a view, I have pagination which send extra parameters in get (so in the url), so that's ok. But that is not ok is that the parameters always stay in the url even if I change page.
In fact, the zend url helper - I use to generate the url of link or form's action - add automaticaly the parameter at the end of the url so whatever the link I click, I have this parameters...
//In my controller
$this->_view->url(array("action"=>"action-name");
// generate for example : "mywebsite/controller-name/action-name/pays/4" but I don't want the "/pays/4"
Thank you for your help
The url method accepts additional parameters. One of them resets the get-string parameters.
url (
array $ urlOptions = array(),
$ name = null,
$ reset = false,
$ encode = true
)
Generates an url given the name of a route.
Parameters:
array $urlOptions - Options passed to the assemble method of the Route object.
mixed $name - The name of a Route to use. If null it will use the current Route
bool $reset - Whether or not to reset the route defaults with those provided
Returns:
string Url for the link href attribute.
It's all in the doc. The above is for ZF version 1.10
The definition or url() is
public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
So try setting the third parameter ($reset) to true

Remove Index from MVC url with routeValue

How can I remove the Index from the MVC url that has a routeValue?
E.g.
http://localhost/Beverage/Index/WhiteWine
to
http://localhost/Beverage/WhiteWine
but still be able to have
http://localhost/Beverage/ShowBeverage/1
You can create a custom route:
MapRoute("My Route Name",
"Beverage/{id}",
new { controller = "Beverage", action = "Index" });
Note that the controller name must be hard-coded in the route, then specified in the defaults to tell MVC which controller to use.
If you take the naive approach and map {controller}/{id}, it will accept any URL of the form a/b, which is not what you want.

Setting routes in application.ini in Zend Framework

I'm a Zend Framework newbie, and I'm trying to work out how to add another route to my application.ini file.
I currently have my routes set up as follows:
resources.router.routes.artists.route = /artists/:stub
resources.router.routes.artists.defaults.controller = artists
resources.router.routes.artists.defaults.action = display
...so that /artists/joe-bloggs uses the "display" action of the "artists" controller to dipslay the profile the artist in question - that works fine.
What I want to do now is to set up another route so that /artists/joe-bloggs/random-gallery-name goes to the "galleries" action of the "artists" controller.
I tried adding an additional block to the application.ini file (beneath the block above) like so:
resources.router.routes.artists.route = /artists/:stub/:gallery
resources.router.routes.artists.defaults.controller = artists
resources.router.routes.artists.defaults.action = galleries
...but when I do that the page at /artists/joe-bloggs no longer works (Zend tries to route it to the "joe-bloggs" controller).
How do I set up the routes in application.ini so that I can change the action of the "artists" controller depending on whether "/:gallery" exists?
I realise I'm probably making a really stupid mistake, so please point out my stupidity and set me on the right path (no pun intended).
Try reversing the order of the routes. ZF matches routes in the opposite order they are added (so that the default route is the last to be matched)
If that doesn't work, you'll probably have to investigate regex routes with optional components.
Your second block needs to have a different route name, rename the 'artists' word to something similar to this for your new block:
resources.router.routes.artists-gal.route = /artists/:stub/:gallery
resources.router.routes.artists-gal.defaults.controller = artists
resources.router.routes.artists-gal.defaults.action = galleries
I usually setup my routes in application/Bootstrap.php (or wherever your Bootstrap.php file is)
add a method like the one below:
protected function _initRoutes()
{
$ctrl = Zend_Controller_Front::getInstance();
$router = $ctrl->getRouter();
$router->addRoute(
'artist_detail',
new Zend_Controller_Router_Route('artists/:stub',
array('controller' => 'artists',
'action' => 'display'))
);
$router->addRoute(
'artist_detail_gallery',
new Zend_Controller_Router_Route('artists/:stub/:gallery',
array('controller' => 'artists',
'action' => 'gallery'))
);
}
As far as checking weather an specific artist has a gallery, in the case of my example, i would have a galleryAction method in the ArtistsController
do a check if a gallery exists for the 'stub' request paramater, if it doesnt throw a 404:
throw new Zend_Controller_Action_Exception("Object does not exist", 404);
or redirect them to some other page:
return $this->_helper->redirector('index', 'index'); //redirect to index action of index controller
Hope this helps.