laravel5.2,I create a UserRequest.php under Requests directory,but in controller,public function add(UserRequest $request) show error,but use public function add(Request $request) is normal.
UserRequest
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()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'user_sn' => 'required|unique',
'user_name' => 'required',
'email' => 'required|unique',
'password' => 'required',
];
}
}
UserController
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class UserController extends Controller
{
public function add(UserRequest $request)
{
if ($request->get('dosubmit')) {
$validator = Validator::make($request->all(), $request
->rules(), $request->messages());
if ($validator->fails()) {
return redirect('user/add')->withErrors($validator)
->withInput();
}
}
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', ['corporation_list' => $corporation_list, 'department_list' => $department_list]);
}
}
Route
Route::group(['middleware'],function (){
Route::any('user/add',['as'=>'user.add','uses'=>'UserController#add']);
});
There are usually 2 reasons you could be having this issue.
You've not added the use statement for the UserRequest.
At the top of your controller (above the class) add:
use App\Http\Requests\UserRequest
assuming that is the correct namespace.
You may need to run composer dump-autoload to make sure the class has been added to the autoloader.
Edit
Firstly, replace the add() method with the following methods:
public function create()
{
$corporation_list = DB::table('corporation')->get();
$department_list = DB::table('department')->get();
return view('user.add', compact('corporation_list', 'department_list'));
}
public function store(UserRequest $request)
{
// If you get to this point the validation will have passed
// Process the request
}
Then change your routes from:
Route::any('user/add',['as'=>'user.add','uses'=>'UserController#add'])
to:
Route::get('user/add', ['as' => 'user.add', 'uses' => 'UserController#create']);
Route::post('user/add', ['as' => 'user.store', 'uses' => 'UserController#store']);
Obviously, feel free to change the as in the Routes to whatever, they should unique though.
Lastly, I would suggest looking at Resource Controllers which is a RESTful approach.
The problem is that you have not identified UserController that you are using UserRequest file
use App\Http\Requests\UserRequest
It will solve the problem
Related
I'm a little bit confused to how I can store data in my api controller,
My json looks like this:
[
{ a: 1 },
{ a: 2 }
]
I have my rules
$rules = [
'*.a' => 'required',
];
I have my validation
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
$error = $validator->messages()->toJson();
return response($error, 200);
}
and now there's my "problem": I would like to make a cleaner code.
My old option was pass the request->all() to a variable , json decode the contenent and make a foreach cycle to store data as here:
foreach ($datas as $data) {
$data = new rawData([
'a' => $data->a,
]);
$newrawData->save();
}
can I do a cleaner thing?? and How?
You can put your validation logic in a custom form request validator.
First, create the validator
php artisan make:request ExampleRequest
You can find the newly created a new class in app/Http/Requests/ExampleRequest.php and you can add your rules as follows
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExampleRequest 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 [
'*.a' => 'required',
];
}
}
Now your controller method/action will not be executed unless the request passes the validation rules. you can use it in your controller method as follows:
In app/Http/Controllers/ExampleController.php
public function store(ExampleRequest $request)
{
// Your normal code.
}
that looks quite good. There is only one small thing I would have done differently. But it's a matter of taste.
foreach ($datas as $data) {
rawData::create($data->toArray());
}
And you can you use the request object directly to validate. or you implement an custom Request Object what you pass as parameter in your function.
$request->validate([
'*.a' => 'required',
]);
For form validation I made a Request class via php artisan make:request UpdatePlanRequest.
However after using the UpdatePlanRequest class in store the method isn't called anymore.
The UpdatePlanRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UpdatePlanRequest 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()
{ //TODO: CHECK IF THE PROTOTYPE IDS ARE OWNED BY THE USER (https://stackoverflow.com/questions/42662579/validate-an-array-of-integers/42693970)
return [
'start_date' => 'required|date',
'end_date' => 'required|date|after:start_date',
'name' => 'required|string'
];
}
}
The controller method:
use App\Http\Requests\UpdatePlanRequest;
public function store(UpdatePlanRequest $request)
{
//
dd('hello');
}
If the function header is store(Request $request) hello is shown, in that example it isn't.
The custom Request class is necessary to call $request->validated(); later for validation purposes according to the docs.
Is there a reason you have your Request class as being abstract? The default class that is created when running php artisan make:request <name> doesn't define the class as being abstract. This seems to work for me, but not when declaring it as abstract.
$request->validated(); is used to retrieve the validated inputs, so just by calling the UpdatePlanRequest it should validate the request
//Try This
use App\Http\Requests\UpdatePlanRequest;
public function store(UpdatePlanRequest $request)
{
$validatedData = $request->validated();
dd('$validatedData');
$profile = new Profile([
'user_id' => $request->get('user_id'),
]);
$profile->save();
echo $request->session()->flash('alert-success', 'Profile details Succefully Added!');
return redirect('create')->with('success', 'Data saved!');
}
Your route will be.
Route::get('profile','ProfileController#store');
Route::post('profile/create','ProfileController#store')->name('create');
Well this works right!
When the method is called, it checks the request class (UpdatePlanRequest). If there is an error, it does not enter the method anymore and you can not see the output of dd() function.
If the data is correct after checking the rules, then dd() will be displayed.
You must manage errors
When we use Laravel Form Requests in our controllers and the validation fails then the Form Request will redirect back with the errors variable.
How can I disable the redirection and return a custom error response when the data is invalid?
I'll use form request to GET|POST|PUT requests type.
I tried the Validator class to fix my problem but I must use Form Requests.
$validator = \Validator::make($request->all(), [
'type' => "required|in:" . implode(',', $postTypes)
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()]);
}
Creating custom FormRequest class is the way to go.
namespace App\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\HttpResponseException;
class FormRequest extends \Illuminate\Foundation\Http\FormRequest
{
protected function failedValidation(Validator $validator)
{
if ($this->expectsJson()) {
$errors = (new ValidationException($validator))->errors();
throw new HttpResponseException(
response()->json(['data' => $errors], 422)
);
}
parent::failedValidation($validator);
}
}
Class is located in app/Http/Requests directory. Tested & works in Laravel 6.x.
This is the same but written differently:
protected function failedValidation(Validator $validator)
{
$errors = (new ValidationException($validator))->errors();
throw new HttpResponseException(
response()->json([
'message' => "",
'errors' => $errors
], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)
);
}
Base class FormRequest has method failedValidation. Try to override it in your FormRequest descendant
use Illuminate\Contracts\Validation\Validator;
class SomeRequest extends FormRequest
{
...
public function failedValidation(Validator $validator)
{
// do your stuff
}
}
use this on function
dont forget to take on top // use App\Http\Requests\SomeRequest;
$validatedData = $request->validated();
\App\Validator::create($validatedData);
create request php artisan make:request SomeRequest
ex.
use Illuminate\Contracts\Validation\Validator;
class SomeRequest extends FormRequest
{
public function rules()
{
return [
'health_id' => 'required',
'health' => 'required',
];
}
}
I am Having the issue of not getting token in postman as well as the following problem
ReflectionException
…\vendor\laravel\framework\src\Illuminate\Container\Container.php790
user controller does not exist
my route file;
Route::post('login', 'API\UserController#login');
Route::post('register', 'API\UserController#register');
Route::group(['middleware' => 'auth:api'], function(){
Route::post('details', 'API\UserController#details');
});
My controller file;
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;
use Illuminate\Http\Request;
class UserController extends Controller {
//
public $successStatus = 200;
/**
* login api
*
* #return \Illuminate\Http\Response
*/
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')-> accessToken;
return response()->json(['success' => $success], $this-> successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
/**
* Register api
*
* #return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]); if ($validator->fails()) {
return response()->json(['error'=>$validator->errors()], 401);
} $input = $request->all();
$input['password'] = bcrypt($input['password']);
$user = User::create($input);
$success['token'] = $user->createToken('MyApp')-> accessToken;
$success['name'] = $user->name; return response()->json(['success'=>$success], $this-> successStatus);
}
/**
* details api
*
* #return \Illuminate\Http\Response
*/
public function details()
{
$user = Auth::user();
return response()->json(['success' => $user], $this-> successStatus);
}
}
How can I Solve this?
If your controller path is /App/Http/Controllers/API, you need to adjust it's namespace :
namespace App\Http\Controllers\API;
If your controller path is /App/Http/Controllers, you need to adjust your routes:
Route::post('login', 'UserController#login');
simply just write folder extension in namespace
for example in your case
namespace App\Http\Controllers\API;
And in route you just write
Route::post('register','api\UserController#register');
It could be because you are not calling the right middleware on the user route that directs to that controller. You would have to create a user middleware.
You can do this by navigating to your App\Http\Middleware and add the user middleware with the name UserMiddleware.php and some code to it.
Firstly, you would need to import the following files;
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
Then you create a class called; class UserMiddleware
Add a handle function to it like so; public function handle($request, Closure $next)
Inside this function include the following code;
if (Auth::user()->usertype == 'user')
{
return $next($request);
}
Next up, head over to you App\Http\Kernel.php and add the following code at the bottom of the protected $routeMiddleware section;
'user' => \App\Http\Middleware\UserMiddleware::class,
Then go over to your route (API) and include this predefined user middleware to your URLs.
Route::group(['middleware' => 'user'], function () {
Route::post('login', 'API\UserController#login');
Route::post('register', 'API\UserController#register');
Route::post('details', 'API\UserController#details');
});
});
For this to work you would need to have a usertype field in your users table that is set to user by default. Your usertype column should look like this;
$table->string('usertype')->nullable()->default('user');
1. Copy the existing functions of your controller and delete it.
2. Recreate your controller but this time specifying the location of were you want to place it, in the Controllers directory. e.g.
php artisan make:controller NameOfYourSubFolder\YourControllersName
3. Paste you functions.
Laravel has web route and API route, with different namespace/path configuration, where the issue such as "Class App\Http\Controllers\API\UserController does not exist" comes from.
Web route:
in controller:
<?php
namespace App\Http\Controllers;
use Auth;
use App\Application;
use Illuminate\Http\Request;
class HomeController extends Controller
{
in web.php route file:
Route::get('/home', 'HomeController#index')->name('home');
API route:
in controller:
the namespace should be App\Http\Controllers\API if you put your API controllers in \API path.
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class CartController extends Controller
{
in api.php route file, add API\ to the controller path.
Route::get('/carts', 'API\CartController#index');
I have used Laravel Authentication (Quickstart). But I need to check the status of the user (approved/pending). If not approved, then an error will be shown in the login page. I need to know in which file I have to make the change and what is the change. Currently I am working on Laravel 5.3.
You can create a Laravel Middleware check the link for additional info
php artisan make:middleware CheckStatus
modify your middleware to get
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CheckStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
//If the status is not approved redirect to login
if(Auth::check() && Auth::user()->status_field != 'approved'){
Auth::logout();
return redirect('/login')->with('erro_login', 'Your error text');
}
return $response;
}
}
then add your middleware to your Kernel.php
'checkstatus' => \App\Http\Middleware\CheckStatus::class,
and finally add the middleware to your route
Route::post('/login', [
'uses' => 'Auth\AuthController#login',
'middleware' => 'checkstatus',
]);
I hope it helps
I found a simple solution for this. Artisan create App\Http\Controllers\Auth\LoginController, in this default controller just add this code if you have some conditions to login, for example I have a field state, you posibbly have status, email_status or other.
// Custom code for Auth process
protected function credentials( Request $request )
{
$credentials = $request->only($this->username(), 'password');
$credentials['state'] = 1;
return $credentials;
}
upper answer saves me
if (Auth::attempt(['email'=>$input['email'],'password'=>$input['password'], 'user_status'=>1 ]))
this will check the status
Just Add following method in my LoginController works like charm
protected function authenticated(Request $request, $user)
{
if ($user->yourFirldName != "Active") {
Auth::logout();
return redirect('/login')->with('error', 'Looks Like Your status is InActive');
}
}
I don't agree with upper answer, which will lead to your application performance is very low, and also don't recommend to modify the Laravel's source code.
So you can rewrite getCredentials function to your app\Http\Controllers\Auth\AuthController.php file like this:
<?php
//app\Http\Controllers\Auth\AuthController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
//you need add this function
protected function getCredentials(Request $request)
{
$data = $request->only($this->loginUsername(), 'password');
$data['is_approved'] = 1;
return $data;
}
}
then you can use Laravel Authentication (Quickstart) directly.
Hope this will help.
The pinned answer is the best approach.
Just a note: if you are using Laravel 5.8+ you need use:
//Default Auth routes
Auth::routes();
//Override and add middleware
Route::post('/login', [
'uses' => 'Auth\LoginController#login',
'middleware' => 'checkstatus',
]);
Follow the steps...
First add a column in your user table (suppose is_approved)
In App/Http/Controllers/Auth/LoginController file
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password, 'is_approved'=>1])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
Hope this will help
Auth/LoginController
Though it is a long time from the question created date. You can go this way.
Go to Auth/LoginController and add this line.
protected function credentials(Request $request)
{
return [
'email' => $request->email,
'password' => $request->password,
'status' => 1,
];
}
For this to work you have to have a column named 'status' in users table. 1 is for active and 0/2 is for inactive user.
Hope this will work for you.
public function login(Request $request){
if ($request->isMethod('post')) {
$data= $request->all();
$roles=[
'email' => 'required|email|max:255',
'password' => 'required',
];
$customessage=[
'email.required' =>'Email is required',
'email.email' => 'Email is not vaild',
'password.required' => 'Password is required',
];
$this->validate($request,$roles,$customessage);
if(Auth::guard('admin')->attempt(['email'=>$data['email'],'password'=>$data['password'],'status'=>1])) {
return redirect('admin/dashboard');
} else {
Session::flash('error_message','You are not Active by Admin');
return redirect()->back();
}
}
return view('admin.admin_login');
}