Laravel 5 : get route parameter in Controller 's constructor - laravel

I defined routes for a controller this way :
/model/{id}/view
/model/something/{id}/edit
I need to get the id parameter in the contructor of this controller. For example :
class ArtController extends Controller {
public function __construct(Request $request){
//dd($this->route('id')); //Doesn't work
//dd($request->segments()[1]); //this works for the first route but not the second
}
}
How can you get the parameter id in the constructor of a Controller in Laravel?

You should be able to do something like this
$id = Route::current()->getParameter('id');
Update:
Starting in laravel 5.4 getParameter was renamed to parameter
$id = Route::current()->parameter('id');

public function __construct(Request $request)
{
$id = $request->route('id');
dump($id);
}

You can call anywhere:
request()->route('id');
No need for injection

not use segments
use segment
public function __construct(Request $request){
dd($request->segment(1));}

Related

Laravel authorization policy not working on Show page

I have a laravel app using Policies to assign roles and permissions, i cant seem to access the show page and im not sure what im doing wrong?
If i set return true it still shows a 403 error as well, so im unsure where im going wrong here. The index page is accessable but the show page is not?
UserPolicy
public function viewAny(User $user)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
public function view(User $user, User $model)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
UserController
public function __construct()
{
$this->authorizeResource(User::class, 'user');
}
public function index()
{
$page_title = 'Users';
$page_description = 'User Profiles';
$users = User::all();
return view('pages.users.users.index', compact('page_title', 'page_description', 'users'));
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show($id)
{
$user = User::findOrFail($id);
$user_roles = $user->getRoleNames()->toArray();
return view('pages.users.users.show', compact('user', 'user_roles'));
}
Base on Authorize Resource and Resource Controller documentation.
You should run php artisan make:policy UserPolicy --model=User. This allows the policy to navigate within the model.
When you use the authorizeResource() function you should implement your condition in the middleware like:
// For Index
Route::get('/users', [UserController::class, 'index'])->middleware('can:viewAny,user');
// For View
Route::get('/users/{user}', [UserController::class, 'view'])->middleware('can:view,user');
or you can also use one policy for both view and index on your controller.
I had an issue with authorizeResource function.
I stuck on failed auth policy error:
This action is unauthorized.
The problem was that I named controller resource/request param with different name than its model class name.
F. ex. my model class name is Acknowledge , but I named param as timelineAcknowledge
Laravel writes in its documentation that
The authorizeResource method accepts the model's class name as its first argument, and the name of the route / request parameter that will contain the model's ID as its second argument
So the second argument had to be request parameter name.
// Here request param name is timelineAcknowledge
public function show(Acknowledge $timelineAcknowledge)
{
return $timelineAcknowledge->toArray();
}
// So I used this naming here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'timelineAcknowledge');
}
Solution was to name request param to the same name as its model class name.
Fixed code example
// I changed param name to the same as its model name
public function show(Acknowledge $acknowledge)
{
return $acknowledge->toArray();
}
// Changed here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'acknowledge');
}
I looked over Laravel policy auth code and I saw that the code actually expects the name to be as the model class name, but I couldn't find it anywhere mentioned in Laravel docs.
Of course in most of the cases request param name is the same as model class name, but I had a different case.
Hope it might help for someone.

How to get result in Laravel with where clause while passing model in controller method

I have a route to get a single post item by slug.
Route
Route::get('post/{post}', 'PostController#details')->name('post.details');
While I want to pass the model in the controller method for the route.
Controller
public function details(Post $post)
{
// how to get the post by slug
}
My question is how can I get the post by slug passing in the route
instead of post ID?
I am aware that I can pass the slug and get the post using where clause.
//Route
Route::get('post/{slug}', 'PostController#details')->name('post.details');
//Controller method
public function details($slug)
{
$post = Post::with('slug', $slug)->first();
}
But I want to learn to do the same by passing the Model in the method.
set route key name to your model class
//Post.php
public function getRouteKeyName()
{
return 'slug';
}
This will inform Laravel injector/resolver to look the variable passed in slug column while fetching the object instance.
What you want to do is implicit route model binding
What you can do is in your Post model define getRouteKeyName like below
<?php
class Post extends Model
{
/**
* Get the route key for the model.
*
* #return string
*/
public function getRouteKeyName()
{
return 'slug';
}
}
and define your route like this:
Route::get('post/{post:slug}', 'PostController#details')->name('post.details');
and then in your controller
public function details(Post $post)
{
// it will return post with slug name
return $post;
}
Hope it helps.
Thanks

Laravel - Paramaters should be how when we use match route?

I want to use match method but I can't take $slug and $request in controller..
Here is my route
Route::match(['get','post] , 'category/{slug}' , ['as'=>'category.show' , 'uses'=>'CategoryController#categoryProducts'])
in Controller, our function will be how ? How we use that post and get data in the same function ? I tried like below, but dosen't work
public function categoryProducts($slug, $request) {
//codes
}
Please use Request::method();
public function categoryProducts(Request $request, $slug) {
//codes
}
to get request type GET/POST
$method = Request::method();
or
if (Request::isMethod('post'))
{
//
}
Since you're trying to inject Request object and not passing it, do this instead:
public function categoryProducts(Request $request, $slug)

Passing page URL parameter to controller in Laravel 5.2

In my application I have a page it called index.blade, with route /index. In its URL, it has some get parameter like ?order and ?type.
I want to pass these $_get parameter to my route controller action, query from DB and pass its result data to the index page. What should I do?
If you want to access the data sent from get or post request use
public function store(Request $request)
{
$order = $request->input('order');
$type = $request->input('type');
return view('whatever')->with('order', $order)->with('type', $type);
}
you can also use wildcards.
Exemple link
website.dev/user/potato
Route
Route::put('user/{name}', 'UserController#show');
Controller
public function update($name)
{
User::where('name', $name)->first();
return view('test')->with('user', $user);
}
Check the Laravel Docs Requests.
For those who need to pass part of a url as a parameter (tested in laravel 6.x, maybe it works on laravel 5.x):
Route
Route::get('foo/{bar}', 'FooController#getFoo')->where('bar', '(.*)');
Controller:
class FooController extends Controller
{
public function getFoo($url){
return $url;
}
}
Test 1:
localhost/api/foo/path1/path2/file.gif will send to controller and return:
path1/path2/file.gif
Test 2:
localhost/api/foo/path1/path2/path3/file.doc will send to controller and return:
path1/path2/path3/file.doc
and so on...

Send parameter to controller via Laravel Route

Given the following code, I simple want the second route to send an arbitrary value for id or any other variable I can access from within show();
Route::get('foo/{id}', 'FoobarController#show')->where('id', '[0-9]+');
Route::get('bar', 'FoobarController#show')->with('id', -1); // This pseudo-code doesn't work. I want to send parameter id with an arbitrary value
Why not like this?
Routes:
Route::get('bar/{id?}', 'FoobarController#show')->where('id', '[0-9]+');
Controller:
class FoobarController extends Controller{
public function show($id){
$id = $id ? $id : "default value";
}
}
Or:
public function show($id="default value"){..}

Resources