From 263e8c7f7e4c8f1e69a860e229c7649223ee6f39 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 2 May 2013 11:57:18 -0400 Subject: [PATCH] Finished CaptchaValidator. --- framework/assets/yii.validation.js | 145 ++++++++++++++++++------------ framework/validators/CaptchaValidator.php | 34 +++---- framework/validators/RangeValidator.php | 28 +++--- 3 files changed, 114 insertions(+), 93 deletions(-) diff --git a/framework/assets/yii.validation.js b/framework/assets/yii.validation.js index 495a72c..8490ba1 100644 --- a/framework/assets/yii.validation.js +++ b/framework/assets/yii.validation.js @@ -30,53 +30,61 @@ yii.validation = (function ($) { valid || messages.push(options.message); }, - compare: function (value, messages, options) { + boolean: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } + var valid = !options.strict && (value == options.trueValue || value == options.falseValue) + || options.strict && (value === options.trueValue || value === options.falseValue); - var compareValue, valid = true; - if (options.compareAttribute === undefined) { - compareValue = options.compareValue; - } else { - compareValue = $('#' + options.compareAttribute).val(); + valid || messages.push(options.message); + }, + + string: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; } - switch (options.operator) { - case '==': - valid = value == compareValue; - break; - case '===': - valid = value === compareValue; - break; - case '!=': - valid = value != compareValue; - break; - case '!==': - valid = value !== compareValue; - break; - case '>': - valid = value > compareValue; - break; - case '>=': - valid = value >= compareValue; - break; - case '<': - valid = value < compareValue; - break; - case '<=': - valid = value <= compareValue; - break; + + if (typeof value !== 'string') { + messages.push(options.message); + return; } - valid || messages.push(options.message); + if (options.min !== undefined && value.length < options.min) { + messages.push(options.tooShort); + } + if (options.max !== undefined && value.length > options.max) { + messages.push(options.tooLong); + } + if (options.is !== undefined && value.length != options.is) { + messages.push(options.is); + } }, - boolean: function (value, messages, options) { + number: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - var valid = !options.strict && (value == options.trueValue || value == options.falseValue) - || options.strict && (value === options.trueValue || value === options.falseValue); + + if (typeof value === 'string' && !value.match(options.pattern)) { + messages.push(options.message); + return; + } + + if (options.min !== undefined && value < options.min) { + messages.push(options.tooSmall); + } + if (options.max !== undefined && value > options.max) { + messages.push(options.tooBig); + } + }, + + range: function (value, messages, options) { + if (options.skipOnEmpty && isEmpty(value)) { + return; + } + var valid = !options.not && $.inArray(value, options.range) + || options.not && !$.inArray(value, options.range); valid || messages.push(options.message); }, @@ -115,43 +123,66 @@ yii.validation = (function ($) { } }, - string: function (value, messages, options) { + captcha: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - if (typeof value !== 'string') { - messages.push(options.message); - return; - } - - if (options.min !== undefined && value.length < options.min) { - messages.push(options.tooShort); + // CAPTCHA may be updated via AJAX and the updated hash is stored in body data + var hash = $('body').data(options.hashKey); + if (hash == null) { + hash = options.hash; + } else { + hash = hash[options.caseSensitive ? 0 : 1]; } - if (options.max !== undefined && value.length > options.max) { - messages.push(options.tooLong); + var v = options.caseSensitive ? value : value.toLowerCase(); + for (var i = v.length - 1, h = 0; i >= 0; --i) { + h += v.charCodeAt(i); } - if (options.is !== undefined && value.length != options.is) { - messages.push(options.is); + if(h != hash) { + messages.push(options.message); } }, - number: function (value, messages, options) { + compare: function (value, messages, options) { if (options.skipOnEmpty && isEmpty(value)) { return; } - if (typeof value === 'string' && !value.match(options.pattern)) { - messages.push(options.message); - return; - } - - if (options.min !== undefined && value < options.min) { - messages.push(options.tooSmall); + var compareValue, valid = true; + if (options.compareAttribute === undefined) { + compareValue = options.compareValue; + } else { + compareValue = $('#' + options.compareAttribute).val(); } - if (options.max !== undefined && value > options.max) { - messages.push(options.tooBig); + switch (options.operator) { + case '==': + valid = value == compareValue; + break; + case '===': + valid = value === compareValue; + break; + case '!=': + valid = value != compareValue; + break; + case '!==': + valid = value !== compareValue; + break; + case '>': + valid = value > compareValue; + break; + case '>=': + valid = value >= compareValue; + break; + case '<': + valid = value < compareValue; + break; + case '<=': + valid = value <= compareValue; + break; } + + valid || messages.push(options.message); } }; })(jQuery); diff --git a/framework/validators/CaptchaValidator.php b/framework/validators/CaptchaValidator.php index ebb0039..4eba9df 100644 --- a/framework/validators/CaptchaValidator.php +++ b/framework/validators/CaptchaValidator.php @@ -9,6 +9,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * CaptchaValidator validates that the attribute value is the same as the verification code displayed in the CAPTCHA. @@ -94,33 +95,22 @@ class CaptchaValidator extends Validator public function clientValidateAttribute($object, $attribute) { $captcha = $this->getCaptchaAction(); - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); $code = $captcha->getVerifyCode(false); $hash = $captcha->generateValidationHash($this->caseSensitive ? $code : strtolower($code)); - $js = " -var hash = $('body').data(' {$this->captchaAction}.hash'); -if (hash == null) - hash = $hash; -else - hash = hash[" . ($this->caseSensitive ? 0 : 1) . "]; -for(var i=value.length-1, h=0; i >= 0; --i) h+=value." . ($this->caseSensitive ? '' : 'toLowerCase().') . "charCodeAt(i); -if(h != hash) { - messages.push(" . json_encode($message) . "); -} -"; - + $options = array( + 'hash' => $hash, + 'hashKey' => 'yiiCaptcha/' . $this->captchaAction, + 'caseSensitive' => $this->caseSensitive, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); if ($this->skipOnEmpty) { - $js = " -if($.trim(value)!='') { - $js -} -"; + $options['skipOnEmpty'] = 1; } - return $js; + return 'yii.validation.captcha(value, messages, ' . json_encode($options) . ');'; } } diff --git a/framework/validators/RangeValidator.php b/framework/validators/RangeValidator.php index 18742ae..2a9e15f 100644 --- a/framework/validators/RangeValidator.php +++ b/framework/validators/RangeValidator.php @@ -9,6 +9,7 @@ namespace yii\validators; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\Html; /** * RangeValidator validates that the attribute value is among a list of values. @@ -60,9 +61,7 @@ class RangeValidator extends Validator public function validateAttribute($object, $attribute) { $value = $object->$attribute; - if (!$this->not && !in_array($value, $this->range, $this->strict)) { - $this->addError($object, $attribute, $this->message); - } elseif ($this->not && in_array($value, $this->range, $this->strict)) { + if (!$this->validateValue($value)) { $this->addError($object, $attribute, $this->message); } } @@ -86,21 +85,22 @@ class RangeValidator extends Validator */ public function clientValidateAttribute($object, $attribute) { - $message = strtr($this->message, array( - '{attribute}' => $object->getAttributeLabel($attribute), - '{value}' => $object->$attribute, - )); - $range = array(); foreach ($this->range as $value) { $range[] = (string)$value; } - $range = json_encode($range); + $options = array( + 'range' => $range, + 'not' => $this->not, + 'message' => Html::encode(strtr($this->message, array( + '{attribute}' => $object->getAttributeLabel($attribute), + '{value}' => $object->$attribute, + ))), + ); + if ($this->skipOnEmpty) { + $options['skipOnEmpty'] = 1; + } - return " -if (" . ($this->skipOnEmpty ? "$.trim(value)!='' && " : '') . ($this->not ? "$.inArray(value, $range)>=0" : "$.inArray(value, $range)<0") . ") { - messages.push(" . json_encode($message) . "); -} -"; + return 'yii.validation.range(value, messages, ' . json_encode($options) . ');'; } }