Laravel 5 validation rules - laravel-5

previously I have used validation within a Request class e.g.
public function rules()
{
return [
'userName' => 'required', 'min:3',
'userEmail' => 'required|email',
'departmentId' => 'required',
'slug' => 'required',
];
}
But I now have another form but I can't see any options within the documentation that might help me.
Basically, lets say I have a form with the same fields as the validation above. The only time validation should fail is if ALL fields contain absolutely no data. So if I put something like "hi" within the slug input and submit, it should pass the validation.
Would something like this be possible?
Thanks

You can probably use the required_without_all validation rule.
http://laravel.com/docs/5.1/validation#rule-required-without-all
The field under validation must be present only when all of the other
specified fields are not present.
It would give you something like
public function rules()
{
return [
'userName' => 'required_without_all:userEmal,departmentId,slug','min:3',
'userEmail' => 'required_without_all:userName,departmentId,slug|email'
...
];
}
But it's not very handy if you have a lot of fields.
If you have to deal with many fields, creating a custom validator might be a better solution.
http://laravel.com/docs/5.1/validation#custom-validation-rules

Related

Array Validation: unique validation on multiple columns

I am trying to check unique validation on three columns employee_id,designation_id,station_id but the data are coming as an array which is making my situation unique and different from other SO questions/answers. I already checked few question like below: checks unique validation on multiple columns
But in my case, I can't get the value as they are inside an array. I also tried to implement Custom Rule or Request but in vain. For all the attempts, I am failing to get the field value such as $request->employee_id as they are inside an array for my case. May be I'm not trying it right.
Controller Code:
$this->validate($request, [
'posting.*.employee_id' => 'required,unique: // what to do here ??',
'posting.*.designation_id' => 'required',
'posting.*.station_id' => 'required',
'posting.*.from_date' => 'required|date',
]);
I am trying to validate uniqueness for both create and update (along with ignore $this->id facility) but don't know how to implement it here for array. It would be no problem if there was no array. Any help/suggestion/guide is much appreciated. Thanks in advance.
You can do this by creating a rule i.e UniquePosting so your controller code would look like
$this->validate($request, [
'posting' => ['required'],
'posting.*' => ['required', new UniquePosting()],
'posting.*.employee_id' => 'required',
'posting.*.designation_id' => 'required',
'posting.*.station_id' => 'required',
'posting.*.from_date' => 'required|date',
]);
Now inside your UniquePosting rule passes function will look like
public function passes($attribute, $value) {
$exists = Posting::where(['employee_id' => $value['employee_id'], 'designation_id' => $value['designation_id'],'station_id' => $value['station_id')->exists();
return !$exists;
}
Add any change if needed, overall that's the concept for testing uniqueness of the whole array.

Laravel validations

I want to validate my backend code with the following data.I passed date as $request->get('date_from'),$request->get('date_to') and time as $request->get('time_from'), $request->get('time_to') from my angular frontend and I convert date time as follows.
$dateTime_from=date('Y-m-d',strtotime($request->get('date_from'))).' '.$request->get('time_from');
$dateTime_to=date('Y-m-d',strtotime($request->get('date_to'))).' '.$request->get('time_to');
Now I want to validate DateTime with laravel backend validations. dateTime_from should be less than dateTime_to.How can write down that code inside validator?
$this->validate($request, [
'vehicle_id'=>'required',
'time_to'=>'required',
'event_id'=>'required',
]);
You can use the after validation rule.
$this->validate($request, [
'vehicle_id' => 'required',
'date_to' => 'required|after:date_from',
'event_id' => 'required'
]);
https://laravel.com/docs/5.8/validation#rule-after
you can use the after rule like follows
'date_to' => 'required|date|after:date_from'
Instead of passing a date string to be evaluated by strtotime, you may specify another field to compare against the date:
Also, you have rule-before as well
EDIT
I think after rule takes the time into consideration as well, but not sure.
And you have really complex validation to do, better write a custom rule class or a closure to handle it for you
'date_to' => [ 'required',
'date',
function ($attribute, $value, $fail) {
if (strtotime($value) <= strtotime($request->date_from) {
$fail(':attribute needs to be higher than date_from!'); // or whatever mesage ou need to send
}
]

Adding validation rule only if all other rules pass, or stop validating entire set of attributes on the first error in Laravel 5.7

I want to allow a user to create a folder on the local storage disk. So the form that is sent to the server quite is simple and has three attributes:
new-folder-name - that is the name of the folder to be created,
relative-path - a path to the directory inside which the new directory should be created relative to an asset root directory, and
asset_id - the id of an asset, I need this id to get the asset's root directory.
The thing is when I validate these attributes I need to also check if the folder the user is going to create already exists. For this purpose I made a rule called FolderExists. So, before I run FolderExists, I have to be sure all other rules have passed successfully because my custom rule should accept relative-path and asset_id to be able to build the path to check against.
Here is my rules() function, I'm doing validation in custom form request:
public function rules()
{
return [
'asset_id' => ['bail', 'required', 'exists:assets,id'],
'relative-path' => ['bail', 'required', 'string'],
'new-folder-name' => ['bail', 'required', 'string', 'min:3', new FolderName, new FolderExists($this->input('asset_id'), $this->input('relative-path')]
];
}
So my question is:
Is it possible to add FolderExists only if all other validation rules pass?
Or maybe it's possible to stop entire validation when the validator encounters first error?
Both options should be fine here.
Thank you!
I have finally found the solution myself. Here is what I ended up with.
To achieve the desired result I created another validator in withValidator() method of my custom form request, this second validator will handle only the FolderExists rule and only if the previous validation fails.
public function rules()
{
return [
'asset-id' => ['bail', 'required', 'integer', 'exists:assets,id'],
'relative-path' => ['bail', 'required', 'string'],
'new-folder-name' => ['bail', 'required', 'string', 'min:3', 'max:150', new FolderName]
];
}
public function withValidator($validator)
{
if (!$validator->fails())
{
$v = Validator::make($this->input(),[
'new-folder-name' => [new FolderExists($this->input('asset-id'), $this->input('relative-path'))]
]);
$v->validate();
}
}
If our main validator passes, we make another validator and pass only FolderExists rule with its arguments, that have already been validated, and call validate() method. That's it.

Laravel: Validate input only if available in DOM

I created a form with the following fields:
Name
Email
Country
City
Address
If the user selects a country that has states (ex. United States) then the form transforms to:
Name
Email
Country
State
City
Address
To validate this I created a separate form request like so:
public function rules()
{
return [
'name' => 'required|max:255',
'email' => 'required|email,
'country_id' => 'required|integer',
'state_id' => 'nullable|integer',
'city_id' => 'required|integer',
'address' => 'required',
];
}
The problem is that if I leave it like that, then if I don't select a state it will pass validation.
If i make it:
'state_id' => 'sometimes|nullable|integer',
Then again it passes validation.
If I make it:
'state_id' => 'required|nullable|integer',
It will not pass validation, but then again it will throw a validation error if there is no state field in the form.
I read a lot of articles about this but nothing seems to solve it for me.
PS1: I want to solve this in the form request, not in the controller. I assume that an
if($request->has('states')){...}
can help, but then again, i would like to keep everything tidy in the form request.
PS2: I am using VueJS and Axios to add/remove states from the form. The whole form is actually a Vue component.
Any clues?
Thank you in advance!
You can conditionally add rules via the sometimes method on Validator.
$v->sometimes('state_id', 'required|integer', function ($input) {
return in_array($input->countries, [1,2,3,4...]
});
You could use the required_with line of parameters, but because the validation is based on the value of the input instead of just the presence, the custom validation rule is probably your best bet.
Per https://laravel.com/docs/5.7/validation#conditionally-adding-rules

Laravel 5.2 Validate File Array

I have a form with three fields: title, body and photo[]. I'm trying to validate it so that at least one item is filled in, but I can't seem to get it to work. If I upload a file I still receive an error for title and body.
public function rules()
{
return [
'title' => 'required_without_all:body,photo.*',
'body' => 'required_without_all:title,photo.*',
'photo.*' => 'required_without_all:title,body',
'photo.*' => 'mimes:jpeg,gif,png',
];
}
Update: Jonathan pointed out that I had my rules wrong. I've fixed them and am now using this. It's still not working; when I try to upload a photo I get the error message that the other fields are required.
public function rules()
{
return [
'title' => 'required_without:body,photo.*',
'body' => 'required_without:title,photo.*',
'photo.*' => 'required_without:title,body|mimes:jpeg,gif,png',
];
}
If you're looking to ensure the photo field is an array then you need 'photo' => 'array' and then you can use 'photo.*' => '' for the other validations of the array's children.
The rules are separated by a pipe character | so if you were going to combine the two in your example it would be 'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',. I don't see you using the pipe to separate rules so I can't be sure you are aware of it.
This may have been where you were going wrong in the first place (two keys in the associative array that are identical) and some kind of precedence taking affect negating one of the rules.
You could try something like this (for the record I think you were on the right track to begin with using required_without_all as this stipulates the need to be required if all of the given fields are missing):
public function rules()
{
return [
'title' => 'required_without_all:body,photo',
'body' => 'required_without_all:title,photo',
'photo' => 'array',
'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',
];
}
Reference

Resources