laravel validation does not work with Auth [closed] - laravel

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to add validation in the controller but it does not work with auth:check. This is the Laravel version 5.7.
This is the function store that has a problem with the validation.
public function store(Request $request)
{
$request->validate([
'first_name' => ['required'|'min:2'|'max:50']
]);
if(Auth::check()){
$player = Player::create([
'first_name' => $request->input('fist_name'),
'last_name' => $request->input('last_name'),
]);
if($player){
return redirect()->route('players.show', ['player'=> $player->id])
->with('success' , 'foo');
}
}
return back()->withInput()->with('errors', 'Foo Error');
}
This is the error message:
[![enter image description here][2]][2]
Update
The validation works now but it generated a new problem. When I save a new player it's shows me this error.
I think the problem is this code
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ $player->first_name }} {{ $player->last_name }} <span class="float-right"><a class="" href="{{ route('players.edit', $player->id)}}">
{{ __('Spieler bearbeiten') }}
</a></span></div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
<ul>
<li>Vorname: {{ $player->first_name }}</li>
<li>Nachname: {{ $player->last_name }}</li>
<li>Land: {{ $player->country }}</li>
<li>Bild: {{ $player->image }}</li>
<li>Grösse: {{ $player->size }}</li>
<li>Gewicht: {{ $player->weight }}</li>
<li>Alter: {{ $player->date_of_birth }}</li>
</ul>
<br>
<br>
Zurück
</div>
</div>
</div>
</div>
</div>
#endsection

Most of your code is unnecessary, you can protect the route and get rid of most of it:
public function store(Request $request)
{
// Your validation is not correct and you are missing the last_name.
// $request->validate() will return the validated data if
// the validation was successful
$request->validate([
'first_name' => ['required' | 'min:2' | 'max:50']
]);
// After protecting the route we can get rid of the auth check
if (Auth::check()) {
$player = Player::create([
// Since $request->validate returns the validated data, this is unncessary
'first_name' => $request->input('fist_name'),
'last_name' => $request->input('last_name'),
]);
// It will either create the player or throw an exception,
// this conditional seems unnecessary
if ($player) {
return redirect()
// If you setup your routes correctly you can pass the model to the route
// so ['player' => $player->id] is unnecessary
->route('players.show', ['player' => $player->id])
->with('success', 'foo');
}
}
// This return seems pointless since it can never be reached
// after protecting the route
return back()->withInput()->with('errors', 'Foo Error');
}
So it would look something like this:
public function __construct()
{
$this->middleware('auth');
}
/**
* #param Request $request
*
* #return RedirectResponse
*/
public function store(Request $request)
{
$validatedData = $request->validate([
'first_name' => 'required|min:2|max:50',
'last_name' => 'required|min:2|max:50',
]);
$player = Player::create($validatedData);
return redirect()
->route('players.show', $player)
->with('success', 'foo');
}

Related

Laravel 5.8: Validation multiple inputs

What I have
I have a form with 3 inputs and I want to check the following conditions:
All inputs are integers and they are required.
We do a math operation with all the numbers and we get if the operation was successfull or not.
Success: we redirect the user to a success page.
No success: we show a error message to the user with a message explaining him that the numbers aren't valid.
I resolved this with the following lines.
Controller:
function formAction(Request $request) {
$this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if($isValid) {
return redirect()->route('success');
} else {
$request->session()->flash('error', 'The numbers are not valid.');
return back();
}
}
View (using Bootstrap):
<form method="POST" action="{{ route('form-action') }}">
#csrf
<div class="form-group">
<label for="number1">number1</label>
<input id="number1" name="number1" class="form-control {{ $errors->has('number1') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number2">number2</label>
<input id="number2" name="number2" class="form-control {{ $errors->has('number2') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number3">number3</label>
<input id="number3" name="number3" class="form-control {{ $errors->has('number3') ? ' is-invalid' : '' }}" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
What I looking for
When MyOwnClass::checkMathOperation($numbers) is false:
To highlight number1, number2 and number3 inputs.
To show an unique custom error message
To hide the number1, number2 and number3 input error messages.
How can I do that with validators?
Solution
Create a Form Request Validation called, for example, NumbersForm using:
php artisan make:request NumbersForm
The previous command creates a App/Http/Requests/NumbersForm.php file. Make authorize() returns true, put the validation rules into rules() and create a withValidatior() function.
class NumbersForm extends FormRequest
{
public function authorize() {
return true;
}
public function rules() {
return [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
];
}
public function withValidator($validator) {
$validator->after(function ($validator) {
$numbers = $this->except('_token'); // Get all inputs except '_token'
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', ' ');
$validator->errors()->add('number2', ' ');
$validator->errors()->add('number3', ' ');
$validator->errors()->add('globalError', 'The numbers are not valid.');
}
});
}
}
Note: It's not important the text in the second param of $validator->errors()->add('number1', ' ');, but it can't be empty. If it is an empty string, $errors->has('number1') returns false, and the field won't be hightlighted.
Set the controller like this:
use App\Http\Requests\NumbersForm;
function formAction(NumbersForm $request) {
$this->validated();
return redirect()->route('success');
}
And, finally, if we want to print an unique error message, we must remove the following lines from view:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
and replace them with:
#if ($errors->has('globalError'))
<div class="alert alert-danger">
{{ $errors->first('globalError') }}
</div>
#else
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#endif
I haven't tested this but I think it can get you going in the right direction.
1 // Highlight the inputs
You can do this by accessing the error object within your view. This object is an instance of the MessageBag object.
Here is the docs: https://laravel.com/docs/5.7/validation#working-with-error-messages
Example:
// if the error exists for the input the class will be added
<input class=" {{ $error->has('number1') ? 'highlight' : '' }}" name="number1">
<input class=" {{ $error->has('number2') ? 'highlight' : '' }}" name="number2">
<input class=" {{ $error->has('number3') ? 'highlight' : '' }}" name="number3">
2 & 3 // Show a unique custom error message and hide the default messages
See the validator docs: https://laravel.com/docs/5.8/validation#custom-error-messages && https://laravel.com/docs/5.7/validation#working-with-error-messages -- this should solve both of these.
There is a validator callback and I think you can pass your second validation into that. If these numbers aren't valid then you can add your custom error messages and access them the same way as I did above.
function formAction(Request $request) {
$validator = $this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$validator->after(function ($validator) {
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', 'Unique message');
$validator->errors()->add('number2', 'Unique message');
$validator->errors()->add('number3', 'Unique message');
}
});
}
Custom Validation Rules:
To add custom messages and validation you can also write a custom validation rule
Example:
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Custom Error Messages:
You could also add custom error messages for rules within a Request:
public function messages()
{
return [
'number1.required' => 'My custom message telling the user he needs to fill in the number1 field.',
'number1.integer' => 'My custom message telling the user he needs to use an integer.',
];
}

Laravel post error

I'm getting the following error message when trying to update user data:
protected function methodNotAllowed(array $others)
{
throw new MethodNotAllowedHttpException($others);
}
I'm logging the user in, then want to give them the option to change their preferences. The form displays fine in the view but won't post.
Here are my routes:
Route::prefix('admin')->group(function(){
Route::get('/login', 'Auth\AdminLoginController#showLoginForm')->name('admin.login');
Route::post('/login', 'Auth\AdminLoginController#login')->name('admin.login.submit');
Route::get('/', 'AdminsController#index')->name('admin.dashboard');
Route::post('/', 'AdminsController#update')->name('admin.dashboard.update');
Route::get('/logout', 'Auth\AdminLoginController#logout')->name('admin.logout');
Here's the Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Admin;
use Auth;
class AdminsController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth:admin');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$id = Auth::user()->id;
$admin = Admin::find($id);
return view('admin')->with('admin',$admin);
}
public function update(Request $request, $id)
{
$this-> validate($request, [
'target_sector' => 'required|max:255',
'target_skillsets' => 'required|max:255',
'target_companies'=> 'required|max:255',
'target_locations'=> 'required|max:255',
]);
//Create Post
$id = Auth::user()->id;
$admin = Admin::find($id);
$admin->target_sector = $request->input('target_sector');
$admin->target_skillsets = $request->input('target_skillsets');
$admin->target_companies = $request->input('target_companies');
$admin->target_locations = $request->input('target_locations');
$admin->save();
return redirect('/admin')->with('success', 'Preferences Updated', 'admin',$admin);
}
}
And here is the view:
#include('includes.nav_login')
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row mt-4">
<div class="col-md-10 offset-md-1">
<div class="card">
<div class="card-header">Admin Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif
You are logged in as ADMIN!
</div>
<div class="card-header">Update Vacancy Preferences</div>
<div class="card-body">
{!! Form::open(['action' => ['AdminsController#update', $admin], 'method' => 'POST']) !!}
<div class="form-group">
{{Form::label('companies', 'Companies')}}
{{Form::text('companies', $admin->target_companies,['class'=>'form-control', 'placeholder'=>'Target Companies'])}}
</div>
<div class="form-group">
{{Form::label('skillsets', 'Skillsets')}}
{{Form::text('skillsets', $admin->target_skillsets,['class'=>'form-control', 'placeholder'=>'Skillsets'])}}
</div>
<div class="form-group">
{{Form::label('sector', 'Sector')}}
{{Form::text('sector', $admin->target_sector,['class'=>'form-control', 'placeholder'=>'Sector'])}}
</div>
<div class="form-group">
{{Form::label('locations', 'Locations')}}
{{Form::text('locations', $admin->target_locations,['class'=>'form-control', 'placeholder'=>'Locations'])}}
</div>
{{Form::hidden('_method', 'PUT')}}
{{Form::submit('Update',['class'=>'btn btn-primary'])}}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
#endsection
Can anyone explain why this isn't working?
You should fix you route, because you are using put method for update, but on routes, you defined as post
Route::post('/', 'AdminsController#update')->name('admin.dashboard.update');
Therefore error occurs.
You should fix your route like this,
Route::put('/{id}', 'AdminsController#update')->name('admin.dashboard.update');
I hope this help you.
The error says MethodNotAllowed which means you are hitting a route with a different request method than it accepts
you open the form like this
{!! Form::open(['action' => ['AdminsController#update', $admin], 'method' => 'POST']) !!}
so till now the form method is POST
but then you spoof the method to be of type put
{{Form::hidden('_method', 'PUT')}}
so now the method becomes of type put not post
however your route expects the method to be post
Route::post('/', 'AdminsController#update')->name('admin.dashboard.update');
This is why you get method not allowed exception
you either change the method on your controller to be put instead of post or remove the method spoofing thing from inside your form
I mean this line
//remove this
{{Form::hidden('_method', 'PUT')}}
once you fix it you will have another error because you don't have csrf field in your form so just add this inside of your form
#csrf
Really appreciate both answers on here - thanks #Mohammad Instanboli and #webdevtr.
Webdevtr was right to advise this:
Route::put('/{id}', 'AdminsController#update')->name('admin.dashboard.update');
I also had to go back and fix the following which I thought would be useful to note if anyone else views this with a similar issue:
Firstly my AdminsController#update method needed the following changes:
I changed the public function update to take one less variable - ($id)
public function update(Request $request)
{
$this-> validate($request, [
'target_sector' => 'required|max:255',
'target_skillsets' => 'required|max:255',
'target_companies'=> 'required|max:255',
'target_locations'=> 'required|max:255',
]);
//Create Post
$id = Auth::user()->id;
$admin = Admin::find($id);
$admin->target_sector = $request->input('target_sector');
$admin->target_skillsets = $request->input('target_skillsets');
$admin->target_companies = $request->input('target_companies');
$admin->target_locations = $request->input('target_locations');
$admin->save();
return redirect('/admin')->with('success', 'Preferences Updated', 'admin',$admin);
}
Then I needed to make sure the $request->input('x') matched the input names in the form in my view - i.e:
<div class="form-group">
{{Form::label('target_sector', 'target_sector')}}
{{Form::text('target_sector', $admin->target_sector,['class'=>'form-control', 'placeholder'=>'Sector'])}}
</div>

Laravel validation not working after submit

This did not show the errors after submit
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Cars;
use App\Images;
use DB;
$this->validate($request,[
'name'=>'required|min:3',
'specifications'=>'required|min:10'
]);
Inserting values into the database.I want to validate on submitting the form
public function store(Request $request)
{
//
$this->validate($request->all(),[
'name'=>'required|min:3',
'specifications'=>'required|min:10'
]);
$cars = New Cars;
$cars->name = $request->name;
$cars->specifications = $request->specifications;
$cars->price = $request->price;
$cars->model_id = $request->model_id;
$cars->year = $request->year;
$cars->milage = $request->milage;
if($cars->save()) {
$id = DB::getPdo()->lastInsertId();
}
return redirect('home');
}
I displayed errors like this, but not working for me
#if(count($errors) > 0)
<div class="alert alert-danger">
#foreach($errors->all() as $error)
<p>{{ $error }}</p>
#endforeach
</div>
#endif
Add this piece of code on your controller method.
return back()->withErrors()->withInput()
you can also access old input value with old(field_name)
Use ->all() here to provide all input value in to validate
$this->validate($request->all(),[
Or you can try like this
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
}
And display error as
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
first, edit your method like this :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Cars;
use App\Images;
use DB;
use Validator;
and inside this method please edit your redirect route and make sure your redirect url, redirect you in the page that had the error message:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name'=>'required|min:3',
'specifications'=>'required|min:10'
]);
if ($validator->fails()) {
return redirect(route('make your route here '))
->withErrors($validator)
->withInput();
}
$cars = New Cars;
$cars->name = $request->name;
$cars->specifications = $request->specifications;
$cars->price = $request->price;
$cars->model_id = $request->model_id;
$cars->year = $request->year;
$cars->milage = $request->milage;
if($cars->save()) {
$id = DB::getPdo()->lastInsertId();
}
return redirect('home');
}
and for displaying error messages inside your blade template make this :
#if(!empty($errors))
#if($errors->any())
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{!! $error !!}</li>
#endforeach
</ul>
</div>
#endif
#endif

laravel pass validation error to custom view

I created a validation but cant show it on view, its important to return search view and don't redirect back user. help me please, thanks all?
Controller :
public function search(Request $request)
{
$msg = Validator::make($request->all(), [
'search' => 'required'
]);
if ($msg->fails()) {
return view('layouts.search')->withErrors($msg->messages());
} else {
return "Thank you!";
}
}
View :
#if($errors->any())
<ul class="alert alert-danger">
#foreach($errors as $error)
<li> {{$error}} </li>
#endforeach
</ul>
#else
You can use $error->first('name_of_error_field') to show error messages.
You can do it like this:
public function search(Request $request)
{
$validator = Validator::make($request->all(), [
'search' => 'required'
]);
if ($validator->fails()) {
return view('layouts.search')->withErrors($validator); // <----- Send the validator here
} else {
return "Thank you!";
}
}
And in view:
#if($errors->any())
<ul class="alert alert-danger">
#foreach($errors as $error)
<li> {{$error->first('name_of_error_field')}} </li>
#endforeach
</ul>
#endif
See more about Laravel Custom Validators
Hope this helps

Laravel 5 Pass and get a flash data not working

i want to pass a flash data from store function to add function but i cant get it to work, i always get null;
here is my controller
public function add()
{
return view('cars.add');
}
public function store(CarFormRequest $request)
{
$car = new Cars(array(
'name' => $request->get('name'),
'color_id' => $request->get('color')
));
$car->save();
$car->position_id = $car->id;
$car->save();
return redirect('/cars/add')->with('status', 'A Car has been added');
}
here is my view:
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif
Add in your controller
session()->flash('status', 'Task was successful!');
and in View:
#if (session->has('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif

Resources