diff --git a/phalcon/Validation/AbstractValidator.zep b/phalcon/Validation/AbstractValidator.zep index f5a783593d7..e25bde104db 100644 --- a/phalcon/Validation/AbstractValidator.zep +++ b/phalcon/Validation/AbstractValidator.zep @@ -210,6 +210,24 @@ abstract class AbstractValidator implements ValidatorInterface return label; } + /** + * Checks if field can be empty. + * + * @return bool + */ + protected function allowEmpty(var field, var value) -> bool + { + var allowEmpty; + + let allowEmpty = this->getOption("allowEmpty", false); + + if typeof allowEmpty == "array" { + let allowEmpty = isset allowEmpty[field] ? allowEmpty[field] : false; + } + + return allowEmpty && empty value; + } + /** * Create a default message by factory * diff --git a/phalcon/Validation/Validator/Alnum.zep b/phalcon/Validation/Validator/Alnum.zep index 78783eb69f9..a589d2ceeff 100644 --- a/phalcon/Validation/Validator/Alnum.zep +++ b/phalcon/Validation/Validator/Alnum.zep @@ -73,6 +73,9 @@ class Alnum extends AbstractValidator var value; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if !ctype_alnum(value) { validation->appendMessage( diff --git a/phalcon/Validation/Validator/Alpha.zep b/phalcon/Validation/Validator/Alpha.zep index af4a31b97e6..d163731544c 100644 --- a/phalcon/Validation/Validator/Alpha.zep +++ b/phalcon/Validation/Validator/Alpha.zep @@ -74,6 +74,9 @@ class Alpha extends AbstractValidator var value; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if preg_match("/[^[:alpha:]]/imu", value) { validation->appendMessage( diff --git a/phalcon/Validation/Validator/Between.zep b/phalcon/Validation/Validator/Between.zep index c08227b50b5..5d05cfe4675 100644 --- a/phalcon/Validation/Validator/Between.zep +++ b/phalcon/Validation/Validator/Between.zep @@ -90,6 +90,10 @@ class Between extends AbstractValidator minimum = this->getOption("minimum"), maximum = this->getOption("maximum"); + if this->allowEmpty(field, value) { + return true; + } + if typeof minimum == "array" { let minimum = minimum[field]; } diff --git a/phalcon/Validation/Validator/Callback.zep b/phalcon/Validation/Validator/Callback.zep index 980dba36bd3..94454bee9e0 100644 --- a/phalcon/Validation/Validator/Callback.zep +++ b/phalcon/Validation/Validator/Callback.zep @@ -95,6 +95,9 @@ class Callback extends AbstractValidator } let returnedValue = call_user_func(callback, data); + if this->allowEmpty(field, returnedValue) { + return true; + } if typeof returnedValue == "boolean" { if !returnedValue { diff --git a/phalcon/Validation/Validator/Confirmation.zep b/phalcon/Validation/Validator/Confirmation.zep index 20a77c6856b..9ff25fb3e79 100644 --- a/phalcon/Validation/Validator/Confirmation.zep +++ b/phalcon/Validation/Validator/Confirmation.zep @@ -66,8 +66,7 @@ class Confirmation extends AbstractValidator * 'template' => '', * 'with' => '', * 'labelWith' => '', - * 'ignoreCase' => false, - * 'allowEmpty' => false + * 'ignoreCase' => false * ] */ public function __construct(array! options = []) diff --git a/phalcon/Validation/Validator/CreditCard.zep b/phalcon/Validation/Validator/CreditCard.zep index 4d163b353c0..0929bb30435 100644 --- a/phalcon/Validation/Validator/CreditCard.zep +++ b/phalcon/Validation/Validator/CreditCard.zep @@ -74,6 +74,9 @@ class CreditCard extends AbstractValidator var value, valid; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } let valid = this->verifyByLuhnAlgorithm(value); diff --git a/phalcon/Validation/Validator/Date.zep b/phalcon/Validation/Validator/Date.zep index d91aef5e9cf..f4d29bd984c 100644 --- a/phalcon/Validation/Validator/Date.zep +++ b/phalcon/Validation/Validator/Date.zep @@ -81,8 +81,11 @@ class Date extends AbstractValidator var value, format; let value = validation->getValue(field); - let format = this->getOption("format"); + if this->allowEmpty(field, value) { + return true; + } + let format = this->getOption("format"); if typeof format == "array" { let format = format[field]; } diff --git a/phalcon/Validation/Validator/Digit.zep b/phalcon/Validation/Validator/Digit.zep index 7a3ea202b52..2e16902cddb 100644 --- a/phalcon/Validation/Validator/Digit.zep +++ b/phalcon/Validation/Validator/Digit.zep @@ -72,6 +72,9 @@ class Digit extends AbstractValidator public function validate( validation, var field) -> bool { var value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if is_int(value) || ctype_digit(value) { return true; diff --git a/phalcon/Validation/Validator/Email.zep b/phalcon/Validation/Validator/Email.zep index defcccd1170..156b0e80010 100644 --- a/phalcon/Validation/Validator/Email.zep +++ b/phalcon/Validation/Validator/Email.zep @@ -72,6 +72,9 @@ class Email extends AbstractValidator public function validate( validation, var field) -> bool { var value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if !filter_var(value, FILTER_VALIDATE_EMAIL) { validation->appendMessage( diff --git a/phalcon/Validation/Validator/ExclusionIn.zep b/phalcon/Validation/Validator/ExclusionIn.zep index 26be4762efc..d1c08e76e9a 100644 --- a/phalcon/Validation/Validator/ExclusionIn.zep +++ b/phalcon/Validation/Validator/ExclusionIn.zep @@ -88,6 +88,9 @@ class ExclusionIn extends AbstractValidator var value, domain, replacePairs, strict, fieldDomain; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } /** * A domain is an array with a list of valid values diff --git a/phalcon/Validation/Validator/Identical.zep b/phalcon/Validation/Validator/Identical.zep index 3b583dbf07e..2253a92dd37 100644 --- a/phalcon/Validation/Validator/Identical.zep +++ b/phalcon/Validation/Validator/Identical.zep @@ -82,6 +82,9 @@ class Identical extends AbstractValidator bool valid; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if this->hasOption("accepted") { let accepted = this->getOption("accepted"); diff --git a/phalcon/Validation/Validator/InclusionIn.zep b/phalcon/Validation/Validator/InclusionIn.zep index c6947a00cf8..b448d36ddfb 100644 --- a/phalcon/Validation/Validator/InclusionIn.zep +++ b/phalcon/Validation/Validator/InclusionIn.zep @@ -82,6 +82,9 @@ class InclusionIn extends AbstractValidator var value, domain, replacePairs, strict, fieldDomain; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } /** * A domain is an array with a list of valid values diff --git a/phalcon/Validation/Validator/Ip.zep b/phalcon/Validation/Validator/Ip.zep index e9a10629699..8e7d1385e49 100644 --- a/phalcon/Validation/Validator/Ip.zep +++ b/phalcon/Validation/Validator/Ip.zep @@ -93,37 +93,28 @@ class Ip extends AbstractValidator */ public function validate( validation, var field) -> bool { - var value, version, allowPrivate, allowReserved, allowEmpty, options; + var value, version, allowPrivate, allowReserved, options; - let value = validation->getValue(field), - version = this->getOption("version", FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6); + let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } + let version = this->getOption("version", FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6); if typeof version == "array" { let version = version[field]; } let allowPrivate = this->getOption("allowPrivate") ? 0 : FILTER_FLAG_NO_PRIV_RANGE; - if typeof allowPrivate == "array" { let allowPrivate = allowPrivate[field]; } let allowReserved = this->getOption("allowReserved") ? 0 : FILTER_FLAG_NO_RES_RANGE; - if typeof allowReserved == "array" { let allowReserved = allowReserved[field]; } - let allowEmpty = this->getOption("allowEmpty", false); - - if typeof allowEmpty == "array" { - let allowEmpty = isset allowEmpty[field] ? allowEmpty[field] : false; - } - - if allowEmpty && empty value { - return true; - } - let options = [ "options": [ "default": false diff --git a/phalcon/Validation/Validator/Numericality.zep b/phalcon/Validation/Validator/Numericality.zep index dd005d86477..e3b6e51c113 100644 --- a/phalcon/Validation/Validator/Numericality.zep +++ b/phalcon/Validation/Validator/Numericality.zep @@ -80,6 +80,10 @@ class Numericality extends AbstractValidator value = str_replace(" ", "", value), pattern = "/((^[-]?[0-9,]+(.[0-9]+)?$)|(^[-]?[0-9.]+(,[0-9]+)?$))/"; + if this->allowEmpty(field, value) { + return true; + } + if !preg_match(pattern, value) { validation->appendMessage( this->messageFactory(validation, field) diff --git a/phalcon/Validation/Validator/PresenceOf.zep b/phalcon/Validation/Validator/PresenceOf.zep index 21779dead98..924c9735f00 100644 --- a/phalcon/Validation/Validator/PresenceOf.zep +++ b/phalcon/Validation/Validator/PresenceOf.zep @@ -72,6 +72,9 @@ class PresenceOf extends AbstractValidator public function validate( validation, var field) -> bool { var value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if value === null || value === "" { validation->appendMessage( diff --git a/phalcon/Validation/Validator/Regex.zep b/phalcon/Validation/Validator/Regex.zep index 9de8fd8a98e..4752333e8dd 100644 --- a/phalcon/Validation/Validator/Regex.zep +++ b/phalcon/Validation/Validator/Regex.zep @@ -84,6 +84,9 @@ class Regex extends AbstractValidator // Check if the value match using preg_match in the PHP userland let matches = null; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } let pattern = this->getOption("pattern"); diff --git a/phalcon/Validation/Validator/StringLength/Max.zep b/phalcon/Validation/Validator/StringLength/Max.zep index c9c4fcf3f96..7900e4845e7 100644 --- a/phalcon/Validation/Validator/StringLength/Max.zep +++ b/phalcon/Validation/Validator/StringLength/Max.zep @@ -89,6 +89,9 @@ class Max extends AbstractValidator var value, length, maximum, replacePairs, included, result; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } // Check if mbstring is available to calculate the correct length if function_exists("mb_strlen") { diff --git a/phalcon/Validation/Validator/StringLength/Min.zep b/phalcon/Validation/Validator/StringLength/Min.zep index 6c467bbc1c4..b9179783fe5 100644 --- a/phalcon/Validation/Validator/StringLength/Min.zep +++ b/phalcon/Validation/Validator/StringLength/Min.zep @@ -89,6 +89,9 @@ class Min extends AbstractValidator var value, length, minimum, replacePairs, included, result; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } // Check if mbstring is available to calculate the correct length if function_exists("mb_strlen") { diff --git a/phalcon/Validation/Validator/Url.zep b/phalcon/Validation/Validator/Url.zep index fe1dd93e251..39164c66f28 100644 --- a/phalcon/Validation/Validator/Url.zep +++ b/phalcon/Validation/Validator/Url.zep @@ -75,6 +75,9 @@ class Url extends AbstractValidator var options, result, value; let value = validation->getValue(field); + if this->allowEmpty(field, value) { + return true; + } if fetch options, this->options["options"] { let result = filter_var(value, FILTER_VALIDATE_URL, options);