Pass parameter from route to controller in laravel? - laravel

I want to pass current agency id from route to controller in laravel 5.2.
ex:- I have one resource controller is AgencyController.
Route::resource('agencies', 'Admin\AgencyController');
I want to add one more route, such as,
Route::get('agencies/me', 'Admin\AgencyController#show', ['middleware' => ['web', 'agency']]);
Here I want to pass agency id from session as default parameter to agencyController#show function.
ex:- Auth::guard('agency')->user()->agencies_id
Is it possible in laravel?

Laravel routes function that if you configure your route like:
Route::get('user/{user}', 'UserController#someMethod');
you can pick up whatever you send after the slash in the controller. So if you call:
www.example.com/user/3
and your controller is like public function someMethod($id) the 3 will be forwarded to $id variable

Related

Find a Controller by the Route in Laravel

I have a route and I need to know a controller that would be used for it.
I know how to find a controller for the current route:
Illuminate\Support\Facades\Route::currentRouteAction();
But how can I do the same for other routes?
Route Facade is the answer. It can return Illuminate\Routing\RouteCollection object.
and then you can get Illuminate\Routing\Route object by route name.
Every Route triggers multiple actions such as middleware and controller methods. So we need only the controller.
use Illuminate\Support\Facades\Route as RouteFacade;
/*#var $route Illuminate\Routing\Route*/
$name = 'admin.reports.my-report.get-filters'; // sample route name
$route = RouteFacade::getRoutes()->getByName($name);
$controllerAction = $route->action['controller'];
$controller = explode('#', $controllerAction)[0];
logger($controller);
P.S.
In cases like that - remember to make a unit test for this functionality to be sure it works as you upgrade your laravel.

How to set a route parameter default value from request url in laravel

I have this routing settings:
Route::prefix('admin/{storeId}')->group(function ($storeId) {
Route::get('/', 'DashboardController#index');
Route::get('/products', 'ProductsController#index');
Route::get('/orders', 'OrdersController#index');
});
so if I am generating a url using the 'action' helper, then I don't have to provide the storeId explictly.
{{ action('DashboardController#index') }}
I want storeId to be set automatically from the request URL if provided.
maybe something like this.
Route::prefix('admin/{storeId}')->group(function ($storeId) {
Route::get('/', 'DashboardController#index');
Route::get('/products', 'ProductsController#index');
Route::get('/orders', 'OrdersController#index');
})->defaults('storeId', $request->storeId);
The docs mention default parameter though in regards to the route helper (should work with all the url generating helpers):
"So, you may use the URL::defaults method to define a default value for this parameter that will always be applied during the current request. You may wish to call this method from a route middleware so that you have access to the current request"
"Once the default value for the ... parameter has been set, you are no longer required to pass its value when generating URLs via the route helper."
Laravel 5.6 Docs - Url Generation - Default Values
In my Laravel 9 project I am doing it like this:
web.php
Route::get('/world', [NewsController::class, 'section'])->defaults('category', "world");
NewsController.php
public function section($category){}
Laravel works exactly in the way you described.
You can access storeId in your controller method
class DashboardController extends Controller {
public function index($storeId) {
dd($storeId);
}
}
http://localhost/admin/20 will print "20"

Want to show name instead of id in the URL field in Laravel

I don't want to show /route_name/{id} in the URL field of my Laravel project. Instead of that I want to show /route_name/{name} but pass the id in the back-end to the controller.
Suppose I have a route named departments and pass an id 3 named knee_pain as a parameter. And it is like /departments/3
But I want to to show /departments/knee_pain in my url and as well as want to pass the id 3 in my controller without showing the id in the url.
How to do that ?
In your model you can use the getRouteKeyName method to bind to another attribute than the default id in your routes :
public function getRouteKeyName()
{
return 'slug'; // Default is 'id'.
}
Rather than using the name attribute, that you could use elsewhere in your application for displaying the name of the entry, I recommend using an attribute made url friendly. You could use Str::slug() for that.
public function setNameAttribute($value) {
$this->name = $value;
$this->slug = \Str::slug($value);
}
It will 'slugify' your string, for example : \Str::slug('Knee pain') => 'knee-pain'.
Note : in Laravel 5.5, use the str_slug() helper.
You should also make sure this string is unique in your database.
First you have to garantee that the name is unique, if don't you will have more than one Id in your controller. For that i recommend you to use Purifier to remove spaces and make it URL friendly:
Purifier
Second, probably the best way to have clean controllers is creating a middleware that understand what kind of name is (what table should middleware look for). You can validate that by route name and send the correct id to controller.
Middleware docs

Laravel - route model binding with request headers

I am wondering is it possible to do something similar to route model binding, but with request headers. I have a query that I check on my api endpoints, that looks like this:
User::where('telephone', $request->header('x-user'))->firstOrFail();
Is it possible to somehow avoid repeating this query in every method in controllers, but to apply it to routes, so that I could just get the user object just like in a route model binding with type hinting in a function, for every route that in an api routes folder:
public function userTransactions(User $user)
{
//
}
Create a middleware and assign it to the desired routes.
Option 1
In your middleware do:
$user = User::where('telephone', $request->header('x-user'))->firstOrFail();
request()->merge(['user_model' => $user]);
You can then request()->get('user_model') anywhere in your controller
Option 2
Start by creating a global scope class that conforms to your query. Here you'd get the header value and use that in the scope.
https://laravel.com/docs/5.5/eloquent#global-scopes
Next in the middleware, add the scope to the model using addGlobalScope
User::addGlobalScope(new HeaderScope())
Now all queries for User will have a where clause with your header value.
You can subsequently remove the scope or ignore global scopes if needed.

Laravel - How to pass a variable to controller through resource route?

I've defined this resource in web.php of Laravel app,
Route::resource('Student', 'StudentCtrl');
and I have a variable which contains name of meta file,
$metaFile = 'student_meta.json';
I want to pass $metaFile to StudentCtrl, so I can catch the file name there.
I'm using Laravel 5.4.
Thanks.
Just pass the variable to the url, And thats it.
if its a get request will be routed to StudentCtrl#show
if its a put request will be routed to StudentCtrl#update
if its a delete request will be routed to StudentCtrl#destroy
And so on.
All you have to do is to define a method of the form. GET,POST,PUT/PATCH,DELETE.
Have a look here.
Passing a single variable from Router to Controller is possible only for Single HTTP request method.
Refer here : https://stackoverflow.com/a/50405137/9809983
For a complete resource route, its possible to send a fixed value to all views under that resource, if that's what you are trying to do
In Controller
public function __construct(Request $request)
{
$action_array = $request->route()->getAction();
$json_file['json_file'] = "student_meta.json";
$new_action_array = array_merge($action_array, $json_file);
$request->route()->setAction($new_action_array);
}
Now you can access the value in all the views under the resource controller like,
In View
{{ request()->route()->getAction('json_file') }}
Tested and perfectly works in Laravel 5.6

Resources