Laravel if one field is filled then others are not required - laravel

I have three nullable fields ( Coupon, Membership, Offer) which are to be filled from requests. I want to validate/restrict users so that they can only fill one of these fields.
As the fields are not required, I cannot use the required:* validators to handle this.
I know this can be handled in the front-end, but I want to do it in the backend as well.
Appreciate any help/insight on this.

You can use required_without_all function from laravel validations.
$request->validate([
'coupon' => ['nullable', 'required_without_all:membership,offer'],
'membership' => ['nullable', 'required_without_all:coupon,offer'],
'offer' => ['nullable', 'required_without_all:membership,coupon'],
]);

I would take the approach of having the options as three possible values for the same field. You could use a select or radio button group on your form to fill in a single field. This way the user can only enter one of the three possible values.
If we call the field type for example, your validation would check that the value given for type is one of the three options.
$request->validate([
'type' => [
'nullable',
Rule::in(['coupon', 'membership', 'offer']),
],
]);
EDIT:
Add the nullable validation to allow the field to have no value at all

Related

Laravel Backpack

I need help. I am currently working with Laravel backpack and I have the following problem: I have a field called Media, that field has two behaviors, one to upload images and the other to write a URL, the problem is that it only lets me create the one time the field. Is there a way in laravel backpack to create 2 different fields with the same name?
I want to achieve something more or less like this:
CRUD::addField([ 'name' => 'url_media', 'label' => 'url_media', 'type' => 'upload',
]);
CRUD::addField([ 'name' => 'url_media', 'label' => 'url_media', 'type' => 'url', ]);
Because of the HTML spec, you cannot have two inputs with the same name in a form. I mean... you can. But only the last one will be sent in the request.
If you don't want to show both fields at the same time, you can use a conditional (if/else) to show either the upload field or the url field.
Otherwise, a different way would be to choose a fake name for the second field (say... url_media_link), then use a Laravel Mutator in your model, in this case setUrlMediaLinkAttribute() to do what you manipulate the model attributes as you want.

Validate a field using another field

I have a dynamic phone number validation rule, and I need 2 values for it: number and country.
The library I'm using to validate the phone number is brick/phonenumber which can include the country code to parse it accurately.
So, my current working approach looks like this:
$request->validate([
'country' => ['required', 'max:2'],
]);
$request->validate([
'number' => ['required', new PhoneNumberValidator($request->input('country')],
]);
Because when I put it like this:
$request->validate([
'country' => ['required', 'max:2'],
'number' => ['required', new PhoneNumberValidator($request->input('country'))],
]);
The number validation runs even if the country is not valid. So I'd like to know if there's a way to have all the validations in one validate() call, so, having the country value validated before calling the number rule (I tried with bail but that stops the validations for 1 attribute, not the rest of attributes in the queue).
You can create a custom rule and validate both inputs at the same time.
You may also want to look at the various validation rules. You might find something helpful.

Laravel form request validation

Is there any way to get original data in request?
I mean, in my case I want to validate updating user's in the form. I want the email to be unique on emails in database except on the email that user wrote to the form.
Laravel already has a validation rule for this, you can add an id of the user to ignore to your unique validator.
'email' => [
'required',
Rule::unique('users')->ignore($currentUser->id),
]
I used something like this:
'email' => ['sometimes', 'email', 'unique:users,email,'.$user->getKey().','.$user->getKeyName().',deleted_at,NULL', 'string'],
Not sure if it is the best solution but works. I kind of do not like it because the $user is based on hidden input from the request.
You can do it liks this:
'email' => 'unique:users,email,'.$user->id
The user id will allow you to keep updating the record but maintain the unique constraint on email. You don't need a hidden input field for $user->id btw.

How to allow empty value for Laravel numeric validation

How to set not require numeric validation for Laravel5.2? I just used this Code but when i don't send value or select box haven't selected item I have error the val field most be numeric... I need if request hasn't bed input leave bed alone. leave bed validate ...
$this->validate($request, [
'provinces_id' => 'required|numeric',
'type' => 'required',
'bed' => 'numeric',
]);
If I understood you correctly, you're looking for sometimes rule:
'bed' => 'sometimes|numeric',
In some situations, you may wish to run validation checks against a field only if that field is present in the input array. To quickly accomplish this, add the sometimes rule to your rule list
In Laravel 6 or 5.8, you should use nullable. But sometimes keyword doesn't work on that versions.
Use sometimes instead of required in validation rules. It checks if only there is a value. Otherwise it treats parameter as optional.
You may need nullable – sometimes and
present didn't work for me when combined with integer|min:0 on a standard text input type - the integer error was always triggered.
A Note on Optional Fields
By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. Because of this, you will often need to mark your "optional" request fields as nullable if you do not want the validator to consider null values as invalid.
Tested with Laravel 6.0-dev
Full list of available rules
In laravel 5.5 or versions after it, we begin to use nullable instead of sometimes.
according to laravel documentation 8 you must to set nullable rule
for example:
$validated = $request->validate([
'firstName' => ['required','max:255'],
'lastName' => ['required','max:255'],
'branches' => ['required'],
'services' => ['required' , 'json'],
'contract' => ['required' , 'max:255'],
'FixSalary' => ['nullable','numeric' , 'max:90000000'],
'Percent' => ['nullable','numeric' , 'max:100'],
]);
in your case :
$this->validate($request, [
'provinces_id' => 'required|numeric',
'type' => 'required',
'bed' => 'nullable|numeric',
]);

Validate against only a part of the defined constraints

I have this field:
$builder->add('offices', 'entity', array(
'class' => 'ControlPanelBundle:Offices',
'property' => 'name',
));
In my form I am only using one field from all possible fields in this Offices object. When I am submitting, it tries to validate all the fields. How can I temporary disable validation only for this time?
Validation Groups are designed specifically for that.

Resources