1: <?php
  2: 
  3:   4:   5: 
  6: class Quform_Element_Recaptcha extends Quform_Element_Field
  7: {
  8:       9:  10:  11:  12: 
 13:     public function getName()
 14:     {
 15:         $provider = $this->config('provider');
 16: 
 17:         if ($provider == 'hcaptcha') {
 18:             return 'h-captcha-response';
 19:         } elseif ($provider == 'turnstile') {
 20:             return 'cf-turnstile-response';
 21:         }
 22: 
 23:         return 'g-recaptcha-response';
 24:     }
 25: 
 26:      27:  28:  29:  30:  31: 
 32:     protected function getElementClasses(array $context = array())
 33:     {
 34:         $classes = parent::getElementClasses($context);
 35: 
 36:         if (in_array($this->config('provider'), array('hcaptcha', 'turnstile'), true)) {
 37:             if ($this->config('recaptchaSize') == 'invisible') {
 38:                 $classes[] = 'quform-recaptcha-no-size';
 39:             }
 40:         } else {
 41:             if (($this->config('recaptchaVersion') == 'v3' || $this->config('recaptchaSize') == 'invisible') && $this->config('recaptchaBadge') != 'inline') {
 42:                 $classes[] = 'quform-recaptcha-no-size';
 43:             }
 44:         }
 45: 
 46:         return $classes;
 47:     }
 48: 
 49:      50:  51:  52:  53:  54:  55:  56: 
 57:     protected function getLabelHtml(array $context = array(), $forAttribute = true, $id = false)
 58:     {
 59:         if ($this->config('recaptchaVersion') == 'v3' || $this->config('recaptchaSize') == 'invisible') {
 60:             return '';
 61:         }
 62: 
 63:         return parent::getLabelHtml($context, false);
 64:     }
 65: 
 66:      67:  68:  69:  70:  71: 
 72:     protected function getInputHtml(array $context = array())
 73:     {
 74:         $output = sprintf('<div class="%s">', Quform::escape(Quform::sanitizeClass($this->getInputClasses($context))));
 75:         $output .= $this->getFieldHtml();
 76:         $output .= '</div>';
 77: 
 78:         return $output;
 79:     }
 80: 
 81:      82:  83:  84:  85:  86: 
 87:     protected function getFieldHtml(array $context = array())
 88:     {
 89:         $output = '';
 90: 
 91:         if ($this->config('provider') == 'hcaptcha') {
 92:             if (!Quform::isNonEmptyString($this->config('hcaptchaSiteKey'))) {
 93:                 $output .= esc_html__('To use hCaptcha you must enter the API keys on the Quform settings page.', 'quform');
 94:             } else {
 95:                 $config = array(
 96:                     'sitekey' => $this->config('hcaptchaSiteKey'),
 97:                     'size' => $this->config('recaptchaSize'),
 98:                     'theme' => $this->config('recaptchaTheme'),
 99:                 );
100: 
101:                 $output .= sprintf(
102:                     '<div class="quform-hcaptcha" data-config="%s"></div>',
103:                     Quform::escape(wp_json_encode($config))
104:                 );
105: 
106:                 $output .= sprintf('<noscript>%s</noscript>', esc_html__('Please enable JavaScript to submit this form.', 'quform'));
107: 
108:                 if (!wp_script_is('quform-hcaptcha')) {
109:                     $args = array(
110:                         'onload' => 'QuformHcaptchaLoaded',
111:                         'render' => 'explicit',
112:                         'recaptchacompat' => apply_filters('quform_hcaptcha_recaptcha_compat', false) ? 'on' : 'off'
113:                     );
114: 
115:                     if (Quform::isNonEmptyString($this->config('hcaptchaLang'))) {
116:                         $args['hl'] = urlencode($this->config('hcaptchaLang'));
117:                     }
118: 
119:                     $url = add_query_arg($args, 'https://js.hcaptcha.com/1/api.js');
120: 
121:                     wp_enqueue_script('quform-hcaptcha', $url, array('jquery'), false, true);
122:                     wp_add_inline_script('quform-hcaptcha', 'window.QuformHcaptchaLoaded=function(){window.hcaptcha&&window.jQuery&&jQuery(".quform-hcaptcha").each(function(){var a=jQuery(this),c=a.data("config");a.is(":empty")&&("invisible"===c.size&&(c.callback=function(){a.closest(".quform-form").data("quform").submit()}),a.data("hcaptcha-id",hcaptcha.render(a[0],c)))})};', 'before');
123:                 }
124:             }
125:         } elseif ($this->config('provider') == 'turnstile') {
126:             if (!Quform::isNonEmptyString($this->config('turnstileSiteKey'))) {
127:                 $output .= esc_html__('To use Cloudflare Turnstile you must enter the API keys on the Quform settings page.', 'quform');
128:             } else {
129:                 $config = array(
130:                     'sitekey' => $this->config('turnstileSiteKey'),
131:                     'size' => $this->config('recaptchaSize'),
132:                     'theme' => $this->config('recaptchaTheme'),
133:                 );
134: 
135:                 if (Quform::isNonEmptyString($this->config('turnstileLang'))) {
136:                     $config['language'] = urlencode($this->config('turnstileLang'));
137:                 }
138: 
139:                 $output .= sprintf(
140:                     '<div class="quform-turnstile" data-config="%s"></div>',
141:                     Quform::escape(wp_json_encode($config))
142:                 );
143: 
144:                 $output .= sprintf('<noscript>%s</noscript>', esc_html__('Please enable JavaScript to submit this form.', 'quform'));
145: 
146:                 if (!wp_script_is('quform-turnstile')) {
147:                     $args = array(
148:                         'onload' => 'QuformTurnstileLoaded',
149:                         'render' => 'explicit'
150:                     );
151: 
152:                     if (apply_filters('quform_turnstile_recaptcha_compat', false)) {
153:                         $args['compat'] = 'recaptcha';
154:                     }
155: 
156:                     $url = add_query_arg($args, 'https://challenges.cloudflare.com/turnstile/v0/api.js');
157: 
158:                     wp_enqueue_script('quform-turnstile', $url, array('jquery'), false, true);
159:                     wp_add_inline_script('quform-turnstile', 'window.QuformTurnstileLoaded=function(){window.turnstile&&window.jQuery&&jQuery(".quform-turnstile").each(function(){var t=jQuery(this),i=t.data("config");t.is(":empty")&&t.data("turnstile-id",turnstile.render(t[0],i))})};', 'before');
160:                 }
161:             }
162:         } else {
163:             if (!Quform::isNonEmptyString($this->config('recaptchaSiteKey'))) {
164:                 $output .= esc_html__('To use reCAPTCHA you must enter the API keys on the Quform settings page.', 'quform');
165:             } else {
166:                 $config = array(
167:                     'sitekey' => $this->config('recaptchaSiteKey'),
168:                     '_version' => $this->config('recaptchaVersion'), 
169:                     'size' => $this->config('recaptchaSize'),
170:                     'type' => $this->config('recaptchaType'),
171:                     'theme' => $this->config('recaptchaTheme'),
172:                     'badge' => $this->config('recaptchaBadge'),
173:                 );
174: 
175:                 $output .= sprintf(
176:                     '<div class="quform-recaptcha" data-config="%s"></div>',
177:                     Quform::escape(wp_json_encode($config))
178:                 );
179: 
180:                 if ($this->config('recaptchaVersion') == 'v3' || $this->config('recaptchaSize') == 'invisible') {
181:                     $output .= sprintf('<noscript>%s</noscript>', esc_html__('Please enable JavaScript to submit this form.', 'quform'));
182:                 } else {
183:                     $output .= '<noscript><div>';
184:                     $output .= '<div style="width: 302px; height: 422px; position: relative;">';
185:                     $output .= '<div style="width: 302px; height: 422px; position: absolute;">';
186:                     $output .= sprintf('<iframe src="%s" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe>', esc_url(sprintf('https://www.google.com/recaptcha/api/fallback?k=%s', $this->config('recaptchaSiteKey'))));
187:                     $output .= '</div></div>';
188:                     $output .= '<div style="width: 300px; height: 60px; border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px;">';
189:                     $output .= '<textarea name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid #c1c1c1; margin: 10px 25px; padding: 0px; resize: none;" aria-hidden="true"></textarea>';
190:                     $output .= '</div></div></noscript>';
191:                 }
192: 
193:                 if (!wp_script_is('quform-recaptcha')) {
194:                     $args = array(
195:                         'onload' => 'QuformRecaptchaLoaded',
196:                         'render' => 'explicit'
197:                     );
198: 
199:                     if (Quform::isNonEmptyString($this->config('recaptchaLang'))) {
200:                         $args['hl'] = urlencode($this->config('recaptchaLang'));
201:                     }
202: 
203:                     $url = add_query_arg($args, 'https://www.google.com/recaptcha/api.js');
204: 
205:                     wp_enqueue_script('quform-recaptcha', $url, array('jquery'), false, true);
206:                     wp_add_inline_script('quform-recaptcha', 'window.QuformRecaptchaLoaded=function(){window.grecaptcha&&window.jQuery&&jQuery(".quform-recaptcha").each(function(){var a=jQuery(this),c=a.data("config");a.is(":empty")&&("v2"===c._version&&"invisible"===c.size&&(c.callback=function(){a.closest(".quform-form").data("quform").submit()}),a.data("recaptcha-id",grecaptcha.render(a[0],c)))})};', 'before');
207:                 }
208:             }
209:         }
210: 
211:         return $output;
212:     }
213: 
214:     215: 216: 217: 218: 219: 
220:     protected function prepareContext(array $context = array())
221:     {
222:         $context = parent::prepareContext($context);
223: 
224:         
225:         if ( ! in_array($context['labelPosition'], array('', 'left'), true)) {
226:             $context['labelPosition'] = '';
227:         }
228: 
229:         
230:         $context['tooltipType'] = 'icon';
231: 
232:         return $context;
233:     }
234: 
235:     236: 237: 238: 239: 240: 
241:     public static function getDefaultConfig($key = null)
242:     {
243:         $config = apply_filters('quform_default_config_recaptcha', array(
244:             
245:             'label' => __('Are you human?', 'quform'),
246:             'description' => '',
247:             'descriptionAbove' => '',
248:             'provider' => 'recaptcha',
249:             'recaptchaVersion' => 'v2',
250:             'recaptchaSize' => 'normal',
251:             'recaptchaType' => 'image',
252:             'recaptchaTheme' => 'light',
253:             'recaptchaBadge' => 'bottomright',
254:             'recaptchaLang' => '',
255:             'hcaptchaLang' => '',
256:             'turnstileLang' => '',
257:             'recaptchaThreshold' => '0.5',
258: 
259:             
260:             'labelIcon' => '',
261:             'customElementClass' => '',
262:             'styles' => array(),
263: 
264:             
265:             'subLabel' => '',
266:             'subLabelAbove' => '',
267:             'tooltip' => '',
268:             'tooltipType' => 'icon',
269:             'tooltipEvent' => 'inherit',
270:             'labelPosition' => 'inherit',
271:             'labelWidth' => '',
272: 
273:             
274:             'logicEnabled' => false,
275:             'logicAction' => true,
276:             'logicMatch' => 'all',
277:             'logicRules' => array(),
278: 
279:             
280:             'visibility' => '',
281: 
282:             
283:             'messageRequired' => '',
284:             'messageRecaptchaMissingInputSecret' => '',
285:             'messageRecaptchaInvalidInputSecret' => '',
286:             'messageRecaptchaMissingInputResponse' => '',
287:             'messageRecaptchaInvalidInputResponse' => '',
288:             'messageRecaptchaError' => '',
289:             'messageRecaptchaScoreTooLow' => ''
290:         ));
291: 
292:         $config['type'] = 'recaptcha';
293: 
294:         if (Quform::isNonEmptyString($key)) {
295:             return Quform::get($config, $key);
296:         }
297: 
298:         return $config;
299:     }
300: }
301: