Zend multiparam URL to one parameter - php

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' => '.+',
]
]
]

Related

ZF2 - Routing with encoded input parameters

I have the following issue which I do not know how to resolve.
I have the following route on a api I am using :
'router' => [
'routes' => [
'test' => [
'type' => 'regex',
'options' => [
'regex' => '/test(?<json>\/.*)?',
'defaults' => [
'controller' => TestController::class,
'action' => 'checkJson',
'json' => '',
],
'spec' => '/path%path%'
],
],
],
],
The idea is to catch all requests ending in a json string /test/[{"this is an example":1}]. This really works but the problem is, I would also like to accept when the input gets encoded like :
/test/%5B%7B%22this%20is%20an%20example%22%3A1%7D%5D
Any idea of how can I achieve what I am expecting ?
When the request is made using an encoded url, I get the following error in the browser :
Not Found
The requested URL /stock//test/[{"this is an example":1}] was not found on this server.
Any idea of how can I resolve this easily ?
Thank you

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
],

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.

Yii2 route using yii\rest\UrlRule with several parameters

I am trying to use Yii 2 routing for REST API.
Following tutorial at http://www.yiiframework.com/doc-2.0/guide-rest-routing.html, I have already defined (with success) a lot of rule for API entry point like so :
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user'
],
],
]
Such a rule defines :
GET /users (list users)
GET /users/123 (show detail of user 123)
Now, my users have games. So I'd like to have urls :
GET /users/123/games (list games of user 123)
GET /users/123/games/864 (details of game 864 for user 123 - such as his scores)
I tried defining my new entry point (withhout success) like so:
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'game'
],
'tokens' => [
'{userid}' => '<userid:\\d>',
'{gameid}' => '<gameid:\\d>',
],
'patterns' => [
'GET,HEAD /users/{userid}/games' => 'index',
'GET,HEAD /users/{userid}/games/{gameid}' => 'view',
]
]
]
This definition seems wrong because I get a 404 Page not found error.
How should I define my new url routes ?
I would like to use an equivalent format for my definitions, extending 'yii\rest\UrlRule'
I am not sure if this is even possible, the tutorial not mentionning this case.
So I figured out how to use more complex rules.
First, the solution, then the explanation.
Here is the solution:
'rules' => [
... previous rules ...,
[
'class' => 'yii\rest\UrlRule',
'controller' => 'game',
'prefix' => '/users/<userid:\\d+>',
'tokens' => [
'{gameid}' => '<gameid:\\d+>',
],
'patterns' => [
'GET,HEAD' => 'index',
'GET,HEAD {gameid}' => 'view',
]
]
]
And now the explanation:
First my userid / gameid attributes were badly defined. There was a missing "+" after "\d"
The controller seems to be automatically added as a prefix to the patterns. So you have to define both a controller and a prefix (that will be added before the controller).
Parameters in the prefix does not seem to be parsed to find tokens. So I wrote directly the regexp in the prefix instead of adding "userid" as a token.
Finally, there are various "/" automatically added during concatenation of "prefix/controller/pattern" so you don't have to write one.
Do not forget the pluralization rule too ! "game" is singular" but valid urls will be
/users/123/games
/users/123/games/789
Hope it will help.
I think there´s a simple solutions, please try this:
'rules' => [
...
'/users/<userId:\\d+>/games' => 'game/index' ,
'/users/<userId:\\d+>/games/<gameId:\\d+>' => 'game/view' ,
....
];
Just use yii2-nested-rest
It provides REST API for MANY-to-MANY relations in Yii2 framework.
Hope comments will make the magic more understandable:
'rules' => [
// this usual rule for base Yii2 rest usage
['class' => 'yii\rest\UrlRule', 'controller' => ['sitecomponent' ,'sitepage' , 'sitedomain'], 'pluralize'=>false
],
// then rules for yii2-nested-rest
[
// url sitepage/NNN/sitecomponent[/MMM]
// ^^^^^^^^^ ^^^^^^^^^^^^
// resourceName model-endpoint
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SitePage',
'resourceName' => 'sitepage',
'relations' => ['components' => ['sitecomponent'=>'sitecomponent'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^
// relation name url-endpoint controller]
// defined in model SitePage model-endpoint with Actions from nested
],
[
// cross url sitecomponent/NNN/sitepage[/MMM]
'class' => 'tunecino\nestedrest\UrlRule',
'modelClass' => 'app\models\SiteComponent',
'resourceName' => 'sitecomponent',
'relations' => ['pages' => ['sitepage' => 'sitepage'] ],
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^
// relation name url-endpoint controller
// from model SiteComponent model-endpoint with Actions from nested
],
],
GET xx.com/v2/publication/12/p/34
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,//controller是否复数
'controller' => 'v2/publication',//此处一定要加上v2
'tokens' => [
'{id}' => '<id:\\d[\\d,]*>',
'{phase}' => '<phase:\\d[\\d,]*>',
],
// 通过extraPatterns和tokens来实现多个参数传递
'extraPatterns' => [
'GET,HEAD {id}/p/{phase}' => 'phase',
],
],
IN ACTION
public function actionPhase($id, $phase){}

Blank Parameters

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']);

Categories