Inject default value in ZF2 Router - php

I currently have a Segment route looking like this: /shop/:shopId/ where shopId has no default value.
Whenever the route is matched a code in Module.php is triggered, that would do some preparation according to the shopId and save it in the session for example.
My question is, if it is possible, at that point, to set the default value for the route to that shopId? The final goal is to be able to assemble URLs without specifying the shopId each time from this moment on.
I remember in ZF1 this behavior was by default, where matched params from the Request were reused when assembling the URL and you had to explicitly specify you wanted them removed. Now I need the same functionality, but configured on a Module.php level, rather than having to rewrite every single assemble() call.

Option one: from your indexAction
$id = $routeMatch->getParam('id', false);
if (!$id)
$id = 1; // id was not supplied set default one note this can be added as constant or from db ....
Option two: set route in module.config.php
'product-view' => array(
'type' => 'Literal',
'options' => array(
'route' => '/product/view',
'defaults' => array(
'controller' => 'product-view-controller',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:cat][/]',
'constraints' => array(
'cat' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
in you controller:
public function indexAction()
{
// get category param
$categoryParam = $this->params()->fromRoute('cat');
// if !cat then get random category
$categoryParam = ($categoryParam) ? $categoryParam : $this->categories[array_rand($this->categories)];
$shortList = $this->listingsTable->getListingsByCategory($categoryParam);
return new ViewModel(array(
'shortList' => $shortList,
'categoryParam' => $categoryParam
));
}

Related

Zend framework routing error

I have a problem with a routing in Zend framework.
'name' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/site/:id/orders[/:page]',
'constraints' => array(
'id' => '[0-9]*',
'page' => '[0-9]*'
),
'defaults' => array(
'controller' => 'Application\Controller\Site',
'action' => 'action'
),
),
),
And in a controller.
$id = (int) $this->params()->fromRoute('id');
And in some (!) cases a browser returns this error - "Missing parameter 'id'", but I don't know why.
Can anybody help me on this issue?
well based on your route configuration id must exist in your routes, so the link you requested didn't have id . and your constrains also should change to 'id' => '[0-9]+' so the id must exist.
and also you get the id in the controller by just typing
$id=$this->params("id");
which will get the id too

ZF2 Restful hierarchical routes

I'm trying to use a hierarchical resource in ZF2 for a Restful API. The resource should looks like clients/1/addresses. What I've tried was this
'clients' => array(
'type' => 'segment',
'options' => array(
'route' => '/clients[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Api\Controller\ClientController',
),
),
'may_terminate' => true,
'child_routes' => array(
'addresses' => array(
'type' => 'segment',
'options' => array(
'route' => '/addresses[/:address_id]',
'constraints' => array(
'address_id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Api\Controller\AddressController',
),
),
),
),
),
There is this conflict of both id's, but I don't know if I rename the route identifier id of the resource addresses like I did will solve it. Anyway, the real problem is that the route clients/1/addresses calls the get method of the AddressController, not the getList, and I think that's because Zend understands that the id of the client belongs to addresses, so its calls the get method.
Do you know how to deal with this?
You are probably right that get is called instead of getList because of the id being present in your route match parameters and the controller by default uses 'id' for matching the route identifier.
The way to deal with this is that you give the route identifiers names that fit the resource. So for client you make client_id and for address you use address_id (like you already did).
And then you configure your AbstractRestfulController instance to "look" for the correct route identifier using the setIdentifierName method:
$clientController->setIdentifierName( 'client_id' );
$addressController->setIdentifierName( 'address_id' );
This is just an example, the best way to do this is (of course) by using a controller factory...

ZF2- Dynamic base route

I'm trying to create a dynamic route in a ZF2 project. It will be something like "domain.com/companyurl/products". The company url is dynamic. I did it:
'company' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:company]',
'defaults' => array(
'controller' => 'IndexController',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
...
),
),
But I always have to pass the company parameter in a route.
$this->url('company/products', array('company' => 'companyurl'));
Is there some way to specify a base route at the runtime, like a base url, then all route will follow it? Something like this:
$this->url('products');
or
$this->url('company/products');
In the both cases I already specified the base route value.
I hope you understand what I mean. Thanks.
There is a $reuseRouteParams option that you can use in the URL helper:
$this->url($name, $params, $options,$reuseMatchedParameters);
If you set this to true it will reuse the previous route match value of companyUrl.
You can read more on this in the docs here.

Zend 2 redirect with toRoute not working

Why is Zend 2 such a !##(#(!##??
OK, so I'm trying to get a simple redirect working. I have a controller called 'listitems' with an action called 'editlistitem'. After hours of banging on it with a hand sledge, I've finally got the form to work and the validation to work and the hydration to Doctrine to work so I can save the result.
The last step is to redirect the user to the 'showlistitem' action which includes the id trailing it. (full route sub path is 'listitem/showlistitem/2' where 2 is the id I want to see)
I have tried:
$this->redirect()->toRoute('/listitem/showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem/2');
$this->redirect()->toRoute('showlistitem/2');
$this->redirect()->toRoute('listitem/showlistitem', array('id' => 2));
$this->redirect()->toRoute('listitem-showlistitem', array('id' => 2));
None of them flippin work! (they all return route not found)
A route to the controller is in modules.config.php with a child route to the action. I can go directly to the url by typing it in manually and it works fine. How in the bleep do I get Zend to redirect the user to that route from an action?
The toRoute method provided by the The Redirect plugin needs the route name to be passed as parameter. This is its desciption :
toRoute(string $route = null, array $params = array(), array $options = array(), boolean $reuseMatchedParams = false)
Redirects to a named route, using the provided $params and $options to assembled the URL.
Given this simple route configuration example :
//module.config.php
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Segment',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
),
'app' => array(
'type' => 'Literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id'=>'[0-9]+',
),
),
),
),
),
),
),
This redirection works :
return $this->redirect()->toRoute('app/default',
array('controller'=>'controller-name', 'action'=>'action-name', 'id'=>$id));
In your case, this would work :
return $this->redirect()->toRoute('app/default',
array('controller'=>'listitem', 'action'=>'showlistitem', 'id'=>2));

Trouble with URL parameters

I am working on a search form that I would like to post the searched by values in the url. I am having trouble getting the url to include the parameters however. They will post if I key in values in the view( if instead of $this->search_zip I key '12345'). Currently the search works as desired except for the url. I am currently getting the search terms from the form, would I need to change my controller setup to get them from the url instead? If this is the case how would I filter?
Ultimately I would like my url to read:
results/12345/otherparam
I am currently getting
results
No matter what variables I key into the form.
Module Config
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'segment',
'options' => array(
'route' => '/',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
'may_terminate' => true, //START OF CHILD ROUTES
'child_routes' => array(
'results' => array(
'type' => 'segment',
'options' => array(
'route' => 'results[/:search_zip][/:search_industry]',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'results',
Results view
$form->setAttribute('action', $this->url(
'home/results',
array(
'action' => 'results',
'search_zip'=> $this->search_zip,
'search_industry' => 'industry_name'
echo $this->formRow($form->get('industry_name'));//this is the form field
echo $this->formSubmit($form->get('submit'));
Controller
//beginning of the results action
$request = $this->getRequest();
$form = new SearchForm($dbAdapter);
if ($request->isPost()) {
$search = new MainSearch();
$form->setInputFilter($search->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
At the end of my resultsAction I return the form and the results (per the album example)
return array(
'form' => $form,
'pros' => $fetchPros,
);
Thank you,
M
//This will give you an array containing your desired parameters
$params = $this->params()->fromRoute();
//Then you can simply use them like this
$search_zip = $params['search_zip'];
$search_industry = $params['search_industry'];

Categories