I'm getting an error using a request class called RolesRequest in my store function in my controller, I have my controller in an Admin folder under controllers. When I change the name just to RoleRequest I still get the same error and I don't know why, I have tried to do a composer dump-autoload but that doesn't help I still get the same error. I'm using laravel 5.5.4 I think
Error Message:
Class App\Http\Requests\RolesRequest does not exist", exception: "ReflectionException"
// Controller
<?php
namespace App\Http\Controllers\Admin;
use App\Role;
use App\Http\Controllers\Controller;
use App\Http\Requests\RolesRequest;
use Illuminate\Http\Request;
class RolesController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('admin.roles');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(RolesRequest $request)
{
dd('hit');
}
}
// RolesRequest Class
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RolesRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return Auth::user()->hasRole('Admin');
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
switch($this->method())
{
case 'GET':
case 'DELETE':
{
return [];
}
case 'POST':
{
$unique = [
'name' => 'required|min:3|max:30|unique:roles,name',
];
break;
}
case 'PUT':
case 'PATCH':
{
$unique = [
'name' => 'required|min:3|max:30|unique:roles,name,'. $this->id
];
break;
}
default:break;
}
$rules = [
'display_name' => 'required|min:4|max:50',
'description' => 'required|min:10|max:100'
]
return $unique + $rules;
}
}
This is one of those fun times when there is more than 1 error happening. You are seeing the second error.
The first error is the parser failing on a syntax error in the class you are trying to use. It is trying to load that file and fails so the file is never loaded, hence the class can not be found (the second error).
Its possible the error shown here is (2/2) in the error page. Check your error log to see if it is showing an error before your "class does not exist" error that you are seeing.
The RolesRequest file has a syntax error before the return. The array definition statement doesn't have a semicolon at the end.
Related
I have a problem with my laravel 9:
Call to undefined method App\Models\Country::id()
I use the Laravel framework version 9.x for programming.
This is my model code:
class Country extends Model
{
use HasApiTokens, HasFactory, Notifiable, HasRoles;
protected $table = 'countries';
protected $fillable = [
'name',
'code'
];
}
This is my controller code:
<?php
namespace App\Http\Controllers;
use App\Models\Country;
use Illuminate\Http\Request;
use App\Services\LogWriter;
use Spatie\Permission\Models\Role;
class CountryController extends Controller
{
...
/**
* Show the form for editing the specified resource.
*
* #param \App\Models\Country $country
* #return \Illuminate\Http\Response
*/
public function edit(Country $country)
{
return view('countries.edit', compact('country'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Models\Country $country
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Country $country)
{
$request->validate([
'name' => 'required|string|max:100',
'code' => 'required|string|max:2|unique:countries',
]);
$country->update($request->all());
message_set("Successful! Country information has been changed.", 'success', 5);
return redirect()->route('countries.index');
}
...
I dont know why I get this error and would be glad if I could get any help.
Lesson learned today, always check your error messages for the full information; assuming the problem was in the Controller can be right in a lot of cases, but Laravel's errors can also be triggered in a .blade.php view.
The problem was in the view edit.blade.php
"Check if you're calling ->id() in there"
I'm facing a problem with custom request. I have created a request with php artisan make:request StoreNewClient.
I have configured the validations logic inside the new request file, like:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreNewClient extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [ ...
];
}
/**
* Get the error messages for the defined validation rules.
*
* #return array
*/
public function messages()
{
return [ ...
];
}
}
In the controller, I imported the file like use App\Http\Requests\StoreNewClient; and after, In the function store() I writed:
public function store(StoreNewClient $request)
{
// Will return only validated data
$validated = $request->validated();
...
}
That what I understood from the documentation, but this give me an error: Class App\Http\Requests\StoreNewClient does not exist but exists (!!).
I already tried to clear caches and dumped the composer but didn't solved the problem. Any help?
Fount the error. In the messages(), 1 line didn't had the comma at the end and neither the app neither the composer dump-autoload, gave any error.
I'm am new to laravel and i am trying to get my custom validation rules to work on my controller.
It's showing that the class does not exist.
ReflectionException thrown with message "Class App\Http\Controllers\StoreBooksRequest does not exist"
I made the request file using the artisan command.
lando artisan make:request StoreBooksRequest
this is my request file :
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreBooksRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
//
'title' => 'required|unique:books|max:150',
'description' => 'required',
'isbn' => 'required|max:20'
];
}
}
and this is the controller where i am trying to get the custom request rules to work :
namespace App\Http\Controllers;
use App\Book;
use Illuminate\Http\Request;
class BooksController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
$books = Book::all();
return view('books.index', compact('books'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('books.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(StoreBooksRequest $request)
{
$book = new Book();
$book->title = $request->title;
$book->description = $request->description;
$book->isbn = $request->isbn;
$book->save();
}
I think the problem is with the error saying that the request file is in the Controllers folder and not in the standard Requests folder.
You have not included the namespace of your custom request's class. Add use App\Http\Requests\StoreBooksRequest; after use Illuminate\Http\Request;
You seem to be using wrong namespace for your
Class App\Http\Controllers\StoreBooksRequest
Your namespace is set to namespace App\Http\Requests; while you are calling it from controller, If you move your Class to App\Http\Requests.
Also, don't forget to import the class in your controller
use StoreBooksRequest
When you execute the php artisan make:request Myrequestname, Laravel create the file inside the App\Http\Request subdirectory, so you need to be careful to use the right namespace, another thing you always had to be carefull is about the name you use, is not the same Mycontroller than mycontroller and is worst if your server is a Linux server, because the file system make differentiation beewteen Caps.
I am getting a very unfriendly field name in my validation errors similar to the array notation used as name for the field's rules
EG.
$rules = [
'resource.*.name' => 'required|string|max:16'
];
// error message.
// the resource.0.name is required.
How do I rename the resource.0.name in the message to something else like name or resource name.
For more convenience you may use laravels form request validation,
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class Resource extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'resource.*.name' => 'required|string|max:16'
];
}
public function messages()
{
return [
'resource.*.name' => 'The Resouce Name must match the criteria'
];
}
}
In your controller:
use App\Http\Requests\Resource;
public function store(Resource $request)
{
}
I am writing the below code in Request Class for Validation and Authorization. So the Below code is for add/Update record.
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRequest extends Request
{
public function authorize()
{
return \Auth::user()->isAdmin();
}
public function rules()
{
return [
'UserName' => 'required|max:50|min:3|unique:tbluser,UserName,' .
\Request::get( 'UserID' ) . ',UserID',
];
}
}
My question is: Should I write the code to check if the current user is authorized or not to delete the record. For that should I use same Request class that is used for Add/Update or an another class specially for delete authentication? If I use same class then rules() will be executed which are meant for add/update
What I would do is the following:
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
switch ($this->method()) {
// Show single record or multiple records
case 'GET':
default:
return true;
break;
// Change a record
case 'POST':
case 'PUT':
case 'PATCH':
case 'DELETE':
if(\Auth::user()->isAdmin()) {
return true;
}
return false;
break;
}
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
switch ($this->method()) {
case 'GET':
case 'DELETE':
return [];
break;
case 'POST':
return [
'UserName' => 'required|max:50|min:3|unique:tbluser,UserName'
];
break;
case 'PUT':
case 'PATCH':
return [
'UserName' => 'required|max:50|min:3|unique:tbluser,UserName,' .
\Request::get( 'UserID' ) . ',UserID',
];
break;
default:
break;
}
}
}
The changes to your code is that in one single request file you can make rules and change the authorization based on what type of method was used. The default and get (to show a user or an index or something like that) does not need permission. For all the other methods (which change a record) the user must be an admin.
In my Laravel applications authorize() request method just returns true. I handle authorization in specific methods of base controller class:
namespace App\Http\Controllers;
use Auth;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function authorizeSameOwner($entity)
{
if (Auth::user()->is_admin) {
return;
}
$this->authorize("same-owner", $entity);
}
}
Controller's authorize() method is performing actual authorization using abilities defined in AuthServiceProvider. This is how it looks in my case:
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
];
/**
* Register any application authentication / authorization services.
*
* #param GateContract $gate
* #return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->define("same-owner", function ($user, $entity) {
if ($user->is_admin) {
return true;
}
if (method_exists($entity, "getOwnerId")) {
$ownerId = $entity->getOwnerId();
} else {
$ownerId = $entity->owner_id;
}
return $user->id === $ownerId;
});
$gate->define("same-user", function ($user, $entity) {
return $user->is_admin || $user->id === $entity->id;
});
}
}
And here is how the actual resource controller methods look like:
/**
* Update the specified resource in storage.
*
* #param StayRequest $request
* #param Stay $stay
* #return Response
*/
public function update(StayRequest $request, Stay $stay)
{
$this->authorizeSameOwner($stay);
$stay->update($request->all());
return redirect()->route("stays.index");
}
/**
* Remove the specified resource from storage.
*
* #param Stay $stay
* #return Response
*/
public function destroy(Stay $stay)
{
$this->authorizeSameOwner($stay);
$stay->delete();
return redirect()->route("stays.index");
}
I think this really depends on what you are really building. If you are making a small app which just have a few restricted areas, then you can easily handle this as you are doing.
However if your restricted area is big, I think you should make use of Laravel Policies which will offer much more control and stay much more organized in their own classes.
About how you should split your Request classes I think a class for any request verb is totally fine. Its very common you can use CreateUserRequest for create and update, however deletion may have different rules as checking the record really exists or checking your deletion validation checkbox is checked... Just create a different class for its rules.
If you think some of these actions can be authorized by the same rule (isAdmin in this case), you can also create an abstract AdminRequest which will handle this authorization. Again, if system is not complex at all.