Validation only required when value is not available - laravel

I have the following code:
{!! Form::select('the_selection', ['' => 'Nothing', 'Foo' => 'Bar']) !!}
And the following:
<input class="input" name="the_other_field" type="text"/>
The the_other_field field should be required only when the_selection is not '' .
So I tried tis validation:
$this->validate($request, [
// 'recurring' => 'required|nullable',
'the_other_field' => 'required_without:the_selection,|date_format:Y-m-d|after:today',
]);
But that doesnt work..

Use required_if
https://laravel.com/docs/5.6/validation
$this->validate($request, [
// 'recurring' => 'required|nullable',
'the_other_field' => 'required_if:recurring,|required_without:the_selection,|date_format:Y-m-d|after:today',
]);
If this not working you may do this:
$rules = [
'the_other_field' => ['date_format:Y-m-d', 'after:today'],
];
if ($request->get('the_selection') != null) {
array_push($rules['the_other_field'], 'required');
}
$this->validate($request, $rules);

If you move your validation to a form request, then you could add a “sometimes” validation rule:
class YourRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'the_selection' => 'required',
];
}
public function withValidator($validator)
{
$validator->sometimes('the_other_field', 'required', function ($input) {
return $input->the_selection != '';
});
}
}

Related

Validate if input is url or email in Laravel 9

I am trying to validate a field but I am not able to do it.
I have this Request Validator
public function rules()
{
return [
...
'input' => 'required|url|email',
];
}
What I want to do is to validate if the input is url or email, can be one of them, what can I do? Here I am validating both cases, but the input can be one of them. Thanks.
public function rules(): array
{
return [
'input' => ['required', function ($field, $value) {
$data = [$field => $value];
$emailValidator = Validator::make($data, [$field => 'email']);
$urlValidator = Validator::make($data, [$field => 'url']);
if ($urlValidator->passes() || $emailValidator->passes()) {
return true;
}
$this->validator->getMessageBag()->add($field, $field . ' must be a valid email address or a valid url');
return false;
}],
];
}

Laravel validate if same item is selected more than once

In my application I have add more functionality for selected multiple devices. I need to show an error message if the user has selected the same device two or more times.
Here is my code.
class ValidateDeviceRequest extends FormRequest
{
private $data = [];
public function __construct()
{
$this->data = request()->all();
}
public function rules()
{
$rules = [
'devices' => ['required', 'array'],
'devices.*.device_company_id' => [
'required',
'integer',
'exists:device_companies,id,company_id,' . session()->get('COMPANY_ID')
],
];
foreach($this->data['devices'] as $key => $array)
{
$rules["devices.{$key}.device_id"] = [
'required',
'integer',
"exists:devices,id,device_company_id," . #$array["device_company_id"]
];
}
# returning
return $rules;
}
}
If you're just checking duplicated values inside the array. You can use the validation rule distinct for this.
'devices.*.device_company_id' => [
'distinct',
// ...
]
If you wish to validate duplicates within a model you can use the rule unique:model
Thanks to #Tommie. Here is my final code.
class ValidateDeviceRequest extends FormRequest
{
private $data = [];
public function __construct()
{
$this->data = request()->all();
}
public function rules()
{
$rules = [
'devices' => ['required', 'array'],
'devices.*.device_company_id' => [
'required',
'integer',
'exists:device_companies,id,company_id,' . session()->get('COMPANY_ID')
],
'devices.*.device_company_id' => [
'required',
'distinct',
]
];
foreach($this->data['devices'] as $key => $array)
{
$rules["devices.{$key}.device_id"] = [
'required',
'distinct',
'integer',
"exists:devices,id,device_company_id," . #$array["device_company_id"]
];
}
# returning
return $rules;
}
}
I also found this Laravel array validation for unique attribute in array but not required to be unique in table

Laravel - How to validate Unique Rule Request as case sensitive

I have this Rules in my Laravel-5.8
Rules: create
public function rules()
{
return [
'location_name' => [
'required',
'string',
'min:3',
'max:80',
Rule::unique('hr_work_locations', 'location_name', 'company_id')
],
];
}
Rules: edit
public function rules()
{
return [
'location_name' => [
'required',
'string',
'min:3',
'max:80',
Rule::unique('hr_work_locations', 'location_name', 'company_id')->ignore($this->work_location)
],
];
}
from the rules,location_name is unique for each company (company_id). Also in the edit rules,
ignore($this->work_location)
is for the route
Controller : create
public function store(StoreWorkLocationRequest $request)
{
try {
$worklocation = HrWorkLocation::create([
'location_name' => $request->location_name,
'is_active' => 1,
]);
Session::flash('success', 'Work Location is created successfully');
return redirect()->route('hr.work_locations.index');
}
catch (Exception $exception)
{
Session::flash('error', 'Action failed!');
return redirect()->route('hr.work_locations.index');
}
}
I observe that it allows location_name as England or england.
How do I make Rule::unique as case sensitive?
Thank you.
Add a custom validation to AppServiceProvider.php under the boot() method:
Validator::extend('iunique', function ($attribute, $value, $parameters, $validator) {
$query = DB::table($parameters[0]);
$column = $query->getGrammar()->wrap($parameters[1]);
return ! $query->whereRaw("lower({$column}) = lower(?)", [$value])->count();
});
This can be extended further to accept the other parameters similar to the unique rule
Now my $rules looks like this:
protected $rules = [
'username' => 'required|alpha_dash|min:5|max:18|iunique:users,username',
];
see an issue reported here
You can make the input lower-cased so you don't have to worry of what the user input in the form.
use Illuminate\Support\Str;
After that, you can call it without the namespace prefix:
Str::lower($request->location_name);

Validation in Laravel. How to transfer the rule and message to the controller?

I am having problems displaying custom error messages.
I received a training project that had the following code:
class StoreProject extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|unique:projects,name|max:255',
'website' => 'url',
];
}
public function messages()
{
return [
'name' => 'Це імʼя вже використовується',
'website' => 'Будь-ласка введіть адресу вашого сайту вірно http://...'
];
}
}
I added the function message( ) myself.
This is the controller code:
public function store(StoreProject $request)
{
$project = new Project($request->except('project_image'));
$project->owner_id = Auth::user()->id;
$project->status_id = StatusProject::UNCONFIRMED;
//send email to moderator and accountant for the moderation
if( $project->save() ) {
$this->dispatch(new ConfirmNewProject($project));
}
// load image from cropie serves
if ($request->has('project_image')) {
$file = self::croppie($request->input("project_image"));
$project->uploadImage($file, 1);
}
return redirect()->route('projects.show', [$project->id]);
}
I tried various methods: withErrors([]) and this method:
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
'name' => 'Це імʼя вже використовується',
'website' => 'Будь-ласка введіть адресу вашого сайту вірно http://...'
],
]
but when checking, I get the key value, not the text of the error message
Errors:
validation.unique
validation.url
How to transfer the rule and message to the controller?
Try to modify the messages() function like that one:
public function messages()
{
return [
'name.required' => 'Name required message',
'name.unique' => 'Name unique message',
'name.max' => 'Name max message',
'website.url' => 'Будь-ласка введіть адресу вашого сайту вірно http://...'
];
}

Laravel Rules Validation two Variables

I want to validate if a user(member) is part of a group via Validation Rules.
This is a part of my function...
public function update(Request $request)
{
$request->validate([
'idgroup' => [
'required', 'numeric', new AdminGroupRequest
],
'member' => [
'required', 'numeric', new UserPartOfGroup
],
]);
And this is the Rules Class where I want to check if User is part of group.
public function passes($attribute, $value)
{
$userofgroup = Member::where([['groupid', /*Here I need idgroup*/], ['member', $value/*This is already member*/]])->select('id')->first();
if($userofgroup){
return true;
}else{
return false;
}
}
Any ideas?
You could either use the request() helpers:
public function passes($attribute, $value)
{
return Member::where('groupid', request('idgroup'))
->where('member', $value)
->exists();
}
Or you could just use a closure inside your FormRequest:
'member' => [
'required', 'numeric', function ($attribute, $value, $fail) {
$exists = Member::where('groupid', $this->input('idgroup'))
->where('member', $value)
->exists();
if (!$exists) {
return $fail('Your error message goes here.');
}
}
],

Resources