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.
Related
There is the situation when i have to validate some form's field certain way depend on which value contains in other form's field.
E.g.
$rules = [
// Bot's setup
"settings.setup.auto_end" => ["required", "boolean"],
// Auto end's time in case of using contest auto ending
"settings.additional.auto_end.type" => ["required_if:settings.setup.auto_end,1", "integer"],
"settings.additional.auto_end.time" => [
"required_if:settings.setup.auto_end,1",
"required_if:settings.additional.auto_end.type,0",
"date_format:U",
"after:now"
],
"settings.additional.auto_end.time" => [
"required_if:settings.setup.auto_end,1",
"required_if:settings.additional.auto_end.type,1",
"cron_time"
],
];
settings.additional.auto_end.time may being validated different ways. In what way exactly, as i see it, depend on settings.additional.auto_end.type field.
In case when settings.additional.auto_end.type == 0, settings.additional.auto_end.time is validated for proper unix timestamp value.
When settings.additional.auto_end.type == 1, settings.additional.auto_end.time must be validated for custom validation rule cron_time.
But each time when i validate request form by this FormRequest implementation, settings.additional.auto_end.time is being validated by second rule.
This caused by that settings.additional.auto_end.time's second validation rule override previous rule. To my mind, it's not obvious behavior. But i understand that this behavior is based on php's array implementation.
Is there a more clear and convenient method to validate form value by certain rule which select based on some condition?
Maybe there is some switch validation rule?
The first thing that comes to mind, is to implement this logic in new custom validation rule.
But in this case of implementation the validation rules are hard-coded in custom validation rule.
I have a multiple fields binded to "x-editable" plugin that sends the changed data and like all of the data, I want to validate them.
But the problem here is that it always sends just 2 fields: name=is_on_probation&value=1. Here, the name key is the field that must be validated (it is the same as DB column) and a value is pretty self-explanatory.
I've written a validation rule like this:
'is_on_probation' => 'sometimes|...'
But then I realized that it won't be validated, because the actual subject of validation is in the value field.
So, the question here is: how can I validate the value field and apply the corresponding rule, accordingly to the name value?
I created this logic in order not to pollute the controller with additional arrays and logic, so it is going to save only the passed parameter.
Kinds regards!
P.S. I've searched for the StackOverflow, but did not find the question that describes my problem the best. May be I am wrong and did not see it.
Update
After thinking a bit, I cam up with the solution to use switch and pass the request field there, like this:
switch($this->request->get('name')) {
case "email":
$rules = [
'value' => 'sometimes|required|unique:users,email|email:rfc',
];
break;
case "phone":
$rules = [
'value' => 'sometimes|required|min:8|max:13|regex:/^(\+371)?\s?[0-9]{8}$/'
];
break;
}
$rules[] = [
'pk' => 'required|exists:users,id'
];
The question is still in place, however - is it the best solution and a good practice to do so?
Try to merge your data into the request before starting validation.
$request->merge([$request->input('name') => $request->merge([$request->input('value')]);
Then your validation
'email' => 'sometimes|...','phone' => 'sometimes|...',
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
}),
I was investigating CakePHP (2.3.4) Model::save method to insert new records and ran into a little snag:
//Two fields provided, email field intended to fail validation
$data = array('Member' => array(
'username' => 'hello',
'email' => 'world'
));
$this->Member->create();
var_dump($this->Member->save($data, true));
The above save() will return false and no data will be written to the database. However if I change the data to:
//One field provided, intended to pass validation
$data = array('Member' => array(
'username' => 'hello'
));
then save() will attempt to write a new record to database with a blank email field. I realize that skipping validation for unspecified fields might be a useful behavior during updates, but is there a CakePHP recommended way to handle partially empty data sets when creating new records? Thanks a lot.
Edit:
Thanks to Sam Delaney for the tip. In case anybody else gets stumped, this did the trick: CakePHP Data Validation: field 'required' key
This key accepts either a boolean, or create or update. Setting this key to true will make the field always required. While setting it to create or update will make the field required only for update or create operations. If ‘required’ is evaluated to true, the field must be present in the data array. For example, if the validation rule has been defined as follows:
I had originally baked the model and forgotten that required => true was left out of the validation rule. Setting it to true or 'create' would've avoided me blank records getting inserted due to gibberish data array.
IMHO what you've experienced is the desired behavior. Consider that you have the same two fields within a form and the user provides a value for only username. Both username and email field are submitted even though email is empty. Then on the server, you try to save the record only to find out that it has failed validation which you feedback to the user. On the other hand, perhaps in your system it is perfectly possible to create a user without requiring an email (for example root access account), CakePHP's validation implementation allows both of these scenarios.
If this flexibility isn't what you desire, just set the required attribute for your validation rule as true:
public $validate = array(
'email' => array(
'rule' => 'email',
'required' => true
)
);
This will satisfy your all or nothing requirement.
Since you can't do this: $this->form_validation->set_rules($VARIABLE, 'Some text', 'required');, is it possible to do something similar to:
$variable = $this->input->post('some_input');
$variable = some_function_which_manipulates_the_input($variable);
$this->form_validation->set_rules($i_want_the_variable_here, '', '');
to manipulate the input before validation check? Adding a custom callback seems a little clumsy to me since one method could do several things (not necessarily targeted at X validation field).
Since you can't do this: $this->form_validation->set_rules($VARIABLE, 'Some text', 'required');
You certainly can do that, as long as $VARIABLE contains the name attribute of the field you want to validate.
It looks like you're passing the actual $_POST value as the first parameter of set_rules() - it should in fact be the field name. See the section on setting rules:
http://codeigniter.com/user_guide/libraries/form_validation.html#validationrules
$this->form_validation->set_rules();
The above function takes three
parameters as input:
The field name - the exact name you've given the form field.
A "human" name for this field, which will be inserted into the error
message.Names.
The validation rules for this form field.
If you want to alter the actual value of the input before or after validation, just add one or more "prepping" rules.
http://codeigniter.com/user_guide/libraries/form_validation.html#preppingdata
Any native PHP function that accepts one parameter can be used as a rule, like htmlspecialchars, trim, MD5, etc.
Note: You will generally want to use the prepping functions after the validation rules so if there is an error, the original data will be shown in the form.
You may use the rules before as well, if you want to trim() something before validating for instance. Callbacks will work as well, they serve the same purpose as any function of the form validation library, or any vanilla php functions - validate the data by returning TRUE/FALSE, or alter the data - just note that by default, the callback must belong to the controller the validation is run in. You may use your own helper functions as well, anything that is available to the current script at the point when the data is validated.
You can modify $_POST directly, before form validation.
For example
// Populate slug automatically
if (!$this->input->post('slug'))
{
$_POST['slug'] = url_title($this->input->post('title'), '-', true);
}
$this->form_validation->set_rules('title', 'Title', 'trim|required');
$this->form_validation->set_rules('slug', 'Slug', 'trim|required|is_unique[categories.slug]');
if ($this->form_validation->run())
You can put the input values into an array prior to validation rules. I dont know what manipulation you want to do but you can do things like this
$dat = array(
'fname' => filter_var($this->input->post('fname'), FILTER_SANITIZE_STRING),
'lname' => filter_var($this->input->post('lname'), FILTER_SANITIZE_STRING),
'email' => filter_var($this->input->post('email'), FILTER_SANITIZE_EMAIL),
'phone' => $this->input->post('phone'),
'relate' => filter_var($this->input->post('relate'), FILTER_SANITIZE_STRING),
);
$this->form_validation->set_rules('lname', 'Last Name', 'required|trim|min_length[3]');
then on to
$this->db->update('contacts', $dat);
You can use most any thing in the array to manipulate it prior to setting rules