diff options
| -rw-r--r-- | HISTORY | 1 | ||||
| -rw-r--r-- | framework/Web/Javascripts/source/prado/validator/validation3.js | 45 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TReCaptcha.php | 33 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TReCaptchaValidator.php | 63 | 
4 files changed, 131 insertions, 11 deletions
| @@ -56,6 +56,7 @@ CHG: Issue #370 - Deprecated TSqliteCache since it's based on php's sqlite exten  BUG: Issue #371 - Sorting on TActiveDataGrid autogenerated column not work (ctrlaltca)  ENH: Issue #372 - ActiveControls's Visible property should be reflected clientside on ajax requests (ctrlaltca)  BUG: Issue #375 - Iconv error using htmlarea in TActiveDataList and chars like "áéíóúñ" (ctrlaltca) +BUG: Issue #377 - THtmlArea Template Pluggin Options Parse Error (ctrlaltca)  Version 3.1.10 Jul 17, 2011  BUG: Added missing timeout on TCacheHttpSession (ctrlaltca) diff --git a/framework/Web/Javascripts/source/prado/validator/validation3.js b/framework/Web/Javascripts/source/prado/validator/validation3.js index c0f770cf..bbf3929a 100644 --- a/framework/Web/Javascripts/source/prado/validator/validation3.js +++ b/framework/Web/Javascripts/source/prado/validator/validation3.js @@ -790,7 +790,6 @@ Prado.WebUI.TBaseValidator.prototype =  		options.OnSuccess = options.OnSuccess || Prototype.emptyFunction;
  		options.OnError = options.OnError || Prototype.emptyFunction;
  	*/
 -
  		/**
  		 * Wether the validator is enabled (default true)
  		 * @var {boolean} enabled
 @@ -839,6 +838,9 @@ Prado.WebUI.TBaseValidator.prototype =  		this.message = $(options.ID);
  		Prado.Registry.set(options.ID, this);
 +
 +		if (this.onInit) this.onInit();
 +
  		if(this.control && this.message)
  		{
  			this.group = options.ValidationGroup;
 @@ -1940,3 +1942,44 @@ Prado.WebUI.TCaptchaValidator = Class.extend(Prado.WebUI.TBaseValidator,  	    return crc ^ (-1);
  	}
  });
 +
 +
 +/**
 + * TReCaptchaValidator client-side control.
 + * 
 + * @class Prado.WebUI.TReCaptchaValidator
 + * @extends Prado.WebUI.TBaseValidator
 + */
 +Prado.WebUI.TReCaptchaValidator = Class.extend(Prado.WebUI.TBaseValidator,
 +{
 +	onInit : function()
 +	{
 +		var obj = this;
 +		var elements = document.getElementsByName(this.options.ResponseFieldName);
 +		if (elements)
 +		 if (elements.length>=1)
 +		 {
 +		  Event.observe(elements[0],'change',function() { obj.responseChanged() });
 +		  Event.observe(elements[0],'keydown',function() { obj.responseChanged() });
 +		 }
 +	},
 +
 +	responseChanged: function()
 +	{
 +		var field = $(this.options.ID+'_1');
 +		if (field.value=='1') return;
 +		field.value = '1';
 +		Prado.Validation.validateControl(this.options.ID);
 +	},
 +
 +	/**
 +	 * Evaluate validation state
 +	 * @function {boolean} ?
 +	 * @return True if the captcha has validate, False otherwise.
 +	 */
 +	evaluateIsValid : function()
 +	{
 +		return ($(this.options.ID+'_1').value=='1');
 +	}
 +});
 +
 diff --git a/framework/Web/UI/WebControls/TReCaptcha.php b/framework/Web/UI/WebControls/TReCaptcha.php index bb956bcb..50886276 100644 --- a/framework/Web/UI/WebControls/TReCaptcha.php +++ b/framework/Web/UI/WebControls/TReCaptcha.php @@ -51,12 +51,17 @@   * @package System.Web.UI.WebControls
   * @since 3.2
   */
 -class TReCaptcha extends TControl implements IValidatable
 +class TReCaptcha extends TWebControl implements IValidatable
  {
  	private $_isValid=true;
  	const ChallengeFieldName = 'recaptcha_challenge_field';
  	const ResponseFieldName = 'recaptcha_response_field';
 +
 +	public function getTagName()
 +	{
 +		return 'span';
 +	}
  	/**
  	 * Returns true if this control validated successfully. 
 @@ -135,7 +140,7 @@ class TReCaptcha extends TControl implements IValidatable  		return /*$this->ClientID.'_'.*/self::ChallengeFieldName;
  	}
 -	protected function getResponseFieldName()
 +	public function getResponseFieldName()
  	{
  		return /*$this->ClientID.'_'.*/self::ResponseFieldName;
  	}
 @@ -170,18 +175,38 @@ class TReCaptcha extends TControl implements IValidatable  	public function onPreRender($param)
  	{
  		parent::onPreRender($param);
 +
  		if("" == $this->getPublicKey())
  			throw new TConfigurationException('recaptcha_publickey_unknown');
  		if("" == $this->getPrivateKey())
  			throw new TConfigurationException('recaptcha_privatekey_unknown');
 +
 +		// need to register captcha fields so they will be sent back also in callbacks 
 +		$page = $this->getPage();
 +		$page->registerRequiresPostData($this->getChallengeFieldName());
 +		$page->registerRequiresPostData($this->getResponseFieldName());
  	}
 -	public function render($writer)
 +	protected function addAttributesToRender($writer)
 +	{
 +		parent::addAttributesToRender($writer);
 +		$writer->addAttribute('id',$this->getClientID());
 +	}
 +
 +	public function regenerateToken()
 +	{
 +		// if we're in a callback, then schedule re-rendering of the control 
 +		// if not, don't do anything, because a new challenge will be rendered anyway
 +		if ($this->Page->IsCallback)
 +			$this->Page->ClientScript->registerEndScript($this->getClientID().'::refresh','Recaptcha.reload();');
 +	}
 +
 +	public function renderContents($writer)
  	{
  		$writer->write(TJavaScript::renderScriptBlock(
  			'var RecaptchaOptions = '.TJavaScript::jsonEncode($this->getClientSideOptions()).';'
  		));
 -	
 +
  		$html = recaptcha_get_html($this->getPublicKey());
  		/*
  		reCAPTCHA currently does not support multiple validations per page
 diff --git a/framework/Web/UI/WebControls/TReCaptchaValidator.php b/framework/Web/UI/WebControls/TReCaptchaValidator.php index ae94ea59..2898a913 100644 --- a/framework/Web/UI/WebControls/TReCaptchaValidator.php +++ b/framework/Web/UI/WebControls/TReCaptchaValidator.php @@ -39,12 +39,29 @@ class TReCaptchaValidator extends TBaseValidator  	 */
  	protected function getClientClassName()
  	{
 -		return '';
 +		return 'Prado.WebUI.TReCaptchaValidator';
  	}
  	public function getEnableClientScript()
  	{
 -		return false;
 +		return true;
 +	}
 +
 +	protected function getCaptchaControl()
 +	{
 +		$control = $this->getValidationTarget();
 +		if (!$control)
 +			throw new Exception('No target control specified for TReCaptchaValidator');
 +		if (!($control instanceof TReCaptcha))
 +			throw new Exception('TReCaptchaValidator only works with TReCaptcha controls');
 +		return $control;
 +	}
 +
 +	public function getClientScriptOptions()
 +	{
 +		$options = parent::getClientScriptOptions();
 +		$options['ResponseFieldName'] = $this->getCaptchaControl()->getResponseFieldName();
 +		return $options;
  	}
  	/**
 @@ -56,17 +73,51 @@ class TReCaptchaValidator extends TBaseValidator  	 */
  	protected function evaluateIsValid()
  	{
 -		// check validity only once (if trying to evaluate multiple times, all redundant checks would fail)
 +		// check validity only once (if trying to evaulate multiple times, all redundant checks would fail)
  		if (is_null($this->_isvalid))
  		{
 -			$control = $this->getValidationTarget();
 -			if(!($control instanceof TCaptcha))
 -				throw new TConfigurationException('recaptchavalidator_captchacontrol_invalid');
 +			$control = $this->getCaptchaControl();
  			$this->_isvalid = $control->validate();
  		}
  		return ($this->_isvalid==true);
  	}
 +	public function onPreRender($param)
 +	{
 +		parent::onPreRender($param);
 +
 +		$cs = $this->Page->getClientScript();
 +
 +		// communicate validation status to the client side
 +		$value = $this->_isvalid===false ? '0' : '1';
 +		$cs->registerHiddenField($this->getClientID().'_1',$value);
 +
 +		// check if we need to request a new captcha too
 +		if ($this->Page->IsCallback)
 +		{
 +		  // force update of validator display
 +		  if ($control = $this->getValidationTarget())
 +		  {
 +		    $cs->registerEndScript(
 +				$this->getClientID().'::validate',
 +				'$(\''.TJavaScript::quoteString($this->getClientID().'_1').'\').value = \''.TJavaScript::quoteString($value).'\';'.
 +				'Prado.Validation.validateControl(\''.TJavaScript::quoteString($control->ClientID).'\');'
 +		    );
 +
 +		    if ($control->getVisible(true))
 +		      if ($this->_isvalid)
 +			{
 +				// if the challenge has been solved + we're in a callback and we still reach prerender phase,
 +				// that means that some other validator failed and the user will be sent back to the page/form with 
 +				// the captcha control. in this case we need to force re-rendering of the control, because once 
 +				// solved, the old challenge won't validate anymore anyway
 +
 +				$control->regenerateToken();
 +			}
 +		  }
 +		}
 +	}
 +
  }
  ?>
\ No newline at end of file | 
