Laravel 5.1 add Query strings in url - php

I've declared this route:
Route::get('category/{id}{query}{sortOrder}',['as'=>'sorting','uses'=>'CategoryController#searchByField'])->where(['id'=>'[0-9]+','query'=>'price|recent','sortOrder'=>'asc|desc']);
I want to get this in url: http://category/1?field=recent&order=desc
How to achieve this?

if you have other parameters in url you can use;
request()->fullUrlWithQuery(["sort"=>"desc"])

Query strings shouldn't be defined in your route as the query string isn't part of the URI.
To access the query string you should use the request object. $request->query() will return an array of all query parameters. You may also use it as such to return a single query param $request->query('key')
class MyController extends Controller
{
public function getAction(\Illuminate\Http\Request $request)
{
dd($request->query());
}
}
You route would then be as such
Route::get('/category/{id}');
Edit for comments:
To generate a URL you may still use the URL generator within Laravel, just supply an array of the query params you wish to be generated with the URL.
url('route', ['query' => 'recent', 'order' => 'desc']);

Route::get('category/{id}/{query}/{sortOrder}', [
'as' => 'sorting',
'uses' => 'CategoryController#searchByField'
])->where([
'id' => '[0-9]+',
'query' => 'price|recent',
'sortOrder' => 'asc|desc'
]);
And your url should looks like this: http://category/1/recent/asc. Also you need a proper .htaccess file in public directory. Without .htaccess file, your url should be look like http://category/?q=1/recent/asc. But I'm not sure about $_GET parameter (?q=).

Related

Laravel route being stuck in UTF-8

i have this controller to redirect:
$zone='لندن';
$type='خانه';
return redirect()->route('searchResult',['zone' => $request->zone , 'type' => $request->type]);
and here is my route:
Route::get('/estates/{zone}/{type}', 'EstateController#searchResult')->name('searchResult');
When Its Redirect I get a URL like this-
http://localhost:8000/estates/لندن/خانه
Instead of above I would like to have this URL-
http://localhost:8000/estates/خانه/لندن
i don't wanna switch the route parameters!
need help ty!
Edited:
i have this route :
/estates/{zone}
and wanna this route
/estates/{zone}/{type} be a sub-route for base route
but its return me a reverse route and its not going friendly! and its why i dont wanna change the route parameters!
I can't reproduce your exact behavior, but Laravel has something to handle better those kind of Sub Parameters that is Optional Parameters. https://laravel.com/docs/5.7/routing#parameters-optional-parameters
Define a single Route, and put ? after your parameter name to make it optional:
Route::get('/estates/{zone}/{type?}', 'EstateController#searchResult')->name('searchResult');
And in your Action method signature, put type parameter as optional too
<?php
public function searchResult($zone, $type=null)
{
echo $zone.' / '.$type;
/*if(!$type) {
$type = 'commune';
return redirect()->route('searchResult',['zone' => request()->zone , 'type' => $type]);
}*/
}
And in your case I don't really see a reason to pass request()->type as parameter to route, because even if it's null or not, you will remain in the same state. If you have a new $type variable in your code, then pass it as :
return redirect()->route('searchResult',['zone' => request()->zone , 'type' => $type]);
EDIT -------
If your code in Controller is really :
$zone='لندن';
$type='خانه';
return redirect()->route('searchResult',['zone' => $request->zone , 'type' => $request->type]);
Then I think you should use $zone and $type variable instead of request parameters value :
$zone='لندن';
$type='خانه';
return redirect()->route('searchResult',['zone' => $zone , 'type' => $type]);

How can I get a route url pattern by route name in laravel?

So I have a route defined in my web.php, like so....
Route::any('/items/{id}/{slug}', 'Items\ItemController#item')->name('items.item');
I am trying to make a function where I can get the string pattern for the URL, '/items/{id}/{slug}' from the route by calling it's name...
I assumed this would work.. but it doesn't (it tells me I'm missing the parameters id and slug).
// Should assign the string 'items/{id}/{slug}' to the variable.
$url_pattern = route('items.item');
I'm using Laravel 5.3.
You can access the Route's uri as follows:
$url_pattern = app('router')->getRoutes()->getByName('items.item')->uri;
var_dump($url_pattern);
// will return:
// "items/{id}/{slug}"
You can always create a faux route. When you are invoking route(), one has to assume you know the params it expects.
If you would like to get it as a string (to be used in JS for example), just pass the names of the params as the params. For example:
$url_pattern = route('items.item', ['id' => '{id}', 'slug' => '{slug}']);
// will generate:
// items/{id}/{slug}
you need to add the parameters in the router function, for example:
$url_pattern = route('items.item', ['id' => $id, 'slug' => $slug]);
https://laravel.com/docs/5.5/routing#named-routes

Pass in hard coded params into named Laravel route

I am creating some hard coded routes that will likely be changed again freely in the future. To abstract the ideas a bit:
We have a controller/method BuySubscriptionController#start:
class BuySubscriptionController
function start()
{
$plan = Plan::findBySlug($request->get('plan'));
return view('someView', ['plan' => $plan]);
}
}
We currently have the following route:
Route::get('/buy-subscription/start', 'BuySubscriptionController#start');
This means the sales team would need to advertise the following urls:
site.com/buy-subscription/start?plan=plan-one
site.com/buy-subscription/start?plan=plan-two
Now we have been requested to have a few specialized routes:
site.com/purchase/the-basic-plan (plan-one)
site.com/purchase/the-mega-plan (plan-two)
Now I am trying to add these specialized urls to my routes. I was hoping to do something as follows, but does not work:
Route::get('/purchase/the-basic-plan', [
'uses' => 'BuySubscriptionController#start',
'with' => ['plan' => 'plan-one']
]);
Route::get('/purchase/the-mega-plan', [
'uses' => 'BuySubscriptionController#start',
'with' => ['plan' => 'plan-two']
]);
Is there any way to achieve this, simply, without over engineering some new translation layer? Keep in mind that next week the url might be /buy/the-god-plan meaning plan-one, so being able to simple add a line to my routes seems ideal.
You can define a route that takes the plan as a parameter, and use Regular Expression Constraints so that parameter can only take certain values that you allow. So your route definition can look like this:
Route::get('/purchase/{plan}', 'BuySubscriptionController#start')
->name('purchase-plan')
->where('plan', 'the-basic-plan|the-mega-plan');
Then in your controller action just use the parameter:
class BuySubscriptionController
{
protected $plans = [
'the-basic-plan' => 'plan-one',
'the-mega-plan' => 'plan-two'
];
function start($plan)
{
// You can use an associative array to convert the $plan parameter
// into the value you need for querying the database
$plan = Plan::findBySlug($this->plans[$plan]);
return view('someView', ['plan' => $plan]);
}
}
If you need to generate URLs for the route you can just use the route helper method and pass it the plan name:
route('purchase-plan', 'the-basic-plan');
And you'll get:
site.com/purchase/the-basic-plan
This solution allows you to add any number of plan names by just adding the public plan for the URL in the where constraint of the route, then associating that value with the one you need for the query in your controller's $plans property.

Yii2 render url with query parameters

I need to add some parameter to url by using render in a Yii2 controller action. For example add cat=all parameter to following url:
localhost/sell/frontend/web/index.php?r=product/index
and this is my index action :
return $this->render('index', [
'product' => $product,
]);
You can create URL like below:
yii\helpers\Url::toRoute(['product/index', 'cat' => 'all']);
You can redirect in controller like below:
$this->redirect(yii\helpers\Url::toRoute(['product/index', 'cat' => 'all']));
Then render your view.
To generate url using the Yii2 yii\helpers\Url to() or toRoute() method:
$url = yii\helpers\Url::to(['product/index', 'cat' => 'all']);
or:
$url = yii\helpers\Url::toRoute(['product/index', 'cat' => 'all']);
And you can then redirect in controller:
return $this->redirect($url);
Also note that the controller redirect() method is merely a shortcut to yii\web\Response::redirect(), which in turn passes it's first argument to: yii\helpers\Url::to(), so you can feed your route array in directly like so:
return $this->redirect(['product/index', 'cat' => 'all']);
Please Note: the other answer by #ali-masudianpour may have been correct in earliest versions of Yii2, but in later versions of Yii2 (including latest - 2.0.15 at time of writing), the Url helper methods only accept unidimensional arrays, which are in turn passed into yii\web\UrlManager methods like createUrl.
You can make redirect route into your controller like this:
$this->redirect(yii\helpers\Url::toRoute(['product/index', 'cat' => 'all']));

CakePHP 3.0 query string parameters vs passed parameters

In CakePHP 3.0 named parameters have been removed (thank god) in favour of standard query string parameters inline with other application frameworks.
What I'm still struggling to get my head around though is that in other MVC frameworks, for example ASP.NET you would pass the parameters in the ActionResult (same as function):
Edit( int id = null ) {
// do stuff with id
}
And that method would be passed the id as a query string like: /Edit?id=1 and you'd use Routing to make it pretty like: /Edit/1.
In CakePHP however anything passed inside the function parameters like:
function edit( $id = null ) {
// do stuff with $id
}
Must be done as a passed parameter like: /Edit/1 which bypasses the query string idea and also the need for routing to improve the URL.
If I name the params in the link for that edit like:
$this->Html->link('Edit', array('action' => 'edit', 'id' => $post->id));
I then have to do:
public function edit() {
$id = $this->request->query('id');
// do stuff with $id
}
To get at the parameter id passed. Would of thought it would pick it up in the function like in ASP.NET for CakePHP 3.0 but it doesn't.
I prefer to prefix the passed values in the edit link instead of just passing them so I don't have to worry about the ordinal as much on the other end and I know what they are etc.
Has anyone played with either of these ways of passing data to their methods in CakePHP and can shed more light on the correct ways of doing things and how the changes in version 3.0 will improve things in this area...
There are a few types of request params in CakePHP 3.0. Let's review them:
The Query String: are accessed with $this->request->query(), are not passed to controller functions as arguments and in order to make a link you need to do Html->link('My link', ['my_query_param' => $value])
Passed arguments: The special type of argument is the one that is received by the controller function as an argument. They are accessed either as the argument or by inspecting $this->request->params['pass']. You Build links with passed args depending on the route, but for the default route you just add positional params to the link like Html->link('My link', ['action' => view, $id, $secondPassedArg, $thirdPassedArg])
Request Params: Passed arguments are a subtype of this one. A request param is a value that can live in the request out of the information that could be extracted from the route. Params can be converted to other types of params during their lifetime.
Consider this route:
Router::connect('/articles/:year/:month/:day', [
'controller' => 'articles', 'action' => 'archive'
]);
We have effectively created 3 request params with that route: year, month and day and they can be accessed with $this->request->year $this->request->month and $this->request->day. In order to build a link for this we do:
$this->Html->link(
'My Link',
['action' => 'archive', 'year' => $y, 'month' => $m, 'day' => $d]
);
Note that as the route specify those parameters, they are not converted as query string params. Now if we wanted to convert those to passed arguments, we connect this route instead:
Router::connect('/articles/:year/:month/:day',
['controller' => 'articles', 'action' => 'archive'],
['pass' => ['year', 'month', 'day']]
);
Our controller function will now look like:
function archive($year, $month, $day) {
...
}

Categories