From 11139b8534781ef3f11c7e77cae7c8dbf7e7b240 Mon Sep 17 00:00:00 2001 From: misantron Date: Mon, 26 Dec 2016 16:28:59 +0300 Subject: [PATCH 1/6] Code style changes and fixes --- .gitignore | 1 + README.md | 1 + src/Valitron/Validator.php | 162 ++++++++++++++++++++++++++++++++----- 3 files changed, 144 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 432c0c1..4a38432 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +.idea/ composer.phar composer.lock vendor diff --git a/README.md b/README.md index c2f7195..c6bd85a 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ V::lang('ar'); * `accepted` - Checkbox or Radio must be accepted (yes, on, 1, true) * `numeric` - Must be numeric * `integer` - Must be integer number + * `boolean` - Must be boolean * `array` - Must be array * `length` - String must be certain length * `lengthBetween` - String must be between given lengths diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index 4496e2d..4601a5b 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -37,6 +37,21 @@ class Validator */ protected $_labels = array(); + /** + * Contains all rules that are available to the current valitron instance. + * + * @var array + */ + protected $_instanceRules = array(); + + /** + * Contains all rule messages that are available to the current valitron + * instance + * + * @var array + */ + protected $_instanceRuleMessage = array(); + /** * @var string */ @@ -503,7 +518,7 @@ class Validator foreach ($this->validUrlPrefixes as $prefix) { if (strpos($value, $prefix) !== false) { $host = parse_url(strtolower($value), PHP_URL_HOST); - + return checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA') || checkdnsrr($host, 'CNAME'); } } @@ -710,7 +725,7 @@ class Validator } else { $cardRegex = array( 'visa' => '#^4[0-9]{12}(?:[0-9]{3})?$#', - 'mastercard' => '#^5[1-5][0-9]{14}$#', + 'mastercard' => '#^(5[1-5]|2[2-7])[0-9]{14}$#', 'amex' => '#^3[47][0-9]{13}$#', 'dinersclub' => '#^3(?:0[0-5]|[68][0-9])[0-9]{11}$#', 'discover' => '#^6(?:011|5[0-9]{2})[0-9]{12}$#', @@ -772,7 +787,8 @@ class Validator } //Validate optional field - protected function validateOptional($field, $value, $params) { + protected function validateOptional($field, $value, $params) + { //Always return true return true; } @@ -887,7 +903,7 @@ class Validator } // Dead end, abort - elseif ($identifier === NULL || ! isset($data[$identifier])) { + elseif ($identifier === null || ! isset($data[$identifier])) { return array(null, false); } @@ -921,8 +937,9 @@ class Validator } // Callback is user-specified or assumed method on class - if (isset(static::$_rules[$v['rule']])) { - $callback = static::$_rules[$v['rule']]; + $errors = $this->getRules(); + if (isset($errors[$v['rule']])) { + $callback = $errors[$v['rule']]; } else { $callback = array($this, 'validate' . ucfirst($v['rule'])); } @@ -945,6 +962,26 @@ class Validator return count($this->errors()) === 0; } + /** + * Returns all rule callbacks, the static and instance ones. + * + * @return array + */ + protected function getRules() + { + return array_merge($this->_instanceRules, static::$_rules); + } + + /** + * Returns all rule message, the static and instance ones. + * + * @return array + */ + protected function getRuleMessages() + { + return array_merge($this->_instanceRuleMessage, static::$_ruleMessages); + } + /** * Determine whether a field is being validated by the given rule. * @@ -965,46 +1002,117 @@ class Validator return false; } + protected static function assertRuleCallback($callback) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException( + 'Second argument must be a valid callback. Given argument was not callable.' + ); + } + } + + /** + * Adds a new validation rule callback that is tied to the current + * instance only. + * + * @param string $name + * @param callable $callback + * @param string $message + * @throws \InvalidArgumentException + */ + public function addInstanceRule($name, $callback, $message = null) + { + static::assertRuleCallback($callback); + + $this->_instanceRules[$name] = $callback; + $this->_instanceRuleMessage[$name] = $message; + } + /** * Register new validation rule callback * * @param string $name - * @param mixed $callback + * @param callable $callback * @param string $message * @throws \InvalidArgumentException */ - public static function addRule($name, $callback, $message = self::ERROR_DEFAULT) + public static function addRule($name, $callback, $message = null) { - if (!is_callable($callback)) { - throw new \InvalidArgumentException('Second argument must be a valid callback. Given argument was not callable.'); + if ($message === null) { + $message = static::ERROR_DEFAULT; } + static::assertRuleCallback($callback); + static::$_rules[$name] = $callback; static::$_ruleMessages[$name] = $message; } + public function getUniqueRuleName($fields) + { + if (is_array($fields)) { + $fields = implode("_", $fields); + } + + $orgName = "{$fields}_rule"; + $name = $orgName; + $rules = $this->getRules(); + while (isset($rules[$name])) { + $name = $orgName . "_" . rand(0, 10000); + } + + return $name; + } + + /** + * Returns true if either a valdiator with the given name has been + * registered or there is a default validator by that name. + * + * @param string $name + * @return bool + */ + public function hasValidator($name) + { + $rules = $this->getRules(); + return method_exists($this, "validate" . ucfirst($name)) + || isset($rules[$name]); + } + /** * Convenience method to add a single validation rule * - * @param string $rule - * @param array $fields + * @param string|callback $rule + * @param array|string $fields * @return $this * @throws \InvalidArgumentException */ public function rule($rule, $fields) { - if (!isset(static::$_rules[$rule])) { + // Get any other arguments passed to function + $params = array_slice(func_get_args(), 2); + + if (is_callable($rule) + && !(is_string($rule) && $this->hasValidator($rule))) + { + $name = $this->getUniqueRuleName($fields); + $msg = isset($params[0]) ? $params[0] : null; + $this->addInstanceRule($name, $rule, $msg); + $rule = $name; + } + + $errors = $this->getRules(); + if (!isset($errors[$rule])) { $ruleMethod = 'validate' . ucfirst($rule); if (!method_exists($this, $ruleMethod)) { - throw new \InvalidArgumentException("Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule()."); + throw new \InvalidArgumentException( + "Rule '" . $rule . "' has not been registered with " . get_called_class() . "::addRule()." + ); } } // Ensure rule has an accompanying message - $message = isset(static::$_ruleMessages[$rule]) ? static::$_ruleMessages[$rule] : self::ERROR_DEFAULT; - - // Get any other arguments passed to function - $params = array_slice(func_get_args(), 2); + $messages = $this->getRuleMessages(); + $message = isset($messages[$rule]) ? $messages[$rule] : self::ERROR_DEFAULT; $this->_validations[] = array( 'rule' => $rule, @@ -1018,7 +1126,6 @@ class Validator /** * @param string $value - * @internal param array $labels * @return $this */ public function label($value) @@ -1031,7 +1138,7 @@ class Validator /** * @param array $labels - * @return string + * @return $this */ public function labels($labels = array()) { @@ -1085,4 +1192,19 @@ class Validator } } } + + /** + * Replace data on cloned instance + * + * @param array $data + * @param array $fields + * @return Validator + */ + public function withData($data, $fields = array()) + { + $clone = clone $this; + $clone->_fields = !empty($fields) ? array_intersect_key($data, array_flip($fields)) : $data; + $clone->_errors = array(); + return $clone; + } } From d9a466b833ede3c99b804317be75ce3f7cfce6a6 Mon Sep 17 00:00:00 2001 From: misantron Date: Thu, 26 Oct 2017 23:09:45 +0300 Subject: [PATCH 2/6] Array contains and unique validators added, code style fixes --- README.md | 2 + src/Valitron/Validator.php | 182 ++++++++++------- tests/Valitron/StaticVsInstanceTest.php | 5 +- .../Valitron/ValidateAddInstanceRuleTest.php | 56 ++--- tests/Valitron/ValidateTest.php | 192 +++++++++++++----- 5 files changed, 278 insertions(+), 159 deletions(-) diff --git a/README.md b/README.md index 0d520fd..d8d0223 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ V::lang('ar'); * `dateBefore` - Field is a valid date and is before the given date * `dateAfter` - Field is a valid date and is after the given date * `contains` - Field is a string and contains the given string + * `arrayContains` - Field is an array and contains the given array + * `unique` - Field is an array and contains unique values * `creditCard` - Field is a valid credit card number * `instanceOf` - Field contains an instance of the given class * `optional` - Value does not need to be included in data array. If it is however, it must pass validation. diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index 77305fa..30319f7 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -100,7 +100,7 @@ class Validator // Load language file in directory $langFile = rtrim($langDir, '/') . '/' . $lang . '.php'; - if (stream_resolve_include_path($langFile) ) { + if (stream_resolve_include_path($langFile)) { $langMessages = include $langFile; static::$_ruleMessages = array_merge(static::$_ruleMessages, $langMessages); } else { @@ -146,9 +146,9 @@ class Validator * @param array $params * @return bool */ - protected function validateRequired($field, $value, array $params= array(), array $fields = array()) + protected function validateRequired($field, $value, array $params = array()) { - if (isset($params[0]) && (bool) $params[0]){ + if (isset($params[0]) && (bool)$params[0]) { $find = $this->getPart($this->_fields, explode('.', $field), true); return $find[1]; } @@ -168,7 +168,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateEquals($field, $value, array $params) @@ -184,7 +183,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateDifferent($field, $value, array $params) @@ -244,7 +242,7 @@ class Validator */ protected function validateInteger($field, $value, $params) { - if (isset($params[0]) && (bool) $params[0]){ + if (isset($params[0]) && (bool)$params[0]) { //strict mode return preg_match('/^-?([0-9])+$/i', $value); } @@ -258,7 +256,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateLength($field, $value, $params) @@ -278,7 +275,7 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @return boolean + * @return bool */ protected function validateLengthBetween($field, $value, $params) { @@ -294,7 +291,7 @@ class Validator * @param mixed $value * @param array $params * - * @return boolean + * @return bool */ protected function validateLengthMin($field, $value, $params) { @@ -310,7 +307,7 @@ class Validator * @param mixed $value * @param array $params * - * @return boolean + * @return bool */ protected function validateLengthMax($field, $value, $params) { @@ -342,7 +339,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateMin($field, $value, $params) @@ -362,7 +358,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateMax($field, $value, $params) @@ -405,7 +400,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateIn($field, $value, $params) @@ -429,7 +423,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateNotIn($field, $value, $params) @@ -441,7 +434,7 @@ class Validator * Validate a field contains a given string * * @param string $field - * @param mixed $value + * @param string $value * @param array $params * @return bool */ @@ -456,10 +449,9 @@ class Validator $strict = true; if (isset($params[1])) { - $strict = (bool) $params[1]; + $strict = (bool)$params[1]; } - $isContains = false; if ($strict) { if (function_exists('mb_strpos')) { $isContains = mb_strpos($value, $params[0]) !== false; @@ -476,6 +468,43 @@ class Validator return $isContains; } + /** + * Validate that all field values contains a given array + * + * @param string $field + * @param array $value + * @param array $params + * @return bool + */ + protected function validateArrayContains($field, $value, $params) + { + if (!isset($params[0])) { + return false; + } + if (!is_array($value) || !is_array($params[0])) { + return false; + } + + $intersect = array_intersect($value, $params[0]); + return array_diff($value, $intersect) === array_diff($intersect, $value); + } + + /** + * Validate that field array has only unique values + * + * @param string $field + * @param array $value + * @return bool + */ + protected function validateUnique($field, $value) + { + if (!is_array($value)) { + return false; + } + + return $value === array_unique($value, SORT_REGULAR); + } + /** * Validate that a field is a valid IP address * @@ -571,7 +600,7 @@ class Validator */ protected function validateSlug($field, $value) { - if(is_array($value)) { + if (is_array($value)) { return false; } return preg_match('/^([-a-z0-9_-])+$/i', $value); @@ -615,7 +644,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateDateFormat($field, $value, $params) @@ -631,7 +659,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateDateBefore($field, $value, $params) @@ -648,7 +675,6 @@ class Validator * @param string $field * @param mixed $value * @param array $params - * @internal param array $fields * @return bool */ protected function validateDateAfter($field, $value, $params) @@ -802,7 +828,8 @@ class Validator } //Validate optional field - protected function validateOptional($field, $value, $params) { + protected function validateOptional($field, $value, $params) + { //Always return true return true; } @@ -836,12 +863,12 @@ class Validator * Add an error to error messages array * * @param string $field - * @param string $msg + * @param string $message * @param array $params */ - public function error($field, $msg, array $params = array()) + public function error($field, $message, array $params = array()) { - $msg = $this->checkAndSetLabel($field, $msg, $params); + $message = $this->checkAndSetLabel($field, $message, $params); $values = array(); // Printed values need to be in string format @@ -865,18 +892,18 @@ class Validator $values[] = $param; } - $this->_errors[$field][] = vsprintf($msg, $values); + $this->_errors[$field][] = vsprintf($message, $values); } /** * Specify validation message to use for error for the last validation rule * - * @param string $msg - * @return $this + * @param string $message + * @return Validator */ - public function message($msg) + public function message($message) { - $this->_validations[count($this->_validations) - 1]['message'] = $msg; + $this->_validations[count($this->_validations) - 1]['message'] = $message; return $this; } @@ -941,7 +968,7 @@ class Validator /** * Run validations and return boolean result * - * @return boolean + * @return bool */ public function validate() { @@ -1011,9 +1038,8 @@ class Validator * * @param string $name The name of the rule * @param string $field The name of the field - * @return boolean + * @return bool */ - protected function hasRule($name, $field) { foreach ($this->_validations as $validation) { @@ -1030,17 +1056,18 @@ class Validator protected static function assertRuleCallback($callback) { if (!is_callable($callback)) { - throw new \InvalidArgumentException('Second argument must be a valid callback. Given argument was not callable.'); + throw new \InvalidArgumentException( + 'Second argument must be a valid callback. Given argument was not callable.' + ); } } - /** * Adds a new validation rule callback that is tied to the current * instance only. * * @param string $name - * @param mixed $callback + * @param mixed $callback * @param string $message * @throws \InvalidArgumentException */ @@ -1073,18 +1100,20 @@ class Validator static::$_ruleMessages[$name] = $message; } + /** + * @param mixed $fields + * @return string + */ public function getUniqueRuleName($fields) { - if (is_array($fields)) - { + if (is_array($fields)) { $fields = implode("_", $fields); } $orgName = "{$fields}_rule"; $name = $orgName; $rules = $this->getRules(); - while (isset($rules[$name])) - { + while (isset($rules[$name])) { $name = $orgName . "_" . rand(0, 10000); } @@ -1095,7 +1124,7 @@ class Validator * Returns true if either a valdiator with the given name has been * registered or there is a default validator by that name. * - * @param string $name + * @param string $name * @return bool */ public function hasValidator($name) @@ -1110,7 +1139,7 @@ class Validator * * @param string|callback $rule * @param array|string $fields - * @return $this + * @return Validator * @throws \InvalidArgumentException */ public function rule($rule, $fields) @@ -1118,12 +1147,10 @@ class Validator // Get any other arguments passed to function $params = array_slice(func_get_args(), 2); - if (is_callable($rule) - && !(is_string($rule) && $this->hasValidator($rule))) - { + if (is_callable($rule) && !(is_string($rule) && $this->hasValidator($rule))) { $name = $this->getUniqueRuleName($fields); - $msg = isset($params[0]) ? $params[0] : null; - $this->addInstanceRule($name, $rule, $msg); + $message = isset($params[0]) ? $params[0] : null; + $this->addInstanceRule($name, $rule, $message); $rule = $name; } @@ -1131,13 +1158,15 @@ class Validator if (!isset($errors[$rule])) { $ruleMethod = 'validate' . ucfirst($rule); if (!method_exists($this, $ruleMethod)) { - throw new \InvalidArgumentException("Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule()."); + throw new \InvalidArgumentException( + "Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule()." + ); } } // Ensure rule has an accompanying message - $msgs = $this->getRuleMessages(); - $message = isset($msgs[$rule]) ? $msgs[$rule] : self::ERROR_DEFAULT; + $messages = $this->getRuleMessages(); + $message = isset($messages[$rule]) ? $messages[$rule] : self::ERROR_DEFAULT; // Ensure message contains field label if (function_exists('mb_strpos')) { @@ -1151,8 +1180,8 @@ class Validator $this->_validations[] = array( 'rule' => $rule, - 'fields' => (array) $fields, - 'params' => (array) $params, + 'fields' => (array)$fields, + 'params' => (array)$params, 'message' => $message ); @@ -1161,8 +1190,7 @@ class Validator /** * @param string $value - * @internal param array $labels - * @return $this + * @return Validator */ public function label($value) { @@ -1174,7 +1202,7 @@ class Validator /** * @param array $labels - * @return $this + * @return Validator */ public function labels($labels = array()) { @@ -1185,29 +1213,29 @@ class Validator /** * @param string $field - * @param string $msg + * @param string $message * @param array $params * @return array */ - protected function checkAndSetLabel($field, $msg, $params) + protected function checkAndSetLabel($field, $message, $params) { if (isset($this->_labels[$field])) { - $msg = str_replace('{field}', $this->_labels[$field], $msg); + $message = str_replace('{field}', $this->_labels[$field], $message); if (is_array($params)) { $i = 1; foreach ($params as $k => $v) { - $tag = '{field'. $i .'}'; + $tag = '{field' . $i . '}'; $label = isset($params[$k]) && (is_numeric($params[$k]) || is_string($params[$k])) && isset($this->_labels[$params[$k]]) ? $this->_labels[$params[$k]] : $tag; - $msg = str_replace($tag, $label, $msg); + $message = str_replace($tag, $label, $message); $i++; } } } else { - $msg = str_replace('{field}', ucwords(str_replace('_', ' ', $field)), $msg); + $message = str_replace('{field}', ucwords(str_replace('_', ' ', $field)), $message); } - return $msg; + return $message; } /** @@ -1220,8 +1248,8 @@ class Validator foreach ($rules as $ruleType => $params) { if (is_array($params)) { foreach ($params as $innerParams) { - if (! is_array($innerParams)){ - $innerParams = (array) $innerParams; + if (!is_array($innerParams)) { + $innerParams = (array)$innerParams; } array_unshift($innerParams, $ruleType); call_user_func_array(array($this, 'rule'), $innerParams); @@ -1237,7 +1265,7 @@ class Validator * * @param array $data * @param array $fields - * @return \Valitron\Validator + * @return Validator */ public function withData($data, $fields = array()) { @@ -1250,29 +1278,30 @@ class Validator /** * Convenience method to add validation rule(s) by field * - * @param string field_name - * @param array $rules + * @param string $field + * @param array $rules */ - public function mapFieldRules($field_name, $rules){ + public function mapFieldRules($field, $rules) + { $me = $this; - array_map(function($rule) use($field_name, $me){ + array_map(function ($rule) use ($field, $me) { //rule must be an array $rule = (array)$rule; //First element is the name of the rule - $rule_name = array_shift($rule); + $ruleName = array_shift($rule); //find a custom message, if any $message = null; - if (isset($rule['message'])){ + if (isset($rule['message'])) { $message = $rule['message']; unset($rule['message']); } //Add the field and additional parameters to the rule - $added = call_user_func_array(array($me, 'rule'), array_merge(array($rule_name, $field_name), $rule)); - if (! empty($message)){ + $added = call_user_func_array(array($me, 'rule'), array_merge(array($ruleName, $field), $rule)); + if (!empty($message)) { $added->message($message); } }, (array) $rules); @@ -1283,10 +1312,11 @@ class Validator * * @param array $rules */ - public function mapFieldsRules($rules){ + public function mapFieldsRules($rules) + { $me = $this; - array_map(function($field_name) use($rules, $me){ - $me->mapFieldRules($field_name, $rules[$field_name]); + array_map(function ($field) use ($rules, $me) { + $me->mapFieldRules($field, $rules[$field]); }, array_keys($rules)); } } diff --git a/tests/Valitron/StaticVsInstanceTest.php b/tests/Valitron/StaticVsInstanceTest.php index 1601189..174334c 100644 --- a/tests/Valitron/StaticVsInstanceTest.php +++ b/tests/Valitron/StaticVsInstanceTest.php @@ -7,8 +7,9 @@ class StaticVsInstanceTest extends BaseTestCase { Validator::lang('ar'); new Validator(array(), array(), 'en'); - $this->assertEquals('ar', Validator::lang(), - 'instance defined lang should not replace static global lang'); + $this->assertEquals( + 'ar', Validator::lang(), 'instance defined lang should not replace static global lang' + ); } /** diff --git a/tests/Valitron/ValidateAddInstanceRuleTest.php b/tests/Valitron/ValidateAddInstanceRuleTest.php index ddefac3..03cf5cb 100644 --- a/tests/Valitron/ValidateAddInstanceRuleTest.php +++ b/tests/Valitron/ValidateAddInstanceRuleTest.php @@ -1,21 +1,23 @@ validate(); - foreach ($v->errors() as $label => $messages) - { - foreach ($messages as $theMessage) - { + foreach ($v->errors() as $label => $messages) { + foreach ($messages as $theMessage) { $msg .= "\n\t{$label}: {$theMessage}"; } } @@ -30,13 +32,11 @@ class ValidateAddInstanceRuleTest extends BaseTestCase "fuzz" => "bazz", )); - $v->addInstanceRule("fooRule", function($field, $value) - { + $v->addInstanceRule("fooRule", function ($field, $value) { return $field !== "foo" || $value !== "barz"; }); - Validator::addRule("fuzzerRule", function($field, $value) - { + Validator::addRule("fuzzerRule", function ($field, $value) { return $field !== "fuzz" || $value === "bazz"; }); @@ -50,8 +50,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase public function testAddInstanceRuleFail() { $v = new Validator(array("foo" => "bar")); - $v->addInstanceRule("fooRule", function($field) - { + $v->addInstanceRule("fooRule", function ($field) { return $field === "for"; }); $v->rule("fooRule", "foo"); @@ -61,7 +60,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase public function testAddAddRuleWithCallback() { $v = new Validator(array("foo" => "bar")); - $v->rule(function($field, $value) { + $v->rule(function ($field, $value) { return $field === "foo" && $value === "bar"; }, "foo"); @@ -71,7 +70,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase public function testAddAddRuleWithCallbackFail() { $v = new Validator(array("foo" => "baz")); - $v->rule(function($field, $value) { + $v->rule(function ($field, $value) { return $field === "foo" && $value === "bar"; }, "foo"); @@ -81,30 +80,30 @@ class ValidateAddInstanceRuleTest extends BaseTestCase public function testAddAddRuleWithCallbackFailMessage() { $v = new Validator(array("foo" => "baz")); - $v->rule(function($field, $value) { + $v->rule(function ($field, $value) { return $field === "foo" && $value === "bar"; }, "foo", "test error message"); $this->assertFalse($v->validate()); - $errors = $v->errors(); + $errors = $v->errors(); $this->assertArrayHasKey("foo", $errors); $this->assertCount(1, $errors["foo"]); $this->assertEquals("Foo test error message", $errors["foo"][0]); } - public function testAddRuleWithNamedCallbackOk() - { - $v = new Validator(array("bar" => "foo")); - $v->rule("callbackTestFunction", "bar"); - $this->assertFalse($v->validate()); - } + public function testAddRuleWithNamedCallbackOk() + { + $v = new Validator(array("bar" => "foo")); + $v->rule("callbackTestFunction", "bar"); + $this->assertFalse($v->validate()); + } - public function testAddRuleWithNamedCallbackErr() - { - $v = new Validator(array("foo" => "bar")); - $v->rule("callbackTestFunction", "foo"); - $this->assertTrue($v->validate()); - } + public function testAddRuleWithNamedCallbackErr() + { + $v = new Validator(array("foo" => "bar")); + $v->rule("callbackTestFunction", "foo"); + $this->assertTrue($v->validate()); + } public function testUniqueRuleName() { @@ -113,7 +112,8 @@ class ValidateAddInstanceRuleTest extends BaseTestCase $this->assertEquals("foo_bar_rule", $v->getUniqueRuleName($args)); $this->assertEquals("foo_rule", $v->getUniqueRuleName("foo")); - $v->addInstanceRule("foo_rule", function() {}); + $v->addInstanceRule("foo_rule", function () { + }); $u = $v->getUniqueRuleName("foo"); $this->assertRegExp("/^foo_rule_[0-9]{1,5}$/", $u); } diff --git a/tests/Valitron/ValidateTest.php b/tests/Valitron/ValidateTest.php index 6abdf6e..1ef30fa 100644 --- a/tests/Valitron/ValidateTest.php +++ b/tests/Valitron/ValidateTest.php @@ -768,14 +768,14 @@ class ValidateTest extends BaseTestCase $this->assertTrue($v->validate()); } - public function testContainsNotFound() + public function testContainsInvalid() { $v = new Validator(array('test_string' => 'this is a test')); $v->rule('contains', 'test_string', 'foobar'); $this->assertFalse($v->validate()); } - public function testContainsStrictNotFound() + public function testContainsStrictInvalid() { $v = new Validator(array('test_string' => 'this is a Test')); $v->rule('contains', 'test_string', 'test'); @@ -783,9 +783,93 @@ class ValidateTest extends BaseTestCase } public function testContainsInvalidValue() + { + $v = new Validator(array('test_string' => false)); + $v->rule('contains', 'test_string', 'foobar'); + $this->assertFalse($v->validate()); + } + + public function testContainsInvalidRule() { $v = new Validator(array('test_string' => 'this is a test')); - $v->rule('contains', 'test_string', array('test')); + $v->rule('contains', 'test_string', null); + $this->assertFalse($v->validate()); + } + + public function testArrayContainsValid() + { + // numeric values + $v = new Validator(array('test_field' => array(81, 3, 15))); + $v->rule('arrayContains', 'test_field', array(45, 15, 3, 7, 28, 81)); + $this->assertTrue($v->validate()); + + // string values + $v = new Validator(array('test_field' => array('white', 'green', 'blue'))); + $v->rule('arrayContains', 'test_field', array('green', 'orange', 'blue', 'yellow', 'white', 'brown')); + $this->assertTrue($v->validate()); + + // mixed values + $v = new Validator(array('test_field' => array(81, false, 'orange'))); + $v->rule('arrayContains', 'test_field', array(45, 'green', true, 'orange', null, 81, false)); + $this->assertTrue($v->validate()); + } + + public function testArrayContainsInvalid() + { + $v = new Validator(array('test_field' => array(81, false, 'orange'))); + $v->rule('arrayContains', 'test_field', array(45, 'green', true, 'orange', null, false, 7)); + $this->assertFalse($v->validate()); + } + + public function testArrayContainsInvalidValue() + { + $v = new Validator(array('test_field' => 'black 45')); + $v->rule('arrayContains', 'test_field', array('black', 45)); + $this->assertFalse($v->validate()); + } + + public function testArrayContainsInvalidRule() + { + // rule value has invalid type + $v = new Validator(array('test_field' => array('black', 45))); + $v->rule('arrayContains', 'test_field', 'black 45'); + $this->assertFalse($v->validate()); + + // rule value not specified + $v = new Validator(array('test_field' => array('black', 45))); + $v->rule('arrayContains', 'test_field'); + $this->assertFalse($v->validate()); + } + + public function testUniqueValid() + { + // numeric values + $v = new Validator(array('test_field' => array(81, 3, 15))); + $v->rule('unique', 'test_field'); + $this->assertTrue($v->validate()); + + // string values + $v = new Validator(array('test_field' => array('white', 'green', 'blue'))); + $v->rule('unique', 'test_field'); + $this->assertTrue($v->validate()); + + // mixed values + $v = new Validator(array('test_field' => array(81, false, 'orange'))); + $v->rule('unique', 'test_field'); + $this->assertTrue($v->validate()); + } + + public function testUniqueInvalid() + { + $v = new Validator(array('test_field' => array(81, false, 'orange', false))); + $v->rule('unique', 'test_field'); + $this->assertFalse($v->validate()); + } + + public function testUniqueInvalidValue() + { + $v = new Validator(array('test_field' => 'lorem ipsum')); + $v->rule('unique', 'test_field'); $this->assertFalse($v->validate()); } @@ -1110,66 +1194,66 @@ class ValidateTest extends BaseTestCase public function testInstanceOfValidWithString() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rule('instanceOf', 'attributeName', 'stdClass'); - $this->assertTrue($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rule('instanceOf', 'attributeName', 'stdClass'); + $this->assertTrue($v->validate()); } public function testInstanceOfInvalidWithInstance() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rule('instanceOf', 'attributeName', new Validator(array())); - $this->assertFalse($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rule('instanceOf', 'attributeName', new Validator(array())); + $this->assertFalse($v->validate()); } public function testInstanceOfValidWithInstance() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rule('instanceOf', 'attributeName', new stdClass()); - $this->assertTrue($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rule('instanceOf', 'attributeName', new stdClass()); + $this->assertTrue($v->validate()); } public function testInstanceOfErrorMessageShowsInstanceName() { - $v = new Validator(array('attributeName' => new Validator(array()))); - $v->rule('instanceOf', 'attributeName', new stdClass()); - $v->validate(); - $expected_error = array( - "attributeName" => array( - "AttributeName must be an instance of 'stdClass'" - ) - ); - $this->assertEquals($expected_error, $v->errors()); + $v = new Validator(array('attributeName' => new Validator(array()))); + $v->rule('instanceOf', 'attributeName', new stdClass()); + $v->validate(); + $expected_error = array( + "attributeName" => array( + "AttributeName must be an instance of 'stdClass'" + ) + ); + $this->assertEquals($expected_error, $v->errors()); } public function testInstanceOfInvalidWithString() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rule('instanceOf', 'attributeName', 'SomeOtherClass'); - $this->assertFalse($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rule('instanceOf', 'attributeName', 'SomeOtherClass'); + $this->assertFalse($v->validate()); } public function testInstanceOfWithAlternativeSyntaxValid() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rules(array( - 'instanceOf' => array( - array('attributeName', 'stdClass') - ) - )); - $this->assertTrue($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rules(array( + 'instanceOf' => array( + array('attributeName', 'stdClass') + ) + )); + $this->assertTrue($v->validate()); } public function testInstanceOfWithAlternativeSyntaxInvalid() { - $v = new Validator(array('attributeName' => new stdClass())); - $v->rules(array( - 'instanceOf' => array( - array('attributeName', 'SomeOtherClassInAlternativeSyntaxInvalid') - ) - )); - $v->validate(); - $this->assertFalse($v->validate()); + $v = new Validator(array('attributeName' => new stdClass())); + $v->rules(array( + 'instanceOf' => array( + array('attributeName', 'SomeOtherClassInAlternativeSyntaxInvalid') + ) + )); + $v->validate(); + $this->assertFalse($v->validate()); } /** @@ -1244,35 +1328,37 @@ class ValidateTest extends BaseTestCase public function testRequiredEdgeCases() { $v = new Validator(array( - 'zero'=>0, - 'zero_txt' => '0', - 'false'=>false, - 'empty_array'=>array() - )); + 'zero' => 0, + 'zero_txt' => '0', + 'false' => false, + 'empty_array' => array() + )); $v->rule('required', array('zero', 'zero_txt', 'false', 'empty_array')); $this->assertTrue($v->validate()); } - public function testRequiredAllowEmpty(){ - $data= array( - 'empty_text'=>'', + public function testRequiredAllowEmpty() + { + $data = array( + 'empty_text' => '', 'null_value' => null, - 'in_array'=>array( - 'empty_text'=>'' + 'in_array' => array( + 'empty_text' => '' ) ); - $v1= new Validator($data); + $v1 = new Validator($data); $v1->rule('required', array('empty_text', 'null_value', 'in_array.empty_text')); $this->assertFalse($v1->validate()); - $v2= new Validator($data); + $v2 = new Validator($data); $v2->rule('required', array('empty_text', 'null_value', 'in_array.empty_text')); $this->assertFalse($v2->validate()); } } -function sampleFunctionCallback($field, $value, array $params) { - return true; +function sampleFunctionCallback($field, $value, array $params) +{ + return true; } From c4be38862b554b6eb40593c09e71e29e38a137e1 Mon Sep 17 00:00:00 2001 From: misantron Date: Fri, 20 Apr 2018 21:00:34 +0300 Subject: [PATCH 3/6] Validation fixes --- README.md | 4 +-- lang/en.php | 62 +++++++++++++++++---------------- lang/ru.php | 62 +++++++++++++++++---------------- src/Valitron/Validator.php | 9 +++-- tests/Valitron/ValidateTest.php | 21 ++++++----- 5 files changed, 85 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 1eb8745..c684bc5 100644 --- a/README.md +++ b/README.md @@ -146,8 +146,8 @@ V::lang('ar'); * `dateBefore` - Field is a valid date and is before the given date * `dateAfter` - Field is a valid date and is after the given date * `contains` - Field is a string and contains the given string - * `arrayContains` - Field is an array and contains the given array - * `unique` - Field is an array and contains unique values + * `arrayContains` - Field is an array or a scalar value and contains the given array + * `containsUnique` - Field is an array and contains unique values * `creditCard` - Field is a valid credit card number * `instanceOf` - Field contains an instance of the given class * `optional` - Value does not need to be included in data array. If it is however, it must pass validation. diff --git a/lang/en.php b/lang/en.php index 10c944b..6b11ba6 100644 --- a/lang/en.php +++ b/lang/en.php @@ -1,34 +1,36 @@ "is 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", - 'length' => "must be %d characters long", - 'min' => "must be at least %s", - 'max' => "must be no more than %s", - 'in' => "contains invalid value", - 'notIn' => "contains invalid value", - 'ip' => "is not a valid IP address", - 'email' => "is not a valid email address", - 'url' => "is not a valid URL", - 'urlActive' => "must be an 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' => "contains invalid characters", - 'date' => "is not a valid date", - 'dateFormat' => "must be date with format '%s'", - 'dateBefore' => "must be date before '%s'", - 'dateAfter' => "must be date after '%s'", - 'contains' => "must contain %s", - 'boolean' => "must be a boolean", - 'lengthBetween' => "must be between %d and %d characters", - 'creditCard' => "must be a valid credit card number", - 'lengthMin' => "must be at least %d characters long", - 'lengthMax' => "must not exceed %d characters", - 'instanceOf' => "must be an instance of '%s'" + 'required' => "is 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", + 'length' => "must be %d characters long", + 'min' => "must be at least %s", + 'max' => "must be no more than %s", + 'in' => "contains invalid value", + 'notIn' => "contains invalid value", + 'ip' => "is not a valid IP address", + 'email' => "is not a valid email address", + 'url' => "is not a valid URL", + 'urlActive' => "must be an 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' => "contains invalid characters", + 'date' => "is not a valid date", + 'dateFormat' => "must be date with format '%s'", + 'dateBefore' => "must be date before '%s'", + 'dateAfter' => "must be date after '%s'", + 'contains' => "must contain %s", + 'boolean' => "must be a boolean", + 'lengthBetween' => "must be between %d and %d characters", + 'creditCard' => "must be a valid credit card number", + 'lengthMin' => "must be at least %d characters long", + 'lengthMax' => "must not exceed %d characters", + 'instanceOf' => "must be an instance of '%s'", + 'containsUnique' => "must contain unique elements only", + 'arrayContains' => "contains invalid value", ); diff --git a/lang/ru.php b/lang/ru.php index 37c914c..01cd448 100644 --- a/lang/ru.php +++ b/lang/ru.php @@ -1,34 +1,36 @@ "обязательно для заполнения", - 'equals' => "должно содержать '%s'", - 'different' => "должно отличаться от '%s'", - 'accepted' => "должно быть указано", - 'numeric' => "должно содержать числовое значение", - 'integer' => "должно быть числом", - 'length' => "должно быть длиннее, чем %d", - 'min' => "должно быть больше, чем %s", - 'max' => "должно быть меньше, чем %s", - 'in' => "содержит неверное значение", - 'notIn' => "содержит неверное значение", - 'ip' => "не является валидным IP адресом", - 'email' => "не является валидным email адресом", - 'url' => "не является валидной ссылкой", - 'urlActive' => "содержит не активную ссылку", - 'alpha' => "должно содержать только латинские символы", - 'alphaNum' => "должно содержать только латинские символы и/или цифры", - 'slug' => "должно содержать только латинские символы, цифры, тире и подчёркивания", - 'regex' => "содержит недопустимые символы", - 'date' => "не является датой", - 'dateFormat' => "должно содержать дату следующего формата: %s", - 'dateBefore' => "должно содержать дату не позднее, чем %s", - 'dateAfter' => "должно содержать дату не ранее, чем %s", - 'contains' => "должно содержать %s", - 'boolean' => "должно содержать логическое значение", - 'lengthBetween' => "должно содержать от %d до %d символов", - 'creditCard' => "должно быть номером кредитной карты", - 'lengthMin' => "должно содержать более %d символов", - 'lengthMax' => "должно содержать менее %d символов", - 'instanceOf' => "должно быть объектом класса '%s'" + 'required' => "обязательно для заполнения", + 'equals' => "должно содержать '%s'", + 'different' => "должно отличаться от '%s'", + 'accepted' => "должно быть указано", + 'numeric' => "должно содержать числовое значение", + 'integer' => "должно быть числом", + 'length' => "должно быть длиннее, чем %d", + 'min' => "должно быть больше, чем %s", + 'max' => "должно быть меньше, чем %s", + 'in' => "содержит неверное значение", + 'notIn' => "содержит неверное значение", + 'ip' => "не является валидным IP адресом", + 'email' => "не является валидным email адресом", + 'url' => "не является валидной ссылкой", + 'urlActive' => "содержит не активную ссылку", + 'alpha' => "должно содержать только латинские символы", + 'alphaNum' => "должно содержать только латинские символы и/или цифры", + 'slug' => "должно содержать только латинские символы, цифры, тире и подчёркивания", + 'regex' => "содержит недопустимые символы", + 'date' => "не является датой", + 'dateFormat' => "должно содержать дату следующего формата: %s", + 'dateBefore' => "должно содержать дату не позднее, чем %s", + 'dateAfter' => "должно содержать дату не ранее, чем %s", + 'contains' => "должно содержать %s", + 'boolean' => "должно содержать логическое значение", + 'lengthBetween' => "должно содержать от %d до %d символов", + 'creditCard' => "должно быть номером кредитной карты", + 'lengthMin' => "должно содержать более %d символов", + 'lengthMax' => "должно содержать менее %d символов", + 'instanceOf' => "должно быть объектом класса '%s'", + 'containsUnique' => "должно содержать только уникальные элементы", + 'arrayContains' => "содержит неверное значение", ); diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index c377b2f..79c4236 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -481,8 +481,11 @@ class Validator if (!isset($params[0])) { return false; } - if (!is_array($value) || !is_array($params[0])) { - return false; + if (!is_array($params[0])) { + $params[0] = array($params[0]); + } + if (is_scalar($value)) { + return $this->validateIn($field, $value, $params); } $intersect = array_intersect($value, $params[0]); @@ -496,7 +499,7 @@ class Validator * @param array $value * @return bool */ - protected function validateUnique($field, $value) + protected function validateContainsUnique($field, $value) { if (!is_array($value)) { return false; diff --git a/tests/Valitron/ValidateTest.php b/tests/Valitron/ValidateTest.php index d5d6f3b..469cef3 100644 --- a/tests/Valitron/ValidateTest.php +++ b/tests/Valitron/ValidateTest.php @@ -884,6 +884,11 @@ class ValidateTest extends BaseTestCase $v = new Validator(array('test_field' => array(81, false, 'orange'))); $v->rule('arrayContains', 'test_field', array(45, 'green', true, 'orange', null, 81, false)); $this->assertTrue($v->validate()); + + // string value and validation target cast to array + $v = new Validator(array('test_field' => 'blue')); + $v->rule('arrayContains', 'test_field', 'blue'); + $this->assertTrue($v->validate()); } public function testArrayContainsInvalid() @@ -913,35 +918,35 @@ class ValidateTest extends BaseTestCase $this->assertFalse($v->validate()); } - public function testUniqueValid() + public function testContainsUniqueValid() { // numeric values $v = new Validator(array('test_field' => array(81, 3, 15))); - $v->rule('unique', 'test_field'); + $v->rule('containsUnique', 'test_field'); $this->assertTrue($v->validate()); // string values $v = new Validator(array('test_field' => array('white', 'green', 'blue'))); - $v->rule('unique', 'test_field'); + $v->rule('containsUnique', 'test_field'); $this->assertTrue($v->validate()); // mixed values $v = new Validator(array('test_field' => array(81, false, 'orange'))); - $v->rule('unique', 'test_field'); + $v->rule('containsUnique', 'test_field'); $this->assertTrue($v->validate()); } - public function testUniqueInvalid() + public function testContainsUniqueInvalid() { $v = new Validator(array('test_field' => array(81, false, 'orange', false))); - $v->rule('unique', 'test_field'); + $v->rule('containsUnique', 'test_field'); $this->assertFalse($v->validate()); } - public function testUniqueInvalidValue() + public function testContainsUniqueInvalidValue() { $v = new Validator(array('test_field' => 'lorem ipsum')); - $v->rule('unique', 'test_field'); + $v->rule('containsUnique', 'test_field'); $this->assertFalse($v->validate()); } From c52612f86c0904ae5a46f8f69e31bf2e13202659 Mon Sep 17 00:00:00 2001 From: misantron Date: Sat, 22 Sep 2018 17:00:34 +0300 Subject: [PATCH 4/6] Tests code style fixes --- composer.json | 4 +-- src/Valitron/Validator.php | 36 +++++++++++++--------- tests/Valitron/BaseTestCase.php | 2 +- tests/Valitron/ErrorMessagesTest.php | 12 +++++--- tests/Valitron/LangTest.php | 4 +-- tests/Valitron/MapRulesTest.php | 12 ++------ tests/Valitron/StopOnFirstFailTest.php | 42 +++++++++++++------------- tests/Valitron/ValidateTest.php | 2 +- 8 files changed, 59 insertions(+), 55 deletions(-) diff --git a/composer.json b/composer.json index 30e5c96..43a760a 100644 --- a/composer.json +++ b/composer.json @@ -4,8 +4,8 @@ "description": "Simple, elegant, stand-alone validation library with NO dependencies", "keywords": ["validation", "validator", "valid"], "homepage": "http://github.com/vlucas/valitron", - "license" : "BSD-3-Clause", - "authors" : [ + "license": "BSD-3-Clause", + "authors": [ { "name": "Vance Lucas", "email": "vance@vancelucas.com", diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index 45c229d..8ab5f69 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -897,7 +897,14 @@ class Validator return $isInstanceOf; } - //Validate optional field + /** + * Validate optional field + * + * @param $field + * @param $value + * @param $params + * @return bool + */ protected function validateOptional($field, $value, $params) { //Always return true @@ -905,7 +912,7 @@ class Validator } /** - * Get array of fields and data + * Get array of fields and data * * @return array */ @@ -997,7 +1004,7 @@ class Validator } // Catches the case where the data isn't an array or object if (is_scalar($data)) { - return array(NULL, false); + return array(null, false); } $identifier = array_shift($identifiers); // Glob match @@ -1012,8 +1019,7 @@ class Validator } } return array($values, true); - } - // Dead end, abort + } // Dead end, abort elseif ($identifier === null || ! isset($data[$identifier])) { if ($allow_empty){ //when empty values are allowed, we only care if the key exists @@ -1083,7 +1089,9 @@ class Validator } } } - if ($set_to_break) break; + if ($set_to_break) { + break; + } } return count($this->errors()) === 0; @@ -1151,9 +1159,9 @@ class Validator * Adds a new validation rule callback that is tied to the current * instance only. * - * @param string $name - * @param callable $callback - * @param string $message + * @param string $name + * @param callable $callback + * @param string $message * @throws \InvalidArgumentException */ public function addInstanceRule($name, $callback, $message = null) @@ -1167,9 +1175,9 @@ class Validator /** * Register new validation rule callback * - * @param string $name - * @param callable $callback - * @param string $message + * @param string $name + * @param callable $callback + * @param string $message * @throws \InvalidArgumentException */ public static function addRule($name, $callback, $message = null) @@ -1221,8 +1229,8 @@ class Validator /** * Convenience method to add a single validation rule * - * @param string|callback $rule - * @param array|string $fields + * @param string|callback $rule + * @param array|string $fields * @return Validator * @throws \InvalidArgumentException */ diff --git a/tests/Valitron/BaseTestCase.php b/tests/Valitron/BaseTestCase.php index ccfc736..40cf559 100644 --- a/tests/Valitron/BaseTestCase.php +++ b/tests/Valitron/BaseTestCase.php @@ -18,7 +18,7 @@ class BaseTestCase extends TestCase protected function resetProperty($name, $value = null) { - $prop = new ReflectionProperty('Valitron\Validator', $name); + $prop = new \ReflectionProperty('Valitron\Validator', $name); $prop->setAccessible(true); $prop->setValue($value); $prop->setAccessible(false); diff --git a/tests/Valitron/ErrorMessagesTest.php b/tests/Valitron/ErrorMessagesTest.php index 94f3333..583b1dd 100644 --- a/tests/Valitron/ErrorMessagesTest.php +++ b/tests/Valitron/ErrorMessagesTest.php @@ -1,4 +1,5 @@ ''), array(), 'en', __DIR__ . '/../lang'); + $v = new Validator(array('name' => ''), array(), 'en', __DIR__ . '/../lang'); $v->rule('required', 'name'); $v->validate(); - $this->assertEquals( $v->errors('name'), array('A value is required for Name')); + $this->assertEquals($v->errors('name'), array('A value is required for Name')); } - public function testMessageWithFieldAndLabelSet(){ - $v = new Validator(array('name'=>''), array(), 'en', __DIR__ . '/../lang'); + public function testMessageWithFieldAndLabelSet() + { + $v = new Validator(array('name' => ''), array(), 'en', __DIR__ . '/../lang'); $v->rule('required', 'name')->label('my name'); $v->validate(); - $this->assertEquals( $v->errors('name'), array('A value is required for my name')); + $this->assertEquals($v->errors('name'), array('A value is required for my name')); } } diff --git a/tests/Valitron/LangTest.php b/tests/Valitron/LangTest.php index 659d5f1..200519f 100644 --- a/tests/Valitron/LangTest.php +++ b/tests/Valitron/LangTest.php @@ -9,7 +9,7 @@ class LangTest extends BaseTestCase } /** - * Lang defined statically should not be overrided by constructor default + * Lang defined statically should not be override by constructor default */ public function testLangDefinedStatically() { @@ -20,7 +20,7 @@ class LangTest extends BaseTestCase } /** - * LangDir defined statically should not be overrided by constructor default + * LangDir defined statically should not be override by constructor default */ public function testLangDirDefinedStatically() { diff --git a/tests/Valitron/MapRulesTest.php b/tests/Valitron/MapRulesTest.php index 46293e4..21e0c3a 100644 --- a/tests/Valitron/MapRulesTest.php +++ b/tests/Valitron/MapRulesTest.php @@ -1,12 +1,11 @@ array( array('threshold' => 50), @@ -36,7 +34,6 @@ class MapRulesTest extends BaseTestCase )); $this->assertFalse($v->validate()); - } public function testMapMultipleFieldsRules() @@ -60,7 +57,6 @@ class MapRulesTest extends BaseTestCase $this->assertFalse($v->validate()); $this->assertFalse($v->errors('myField1')); $this->assertEquals(2, sizeof($v->errors('myField2'))); - } public function testCustomMessageSingleField() @@ -82,10 +78,10 @@ class MapRulesTest extends BaseTestCase { $rules = array( 'myField1' => array( - array('lengthMin', 14, 'message'=>'My Custom Error 1') + array('lengthMin', 14, 'message' => 'My Custom Error 1') ), 'myField2' => array( - array('lengthMin', 14, 'message'=>'My Custom Error 2') + array('lengthMin', 14, 'message' => 'My Custom Error 2') ) ); @@ -100,8 +96,6 @@ class MapRulesTest extends BaseTestCase $errors1 = $v->errors('myField1'); $this->assertEquals('My Custom Error 1', $errors1[0]); - - $errors2 = $v->errors('myField2'); $this->assertEquals('My Custom Error 2', $errors2[0]); } diff --git a/tests/Valitron/StopOnFirstFailTest.php b/tests/Valitron/StopOnFirstFailTest.php index 656427d..1e624f6 100644 --- a/tests/Valitron/StopOnFirstFailTest.php +++ b/tests/Valitron/StopOnFirstFailTest.php @@ -1,28 +1,28 @@ array( + array('lengthMin', 5, 'message' => 'myField1 must be 5 characters minimum'), + array('url', 'message' => 'myField1 is not a valid url'), + array('urlActive', 'message' => 'myField1 is not an active url') + ) + ); -class StopOnFirstFail extends BaseTestCase { + $v = new Validator(array( + 'myField1' => 'myVal' + )); - public function testStopOnFirstFail() { - $rules = array( - 'myField1' => array( - array('lengthMin', 5, 'message'=>'myField1 must be 5 characters minimum'), - array('url', 'message' => 'myField1 is not a valid url'), - array('urlActive', 'message' => 'myField1 is not an active url') - ) - ); - - $v = new Validator(array( - 'myField1' => 'myVal' - )); - - $v->mapFieldsRules($rules); - $v->stopOnFirstFail(true); - $this->assertFalse($v->validate()); - - $errors = $v->errors(); - $this->assertCount(1, $errors['myField1']); - } + $v->mapFieldsRules($rules); + $v->stopOnFirstFail(true); + $this->assertFalse($v->validate()); + $errors = $v->errors(); + $this->assertCount(1, $errors['myField1']); + } } diff --git a/tests/Valitron/ValidateTest.php b/tests/Valitron/ValidateTest.php index c74697f..d33977d 100644 --- a/tests/Valitron/ValidateTest.php +++ b/tests/Valitron/ValidateTest.php @@ -1302,7 +1302,7 @@ class ValidateTest extends BaseTestCase public function testFalseStillTriggersValidation() { - $v = new Validator(array('test' => FALSE)); + $v = new Validator(array('test' => false)); $v->rule('min', 'test', 5); $this->assertFalse($v->validate()); } From 873c996db06bf19336fb48ac640538595d92dc6b Mon Sep 17 00:00:00 2001 From: misantron Date: Sat, 22 Sep 2018 17:52:25 +0300 Subject: [PATCH 5/6] Fix .gitignore: remove duplicated row --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index a2330fd..17193f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .DS_Store -.idea/ composer.phar composer.lock vendor From ee2ed6c3b9127eb110ac31caec75009d0b609e53 Mon Sep 17 00:00:00 2001 From: misantron Date: Sun, 23 Sep 2018 00:53:19 +0300 Subject: [PATCH 6/6] Change validation rule to 'subset', document and translation fixes --- README.md | 2 +- lang/en.php | 4 +++- lang/ru.php | 10 ++++++---- src/Valitron/Validator.php | 2 +- tests/Valitron/ValidateTest.php | 24 ++++++++++++------------ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 0f7a8fc..337412b 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ V::lang('ar'); * `dateBefore` - Field is a valid date and is before the given date * `dateAfter` - Field is a valid date and is after the given date * `contains` - Field is a string and contains the given string - * `arrayContains` - Field is an array or a scalar value and contains the given array + * `subset` - Field is an array or a scalar and all elements are contained in the given array * `containsUnique` - Field is an array and contains unique values * `creditCard` - Field is a valid credit card number * `instanceOf` - Field contains an instance of the given class diff --git a/lang/en.php b/lang/en.php index 6b11ba6..0c9e5a1 100644 --- a/lang/en.php +++ b/lang/en.php @@ -13,6 +13,8 @@ return array( 'in' => "contains invalid value", 'notIn' => "contains invalid value", 'ip' => "is not a valid IP address", + 'ipv4' => "is not a valid IPv4 address", + 'ipv6' => "is not a valid IPv6 address", 'email' => "is not a valid email address", 'url' => "is not a valid URL", 'urlActive' => "must be an active domain", @@ -32,5 +34,5 @@ return array( 'lengthMax' => "must not exceed %d characters", 'instanceOf' => "must be an instance of '%s'", 'containsUnique' => "must contain unique elements only", - 'arrayContains' => "contains invalid value", + 'subset' => "contains an item that is not in the list", ); diff --git a/lang/ru.php b/lang/ru.php index 01cd448..44957b2 100644 --- a/lang/ru.php +++ b/lang/ru.php @@ -2,17 +2,19 @@ return array( 'required' => "обязательно для заполнения", - 'equals' => "должно содержать '%s'", + 'equals' => "должно совпадать со значением '%s'", 'different' => "должно отличаться от '%s'", 'accepted' => "должно быть указано", 'numeric' => "должно содержать числовое значение", 'integer' => "должно быть числом", 'length' => "должно быть длиннее, чем %d", - 'min' => "должно быть больше, чем %s", - 'max' => "должно быть меньше, чем %s", + 'min' => "должно быть не менее, чем %s", + 'max' => "должно быть не более, чем %s", 'in' => "содержит неверное значение", 'notIn' => "содержит неверное значение", 'ip' => "не является валидным IP адресом", + 'ipv4' => "не является валидным IPv4 адресом", + 'ipv6' => "не является валидным IPv6 адресом", 'email' => "не является валидным email адресом", 'url' => "не является валидной ссылкой", 'urlActive' => "содержит не активную ссылку", @@ -32,5 +34,5 @@ return array( 'lengthMax' => "должно содержать менее %d символов", 'instanceOf' => "должно быть объектом класса '%s'", 'containsUnique' => "должно содержать только уникальные элементы", - 'arrayContains' => "содержит неверное значение", + 'subset' => "содержит элемент, не указанный в списке", ); diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index 8ab5f69..93c06be 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -481,7 +481,7 @@ class Validator * @param array $params * @return bool */ - protected function validateArrayContains($field, $value, $params) + protected function validateSubset($field, $value, $params) { if (!isset($params[0])) { return false; diff --git a/tests/Valitron/ValidateTest.php b/tests/Valitron/ValidateTest.php index d33977d..ba59117 100644 --- a/tests/Valitron/ValidateTest.php +++ b/tests/Valitron/ValidateTest.php @@ -941,53 +941,53 @@ class ValidateTest extends BaseTestCase $this->assertFalse($v->validate()); } - public function testArrayContainsValid() + public function testSubsetValid() { // numeric values $v = new Validator(array('test_field' => array(81, 3, 15))); - $v->rule('arrayContains', 'test_field', array(45, 15, 3, 7, 28, 81)); + $v->rule('subset', 'test_field', array(45, 15, 3, 7, 28, 81)); $this->assertTrue($v->validate()); // string values $v = new Validator(array('test_field' => array('white', 'green', 'blue'))); - $v->rule('arrayContains', 'test_field', array('green', 'orange', 'blue', 'yellow', 'white', 'brown')); + $v->rule('subset', 'test_field', array('green', 'orange', 'blue', 'yellow', 'white', 'brown')); $this->assertTrue($v->validate()); // mixed values $v = new Validator(array('test_field' => array(81, false, 'orange'))); - $v->rule('arrayContains', 'test_field', array(45, 'green', true, 'orange', null, 81, false)); + $v->rule('subset', 'test_field', array(45, 'green', true, 'orange', null, 81, false)); $this->assertTrue($v->validate()); // string value and validation target cast to array $v = new Validator(array('test_field' => 'blue')); - $v->rule('arrayContains', 'test_field', 'blue'); + $v->rule('subset', 'test_field', 'blue'); $this->assertTrue($v->validate()); } - public function testArrayContainsInvalid() + public function testSubsetInvalid() { $v = new Validator(array('test_field' => array(81, false, 'orange'))); - $v->rule('arrayContains', 'test_field', array(45, 'green', true, 'orange', null, false, 7)); + $v->rule('subset', 'test_field', array(45, 'green', true, 'orange', null, false, 7)); $this->assertFalse($v->validate()); } - public function testArrayContainsInvalidValue() + public function testSubsetInvalidValue() { $v = new Validator(array('test_field' => 'black 45')); - $v->rule('arrayContains', 'test_field', array('black', 45)); + $v->rule('subset', 'test_field', array('black', 45)); $this->assertFalse($v->validate()); } - public function testArrayContainsInvalidRule() + public function testSubsetInvalidRule() { // rule value has invalid type $v = new Validator(array('test_field' => array('black', 45))); - $v->rule('arrayContains', 'test_field', 'black 45'); + $v->rule('subset', 'test_field', 'black 45'); $this->assertFalse($v->validate()); // rule value not specified $v = new Validator(array('test_field' => array('black', 45))); - $v->rule('arrayContains', 'test_field'); + $v->rule('subset', 'test_field'); $this->assertFalse($v->validate()); }