PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.12
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.12
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/models/fields/FrmFieldCaptcha.php +102 -54 6.36.12 View file →
@@ -41,13 +41,16 @@
41 41 /**
42 42 * @return array
43 43 */
44 44 protected function field_settings_for_type() {
45 + $settings = FrmCaptchaFactory::get_settings_object();
45 46 return array(
46 - 'required' => false,
47 - 'invalid' => true,
48 - 'captcha_size' => true,
49 - 'default' => false,
47 + 'required' => false,
48 + 'invalid' => true,
49 + 'captcha_size' => $settings->should_show_captcha_size(),
50 + 'captcha_theme' => $settings->should_show_captcha_theme(),
51 + 'captcha_theme_auto_option' => $settings->should_show_captcha_theme_auto_option(),
52 + 'default' => false,
50 53 );
51 54 }
52 55
53 56 /**
@@ -74,9 +77,9 @@
74 77
75 78 /**
76 79 * Remove the "for" attribute for captcha
77 80 *
78 - * @param array $args
81 + * @param array $args
79 82 * @param string $html
80 83 *
81 84 * @return string
82 85 */
@@ -88,8 +91,10 @@
88 91 return $replaced_for;
89 92 }
90 93
91 94 /**
95 + * @param array $args
96 + * @param array $shortcode_atts
92 97 * @return string
93 98 */
94 99 public function front_field_input( $args, $shortcode_atts ) {
95 100 $frm_settings = FrmAppHelper::get_settings();
@@ -96,27 +101,17 @@
96 101 if ( ! self::should_show_captcha() ) {
97 102 return '';
98 103 }
99 104
100 - $class_prefix = $this->class_prefix( $frm_settings );
101 - $captcha_class = $this->captcha_class( $frm_settings );
102 - $captcha_size = $this->captcha_size( $frm_settings );
103 - $allow_mutiple = $frm_settings->re_multi;
105 + $settings = FrmCaptchaFactory::get_settings_object();
106 + $div_attributes = array(
107 + 'id' => $args['html_id'],
108 + 'class' => $this->class_prefix( $frm_settings ) . $this->captcha_class( $frm_settings ),
109 + 'data-sitekey' => $settings->get_pubkey(),
110 + );
111 + $div_attributes = $settings->add_front_end_element_attributes( $div_attributes, $this->field );
112 + $html = '<div ' . FrmAppHelper::array_to_html_params( $div_attributes ) . '></div>';
104 113
105 - if ( $frm_settings->active_captcha === 'recaptcha' ) {
106 - $site_key = $frm_settings->pubkey;
107 - $recaptcha_options = ' data-size="' . esc_attr( $captcha_size ) . '" data-theme="' . esc_attr( $this->field['captcha_theme'] ) . '"';
108 - } else {
109 - $site_key = $frm_settings->hcaptcha_pubkey;
110 - }
111 -
112 - $html = '<div id="' . esc_attr( $args['html_id'] ) . '" class="' . esc_attr( $class_prefix ) . $captcha_class . '" data-sitekey="' . esc_attr( $site_key ) . '"';
113 - $html .= ! empty( $recaptcha_options ) ? $recaptcha_options : '';
114 - if ( $captcha_size === 'invisible' && ! $allow_mutiple ) {
115 - $html .= ' data-callback="frmAfterRecaptcha"';
116 - }
117 - $html .= '></div>';
118 -
119 114 return $html;
120 115 }
121 116
122 117 /**
@@ -128,38 +123,58 @@
128 123 wp_register_script( 'captcha-api', $api_js_url, array( 'formidable' ), '3', true );
129 124 wp_enqueue_script( 'captcha-api' );
130 125 }
131 126
127 + /**
128 + * Get the URL for the script JS that is loaded on the front end.
129 + *
130 + * @return string
131 + */
132 132 protected function api_url() {
133 133 $frm_settings = FrmAppHelper::get_settings();
134 - if ( $frm_settings->active_captcha === 'recaptcha' ) {
134 + $active_mode = $frm_settings->active_captcha;
135 +
136 + if ( 'recaptcha' === $active_mode ) {
135 137 return $this->recaptcha_api_url( $frm_settings );
136 138 }
137 139
138 - return $this->hcaptcha_api_url();
140 + if ( 'hcaptcha' === $active_mode ) {
141 + return $this->hcaptcha_api_url();
142 + }
143 +
144 + return $this->turnstile_api_url();
139 145 }
140 146
141 147 /**
142 148 * @param FrmSettings $frm_settings
149 + * @return string
143 150 */
144 151 protected function recaptcha_api_url( $frm_settings ) {
145 152 $api_js_url = 'https://www.google.com/recaptcha/api.js?';
146 153
147 - $allow_mutiple = $frm_settings->re_multi;
148 - if ( $allow_mutiple ) {
154 + $allow_multiple = $frm_settings->re_multi;
155 + if ( $allow_multiple ) {
149 156 $api_js_url .= '&onload=frmRecaptcha&render=explicit';
150 157 }
151 158
152 159 $lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field );
153 - if ( ! empty( $lang ) ) {
160 + if ( $lang ) {
154 161 $api_js_url .= '&hl=' . $lang;
155 162 }
156 163
164 + /**
165 + * @param string $api_js_url
166 + */
157 167 $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url );
158 168
159 169 return $api_js_url;
160 170 }
161 171
172 + /**
173 + * @since 6.0
174 + *
175 + * @return string
176 + */
162 177 protected function hcaptcha_api_url() {
163 178 $api_js_url = 'https://js.hcaptcha.com/1/api.js';
164 179
165 180 /**
@@ -174,8 +189,36 @@
174 189 return $api_js_url;
175 190 }
176 191
177 192 /**
193 + * @since 6.8.4
194 + *
195 + * @return string
196 + */
197 + protected function turnstile_api_url() {
198 + $api_js_url = 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=frmTurnstile&render=explicit';
199 +
200 + /**
201 + * Allows updating hcaptcha js api url.
202 + *
203 + * @since 6.8.4
204 + *
205 + * @param string $api_js_url
206 + */
207 + $api_js_url = apply_filters( 'frm_turnstile_js_url', $api_js_url );
208 +
209 + // Prevent render=explicit from happening twice in case someone patched
210 + // the double rendering issue using the frm_turnstile_js_url hook.
211 + $api_js_url = str_replace(
212 + '&render=explicit&render=explicit',
213 + '&render=explicit',
214 + $api_js_url
215 + );
216 +
217 + return $api_js_url;
218 + }
219 +
220 + /**
178 221 * @param FrmSettings $frm_settings
179 222 *
180 223 * @return string
181 224 *
@@ -198,9 +241,10 @@
198 241 *
199 242 * @psalm-return 'g-recaptcha'|'h-captcha'
200 243 */
201 244 protected function captcha_class( $frm_settings ) {
202 - return $frm_settings->active_captcha === 'recaptcha' ? 'g-recaptcha' : 'h-captcha';
245 + $settings = FrmCaptchaFactory::get_settings_object();
246 + return $settings->get_element_class_name();
203 247 }
204 248
205 249 protected function allow_multiple( $frm_settings ) {
206 250 return $frm_settings->re_multi;
@@ -206,21 +250,8 @@
206 250 return $frm_settings->re_multi;
207 251 }
208 252
209 253 /**
210 - * @return string
211 - *
212 - * @param FrmSettings $frm_settings
213 - */
214 - protected function captcha_size( $frm_settings ) {
215 - if ( in_array( $frm_settings->re_type, array( 'invisible', 'v3' ), true ) ) {
216 - return 'invisible';
217 - }
218 - // for reverse compatibility
219 - return $this->field['captcha_size'] === 'default' ? 'normal' : $this->field['captcha_size'];
220 - }
221 -
222 - /**
223 254 * @since 4.07
224 255 * @param array $args
225 256 * @return array
226 257 */
@@ -289,11 +320,10 @@
289 320 if ( ! $this->should_validate() ) {
290 321 return array();
291 322 }
292 323
293 - // phpcs:ignore WordPress.Security.NonceVerification.Missing
294 - if ( ! isset( $_POST['g-recaptcha-response'] ) && ! isset( $_POST['h-captcha-response'] ) ) {
295 - // There was no captcha submitted.
324 + $missing_token = ! self::post_data_includes_token();
325 + if ( $missing_token ) {
296 326 return array( 'field' . $args['id'] => __( 'The captcha is missing from this form', 'formidable' ) );
297 327 }
298 328
299 329 return $this->validate_against_api( $args );
@@ -299,18 +329,28 @@
299 329 return $this->validate_against_api( $args );
300 330 }
301 331
302 332 /**
333 + * @since 6.8.4
334 + *
335 + * @return bool
336 + */
337 + protected static function post_data_includes_token() {
338 + $settings = FrmCaptchaFactory::get_settings_object();
339 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
340 + return ! empty( $_POST[ $settings->token_field ] );
341 + }
342 +
343 + /**
344 + * Check if the active captcha type's public key is set.
345 + *
303 346 * @since 4.07
347 + *
304 348 * @return bool
305 349 */
306 350 public static function should_show_captcha() {
307 - $frm_settings = FrmAppHelper::get_settings();
308 - if ( $frm_settings->active_captcha === 'recaptcha' ) {
309 - return ! empty( $frm_settings->pubkey );
310 - }
311 -
312 - return ! empty( $frm_settings->hcaptcha_pubkey );
351 + $settings = FrmCaptchaFactory::get_settings_object();
352 + return $settings->has_pubkey();
313 353 }
314 354
315 355 /**
316 356 * @return bool
@@ -328,11 +368,10 @@
328 368 /**
329 369 * @param FrmSettings $frm_settings
330 370 */
331 371 protected function send_api_check( $frm_settings ) {
332 - $captcha_settings = new FrmFieldCaptchaSettings( $frm_settings );
333 -
334 - $arg_array = array(
372 + $captcha_settings = FrmCaptchaFactory::get_settings_object();
373 + $arg_array = array(
335 374 'body' => array(
336 375 'secret' => $captcha_settings->secret,
337 376 'response' => FrmAppHelper::get_param( $captcha_settings->token_field, '', 'post', 'sanitize_text_field' ),
338 377 'remoteip' => FrmAppHelper::get_ip_address(),
@@ -359,6 +398,15 @@
359 398 }
360 399 }
361 400
362 401 return $values;
402 + }
403 +
404 + /**
405 + * @param FrmSettings $frm_settings
406 + * @return string
407 + */
408 + protected function captcha_size( $frm_settings ) {
409 + _deprecated_function( __METHOD__, '6.8.4' );
410 + return 'normal';
363 411 }
364 412 }