* * * * * @author Cristian Camilo Naranjo Valencia * @package System.Web.UI.WebControls * @since 3.3.1 */ class TReCaptcha2 extends TActivePanel implements ICallbackEventHandler, IValidatable { const ChallengeFieldName = 'g-recaptcha-response'; private $_widgetId=0; private $_isValid=true; public function __construct() { parent::__construct(); $this->setAdapter(new TActiveControlAdapter($this)); } public function getActiveControl() { return $this->getAdapter()->getBaseActiveControl(); } public function getClientSide() { return $this->getAdapter()->getBaseActiveControl()->getClientSide(); } public function getClientClassName() { return 'Prado.WebUI.TReCaptcha2'; } public function getTagName() { return 'div'; } /** * Returns true if this control validated successfully. * Defaults to true. * @return bool wether this control validated successfully. */ public function getIsValid() { return $this->_isValid; } /** * @param bool wether this control is valid. */ public function setIsValid($value) { $this->_isValid=TPropertyValue::ensureBoolean($value); } public function getValidationPropertyValue() { return $this->Request[$this->getResponseFieldName()]; } public function getResponseFieldName() { $captchas = $this->Page->findControlsByType('TReCaptcha2'); $cont = 0; $responseFieldName = self::ChallengeFieldName; foreach ($captchas as $captcha) { if ($this->getClientID() == $captcha->ClientID) { $responseFieldName .= ($cont > 0) ? '-'.$cont : ''; } $cont++; } return $responseFieldName; } /** * Returns your site key. * @return string. */ public function getSiteKey() { return $this->getViewState('SiteKey'); } /** * @param string your site key. */ public function setSiteKey($value) { $this->setViewState('SiteKey', TPropertyValue::ensureString($value)); } /** * Returns your secret key. * @return string. */ public function getSecretKey() { return $this->getViewState('SecretKey'); } /** * @param string your secret key. */ public function setSecretKey($value) { $this->setViewState('SecretKey', TPropertyValue::ensureString($value)); } /** * Returns your language. * @return string. */ public function getLanguage() { return $this->getViewState('Language', 'en'); } /** * @param string your language. */ public function setLanguage($value) { $this->setViewState('Language', TPropertyValue::ensureString($value), 'en'); } /** * Returns the color theme of the widget. * @return string. */ public function getTheme() { return $this->getViewState('Theme', 'light'); } /** * The color theme of the widget. * Default: light * @param string the color theme of the widget. */ public function setTheme($value) { $this->setViewState('Theme', TPropertyValue::ensureString($value), 'light'); } /** * Returns the type of CAPTCHA to serve. * @return string. */ public function getType() { return $this->getViewState('Type', 'image'); } /** * The type of CAPTCHA to serve. * Default: image * @param string the type of CAPTCHA to serve. */ public function setType($value) { $this->setViewState('Type', TPropertyValue::ensureString($value), 'image'); } /** * Returns the size of the widget. * @return string. */ public function getSize() { return $this->getViewState('Size', 'normal'); } /** * The size of the widget. * Default: normal * @param string the size of the widget. */ public function setSize($value) { $this->setViewState('Size', TPropertyValue::ensureString($value), 'normal'); } /** * Returns the tabindex of the widget and challenge. * If other elements in your page use tabindex, it should be set to make user navigation easier. * @return string. */ public function getTabIndex() { return $this->getViewState('TabIndex', 0); } /** * The tabindex of the widget and challenge. * If other elements in your page use tabindex, it should be set to make user navigation easier. * Default: 0 * @param string the tabindex of the widget and challenge. */ public function setTabIndex($value) { $this->setViewState('TabIndex', TPropertyValue::ensureInteger($value), 0); } /** * Resets the reCAPTCHA widget. * Optional widget ID, defaults to the first widget created if unspecified. */ public function reset() { $this->Page->CallbackClient->callClientFunction('grecaptcha.reset',array(array($this->WidgetId))); } /** * Gets the response for the reCAPTCHA widget. */ public function getResponse() { return $this->getViewState('Response', ''); } public function setResponse($value) { $this->setViewState('Response', TPropertyValue::ensureString($value), ''); } public function getWidgetId() { return $this->getViewState('WidgetId', 0); } public function setWidgetId($value) { $this->setViewState('WidgetId', TPropertyValue::ensureInteger($value), 0); } protected function getClientOptions() { $options['ID'] = $this->getClientID(); $options['EventTarget'] = $this->getUniqueID(); $options['FormID'] = $this->Page->getForm()->getClientID(); $options['onCallback'] = $this->hasEventHandler('OnCallback'); $options['onCallbackExpired'] = $this->hasEventHandler('OnCallbackExpired'); $options['options']['sitekey'] = $this->getSiteKey(); if ($theme = $this->getTheme()) $options['options']['theme'] = $theme; if ($type = $this->getType()) $options['options']['type'] = $type; if ($size = $this->getSize()) $options['options']['size'] = $size; if ($tabIndex = $this->getTabIndex()) $options['options']['tabindex'] = $tabIndex; return $options; } protected function registerClientScript() { $id = $this->getClientID(); $options = TJavaScript::encode($this->getClientOptions()); $className = $this->getClientClassName(); $cs = $this->Page->ClientScript; $code = "new $className($options);"; $cs->registerPradoScript('ajax'); $cs->registerEndScript("grecaptcha:$id", $code); } public function validate() { if ((is_null($this->getValidationPropertyValue())) || (empty($this->getValidationPropertyValue()))) return false; return true; } /** * Checks for API keys * @param mixed event parameter */ public function onPreRender($param) { parent::onPreRender($param); if("" == $this->getSiteKey()) throw new TConfigurationException('recaptcha_publickey_unknown'); if("" == $this->getSecretKey()) throw new TConfigurationException('recaptcha_privatekey_unknown'); // need to register captcha fields so they will be sent postback $this->Page->registerRequiresPostData($this->getResponseFieldName()); $this->Page->ClientScript->registerHeadScriptFile('grecaptcha2', 'https://www.google.com/recaptcha/api.js?onload=TReCaptcha2_onloadCallback&render=explicit&hl=' . $this->getLanguage()); } protected function addAttributesToRender($writer) { $writer->addAttribute('id',$this->getClientID()); parent::addAttributesToRender($writer); } public function raiseCallbackEvent($param) { $params = $param->getCallbackParameter(); if ($params instanceof stdClass) { $callback = property_exists($params, 'onCallback'); $callbackExpired = property_exists($params, 'onCallbackExpired'); if ($callback) { $this->WidgetId = $params->widgetId; $this->Response = $params->response; $this->Page->CallbackClient->jQuery($params->responseField, 'text',array($params->response)); if ($params->onCallback) { $this->onCallback($param); } } if ($callbackExpired) { $this->Response = ''; $this->reset(); if ($params->onCallbackExpired) { $this->onCallbackExpired($param); } } } } public function onCallback($param) { $this->raiseEvent('OnCallback', $this, $param); } public function onCallbackExpired($param) { $this->raiseEvent('OnCallbackExpired', $this, $param); } public function render($writer) { $this->registerClientScript(); parent::render($writer); } }