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.
Related
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
In the given scenario
request()->validate([
'type' => 'required',
'category' => 'required'
]);
and Again
request()->validate([
'name' => 'required',
'gender' => 'required
]);
Is it possible to get some sort of centralized or complied error that encompasses both the validations?
Then you should use Validator facade to handle this kind of cases.
for ex.
$validator = Validator::make($request->only('type', 'category), [
'type' => 'required',
'category' => 'required'
]);
$validator2 = Validator::make($request->only('name', 'gender'), [
'name' => 'required',
'gender' => 'required'
]);
if ($validator->fails() || $validator2->fails()) {
// return merge $validator->errors() and $validator2->errors();
}
I want to do "unique" validation on multiple fields. I have written below validation rule but not sure how to include brand_id and company_id in it
$request->validate([
'name' => 'required|string|unique:products',
'company_id' => 'required',
'brand_id' => 'required',
]);
So what I am trying to do is, ADD PRODUCT but check if the name is unique for the given company_id and brand_id. How can I do that?
We can use Rule::unique() function to add custom conditions to unique validation.
$request->validate([
'company_id' => 'required',
'brand_id' => 'required',
'name' => [
'required',
'string',
Rule::unique('products')->where(function($query) {
$query->where('company_id', request('company_id'));
$query->where('brand_id', request('brand_id'));
}),
],
]);
Sometimes you may wish to stop running validation rules on an attribute after the first validation failure. To do so, assign the bail rule to the attribute:
$request->validate([
'name' => 'bail|required|string|unique:products',
'company_id' => 'bail|required',
'brand_id' => 'required',
]);
You can add additional wheres after the ignore options (the NULL,id below), e.g.:
$request->validate([
'company_id' => 'required',
'brand_id' => 'required',
'name' => 'required|string|unique:products,name,NULL,id,company_id,'.request('company_id').',brand_id,'.request('brand_id'), '
]);
I have added 3 fields to the Laravel OOB Registration Form, they are Birth Month, Day, and Year. I pass these fields to the validator function in the RegisterController and convert them to an age with Carbon:
$theAge = Carbon::createFromDate($data['birthyear'], $data['birthmonth'], $data['birthday'])->age;
This part works fine, I can pass the variable to a field in the table and see the correct age.
How do I add $theAge to my Validator?
return Validator::make($data, [
'email' => 'required|string|email|max:255|unique:users|confirmed',
'password' => 'required|string|min:8|confirmed',
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'address' => 'required|string|max:255',
'city' => 'required|string|max:255',
'state' => 'required|string|max:2',
'zipcode' => 'required|string|max:10',
'brand' => 'required',
'opt_in' => 'required',
'g-recaptcha-response' => 'required|captcha',
'birthmonth' => 'required',
'birthday' => 'required',
'birthyear' => 'required',
]);
I have tried the following but it appears to be ignored on validation:
$theAge => 'bail|min:21'
I have looked into the After Validation Hook but don't understand how to use it in my situation.
you can add the $theAge variable to the data array.
$data['age'] = Carbon::createFromDate($data['birthyear'], $data['birthmonth'], $data['birthday'])->age;
You can put the calculated value back in the $data before you call the validator like this:
$theAge = Carbon::createFromDate($data['birthyear'], $data['birthmonth'], $data['birthday'])->age;
$data['age'] = $theAge;
return Validator::make($data, [
'email' => 'required|string|email|max:255|unique:users|confirmed',
'password' => 'required|string|min:8|confirmed',
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'address' => 'required|string|max:255',
'city' => 'required|string|max:255',
'state' => 'required|string|max:2',
'zipcode' => 'required|string|max:10',
'brand' => 'required',
'opt_in' => 'required',
'g-recaptcha-response' => 'required|captcha',
'birthmonth' => 'required',
'birthday' => 'required',
'birthyear' => 'required',
'age' => 'min:21'
]);
Alternatively, you can let the user select their date of birth using date picker (e.g. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date) like this:
<input name="birthday" type="date">
and in your validator, do this define the age check plus a custom error message:
return Validator::make($data, [
// ... snipped
'birthday' => 'required|date|before_or_equal:' . Carbon::now()->subYears(21)->toDateString()
], [
'birthday.before_or_equal' => 'You must be at least 21 years old.'
]);
I am running some basic validation inside a Laravel 5.5 controller like this...
$this->validate($request, [
'name' => 'required|max:30',
'email' => 'required|unique:users|email',
'password' => 'required|max:20',
'mykey' => 'required',
]);
Is there a way to check if 'mykey' matches a php string I have saved? I know I can do an if statement and compare them but wondered if there was a way I could do this inside the validation itself?
You can use in rule, This works for n number of values
$request->validate([
'name' => 'required|max:30',
'email' => 'required|unique:users|email',
'password' => 'required|max:20',
'mykey' => [
Rule::in([env('MY_KEY'),config('app.another_key')]),
]
]);
Laravel provides a regex option for validation. Depending on the complexity of the string comparison it may be useful:
https://laravel.com/docs/5.5/validation#rule-regex
You can this rule:
$key = "my_saved_key"
$request->validate([
'name' => 'required|max:30',
'email' => 'required|unique:users|email',
'password' => 'required|max:20',
'mykey' => 'in:' . $key,
]
]);