4 * TReCaptchaValidator class file
6 * @author Bérczi Gábor <gabor.berczi@devworx.hu>
7 * @link http://www.devworx.hu/
8 * @copyright Copyright © 2011 DevWorx
9 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
10 * @package System.Web.UI.WebControls
13 Prado::using('System.Web.UI.WebControls.TBaseValidator');
14 Prado::using('System.Web.UI.WebControls.TReCaptcha');
17 * TReCaptchaValidator class
19 * TReCaptchaValidator validates user input against a reCAPTCHA represented by
20 * a {@link TReCaptcha} control. The input control fails validation if its value
21 * is not the same as the token displayed in reCAPTCHA. Note, if the user does
22 * not enter any thing, it is still considered as failing the validation.
24 * To use TReCaptchaValidator, specify the {@link setCaptchaControl CaptchaControl}
25 * to be the ID path of the {@link TReCaptcha} control.
27 * @author Bérczi Gábor <gabor.berczi@devworx.hu>
28 * @package System.Web.UI.WebControls
31 class TReCaptchaValidator extends TBaseValidator
33 protected $_isvalid = null;
36 * Gets the name of the javascript class responsible for performing validation for this control.
37 * This method overrides the parent implementation.
38 * @return string the javascript class name
40 protected function getClientClassName()
42 return 'Prado.WebUI.TReCaptchaValidator';
45 public function getEnableClientScript()
50 protected function getCaptchaControl()
52 $control = $this->getValidationTarget();
54 throw new Exception('No target control specified for TReCaptchaValidator');
55 if (!($control instanceof TReCaptcha))
56 throw new Exception('TReCaptchaValidator only works with TReCaptcha controls');
60 public function getClientScriptOptions()
62 $options = parent::getClientScriptOptions();
63 $options['ResponseFieldName'] = $this->getCaptchaControl()->getResponseFieldName();
68 * This method overrides the parent's implementation.
69 * The validation succeeds if the input control has the same value
70 * as the one displayed in the corresponding RECAPTCHA control.
72 * @return boolean whether the validation succeeds
74 protected function evaluateIsValid()
76 // check validity only once (if trying to evaulate multiple times, all redundant checks would fail)
77 if (is_null($this->_isvalid))
79 $control = $this->getCaptchaControl();
80 $this->_isvalid = $control->validate();
82 return ($this->_isvalid==true);
85 public function onPreRender($param)
87 parent::onPreRender($param);
89 $cs = $this->Page->getClientScript();
90 $cs->registerPradoScript('validator');
92 // communicate validation status to the client side
93 $value = $this->_isvalid===false ? '0' : '1';
94 $cs->registerHiddenField($this->getClientID().'_1',$value);
96 // update validator display
97 if ($control = $this->getValidationTarget())
99 $fn = 'captchaUpdateValidatorStatus_'.$this->getClientID();
101 // check if we need to request a new captcha too
102 if ($this->Page->IsCallback)
104 if ($control->getVisible(true))
105 if (!is_null($this->_isvalid))
107 // if the response has been tested and we reach the pre-render phase
108 // then we need to regenerate the token, because it won't test positive
109 // anymore, even if solves correctly
111 $control->regenerateToken();
115 $cs->registerEndScript($this->getClientID().'::validate', implode(' ',array(
116 // this function will be used to update the validator
117 'function '.$fn.'(valid)',
119 ' jQuery('.TJavaScript::quoteString('#'.$this->getClientID().'_1').').val(valid);',
120 ' Prado.Validation.validateControl('.TJavaScript::quoteString($control->ClientID).'); ',
123 // update the validator to the result if we're in a callback
124 // (if we're in initial rendering or a postback then the result will be rendered directly to the page html anyway)
125 $this->Page->IsCallback ? $fn.'('.$value.');' : '',
127 // install event handler that clears the validation error when user changes the captcha response field
128 'jQuery("#'.$control->getClientID().'").on("keyup", '.TJavaScript::quoteString('#'.$control->getResponseFieldName()).', function() { ',