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: