Laravel In Array validation - php

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']

Related

Laravel validation requiredIf with array index

I need to apply a required rule to a array field in my form request when the another array field, in the same index, has a certain value. Example:
public function rules(): array
{
return [
'data' => 'array',
'data.*.is_admin' => 'required|boolean',
'data.*.area' => [
'nullable',
Rule::requiredIf($condition),
// other rules...
]
]
}
When evaluating the first item in the array, if data.0.is_admin = 1, I'll add required to data.0.area. The problem is that I'm unable to access the current index inside the requiredIf method.
Using closures I was able to access the current index, but I can't override the nullable rule unless I add a required one and I need to be able to pass null to area. I can't use sometimes because I need to ignore the other rules when area = null.
Right now I'm looping through $request->data and adding the rules conditionally for each index. I wonder if there is a way I can achieve this using Laravel's array sintax.
Thank you

required_if validation in Laravel

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
}),

Laravel: Validate field only when the value changed

Some form fields in my laravel 5.5 application have validation rules that run against a remote API and take quite some time. I would thus only want to run these expensive checks when the field value changes (is different from the value currently stored in the model).
Is there something that implements this already, e.g. as a rule similar to sometimes?
I would image it like this: only_changed|expensive_validation|expensive_validation2. The latter rules would only be executed when the field value has changed.
Assuming you are using a custom Request class, the rules() method expects an associative array to be returned before it applies the validation.
You can build your array of rules dynamically using the request contents before applying the validation like so:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$validation_array = [
'name' => 'required|string|max:255',
];
if ($this->my_field === $some_condition) {
$validation_array = array_merge($validation_array. [
'my_field' => "required|expensive_validation|expensive_validation2"
]);
}
return $validation_array;
}
Note: I haven't run this yet but the principle should be fine.

Is there a validation rule for "not present"?

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 to use regular expressions with resources in Laravel 4

If we create a simply route with Laravel 4 we can use where to set a regular expression for each param. passed in the URI. For example:
Route::get('users/{id}',function($id){
return $id;
})->where('id','\d+');
For every get request second param. must be digits. Problem comes when we create resources, if we use ->where() it throws an error about this is not an object.
I've tried to place where into a group, as an array as third param. in the resource but has not worked.How could we use the power of the regular expressions with the power of Laravel 4 resources?
He Joss,
I was going mad with the same question, so I did some research. All I could come to is the following conclusion: you do not need this method. In each of your controller methods you can specify your default values after each argument:
public function getPage(id = '0', name = 'John Doe'){
Next to this you can do a regular expression check, and a lot of other checks with the laravel validator like this:
//put the passed arguments in an array
$data['id'] = $id;
$data['name'] = $name;
//set your validation rules
$rules = array(
"id" => "integer"
"name" => "alpha"
);
// makes a new validator instance with the data to be checked with the given
// rules
$validator = Validator::make($data, $rules);
// use the boolean method passes() to check if the data passes the validator
if($validator->passes()){
return "stuff";
}
// set a error response that shows the user what's going on or in case of
// debugging, a response that confirms your above averages awesomeness
return "failure the give a response Sire";
}
Since most of the validation are already in the options list of laravel you might not need the regular expression check. Yet it is an option (regex:pattern).
My theory behind the none existence of the where() method in the controllers is that the method offers you the opportunity to do validation within you Route file. Since you already have this possibility in your controller there is just no need for it.

Categories