Validate Two Inputs which depends on each other - laravel-5

I have two Inputs 'creditor' and 'debtor' , I want The user to put value in one of them at least, or both.
this is the approach i am using
if($request->input('creditor')==Null && $request->input('debtor')==Null){
Session::flash('danger','Please add Value in one of the two inputs at least');
return redirect()->back();
}
How to do the same thing with laravel validation
like in example :
$request->validate([
'creditor' => 'required',
'debtor' => 'required',
]
but what i want if one of the inputs has avalue there is no need to check for the other

There are many ways to tackle this problem but I recommend you use $request->filled() as it checks if a field is present and that it has value. So, it does isset() and !empty() together.
The || AKA OR logic returns true if one of the statements/conditions is true and returns false if both conditions are false.
if($request->filled('creditor') || $request->filled('debtor')){
// Either of the has value in it.
} else {
Session::flash('danger','Please add Value in one of the two inputs at least');
return redirect()->back();
}
EDIT
Your could also use required_without_all:foo,bar,
An Example:
$rules = array(
'creditor' => 'required_without_all:debtor',
'debtor' => 'required_without_all:creditor',
);
$validator = \Validator::make($request->all(), $rules);
if($validator->fails()){
Session::flash('danger','Please add Value in one of the two inputs at least');
return redirect()->back();
}

You can simply check with OR operator..

Related

Laravel - custom validation

I have this validation:
$data = request()->validate([
'qty100' => ['integer'],
'qty250' => ['integer'],
'qty500' => ['integer'],
]);
I would need to check if at least one of them is bigger than 0... how can this be done?
I think there is no built-in validation rule does something like what you want in Laravel, so you'll need to implement a custom validator, that will let you reuse validation where needed.
this is one way of doing it.
request()->validate([
'intone' => ['required', 'integer', 'greaterThanZeroWithoutAll:inttwo,intthree'],
'inttwo' => ['required', 'integer'],
'intthree' => ['required', 'integer'],
]);
in your AppServiceProvider
public function boot()
{
//here we are creating a custom rule. called 'greaterThanZeroWithoutAll'
//$attribute is the name we are validating,
//$value is the value we get from the request,
//$parameters are the arguments we pass in like greaterThanZeroWithoutAll:inttwo,intthree inttwo and intthree are parameters
//$validator is the validator object.
Validator::extend('greaterThanZeroWithoutAll', function ($attribute, $value, $parameters, $validator) {
//$validator->getData() is all the key value pairs from greaterThanZeroWithoutAll rule.
//array_values($validator->getData()) we are only interested in the values, so this will return all the values.
//implode(array_values($validator->getData())) will turn it into string
//!(int) implode(array_values($validator->getData())) this uses no glue when imploding, then explicitly casts the generated string as an integer, then uses negation to evaluate 0 as true and non-zero as false. (Ordinarily, 0 evaluates as false and all other values evaluate to true.)
if (!(int) implode(array_values($validator->getData()))) {
//means all values are 0
return false;
}
return true;
});
// this is error message
Validator::replacer('greaterThanZeroWithoutAll', function ($message, $attribute, $rule, $parameters) {
return 'not all fields are greater 0';
});
}
!(int) implode(array_values($validator->getData())) this code basically checks all the values are zero, there should many other ways to do this.
The reason we only do on the first value is that, we pass the other two values in and compare with it. So, it does it.

Laravel 5: Validating Edits In-Place

I had previously asked a question here in regards for setting up in-place editing with Laravel 5 and AJAX. I hadn't updated it because I had managed offline to figure out what was wrong with it.
While the table is capable of editing user rows in-place, I'm now trying to add validation on top of it, intending on utilizing Laravel's built-in validator. However, for some reason it doesn't seem to be working. When I try to pass in the failed validator back through the JSON, it spits out every possible error I'm checking for. It's as if the validator is treating every input as empty, which doesn't make sense, as the rest of the function is clearly taking in the inputs as intended.
The code snippets in my previous question are still mostly relevant, but there have been updates to HomeController.php, as can be seen below:
public function updateTable(Users $users){
$user = request()->input('user');
$first_name = request()->input('first_name');
$last_name = request()->input('last_name');
$validator = Validator::make(request()->all(), [
'firstName' => 'required|alpha',
'lastName' => 'required|alpha'
], [
'firstName.required' => 'You need to give a first name!',
'firstName.alpha' => 'A first name can only contain letters!',
'lastName.required' => 'You need to give a last name!',
'lastName.alpha' => 'A last name can only contain letters!'
]);
if ($validator->fails()) {
return response()->json($validator, 404);
}
$employees->editUser($user, $first_name, $last_name);
return response()->json($user);
}
So I realized the issue was twofold. First, what I was trying to return when the validator failed was incorrect. Rather than simply passing the whole validator, I needed to simply pass its messages, like so:
if ($validator->fails()) {
return response()->json($validator->messages(), 404);
}
The second issue actually had to do with calling "request()->all()". I had assumed the array obtained would have worked, but for some reason it didn't. When I created a new array based on the values in "request()" it was able to get the validator results I was expecting.

Laravel Validation sometimes rules for date validation

I currently have a validation rule which looks like this:
public function rules()
{
return [
'startDate' => 'required|sometimes|before_or_equal:endDate',
'endDate' => 'sometimes|required|after_or_equal:startDate',
];
}
The sometimes option works as I understand it on the basis that if the field is present, run the validation rule. However, if the end date is not sent or is null, my before or equal rule kicks in and fails. In some instances within my application, end date will be null. Is there a way to 'cancel' the startDate validation rule in this instance or would I need to create a custom validator for this purpose?
something like before_or_equal_when_present ?
You can use IFs to add and manipulate rules in the rules function. You can access the inputs there referring to $this as the request itself:
public function rules()
{
$rules = [
'startDate' => 'required|sometimes|before_or_equal:endDate',
'endDate' => 'sometimes|required|after_or_equal:startDate',
];
if( $this->input('endDate') > 0)
$rules['endDate'] = "rule". $rules['endDate']
return $rules;
}
This is just a mockup just to let you know that you can manipulate and have access to the fields passed.

One-shot laravel validator

I have a form where someone searches for something. Based on this form, I validate if the input is correct:
$validator = Validator::make(Input::all() , array(
'address' =>'required',
));
if($validator->fails()) {
return Redirect::to('/')->withErrors($validator);
}
After this, I want to validate something else (that a result object isn't empty), which is completely unrelated to the search. In other words, it's NOT input from a form.
1) Do I create another validator to validate this? Or
2) Is there a better way to simply check this value and spawn an object that can be returned with "withErrors"?
UPDATE
This isn't working for me:
$validator = Validator::make(
array(
'searches' => sizeof($search)
) ,
array(
'searches' => 'required|min:1'
)
);
if($validator->fails()) {
return Redirect::to('/')->withErrors($validator);
}
It's not working because for some reason it's picking up that the "searches" item should only be validated "sometimes"
you have two ways. one is custom validator
or there is a simpler way,
suppose,
private function foo()
{
$data = ''; //retrieved the data error here with whatever call you want to make
return !empty($data) ? true : false;
}
in the controller,
public function bar()
{
if(!$this->foo())
{
$messages = new \Illuminate\Support\MessageBag;
// you should use interface here. i directly made the object call for the sake of simplicity.
$messages->add('custom', 'custom error');
return Redirect::back()->withErrors($messages)->withInput();
}
}
in the view:
#if($errors->has('custom'))
<p>custom error output.</p>
#endif
it is just the outline to give you the idea.

How can I validate input does not contain specific words?

In my signup form I have a nickname field that users can enter text in to identify themselves on my site. In the past some users have entered nicknames which others might find offensive. Laravel provides validation functionality for forms, but how can I ensure that a form field doesn't contain words users might find offensive?
Whilst Laravel has a wide range of validations rules included, checking for the presence of a word from a given list isn't one of them:
http://laravel.com/docs/validation#available-validation-rules
However, Laravel also allows us to create our own custom validation rules:
http://laravel.com/docs/validation#custom-validation-rules
We can create validation rules using Validator::extend():
Validator::extend('not_contains', function($attribute, $value, $parameters)
{
// Banned words
$words = array('a***', 'f***', 's***');
foreach ($words as $word)
{
if (stripos($value, $word) !== false) return false;
}
return true;
});
The code above defines a validation rule called not_contains - it looks for presence of each word in $words in the fields value and returns false if any are found. Otherwise it returns true to indicate the validation passed.
We can then use our rule as normal:
$rules = array(
'nickname' => 'required|not_contains',
);
$messages = array(
'not_contains' => 'The :attribute must not contain banned words',
);
$validator = Validator::make(Input::all(), $rules, $messages);
if ($validator->fails())
{
return Redirect::to('register')->withErrors($validator);
}
In Laravel 5.7 and possibly earlier versions, you could use the built in not_regex rule to check for some strings. Like this for example, within a controller using the validate method. Validate form input that expects a name for a dog. :
...
public function update(Request $request) {
$custom_validation_messages = [
'not_regex' => "C'mon! Be original. Give your dog a more interesting name!"
];
$this->validate($request, [
'pet_name' => [ 'not_regex:/^(fido|max|bingo)$/i' ],
], $custom_validation_messages);
...
}
In this case if the submitted 'pet_name' value is:
fido
FIDO
MaX
MAx
BinGO
bingo
etc.
Then validation will fail.
For the inverse of this, i.e. you only want Fido, Max or Bingo then you could use the regex rule like so:
[ 'regex:/^(fido|max|bingo)$/i' ]
See Laravel Validation (not regex).

Resources