I recently met an issue with validator (illuminate/validation) under Lumen (5.4.6) (Laravel Components 5.4.*). It seems like the integer rule doesn't work.
I used Paw(or postman) to send companyName with type string and it can pass the validation and 'here i am' can printed out. Even a boolean type, let's say (boolean)companyName=TRUE can pass the validation. Have you met the same issue? this bug is quite obvious but I didn't find the similar discussion on google.
I also tested the string rule 'required|string|min:1' and it works accordingly, neither integer nor boolean parameters can pass the validation.
code screen-shot
Laravel/Lumen makes use of PHP filter_var() function for integer rule validation:
Class Illuminate\Validation\Concerns\ValidatesAttributes:
protected function validateInteger($attribute, $value)
{
return filter_var($value, FILTER_VALIDATE_INT) !== false;
}
As mentioned in the docs:
Note that scalar values are converted to string internally before they are filtered.
So boolean true is converted to string 1 internally and therefore passes validation.
It's not considered a bug, but an implementation detail.
Related
Here's how my model works. I have a Post model that has a expires_at column. Users provide an integer for the number of days they would like the Post to last.
This was pretty straightforward when I was doing validation in the controller. Just validate the "days" field and then transform that into a future expiration date. But now I'm doing the validation in the model with Ardent and I'm not sure how to accomplish this. I think I need to use a mutator but setting expires_at as an integer seems counterintuitive. I'm also not sure if Ardent validates before or after mutation.
I figured out how to do it using the code that removes redundant from data like confirmation fields.
public $autoPurgeRedundantAttributes = true;
function __construct() {
parent::__construct();
$this->purgeFilters[] = function($key) {
$purge = array('tempData', 'myAttribute');
return ! in_array($key, $purge);
};
}
You need to enable $autoPurgeRedundantAttributes or the filters won't be called. Then you add a closure to the $purgeFilters array which returns false if the provided attribute should be removed. ("days" in this case)
Then you just need to make sure to manually set the field you want validated
$this->attributes['days'] = $value;
Edit: This is in the official docs now. I replaced my code above with theirs.
I'm building a pretty complex and dynamic form via the Lithium PHP framework.
I've got the form working and saving to MongoDB with little problem. But I am having trouble with validation.
Simple validations (such as checking if a field is not empty or is numeric) are working fine. But I have to do a few complex validations that rely on a number of fields in the form.
For example, I have a form where a user can enter a question and then enter an unlimited number of possible answers for this question. The field ID for each answer is listed such as "answer_1", "answer_2", "answer_3", etc. The user can add an unlimited number of answers. This happens via some fancy JavaScript that inserts extra elements to the form on the client side.
At the validation level, I want to make sure that every answer which was added is not null.
I would like to do this using the "traditional" Validator functionality built within Lithium. I am also doing this at the Model level, not the Controller level (note - I have a workaround to solve this on the Controller level, but would rather do it the "right" way at the Model)
The problem, as far as I can tell, is that you can only pass a single value to the validator rule. I just need to pass back ALL values in the form to the validator. If I could do that, I would be golden. The pseudo-code for what I'm looking to do looks like this:
Validator::add('CorrectTest', function(&$value, $format = null, array $options = array()) {
foreach ($_data as $key => $value) {
if (stristr($key, "answer_")) {
if ($value == "") {
return false;
}
}
}
return true;
});
This code doesn't work, because the $_data value is not present. If I could just figure out a way to get a fully-populated "$_data" object into the Validator function, I think I could get this to work.
Thanks in advance for the help
Take a look at what's inside $options. You should have a 'values' key in there that has all of the values from the form.
So try
$_data = $options['values'];
I'm using 2.4.7 and I want to include some validation for two fields which take in prices (e.g. €1 or 2 for €3). Originally I thought that perhaps I would need to resort to validating user input but as the answer suggests it was a database issue.
The encoding within SilverStripe was defaulting to ASCII which converted the symbols such as the euro symbol. In the end I need to add
$this->response->addHeader("Content-Type", "application/json; charset='utf-8'");
to the init method in the controller. This corrected the encoding issue and prevented a hacky workaround taking place. Many thanks for the insight on this one.
Thanks
I'm assuming you want to do this in the CMS. If that's the case, the easiest way is probably to create a new class which extends the TextField class and adds a public function validate() method which performs your validation (see the CreditCardField class for an example).
class FancyCurrencyField extends TextField {
public function validate($validator) {
// Do your validation
if ($invalid) {
$validator->validationError(
$this->name,
"Please don't use currency symbols.",
"validation",
false
);
return false;
}
return true;
}
}
Once you've created your class, you can modify the form fields in your getCMSFields() function on the DataObject and use the new class in place of TextField.
Having said that, it feels like output encoding and not input validation is the root cause of your problem. I'd check to make sure that everything is setup to use UTF-8.
I encountered a problem with the PHP function substr. I just used mb_substr instead and it solved my issue.
Please view http://www.silverstripe.org/general-questions/show/11797#post369831
I have the following php code using the codeigniter framework
$this->form_validation->set_rules('money', 'Money', 'integer|required|xss_clean');
It validates a money field as an integer. How can i validate the field as an integer OR a decimal number.
I guessed it would be something simple like
$this->form_validation->set_rules('money', 'Money', '(decimal||integer)|required|xss_clean');
but it doesnt work!
From the CI Form Validation docs:
Note: You can also use any native PHP functions that permit one parameter.
is_numeric() could work for you, but it accepts some formats that are very unlike money.
is_float() would work, except it will fail on strings and integers.
Both these functions are also too lenient in validating a numeric integer or decimal that you would normally accept as a money value. The built in CI decimal() function requires the decimal point and allows + and - characters.
Yeah, I know - not helpful, but hopefully it gets you thinking. The syntax you would like to use will simply not work. I'd suggest creating your own form validation rule for validating money by extending the Form_validation library.
Create the file /application/libraries/MY_Form_validation.php
Something like this:
class MY_Form_validation extends CI_Form_validation {
function is_money($input = '')
{
// Validate input here and return TRUE or FALSE
}
}
I had written a broken example initially, then I tried writing something that would work and realized that it's up to you. You may or may not want to allow characters like $, €, -, +, or decimals beyond two places, or a decimal with only one place, or commas in the digit to separate thousands... Use whatever validation method you see fit.
There's a good example here on money format validation: How to check if an entered value is currency
use numeric directly .... numeric|required
This is what I use in MY_Form_validation class.
/**
* Money, decimal or integer
*
* #access public
* #param string
* #return bool
*/
public function money($str)
{
//First check if decimal
if(!parent::decimal($str))
{
//Now check if integer
return (bool) parent::integer($str);
}
return TRUE;
}
And of course in your /system/language/english/form_validation_lang.php you should add appropriate message for validation error.
You could try a custom callback :
$this->form_validation->set_rules('money', 'Money', 'callback_money_type');
function money ($param) {
//conditional statements here
if(is_int($param) || is_float($param){
$this->form_validation->set_message('money_type', 'Your message here');
return false;
} else {
return true;
}
}
ctype_digit may be of use, it's a built-in PHP function.
Instead of using decimal||integer now we can use numeric to validate the numeric characters.
You can use like below
$this->form_validation->set_rules('reward', 'Reward', 'callback_validate_money');
public function validate_money ($input) {
if(preg_match('/^[0-9]*\.?[0-9]+$/', $input)){
return true;
} else {
$this->form_validation->set_message('validate_money','Please enter valid reward!');
return false;
}
}
Using #RenderSection("SectionName", false), why do I need to explicitly set the 2nd parameter to false when the Intellisense already states that the default is false?
Update:
The RTM signature of the RenderSection method is:
public HelperResult RenderSection(string name, bool required)
There also exists an override that looks like this:
public HelperResult RenderSection(string name) {
return RenderSection(name, required: true);
}
Note that this method no longer uses default parameters, instead opting for explicit overrides.
The signature of this method changed twice during the development of MVC 3 which explains why you might be seeing confusing examples.
Edit: It appears that the MVC 3 RTM documentation is incorrect and erroneously references a default value of the required parameter.
it needs to be true. You are saying that the section is optional.
#RenderSection("SectionName", true)
or
#RenderSection("SectionName", optional: true)