$request-merge() disappears in parent controller - laravel

I'm stuck on a weird issue...
I have a simple middleware.
$request->merge([
'user' => $jwt->toArray(),
'app_version' => $request->header('app-version')
]);
When I do a dump right before the $next($request); the it has the user object and the app_version. All good! See image below:
Moving to the controller. When in the function of defined in the route, and doing a dump($request); it has the user Object
The InstallController extends the controller.php which extends the use Illuminate\Routing\Controller as BaseController;
In the controller.php we have a construct function.
For some reason here the $request is empty and lost the object.
Why is this happening? And why is this available in the InstallController but not in the parent?

What turned out is the following. In Laravel lumen, controller constructors are called after the middleware has completed the request. In Laravel the constructors are called before the middleware.
Meaning that adding params to the request in the middleware in Laravel doesn't work.
Thanks for pointing me in the right direction.

Related

Cant get Auth::user() inside resource

I'm trying to get Auth::user() inside resource, but it returns null.
public function toArray($request)
{
return [
'test' => Auth::user(),
];
}
Please be more precise. Is this resource inside the api.php or inside the web.php? It is important since API is stateless; it is normal to return null if you are trying to access the user inside a route from the api.php and if you are not assigning the auth:api middleware to that route.
If the resource is inside the api.php, it should look like this:
Route::get('/something', 'Api\SomethingController#toArray')->middleware('auth:api');
Otherwise, if it's in web.php and you still don't get the user, try to inspect the browser cookies/sessions and make sure that after you're logged you see that in the storage.

laravel Controller error when using Request in function

I make controller by using php artisan make:controller newsController --resource
And after that when I go to my controller in function index, I want to add Request $request
public function index(Request $request)
{
}
It's return error:
Declaration of
App\Http\Controllers\Admin\NewsController::index(Illuminate\Http\Request
$request) should be compatible with
App\Http\Controllers\Controller::index()
How to fix it? I try many way but it still didn't work!
EDIT — Controller
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
UPDATED — Routes
Route::post('admin/news', 'Admin\NewsController#store');
Route::resource('admin/news', 'Admin\NewsController');
It's quite simple, just create your Resource controller without the index route Or Create new get route, like this:
Route::resource('admin/news', 'Admin\NewsController', ['except' => ['index']]);
Then add your route before the resource declaration, something like this:
Route::post('admin/news', 'Admin\NewsController#index');
Route::resource('admin/news', 'Admin\NewsController', ['except' => ['index']]);
Hope this helps you!!
This doesn't require any Laravel work arounds.
Fix:
a) Remove the index method from the base controller
or
b) Make the index method in the base controller take a Illuminate\Http\Request as an argument and use that same method signature in every controller's index method that inherited from the base in the entire application.
or
c) Figure out why there is an index method defined in the base in the first place and, if needed, move it to a trait to use in child classes instead. (allows you to override the method completely)
b is not a good option, it is just to illustrate a point
Issue demonstrated:
class Foo
{
public function index()
{
//
}
}
class Bar extends Foo
{
public function index(\Illuminate\Http\Request $request)
{
}
}
Declaration of Bar::index(Illuminate\Http\Request $request) should be compatible with Foo::index()
You want to override the index action.
You also want to pass parameters into this index action.
The App\Http\Controllers\Controller::index() does not take parameters.
So they are not "compatible".
Try this "helper-funtion" way:
public function index() {
$request = request() // use the helper function
// ...you code here...
}
You can disable index from resources and define route with different method name before or after resource:
Route::get('resources', 'ResourceController#getResources');
Route::resource('resources', 'ResourceController', $restResource)->except(['index']);

Passing two models to the Authorize middleware (also called can)

I am trying to pass two models to the Authorize middleware, used under the name can.
routes/api.php
Route::middleware('can:reach,profile,photo')->resource('users/{user}/profiles/{profile}/photos', 'PhotoController');
Then I try to retrieve arguments like so:
app/Policies/PhotoPolicy.php
public function reach(User $user, Profile $profile, Photo $photo)
{
return $profile->id === $photo->profile->id;
}
But the middleware is totally ignored. I checked the definition of the middleware and I cannot see why this would not work.
Thanks in advance.
I think you have to add the middleware to the resource, not the opposite. Or, you can create a group.
Example:
Route::group(['middleware' => 'can:reach,profile,photo'], function($router){
$router->resource('users/{user}/profiles/{profile}/photos', 'PhotoController');
});

How to bind a model to resource store method in Laravel 5.3

I am trying to assign a Product model for store route which is made by Route::resource method
public function store(Request $request, Product $product)
I already worked with Route Model Binding a little, and it works very nice with
public function show(Product $product)
But I can't force a store method to use Product model.
Ok, since somebody marked this question as favourite I will explain what I did to make it work
This is how we declare our routes, we need to place out specific route before Route::resource call
Route::post('foo/{baz}', [
'as' => 'foo.store',
'uses' => 'FooController#store']
);
Route::resource('foo', 'FooController');
Our Foo controller store method:
public function store(Baz $baz, Request $request){
}
The $baz variable is just passed after url slash in form action url. it can be like that
<form action="foo/5">
Keep in mind that "foo&baz=5" won't work
For some reason I didn't have to, or at least didn't try to bind a Foo model with controller - it just works.
The order of routes and parameters in controller method if important for PHP reflection

Bind middleware to controller in laravel 5

I want to use middleware in my controller , but I don't know route beforehand, as I take slug from my DB.
Is it possible in laravel 5?
Thank you in advance
Inside your controller's constructor, do the following:
public function __construct()
{
//This will apply to every method inside the controller
$this->middleware('auth');
//This will apply only to the methods listed inside the array
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
//This will apply only to the methods except the ones listed inside the array
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
You can read about that here

Resources