Laravel 5.0 pass variable to middleware - laravel-5

At the moment I have to check if job record, which is being edited, belongs to right person. My get job edit route:
/user/job-edit/{slug}
So I created JobEditMiddleware but the problems is I can't access {slug} variable in my middlewar. Is there any way to do it? Thanks.

You can use segment() method to retrieve various segments of your URI.
Try following in your middleware,
\Request::segment(3)
Read More

You can access to your slug parameter easier.
public function handle($request, Closure $next, $role) {
//
}
You have to call your slug parameter like this :
$request->slug;
I think it's a better way than segment if you'll need to change your route later.

Related

Laravel - Controller dependency is injected before middleware is executed

So I created a middleware to limit the data a connected user has access to by adding global scopes depending on some informations:
public function handle(Request $request, Closure $next)
{
if (auth()->user()?->organization_id) {
User::addGlobalScope(new OrganizationScope(auth()->user()->organization));
}
return $next($request);
}
The middleware is added to the 'auth.group' middleware group in Kernel.php which is used in web.php:
Route::middleware(['auth.group'])->group(function () {
Route::resource('users', UserController::class);
});
Then in the controller, I would expect a user to get a 404 when trying to see a page of a user he has no rights to. But the $user is retrieved before the middleware applies the global scope!
public function show(User $user, Request $request) {
// dd($user); // <= This actually contains the User model! It shouldn't, of course.
// dd(User::find($user->id)); // <= null, as it should!
}
So, the dependency is apparently calculated before the middleware is applied. If I'm trying to move the middleware into the 'web' group in Kernel.php it's the same. And in the main $middleware array, the authenticated user's data is not available yet.
I found this discussion that seems to be on topic : https://github.com/laravel/framework/issues/44177 but the possible solutions (and Taylor's PR) seems to point to a solution in the controller itself. Not what I'm trying to do, or I can't see how to adapt it.
Before that I was applying the global scopes at the Model level, in the booted function (as shown in the docs). But I had lots of issues with that - namely, accessing a relationship from there to check what is allowed or not is problematic, as the relationship call will look for something in the Model itself, and said model is not ready (that's the point of the booted method, right...). For example, checking a relationship of the connected user on the User model has to be done with a direct query to the db, that will be ran every time the Model is called... Not good.
Anyway, I like the middleware approach as it is a clean way to deal with rights as well, I think. Any recommandation?
Not a recommendation, just my opinion.
This issue is just because of that Laravel allow you add middleware in controller constructor, and that's why it calculate before midddleware in your case.
I agree that middleware is a clean way to deal with auth, but i also think that you are not completely doing auth in your middleware, for example if you create a new route will you need to add something auth action into your new controller or just add auth middleware to route?
If does needs add something to controller, that means your auth middleware is just put some permissions info into global scope and you are doing the auth in controller which i think it's not right.
Controller should be only control the view logic, and you should do full auth in your auth middleware, once the request passed into your controller function that means user passed your auth.
For some example, if you auth permissions like below, you can just add auth middleware to new route without any action in your controller when you trying to create new route.
public function handle(Request $request, Closure $next)
{
if (auth()->user()->canView($request->route())) { // you should do full auth, not just add informations.
return $next($request);
}
else
abort(404);
}

What is better practice for accessing laravel request variables

What is better practice for accessing request values in laravel.
For example I have method update() in laravel controller.
I want to get values from request, which is better way:
method(Request $request) {
$request->inputName;
}
or
method() {
request('inputName');
}
Is it better to create request instance as method attribute or to use Laravel helper method request().
Thanks
Both are the same, the first approach might be better in case you create a custom form request where you do the validation of the form. Other than that both provide the same thing.
In your Controller
use Illuminate\Http\Request;
public function update(Request $request)
{
$name = $request->input('name');
}
I think this is best way to use
method(Request $request) {
$request->inputName;
}
Even laravel documentation suggest this.
laravel provides you with methods to get values from the request
now I have request variable is $request, it is instance of Request
The better practice for accessing laravel request variables:
If GET method, you should use $request->get('variable_name')
If POST method, you should use $request->input('variable_name')
if you want check request has variable you can use $request->has('variable_name')
Good luck

Set Locale when using Auth::loginUsingId for phpunit

I have several languages in my Laravel 5.2 app. Each locale is stored in DB in th User Model. So, each time a user log, the locale must update.
Thing is in my Test, I use a lot Auth::loginUsingId, because I need to test function with differents user profiles.
So, I don't want to append to each of those calls with a App::setLocale(Auth::user->locale), nor extract it to a function.
Any Idea how should I do it???
What I did to address this problem is creating a middleware with
public function handle($request, Closure $next)
{
if ($user = Auth::user()) {
App::setLocale($user->locale);
}
return $next($request);
}
By handling all routes through this middleware, you can have the locale set automatically at each request.

middleware does not working laravel 5

I'm trying to use auth middleware within my controller at construct method with except argument and it does not working.
I created my controller with artisan command and its contains methods like create, edit, show, etc.
here is my construct:
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
if i visit some methods like edit and create when i'm not logged in middleware does not works and i can see the content. i also tried only instead of except, same result.
did you change Authenticate.php for auth middleware this function
public function handle($request, Closure $next)
{
}
I figure out that problem was with my addressing/
i had except index and show at my construct and i was trying to access the edit method with /controller/edit which is wrong, because controller assume the edit part as an index method argument, so i changed the url to /controller/1/edit and it's working.
it was my bad, cause i used Codeigniter for a long time, sometimes i still think that i'm working with Ci.

How to retrieve Route parameters in Controller __construct()

I'm trying to pull two parameters into my Controller's __construct() method, but I keep getting the following debug
Call to undefined method Illuminate\Routing\Router::parameters()
What I'm specifically trying to do is.
Pull the "portal" and "issue" parameters into my __construct and set the $currentPortal and $currentIssue variables in my class (protected variables)
Use those two protected vars when I please in different Controller actions
Down below you'll find my __construct() method
protected $portals, $issues, $currentPortal, $currentIssue;
public function __construct(\App\Entities\Portal $portals, \App\Entities\Issue $issues){
$this->portals = $portals;
$this->issues = $issues;
dd(\Route::parameters());
if($portal = \Route::getParameter('portal'))
$this->currentPortal = $this->portals->findBySlug($portal);
if($issue = \Route::getParameter('issue'))
$this->currentIssue = $this->issues->findByKey($issue);
}
As you can notice, I'm using dd() as a debug helper in order to see if the current Route parameters and being pulled.
There's no issue in the router.php definitions, as I have already tested them before trying to implement this handy "hack" to pull the current objects.
Any help in order to get the current Route params?
Thanks!
Oh yeah, I figured it out just after posting this question!
I'm leaving the answer in case anyone is having the same issue as I was..
You need to pull the current() route before appending any other requests, so in my case, I should've done
Route::current()->getParameter('MY PARAM NAME')
That should be it

Resources