Laravel validation does not work with many fields - laravel

I have a strange Laravel behaviour. If I validate my form with less than about 10 fields, everything works perfectly fine, including showing error messages (e.g. "field1 is required"):
public function myFctName(Request $request)
{
$validator = Validator::make($request->all(), [
'year' => 'required',
'field1' => 'required',
'field2' => 'required'
]);
if ($validator->fails()) {
return back()->withErrors($validator->errors())->withInput();
}
return view('companiesView');
}
My form has 23 fields. As soon as I add around 10 fields, everythings works fine if there are no validation errors. Here is the second examplecode:
public function myFctName(Request $request)
{
$validator = Validator::make($request->all(), [
'year' => 'required',
'field1' => 'required',
'field2' => 'required',
'field3' => 'required',
'field4' => 'required',
'field5' => 'required',
'field6' => 'required',
'field7' => 'required',
'field8' => 'required',
'field9' => 'required',
'field10' => 'required',
'field11' => 'required',
'field12' => 'required',
'field13' => 'required',
'field14' => 'required'
]);
if ($validator->fails()) {
return back()->withErrors($validator->errors())->withInput();
}
return view('companiesView');
}
If there is an validation error, the redirect (back()) still works. However, there is no error message displayed.
If I change the line return back()->withErrors($validator->errors())->withInput(); to return back()->withErrors($validator->errors());, the error messages are displayed. So the problem must be with the withInput() function.
Moreover, with the withInput() part in place, there is a warning in the Chrome console (not happening in Firefox though): Set Cookie header is ignored in response from url: ... Cookie length should be less than or equal to 4096 characters. I am not actively doing anything with Cookies at this point.
Does anyone know what the problem could be?

withInput() is using cookie/session under the hood to store the old values. Maybe those are flooding.
An alternate could be
$request->validate([
'year' => 'required',
]);
<input type="text" name="year" value="{{old('year')}}">
for displaying the errors
#if($errors->any())
#foreach($errors->all() as $error)
{{$error}}
#endforeach
#endif

The problem is with the session driver. It is probably set to cookie which can only store 4096 characters. Set it to file, database, or redis.
In .env
SESSION_DRIVER=cookie
to
SESSION_DRIVER=database

Related

how to exclude the first value of the option in a select

I have a little problem and i don't know how to fix it.
I have a select like this in my request
<select class="form-control" name="start_time" id="time">
<option>Aanvangstijd *</option>
<option value="11:00" id="time">11:00</option>
<option value="11:30" id="time">11:30</option>
<option value="12:00" id="time">12:00</option>
</select>
But the first option <option>Aanvangstijd *</option> should not pass the validation in my request, but it of course does because it has a value.
Here is my Request
public function rules()
{
return [
'name' => 'required',
'phone' => 'required',
'email' => 'required',
'msg' => 'required',
'start_time' => 'required',
'avg' => 'required',
];
}
So my question is, how can I get it to work that it only passes this validation when an option is passed that isn'tAanvangstijd *`
Laravel has great validation rules so you can be strict and specific about what is allowed in the input, including the date/time format. From what I see, you expect "start_time" input
to be required
to be string
of 5 characters
and to be valid time.
So, we can write just that:
public function rules()
{
return [
'name' => 'required',
'phone' => 'required',
'email' => 'required',
'msg' => 'required',
'start_time' => 'required|string|size:5|date_format:H:i',
'avg' => 'required',
];
}
Maybe you wish to limit the time range between 11:00 and 12:00, or, specifically:
to be equal or after 11:00
and to be equal or before 12:00
So you can add this rules on your validation:
'start_time' => 'required|string|size:5|date_format:H:i|after_or_equal:11:00|before_or_equal:12:00'
Additionaly you may wish to limit "start_time" to be only 11:00, 11:30 or 12:00:
'start_time' => 'required|string|size:5|date_format:H:i|after_or_equal:11:00|before_or_equal:12:00|in:11:00,11:30,12:00',
At the and we can increase our readability by using array syntax:
public
function rules()
{
return [
'name' => 'required',
'phone' => 'required',
'email' => 'required',
'msg' => 'required',
'start_time' => [
'required',
'string',
'size:5',
'date_format:H:i',
'after_or_equal:11:00',
'before_or_equal:12:00',
Rule::in(['11:00', '11:30', '12:00']),
],
'avg' => 'required',
];
}
And, one advice: TRUST NO ONE, NOT EVEN YOU! Even if you wrote frontend code and (you think) you are 100% sure you know what your html form will be sending your backend, please, use good, strict validation rules.

How can I use fails method validation in controller

controller validator in laravel :
$validationController = $this->validate(request(), [
'title' => 'min:100',
'text' => 'required',
'image' => 'required',
]);
and we can make validator with :
$validationNormaly = Validator::make(request(), [
'title' => 'min:100',
'text' => 'required',
'image' => 'required',
]);
and i can't use $validationController->fails(). how can i use it?
The first validation that you mentioned will fail automatically as designed by the laravel code base.
The Validator::make() i typically use when doing ajax requests and such to the controller method. You will need to run the validation fails method to invoke the failed response like so:
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
You Can Use :
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
take advantage of the automatic redirection with error messages

Laravel one validation function for Store and Update

I am trying to have one validation function for both store and update. So I don't repeat code. It works well. The problem is testing 'unique'. I worked around with this idea. But feels long-winded. Is there a better way to do it?
I want to check for unique at the store.
At update, unique check ignores own id.
I don't want different validations like I did as the user will be
first notified of the unique error, he will fix it. then something
else might be wrong and he has to fix again.
.
public function validateRequest($request){
if($request->method() == "PUT")
{
$val = $this->validate($request, [
'name' => 'unique:customers,id',
'phone' => 'unique:customers,id',
]);
}
if($request->method() == "POST"){
$val = $this->validate($request, [
'name' => 'unique:customers',
'phone' => 'unique:customers'
]);
}
$validation = $this->validate($request, [
'name' => 'required',
'phone' => 'required|integer|gt:0',
'phone2' => 'nullable|integer|gt:0|',
'email' => 'email|nullable',
'note' => 'nullable',
],
[
'phone.integer' => "Invalid phone format. Use international format. Eg: 971550000000",
'phone2.integer' => "Invalid phone format. Use international format. Eg: 971550000000",
'required' => "Required Field",
]);
return $validation;
}

Getting validation error messages on register page

I have a login page http://localhost/register the register method displays the register page. I am posting the data and validating it in this way
$rules = array(
'telephone' => 'required',
'theemail' => 'required',
'fullnames' => 'required',
'profilepicture' => 'required',
'password' => 'required',
'confirm-password' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
$messages = $validator->messages();
return Redirect::back()->withErrors($validator);
}
I used the method above to validate a form but when i try the above code, it seems not to validate. My last app was simplistic and the form names were also the column names in the database.
In my case, the array
$rules = array(
'telephone' => 'required',
'theemail' => 'required',
'fullnames' => 'required',
'profilepicture' => 'required',
'password' => 'required',
'confirm-password' => 'required'
);
does not contain names of columns. Must the rules contain the column names of the table i am writing to?.
Try something like this:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'telephone' => 'required',
'theemail' => 'required',
'fullnames' => 'required',
'profilepicture' => 'required',
'password' => 'required',
'confirm-password' => 'required'
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
// Store the blog post...
}
}
Be sure to match the column name in the $rule array with the other in the DB table, and if you mean the validation error doesn't appear, then you have to put this in the blade file which you want to show in.
#if(!empty($errors))
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
of course you have to add the needed classes

$this->validation custom redirect

I have a form with four tab so after validation it redirect me on first tab always, but i want it redirect me on that which have error message
Here is my code
$this->validate($request,
[
'name' => 'required|min:3|alpha_spaces',
'date_of_birth' => 'required|date|date_format:"Y-m-d"',
'place_of_birth' => 'required',
'nationality' => 'required',
'address' => 'required',
'port_name' => 'required',
'contact_number' => 'required|digits_between:8,15|numeric',
'religion' => 'required',
'education_level' => 'required',
'marital_status' => 'required',
'interview_method' => 'required',
'can_be_interviewed_via' => 'required',
'date_to' => 'required',
'date_from' => 'required',
'country' => 'required',
]);
and for redirect i m using on every tab i m using submit button with hidden filed selecttab
if ($data['selecttab'] == 'tab0') {
return redirect("fdws/".$id."/edit?tab=tab0");
}elseif($data['selecttab'] == 'tab1'){
return redirect("fdws/".$id."/edit?tab=tab1");
}elseif($data['selecttab'] == 'tab2'){
return redirect("fdws/".$id."/edit?tab=tab2");
}else{
return redirect("fdws/".$id."/edit?tab=tab3");
}
When no validation apply it work fine
Before you call your `$this->validate($request, ...` set `$redirect` to the result of your `if ($data['selecttab'] == 'tab0') { ...` statement. Therefore, I suggest first do your if statement and have a variable named `$redirect` that catches the result of the if statment
if ($data['selecttab'] == 'tab0') {
$redirect = "fdws/".$id."/edit?tab=tab0";
}elseif($data['selecttab'] == 'tab1'){
$redirect = "fdws/".$id."/edit?tab=tab1";
}elseif($data['selecttab'] == 'tab2'){
$redirect = "fdws/".$id."/edit?tab=tab2";
}else{
$redirect = "fdws/".$id."/edit?tab=tab3";
}
And then `$this->validate(...)`.
Scratch that! I made a big mistake. According to official Laravel 5.0 documentation, and also looking at the Illuminate\Foundation\ValidatesRequests trait, when using Controller Validation, it is NOT possible to just chose the redirect route without modification to the traits or other codes. I think using Form Request will give you the power you want with a lot less hassle.
Solution found,
I done like that and its working fine :)
$validator = Validator::make($request->all(), [
'can_be_interviewed_via' => 'required',
]);
if ($validator->fails()) {
return redirect("fdws/".$id."/edit?tab=tab3")
->withErrors($validator)
->withInput();
}
In Laravel 5 use Middleware as helpers for controllers and routes. This will help you a lot.

Resources