Blank Parameters - php

Following up on my previous question
Why are my params not showing up in the url?
What is the best way to deal with blank parameters? Do I need to write an if statement for each field and assign a value if null? Currently I have 2 parameters and if the first one is blank it is setting the value of the second parameter as the first
Below is an example. If Zip is the first parameter and bar is the second...
www.foo.com/results/12345/bar
zip = 12345
bar = bar
if the first param is empty...
www.foo.com/results/bar/
zip = bar
I would like to do this in the url so the below won't work.
$search_zip = $this->params()->fromRoute('zip','default');
Below is where I post the params.
return $this->redirect()->toRoute('home/results',array(
'zip'=>$homeSearch->search_zip ,

You need create a route
'results' => [
'type' => 'Segment',
'options' => [
'route' => 'results[/:zip][/:bar][/]',
'defaults' => [
'__NAMESPACE__' => '...',
'controller' => '...',
'action' => '...',
'zip' => 'default',
'bar' => 'default'
],
'constraints' => [
'zip' => '[0-9]+',
'bar' => '[a-z]+'
]
]
]
]
in controller
$this->params('zip');
$this->params('bar');
$this->redirect()->toRoute('results', ['zip' => 123, 'bar' => 'bar']);

Related

Yii2: how to build right pattern with pagination for the UrlManager?

I have following conditions:
1) expected request is /a1,a2,aN[/.../n1,n2,nN][?range=xxx-yyyy[&search=string]]
(square brackets contain optional parts)
2) action method signature is public function actionIndex(string $alias = '', string $range = '', string $search = ''): string
3) so I used a rule for this:
[
'pattern' => '<alias:[\\w-,\\/]+>',
'route' => 'shop/products/index',
'encodeParams' => false,
],
It works properly until I try to add pagination, LinkPager ignores a rule I wrote:
[
'pattern' => '<alias:[\\w-,\\/]+>/<page:\d+>',
'route' => 'shop/products/index',
'encodeParams' => false,
],
and displays the alias and page params as GET variables.
What is a right rule adding the page number in the end of request URI like
/a1,a2,aN/n1,n2,nN/2 and ignoring if the number is 1?
UPD: I found a reason, this is a rule I defined before:
'/shop' => 'shop/products/index', //it breaks following rules
[
'pattern' => '<alias:[\\w-,\\/]+>/<page:\d+>',
'route' => 'shop/products/index',
'encodeParams' => false,
],
[
'pattern' => '<alias:[\\w-,\\/]+>',
'route' => 'shop/products/index',
'encodeParams' => false,
],
So, how I to make all these rules work together?
Solution 1: To make another action method which works without alias argument and calls actionIndex with empty one.
Solution 2: To make same rules with different mode in special order:
[
'name' => 'This rule is first when we create a link',
'pattern' => '<alias:[\\w-,\\/]+>/<page:\d+>',
'route' => 'shop/products/index',
'encodeParams' => false,
'mode' => \yii\web\UrlRule::CREATION_ONLY,
],
[
'name' => 'This rule is first when we parse a request',
//
'pattern' => 'shop/<page:\d+>',
'route' => 'shop/products/index',
],
[
'name' => 'Used for parsing when previous rule does not match',
'pattern' => '<alias:[\\w-,\\/]+>/<page:\d+>',
'route' => 'shop/products/index',
'encodeParams' => false,
'mode' => \yii\web\UrlRule::PARSING_ONLY,
],
[
'name' => 'Same as first but when link has no page number',
'pattern' => '<alias:[\\w-,\\/]+>',
'route' => 'shop/products/index',
'encodeParams' => false,
'mode' => \yii\web\UrlRule::CREATION_ONLY,
],
[
'name' => 'First when parsing request with no page number',
'pattern' => 'shop',
'route' => 'shop/products/index',
],
[
'name' => 'Used for parsing when previous rule does not match',
'pattern' => '<alias:[\\w-,\\/]+>',
'route' => 'shop/products/index',
'encodeParams' => false,
'mode' => \yii\web\UrlRule::PARSING_ONLY,
],
If you know a better solution with one action I'll be glad to see it.

ZF2 - Controller managing route with and without params

I am writting an application with zf2 and I came to this issue which I don't know how to implement.
At the moment I have a router like this :
'routes' => [
'stock' => [
'type' => 'regex',
'options' => [
'regex' => '/stock(?<sku>\/.*)',
'defaults' => [
'controller' => MyController::class,
'action' => 'check',
],
'spec' => '/path%path%'
],
So when my url contains ../stock/13567/2312 the parameter gets passed into the checkAction function.
However, I would like to show a different content when the url is just ../stock/ or ../stock without any parameter sent. How can I achieve this ?
Thanks.
If you want to show different content depending if sku parameter is passed you can do following thing in your controller:
public function indexAction()
{
// Return sku parameter if exists, false otherwise
$sku = $this->params('sku', false);
if ($sku) {
// For example get single item
...
$view->setTemplate('template-a');
} else {
// Get all items
...
$view->setTemplate('template-b');
}
return $view;
}
Just augment the regex to mark the param as optional, as in the docs:
'regex' => '/stock(?<sku>\/.*)?'
... and don't forget to provide the explicit default value:
'defaults' => [
'controller' => MyController::class,
'action' => 'check',
'sku' => '' // or else
],

Zend multiparam URL to one parameter

Is there any solution to create this URL in Zend and get more URL parts as 1 parameter?
Ex.: /someApp/someFolder/Separator/Need/This/As/One/param/
and I need "Need/This/As/One/param" as 1 parameter...
My basic route is
"someApp/someFolder/Separator/:path/"
, I've tried something like
".../:path/*"
,... but nothing works ok. There will be no other param on the end of URL so it should be ok.
It get string after site/. For example: site/Need/This/As/One/param. variable path will have string Need/This/As/One/param
'type' => 'Segment',
'options' => [
'route' => 'site/:path[/]'
'defaults' => [...],
'constraints' => [
'path' => '.+',
]
]
]

zf2 - url view helper: specify parameters for route

My main router goes like this (simplified):
'router' => [
'routes' => [
'blog' => [
'type' => 'regex',
'options' => [
'regex' => "/(?<language>[a-z]{2})?",
'spec' => "/%language%",
'defaults' => [
'controller' => 'Blog\Controller\Posts',
'action' => 'index'
],
],
'may_terminate' => true,
'child_routes' => [
// [...]
'add_post' => [
'type' => 'literal',
'options' => [
'route' => '/admin/post/add',
'defaults' => [
'controller' => 'Blog\Controller\Posts',
'action' => 'add'
]
]
], // end add post
] // end child routes
] // end blog route (main route)
] // end routes
] // end Router
And in the template displayed on "/en/admin/post/add" I have a call to $this->url(), that ends up printing /%language%/admin/post/add.
I have the language code available on $language on my template, and
I'd like to pass it on to url() so it properly constructs the the url using the spec.
Also, I'd like, if possible, not to specify the name of the route on my call to url(), so it uses the default one for $this.
How would I go around to accomplish this?
Thanks and regards
You could use a segment route instead of a regex one and then use
$this->getHelperPluginManager()->getServiceLocator()->get('request')->getUri()->getPath();
in your view to print the actual route it's been used
While #marcosh answer works, since then I've found a simpler solution:
$this->url($this->route, ['language' => $language]);
Will output what I want. Seems clearer to me.

ZF2 optional route constraints in child routes

I'm having an issue with an optional constraint in a route that is non-optional in it's children. My routing structure is as follows:
'profile' => [
'type' => 'segment',
'options' => [
'route' => '/profile[/:id]',
'constraints' => ['id' => '[0-9]*'],
'defaults' => [
'controller' => 'User\Controller\User',
'action' => 'profile'
]
],
'may_terminate' => true,
'child_routes' => [
'sessions' => [
'type' => 'literal',
'options' => [
'route' => '/sessions',
'defaults' => ['action' => 'sessions']
]
]
]
]
Which to my mind should give me the following routes:
/profile - works
/profile/123 - works
/profile/sessions - doesn't work
/profile/123/sessions - works
When I use route 3 in the URL view helper I get the following error:
$this->url('profile/sessions');
Zend\Mvc\Router\Exception\InvalidArgumentException: Missing parameter "id"
I originally had [0-9]+ as my constraint but making it optional (*) doesn't seem to have helped. Has anyone experienced this case before?
Add it to your parent route.
'profile' => [
'type' => 'segment',
'options' => [ // ↓
'route' => '/profile[/:id][/:action]',
'constraints' => [ 'id' => '[0-9]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*' ],
'defaults' => [
'controller' => 'User\Controller\User',
'action' => 'profile',
],
],
]
This will make it optional to have id and/or action.
At least in theory it should make all your listed routes possible, there have been some issues with this.
I had the same issue once, the only solution I found was to create a separate route (in your case for /profile/sessions) as the optional parameter for the base route, seems to become obligatory when accessing a child route.

Categories