I am trying to add a rule to validate a field. The 'snippet' field needs to be required only if the body field contains HTML. I have the following in my controller store method, but I can't quite figure out how the required_if would work in conjunction with a regex for checking if the field contains HTML:
$newsitem->update(request()->validate([
'snippet' => 'nullable|max:255|not_regex:/[<>]/',
'body' => 'required',
]));
From the Laravel docs, it looks like the: 'required_if:anotherfield,value' validation rule returns a boolean based on a value, but I need to return a boolean based on a regex check of the body field.
I know I could check if the body is equal to one:
'snippet' => 'required_if:body,==,1|nullable|max:255|not_regex:/[<>]/'
...but I need something that checks if the body contains < or >.
(I could add a hidden field in my form submission which would get a value set if the body contained html using javascript, but I wanted to be able to handle this with backend validation.)
Do I need to use a custom validation rule, or can this be handled with the default Laravel validation rules alone?
I have seen in the Laravel docs that you can use the: Rule::requiredIf method to build more complex conditions. Is this something I can use alongside a contains_hmtl function?
'snippet' => Rule::requiredIf($request->snippet()->contains_html),
I really feel like I am missing something here, so any pointers would be much appreciated.
Try the following regex with RequiredIf:
[
...,
'snippet' => ['nullable', 'max:255', new RequiredIf(function () {
return preg_match('/<[^<]+>/m', request()->input('body')) !== 0;
})],
...,
]
RequiredIf rule accepts a closure which should return a boolean value.
Rule::requiredIf(function () use ($request) {
//Perform the check on $request->snippet to determine whether it is a valid HTML here
//Return true if it is valid HTML else return false
}),
Related
Let's assume I can do validation in two ways
'active' => {
'sometimes',
}
and
'active' => {
'nullable',
}
What's the difference? When the one will pass and the other won't?
And the same question about this:
'user_id' => {
'sometimes|exists:user,id',
}
and
'user_id' => {
'nullable|exists:user,id',
}
I've read multiple posts on a subject, including the documentation and I still don't get it. Does sometimes or nullable make even sense when using with no other rules (like in my first example)?
Nullable:
Laravel converts empty value to null using middleware ConvertEmptyStringsToNull. 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.
Sometimes :
If you want to validate the field only if the field is present in request. This is useful when we manipulate the DOM using javascript or jQuery.
Read More
I am trying to validate a payment methods field.
Requirement is the field under validation must be of type array (Multiple values allowed) and the items should not be other than the defined option
'payment_method' => 'required|array|in:american_express,cash_on_delivery,paypal,paypal_credit_card,visa_master_card'
So the user should pass an array of values for e.g
array('american_express','paypal');
But should not pass
array('american_express', 'bank');
I am unable to find any such method in Laravel 4.1 documentation. Is there any work around for this ?
If you're using a later version of Laravel (not sure when the feature becomes available - but certainly in 5.2) you can simply do the following:
[
'payment_method' => 'array',
'payment_method.*' => 'in:american_express,cash_on_delivery,paypal,paypal_credit_card,visa_master_card'
];
You check that the payment_method itself is an array if you like, and the star wildcard allows you to match against any in the array input.
You might consider putting this into the rules() method of a request validator (that you can generate with php artisan make:request PaymentRequest as an example.
You can actually extend the Laravel validator and create your own validation rules. In your case you can very easily define your own rule called in_array like so:
Validator::extend('in_array', function($attribute, $value, $parameters)
{
return !array_diff($value, $parameters);
});
That will compute the difference between the user input array found in $value and the validator array found in $parameters. If all $value items are found in $parameters, the result would be an empty array, which negated ! will be true, meaning the validation passed. Then you can use the rule you already tried, but replace in with in_array like so:
['payment_method' => 'required|array|in_array:american_express,cash_on_delivery,paypal,paypal_credit_card,visa_master_card']
I need to check if the key is not set in the array using Laravel validator.
That would be the complete opposite of the "required" validation rule.
Basically the array will be passed to update method if it passes the validation and I want to make sure one column will not be updated.
Is there a way to check if the value "is not present"?
Thank you
EDIT:
I'm currently using Laravel 5
EDIT:
I managed to write my own validation rule by calling Validator::extendImplicit. However I get $value as null to my validation function both when I set it to null or when I don't set it at all. Is there a way to check if the value is set?
I believe I found a solution:
$validator->extendImplicit('not_present', function($attribute, $value, $parameters)
{
return !array_key_exists($attribute, $this->data);
});
I'm not calling extendImplicit statically because the Validator class object is injected to the controller of my class.
I need to access $this->data ($this referring to the Validator object) to make sure the key doesn't exist in the array being validated.
Based on the #MaGnetas answer I came up with this 2 rules that can be applied on any model.
I'm using Laravel 5.4 so putting this lines on your AppServiceProvider.php should work.
The first approach (extendImplicit and array_key_exists)
Validator::extendImplicit('not_present', function($attribute, $value, $parameters, $validator)
{
return !array_key_exists($attribute, $validator->getData());
});
Ussing $validator->getData() we could use the Validator statically.
The second approach (extend and false)
Validator::extend('not_present', function($attribute, $value, $parameters, $validator)
{
return false;
});
You could use extend because we don't need the rule to be executed if the data has not the property (because that's exactly what we want right?)
On the docs:
By default, when an attribute being validated is not present or contains an empty value as defined by the required rule, normal validation rules, including custom extensions, are not run. more info
Important: The only difference is that using extend, empty strings will not run the validation. But if you have setting TrimStrings and ConvertEmptyStringsToNull on your middleware (which AFAIK is the default option) there will be no problem
No there is no build in validtion rule for this, but you can create your own validation rule.
The simplest way to do this:
Validator::extend('foo', function($attribute, $value, $parameters)
{
// Do some stuff
});
And check if key exists.
More information:
http://laravel.com/docs/4.2/validation#custom-validation-rules
For people looking for the not_present logic in 7.x apps (applicable for all versions), remember that you can simply use the validated data array for the same results.
$validatedKeys = $request->validate([
'sort' => 'integer',
'status' => 'in:active,inactive,archived',
]);
// Only update with keys that has been validated.
$model->update(collect($request->all())->only($validatedKeys)->all());
my model has more attributes but only these two should be updatable, therefore I too were looking for an not_present rule but ending up doing this as the results and conceptual logic is the very same. Just from another perspective.
I know this question is really old but you can also use
'email' => 'sometimes|required|not_regex:/^/i',
If the email is present in the request, the regex will match any characters in the request and if the email is an empty string but is present in request the sometimes|required will catch that.
how could one make the following validation:
something like exclude_if:field,value
The field under validation cannot be present if the field "field" is equal to value.
I thought of doing a custom validation, but I am not sure how to pass the value of the other field into the custom validation class.
A real world example for this case would be if we have let's say two checkboxes A and B, and we want to make sure that if A is checked then B cannot be checked.
Anybody? Thanks!
Laravel has this covered out of the body. Lets say you don't want additional_field to be required to be filled in if the field is greater than the value 100.
Firstly - do your static rules that never change:
$v = Validator::make($data, array(
'name' => 'required',
'field' => 'required|numeric',
));
Then you can validate a sometimes rule against the field rule:
$v->sometimes('additional_field', 'required, function($input)
{
return $input->field > 100;
});
You can read more about conditionally adding rules in the Laravel Docs here.
I have an input field which needs to be empty, otherwise I want the validation to fail. This is an attempt at stopping spam through a contact form.
I've looked at the documentation for the validation but there's nothing to do this, other than the "max" rule, but this doesn't work.
Any other options?
Here's a clean and (probably) bullet-proof solution:
'mustBeEmpty' => 'present|max:0',
In the method where you are validation, extend/add custom rule:
Validator::extend('mustBeEmpty', function($attr, $value, $params){
if(!empty($attr)) return false;
return true;
});
Then you may use this rule like:
protected $rules = array(
'emptyInputField' => 'mustBeEmpty'
);
Then everything is as usual, just use:
$v = Validator::make(Input::except('_token'), $rules);
if($v->passes()) {
// Passed, means that the emptyInputField is empty
}
There are other ways to do it without extending it like this or extending the Validator class but it's an easy Laravelish way to do it. Btw, there is a package available on Github as Honeypot spam prevention for Laravel applications, you may check that.
For Laravel 8.x and above, you may use the prohibited validation rule:
return [
'emptyInputField' => 'prohibited',
];
In laravel 5.8 you can use sometimes for conditional rules adding. 'email' => 'sometimes|email' . This rules will be applied if there is something present in input field.
You can use the empty rule. Details can be seen here: https://laravel.com/docs/5.2/validation#conditionally-adding-rules