CakePHP3: validate decimal input - php

This is probably a trivial question, but I can't figure it out.
I want my price value to have 2 decimal places. CakePHP should validate this, but it doesn't. CakePHP only checks if the input is a number and doesn't allow to pass decimal values.
I want it to check and pass values like 2.22 but also 2. Now it only allows the latter.
Part of validationDefault method:
$validator
->decimal('price')
->allowEmpty('price');
I checked CakePHP API and found decimal() method description:
decimal( float $check , integer|null $places null , string|null $regex null )
Checks that a value is a valid decimal. Both the sign and exponent are
optional.
But it does not take string as a parameter in this context(and CakePHP assign decimal() to my price column automatically during baking), so I guess this is why decimal('price', 2) don't work.
Any ideas?
REQUESTED EDIT:
Whole validationDefault method:
public function validationDefault(Validator $validator)
{
//$validator for other columns
$validator
->allowEmpty('price')
->add('price', 'money', array('rule' =>
array('money', 'left'),
'message' => 'Please supply a valid monetary amount.'));
return $validator;
}
My input field is created using HTML helper.

You should use money to validate price
$validator->notEmpty('price',array('message' => 'Please provide your amount'))
->add('price', 'money', array('rule' => array('money','left'),
'message' => 'Please supply a valid monetary amount.'));
Your can also try this
$validator->notEmpty('amount',array('message' => 'Please provide your amount'))
->add('amount','numeric',array('rule' => 'numeric' ,'message'=> 'Please provide a valid amount'));

Related

Laravel 5.2 validator: Validate Array request parameter, at least one value must be selected

I am having a form where i am having title, body, answers[][answer] and options[][option].
I want atleast one answer must be selected for the given question, for example:
i have ABC question and having 5 options for that question,now atleast one answer must be checked or all for given question.
Efforts
protected $rules = [
'title' => 'required|unique:contents|max:255',
'body' => 'required|min:10',
'type' => 'required',
'belongsto' => 'sometimes|required',
'options.*.option' => 'required|max:100',
'answers.*.answer' => 'required',
];
But this is not working. i want atleast one answer must be selected.
Please help me.
The problem is that on $_POST an array filled with empty strings will be passed if no answer is selected.
$answers[0][0] = ''
$answers[0][1] = ''
$answers[0][2] = ''
Hence the following will not work since array count will be greater than zero due to the empty strings:
$validator = Validator::make($request->all(), [
'answers.*' => 'required'
]);
The easiest way to solve this is to create a custom Validator rule by using Laravel's Validator::extend function.
Validator::extendImplicit('arrayRequireMin', function($attribute, $values, $parameters)
{
$countFilled = count(array_filter($values));
return ($countFilled >= $parameters[0]);
});
And then call it in your Validation request:
$validator = Validator::make($request->all(), [
'answers.*' => 'arrayRequireMin:1'
]);
The magic happens in array_filter() which removes all empty attributes from the array. Now you can set any minimum number of answers required.
Validator::extendImplicit() vs Validator::extend()
For a rule to run even when an attribute is empty, the rule must imply that the attribute is required. To create such an "implicit" extension, use the Validator::extendImplicit() method:
Laravel's validation docs
Try this,
'answer.0' => 'required'
it will help you. I think.

Validate value 0 and range based validation in Lumen

I want to perform following validation on my textfield using Lumen Validation:
The value must be greater than 0 and less than or equal to 100
My current code is:
$validator = Validator::make($params, [
'weight' => 'required'
]);
if ($validator->fails()) {
$messages = $validator->errors();
$message = $messages->first();
return $message;
exit;
}
You can use the between validation rule to check this. The parameters are inclusive.
You also need to add in the numeric validation rule so that between will know to check if the numeric value is between the supplied values. Without the numeric validation, it would validate the length of the string, not the numeric value of it.
$validator = Validator::make($params, [
'weight' => 'required|numeric|between:1,100'
]);

Laravel 4 validation constant pass

I'm using Laravel 4.2.8 and trying to validate the next form:
The first select field is required. And only one is required from the next three fields.
Phone with formatting is the last. And another two are for digits (some IDs).
I validate in controller, the code is next:
public function getApplication()
{
$input = Input::except('_token');
Debugbar::info($input);
$input['phone'] = preg_replace('/[^0-9]/', '', $input['phone']); // remove format from phone
$input = array_map('intval', $input); // convert all numeric data to int
Debugbar::info($input);
$rules = [ // Validation rules
['operation-location' => 'required|numeric'],
['app-id' => 'numeric|min:1|required_without_all:card-id,phone'],
['card-id' => 'numeric|digits:16|required_without_all:app-id,phone'],
['phone' => 'numeric|digits:12|required_without_all:app-id,card-id']
];
$validator = Validator::make($input, $rules);
if ($validator->passes()) {
Debugbar::info('Validation OK');
return Redirect::route('appl.journal', ['by' => 'application']);
}
else { // Validation FAIL
Debugbar::info('Validation error');
// Redirect to form with error
return Redirect::route('appl.journal', ['by' => 'application'])
->withErrors($validator)
->withInput();
}
}
As you may see I convert numeric IDs to integers myself and leave only number for phone number.
The problem is when I submit form as it is, it passes validation, despite one field is required and starter phone format is too short.
I've tried changing required_without_all to just required on all fields (!), but it still passes fine with blank empty form submitted.
And I expect at least one field to be properly filled.
Debug of my inputs.
Initial:
array(4) [
'operation-location' => string (1) "0"
'app-id' => string (0) ""
'card-id' => string (0) ""
'phone' => string (6) "+3 8(0"
]
After conversion to int:
array(4) [
'operation-location' => integer 0
'app-id' => integer 0
'card-id' => integer 0
'phone' => integer 380
]
Posted similar smaller problem to Laravel issues.
I know this sounds weird but I think this is just an issue with your rules array.
You current rules array is an array of arrays. The Validator looks for an array with keys and values. I believe your current rules are being parsed as keys, but with no value. And then the Validator was basically seeing no rules, and it automatically passed. Try this.
$rules = [
'operation-location' => 'required|numeric',
'app-id' => 'numeric|min:1|required_without_all:card-id,phone',
'card-id' => 'numeric|digits:16|required_without_all:app-id,phone',
'phone' => 'numeric|digits:12|required_without_all:app-id,card-id'
];

Zend Framework - integer validator

Zend Framework seems to have a feature for validating integers (checked the /Validate/Int.php in the library for the purpose) which validates correctly float numbers as integer, while I want to show error when float number is given.
Here is a snippet from my form:
$form['my_int'] = new Zend_Form_Element_Text('my_int');
$form['my_int']->setLabel('My Int')
->setRequired(true)
->addFilter('StringTrim')
->addDecorator('Errors', array('placement'=>'prepend',
'class'=>'my-err'))
->addValidator('NotEmpty', true, array('messages' =>
array('isEmpty' => 'Please provide data')))
->addValidator('int', true, array(
'locale' => 'en_US',
'messages' => array(
'intInvalid' => 'Please provide valid data',
'notInt' => 'Please provide valid data'
)
));
So when I provide something different from string, integer or float, 'intInvalid' error is triggered and my custom message is shown. When float number like 1.23 is provided 'notInt' error is shown. The problem is when you provide e.g. 1.00, then the validator checks for "!Zend_Locale_Format::isInteger($value, array('locale' => $this->_locale))" and decides the input is integer and when you try to add float number in the the database in an integer field, you get error.
How should I organize my form validation so that when float number is provided, no matter what, to show error to the user?
You should add the Int filter to that element.
$element->addFilter(new Zend_Filter_Int());

Change validation rules on the fly

I'm working on a form that contains user data, specifically a phone number field. The phone number typically isn't required so the only validation rule in the model is the usphone rule. However, if the user is submitting this form, the phone number becomes necessary. I thought I'd be able to simply add a validate rule on the fly, set the model and call the validates method, but either I'm doing it wrong or it's not working the way I expected.
In my controller:
# Update a few validation rules that are specific to this context
$this->Proposal->Requestor->validate['phone_number']['notempty'] = array(
'rule' => 'notEmpty',
'message' => 'Please enter a phone number so can can contact you with any questions about the work.',
'allowEmpty' => false,
'required' => true,
);
$validationErrors = array();
$this->Proposal->Requestor->set( $this->data['Requestor'] ); # $this->data['Requestor']['phone_number'] only (no other requestor data)
if( !$this->Proposal->Requestor->validates( array( 'fieldList' => array( 'phone_number' ) ) ) ) {
$validationErrors['Requestor'] = $this->Proposal->Requestor->validationErrors;
}
No errors are reported, even if I leave the phone number field empty. In this case, the only information I'm requesting from the user is their phone number, so the rest of the Requestor data is empty, but I've tried merging in the rest of the user data and I get the same result. If I remove the fieldList option, I get an error on a different field, but still nothing on the empty phone number.
Any idea what I'm missing here? I've been monkeying around with this for hours now and I just haven't found the right answer.
Thanks.
The solution ended up being twofold:
I had existing rule on the phone_number field that forced the value to be a US phone number. That rule also set allowEmpty to true and required to false. I wanted to catch an empty value so I could display a particularly precise message.
I had to update the existing rule to flip the allowEmpty and required values and also add a new rule with its last value set to true.
The final change, added in my controller action looks like this:
$this->Proposal->Requestor->validate = Set::merge(
$this->Proposal->Requestor->validate,
array(
'phone_number' => array(
'notempty' => array(
'rule' => 'notEmpty',
'message' => 'Please enter a phone number so can can contact you with any questions about the work.',
'allowEmpty' => false,
'required' => true,
'last' => true,
),
'usphone' => array(
'allowEmpty' => false,
'required' => true,
),
)
)
);
I can't remember whether I verified that the change to the existing usphone rule was strictly necessary given the last value of the new rule, but this combination is working fine.
You could try using the Multivalidatable Behaviour - http://bakery.cakephp.org/articles/dardosordi/2008/07/29/multivalidatablebehavior-using-many-validation-rulesets-per-model

Categories