vlucas / valitron Goto Github PK
View Code? Open in Web Editor NEWValitron is a simple, elegant, stand-alone validation library with NO dependencies
License: BSD 3-Clause "New" or "Revised" License
Valitron is a simple, elegant, stand-alone validation library with NO dependencies
License: BSD 3-Clause "New" or "Revised" License
Length validation returns "must be longer.." even if the value is shorter. Sorry I don't have the time to add a pull request, here's my fix:
Replaced
'length' => "must be longer than %d",
with
'length' => "length must be between %d and %d",
Current text:
lengthMin - String must be greater than given length
lengthMax - String must be less than given length
Needs to say: greater than or equal to. Same for the other one.
Hello when I validate a filed as beeing integer, I'm expecting to return false in case it's "123" because internally this is a string.
Instead using return filter_var($value, \FILTER_VALIDATE_INT) !== false; I think better to use is_int .
Title says it all.
It is not hard to do it manually but including old input with errors would be a nice feature.
Recently I was working on a project and I needed to validate a credit card was valid, so I created a new basic filter for Valitron and it worked ok.
I was going to work on an improved filter for it (more verbose) but before I do I wondered if it is something you would consider implementing into the core?
My original code checked only if a card was valid but a more verbose system would optionally filter by card type and suchlike.
Hi all:
Would it be possible to add an example of a custom rule to the README that shows how to compare two items of supplied data, in the same way as the already-defined equals
and different
rules do? Even something simple like a lessThan
or greaterThan
rule would be great to illustrate how that would work.
Thanks :)
At the moment, Valitron has to be initialized with an array of field->value mappings. So, there is no way to add data to be validated after initialization. Any thoughts on adding a setData
method?
It would be good to add field label when defining rules rather than the code trying to work out what the label should be based on the field name.
Currently I have a password confirm field and the label is Password Confirm but the output from validation is. I want to be able to define this.
$v->rule('required', array('first_name', 'last_name', 'email_address', 'dob'));
$v->label(array(
'first_name' => 'First Name',
'last_name' => 'Last Name',
'email_address' => 'Email',
'dob' => 'Date of Birth',
));
Something like this would be useful, because I could define all my field labels globally. I have this working on my current setup but I find my solution a bit hacky, when I work out a cleaner solution I will send a PR.
Assuming the following validation rule stipulating that the firstname and lastname fields should be between 2 and 25 characters in length:
'length' => [['firstname', 2, 25], ['lastname', 2, 25]],
The language file supplies the following error message regardless:
'length' => "must be longer than %d",
a better solution would be to have a between for text lengths:
'between' => "must be between %d and %d characters",
Is it possible to set the checkAndSetLabel() as protected?
When I want to extend the class with custom error() function cannot because the checkAndSetLabel() is private.
Thanks.
While lengthMin rule sets the minimum ALLOWED length of the string the validation error that is triggered is as follows:
"lengthMin" => "must contain greater than %d characters",
instead of something that includes the minimum value like
"lengthMin" => "must contain equal to or greater than %d characters",
If min is set to 1 then 0 still passes as a valid value:
php > $v = new Valitron\Validator(array('name' => 0));
php > $v->rule('min', 'name', 1);
php > var_dump($v->validate());
bool(true)
This doesn't appear to be the case if the value is non-zero:
php > $v = new Valitron\Validator(array('name' => 1));
php > $v->rule('min', 'name', 2);
php > var_dump($v->validate());
bool(false)
There is no more lengthBetween. According to the code one just adds another parameter to length for lengthBetween functionality. This is confusing as the README still lists lengthBetween but if you try lengthBetween it'll throw an addRule error.
This is part of code in rule methode
$this->_validations[] = array(
'rule' => $rule,
'fields' => (array) $fields,
'params' => (array) $params,
'message' => '{field} ' . $message
);
return $this;
If we define in language file rule like this ''required' => "Field {field} is required" it will output
"Email Field Email is required"
I know that i can do some thing like this:
$v->rule('required', array('name', 'email'))->message('{field} is required')->label('Name');
But adding this in multiple places and than, for example, client want me to change message can be pain in ass.
Am I missing something?
I don't see a way to set the custom messages for rules set by:
$rules = [
'required' => 'foo',
'accepted' => 'bar',
'integer' => 'bar'
];
$v = new Valitron\Validator(array('foo' => 'bar', 'bar' => 1));
$v->rules($rules);
Am I missing something?
could add:
public function messages($msgs)
{
static::$_ruleMessages = array_merge(static::$_ruleMessages, $msgs);
return $this;
}
But that has to be run before the rules have been set
I am talking about the changes in this commit.
#114
Though I have added an argument for the strict flag, It just doesn't seem to work and always defaults to false no matter what I pass it.
Since I do not have a lot of time I just reverted the changes and just created a clone function with everything similar with the strict flag added, and named it "validateIns" as compared to original "validateIn".
eg.
$v->rule('ins', 'xyz', array('0', '1'));
And this is working fine for me.
But if you could make it better( as to why and how my suggested commit isn't working) I'd be glad.
If I get some time I myself shall try fixing it.
Thanks for your immense contribution.
This library is exactly that worked for me, since most of my applications are a bit complex and not quiet easy with other libraries like GUMP.
Sometimes when you want to validate a field first
you need to look at another field, second
. That's the case when you are comparing two password fields for instance, and for that you would use the builting equals
validator. But what if you need such functionality in a custom validation rule that you add using the static method addRule()
? At the moment it is not possible.
Perhaps it would be possible to pass a read-only version of the protected $_fields
property of Validator
to the callback used in addRule()
.
Of course this is a non-issue if one is okay with just extending the Validator
class and adding validation methods to it.
How would you do array validation?
Say I have this input:
$_POST = [
'users' => [
7 => '[email protected]',
12 => '[email protected]',
]
];
I want to validate that the users
key exists in $_POST
, and its value is an array.
Then for each key of the users array, I want to validate the key is a user ID (callback).
Then for each value of the users array, I want to validate that the value is an email address.
Is this possible with this library? If so, how?
The keys of the array "_validations" aren't a name of a validation method.
Check function "hasRule": [https://github.com/vlucas/valitron/blob/master/src/Valitron/Validator.php#L533].
As the _validations array has a numeric index, this function will always return FALSE when being called from validate().
Hello,
Is there a way to add custom messages when adding rules with the alternate syntax.
Like in this example, where to add custom messages?
$rules = [
'required' => [
['foo'],
['bar']
],
'length' => [
['foo', 3]
]
];
Thanks,
Requiring to set the data in the constructor is an odd choice that removes the ability to validate several values with the same rules (user has to config a new object each time). Simple fix: add setData()
.
As it is, storing data in the object makes this not a validator but a sort of validating-container hybrid; I can't just serialize this and store it somewhere without also storing the data.
Moving the static state to object state would also help there.
Hi,
there is possibility to validate string with spaces, accents, etc like "hello it's my message... XD".
I thinks it's possible if you use is_string() php function.
It's possible to add this function? :)
thanks
Leo
Please remove the version property from the composer.json file, since when this is forgotten we still have 1.1.7 when current latest release is 1.1.8. Let packagist manage the version based on tags instead of looking for the version property in the composer.json.
I love the concept of this project, and I'm looking to integrate this with one of my current projects (https://github.com/alexweissman/UserFrosting). Right now, our validation rules are hardcoded, repetitive if-else
statements all over our codebase. This would help clean it up nicely.
I was wondering, do you have any recommendations for how to deal with "pseudo-optional" HTML form fields such as checkboxes? I.e., fields which aren't really "optional", but whose absence is interpreted as false
and presence as true
? Right now we're using the isset
function, but I wonder if there is a more elegant way using Valitron.
Still working on the client-side interface, but in the meantime I've come up with something that others might find useful. Basically, the purpose is to allow default values for non-required fields. So, if a $_GET
or $_POST
array is passed into valitron, it can be easily updated with default values for missing parameters.
Extra function in valitron:
public function setDefault($field, $defaultValue) {
if (!isset($this->_fields[$field])){
$this->_fields[$field] = $defaultValue;
}
return true;
}
Usage:
// Sanitize input data
$get = filter_input_array(INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS);
// Initialize validation
$v = new Valitron\Validator($get);
// Required fields
$v->rule('required', 'box_id');
// Optional fields with default values
$v->setDefault('title', 'Cool Dude');
$v->setDefault('limit', null);
// Validate!
$v->validate();
// Handle errors
if (count($v->errors()) > 0)
exit();
// Update input array with any new default values
$get = $v->data();
I'm having some trouble getting the labels to perform correctly. Valitron continues to use the actual HTML field name (i.e. passwordConfirm) in the display to users instead of the label I am trying to apply: "Password Confirmation." Here's some sample code:
$v->rule('required', ['firstName', 'lastName', 'email', 'phone1', 'phone2', 'phone3', 'password', 'passwordConfirm', 'terms', 'companyCode']);
$v->rule('email', 'email');
$v->rule('integer', ['phone1', 'phone2', 'phone3']);
$v->rule('accepted', 'terms');
$v->rule('length', 'phone1', 3);
$v->rule('length', 'phone2', 3);
$v->rule('length', 'phone3', 4);
$v->rule('equals', 'password', 'passwordConfirm');
$v->labels(array(
'firstName' => 'First name',
'lastName' => 'Last name',
'email' => 'Email address',
'phone1' => 'Area Code',
'phone2' => 'Phone Number',
'phone3' => 'Phone Number',
'password' => 'Password',
'passwordConfirm' => 'Password',
'terms' => 'Terms and Conditions',
'companyCode' => 'Employer Company Code'
));
Additionally, here is the en.php file in the languages folder:
<?php
return array(
'required' => "Required",
'equals' => "Must be the same as '%s'",
'different' => "Must be different than '%s'",
'accepted' => "Must be accepted",
'numeric' => "Must be numeric",
'integer' => "Must be an integer (0-9)",
'length' => "Must be longer than %d",
'min' => "Must be greater than %s",
'max' => "Must be less than %s",
'in' => "Invalid value",
'notIn' => "Invalid value",
'ip' => "Invalid IP address",
'email' => "Invalid email address",
'url' => "Invalid URL",
'urlActive' => "Must be active domain",
'alpha' => "Must contain only letters a-z",
'alphaNum' => "Must contain only letters a-z and/or numbers 0-9",
'slug' => "Must contain only letters a-z, numbers 0-9, dashes and underscores",
'regex' => "Invalid format",
'date' => "Invalid date",
'dateFormat' => "Must be date with format '%s'",
'dateBefore' => "Must be date before '%s'",
'dateAfter' => "Must be date after '%s'",
'contains' => "Must contain %s"
);
?>
So for a while, I've been thinking about how validation plugins for different languages/platforms each have their own particular "language" for specifying validation rules and parameters. For example, FormValidation has the greaterThan
validator, while Valitron has the min
rule, Symfony2 has the GreaterThan
constraint, Djanjo has MinValueValidator
, etc.
The lack of a standard for validation rules is a problem, because it limits interoperability between client- and server-side code, as well as among different client- and server-side languages/frameworks/plugins.
I was going to try to develop my own standard, but I found out there is already an effort called JSON Schema. Would you consider extending Valitron to be able to load validation rules from a schema in this format?
Title says it all.
How would you implement this?
Now all validators are stored together with the logic of the library in the one class.
In my opinion it is not very pretty. It would be logical to put validators into a separate class.
And while creating instance of the Valitron, we inject validators class into Valitron via constructor.
For example:
class Validator
{
public function __construct($v = null, ect...)
{
$this->validators = $v === null ? new Validators : $v;
// ....
}
}
class Validators
{
public function length($args ...)
{
// ...
return $result
}
// ...
}
This also allows to put my own class, which contains my set of the validators.
I am validating an array like so:
$v->rule('numeric', array('grades.*'));
$v->rule('min', array('grades.*'), 0);
$v->rule('max', array('grades.*'), 10);
However in case of validation failure i can't find a way to get the index of the specific field that failed validation as $v->errors() returns something like the following:
Array ( [grades.*] => Array ( [0] => Grades.* mplah mpah mplah validation error ) )
Am i missing something here? Or is it a valitron's shortcoming?
->rule('length', 'phone', 12]);
The phone have to be 12 longer but on message you say "must be longer than 12".
Is this right?
In English language file:
'regex' => "contains invalid chatacters",
it's chaRacters 😄
While working with php frameworks I came across one small problem which could help others.
Laravel, slim... are returning NULL for checkbox input type in state when checkbox is not accepted .
Because of that checkbox won't be run against validation. Simple fix is to set checkbox value to 'off' instead of NULL.
I suggest that field name in error messages should come from displayed field name.
And I think Valitron should provide interface for manipulating field name in error messages.
Currently field names are generated from key of input array in Validator
constructor.
However this behavior is very nasty when the message should be non-English, which requires extraneous str_replace
s for all field names.
All suggestion are welcomed.
Thank you.
The issue happens when you try to validate a date in pt-br format (d/m/Y). I changed the return in method validateDateFormat to: return $parsed['warning_count'] === 0;
I have been trying to add a custom rule using "addRule" which uses an array as an extra parameter.
This is what I am validating with
$v->addRule('validNewsletter', array($this, 'validNewsletters'));
$valid_keys = array('news','sport');
$v->rule('validNewsletter', 'newsletters', $valid_keys)->message('Invalid newsletter selected.');
Unfortunately this currently breaks on line 611 of the Validator class
$label = isset($params[$k]) && isset($this->_labels[$params[$k]]) ? $this->_labels[$params[$k]] : $tag;
It complains that the isset value is not a string
Could this line be changed to this - which does work in this use case?
$label = isset($params[$k]) && !is_array($params[$k]) && isset($this->_labels[$params[$k]]) ? $this->_labels[$params[$k]] : $tag;
Should we give the option of length between being optionally non-greedy?
For instance, length between 5-10 greedy would be 5,6,7,8,9,10
Non-greedy would be 6,7,8,9
We could also have low or high greedy, so it'd match 5,6,7,8,9 for low greedy or 6,7,8,9,10 for high greedy
It would basically involve adding a third parameter, with a value of either 'low', 'high', 'both' or false
if we wanted to go the whole hog.
I wanted to get opinions before I go ahead and create it on whether it would be beneficial, what terminology we should use for 'low greedy' etc if we take that path and also to see if anybody else has an opinion about things like this!
Given:
$v = new \Valitron\Validator(array('foo' => '', 'bar' => ''));
$v->rule('different', 'foo', 'bar');
$v->validate(); // true
That doesn't seem correct to me; foo and bar are not different at all. In my case either foo or bar should be filled, but if both are empty, validation should fail.
I guess this is caused by #14. I can't require both fields; as foo is only required when bar is empty, and vice versa.
Hey!
I'm just wondering -- I don't really know if there's something I'm missing or if it's a bug, but there seems to be problems when trying to validate alpha/alphanumeric strings that contain accented characters.
require 'lib/Valitron/Validator.php';
use Valitron\Validator as Validator;
$arr = [
"last_name" => "áéíñ"
];
$v = new Validator($arr);
$v->rule('alpha','last_name');
$v->validate();
var_dump($v->errors()); // prints array(1) { ["last_name"]=> array(1) { [0]=> string(39) "Last Name must contain only letters a-z" } }
Any ideas or anyhing that needs to be set up before using Valitron?
Thanks!
In modern web applications, is important to validate form data on both the server-side (for security) and the client-side (for usability). Valitron does the server-side validation quite nicely, and there are some very good client-side validation plugins out there, such as bootstrapvalidator.
However, every time one builds or modifies a form, one must add the appropriate rules to both the server- and client-side code. A really useful feature would be if Valitron could generate the appropriate client-side rules (in JSON, for example) automatically. The client could then fetch these rules from Valitron either when they load the form, or through a separate AJAX request.
Adopted one of the examples to my needs and came across a possible bug:
$v = new \Valitron\Validator(array('settings' => array(
array('threshold' => '50')
)));
$v->rule('required', 'settings.threshold');
if($v->validate()) {
echo "Yay! We're all good!";
} else {
// Errors
print_r($v->errors());
}
Output:
Array ( [settings.threshold] => Array ( [0] => Settings.threshold is required ) )
Running the same code but with this validator:
$v->rule('lengthMin', 'settings.threshold',1);
produces the expected output:
Yay! We're all good!
$rules = array(
'length' => array(array('input1', 6),array('input2', 10)),
);
this rule gives following error when:
input1 = 'abcdefghdkjfakjdkjkf'
[1] => Input1 must be longer than 6
I think it should output folowing error:
[1] => Input1 must be exactly 6 digits.
Installing vlucas/valitron (1.1.4)
Downloading: connection...
[Composer\Downloader\TransportException]
Composer\Downloader\TransportException]
The "https://api.github.com/repos/vlucas/valitron/zipball/4465bfd4a126f789af25b3284618252c2cae7813" file could not be downloaded (HTTP/1.0 502 Bad Gateway)
Here's a comprehensive URL validation regex: https://gist.github.com/dperini/729294
The tests were done here comparing different URL regular expressions: http://mathiasbynens.be/demo/url-regex
I suggest Valitron should use this instead of PHP's one.
Or this upgraded one which supports ipv6 and punycode: https://gist.github.com/HenkPoley/8899766
Currently, when using instanceOf validator with Doctrine entities, it will always fail since Doctrine is using Proxy classes (See: http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html ). Is possible to get real class name by using ClassUtils::getRealClass
(From: http://stackoverflow.com/a/14895345/360186 )
Thanks for giving me an alternative to that awkward Respect/Validator thing.
I know there is a function errors() in the Valitron library, can someone add a function to allow retrieval of the error string that represents one particular field.
I realise I can just do $v->errors() and get the index of the array. However I think it's cleaner for future dev to have a function that retrieves it to save breaking changes later on if you ever change the format of the errors. Even if that function is simply indexing the array for the time being.
Cheers.
There is a little Problem with the "accepted"-Rule. If i wan't that the accepted rule work, i have to set to the field also the "required"-rule. The Problem is that in the function Validate a field have not to be empty, except the field has a "required"-rule.
I have change your code at line 752,
if (($v['rule'] !== 'required' && !$this->hasRule('required', $field) && (!isset($value) || $value === '')) && !$this->hasRule('accepted', $field)) {
continue;
}
Would you accept a PR to add rules in bulk? To keep it simple, the method would accept an array of arrays. Each internal array would be the same values you would have passed to the rule() method individually.
I'd propose naming the method setRules() or perhaps even just rules().
$rules = array(
array('required', 'name'),
array('length', 'name', 14)
);
$v = new Validator(array('name' => 'Chester Tester'));
$v->rules($rules);
$v->validate();
If we wanted to get a little more clever, perhaps we could use a slightly more complex structure, allowing for a more readable rules array:
$rules = array(
'required' => 'name',
'length' => array(
array('name', 14),
array('gender', 1)
)
);
$v = new Validator(array('name' => 'Chester Tester', 'gender' => 'M'));
$v->rules($rules);
$v->validate();
In this format, the top level array is just keys/values where the key is a rule type and the val is either a single param, array of params or array of arrays. An array of params would allow for rules that require an array of params. The array of arrays would allow you to specify multiple rules of a single type (like my length example).
The second structure would look really nice with array literals in 5.4.
I'm also not quite sure how to write an effective unit test for this since $_validators is protected. Ideas?
For example, I have a non-mandatory date field, but I want to validate the date if it is entered. Is this possible?
Hi,
At the moment the constructor takes a single $data argument and the other arguments are optional. Is it not a better solution to have the constructor take a single optional argument of type array that holds all the necessary/optional construction data for easier integration into existing systems?
__construct($params = array())
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.