| @@ -30,15 +30,9 @@ | ||
| 30 | 30 | public static function get_captcha_image_name() { |
| 31 | 31 | $frm_settings = FrmAppHelper::get_settings(); |
| 32 | 32 | $active_captcha = $frm_settings->active_captcha; |
| 33 | 33 | |
| 34 | - if ( $active_captcha === 'recaptcha' && $frm_settings->re_type === 'v3' ) { | |
| 35 | - $image_name = 'recaptcha_v3'; | |
| 36 | - } else { | |
| 37 | - $image_name = $active_captcha; | |
| 38 | - } | |
| 39 | - | |
| 40 | - return $image_name; | |
| 34 | + return $active_captcha === 'recaptcha' && $frm_settings->re_type === 'v3' ? 'recaptcha_v3' : $active_captcha; | |
| 41 | 35 | } |
| 42 | 36 | |
| 43 | 37 | /** |
| 44 | 38 | * @return array |
| @@ -77,10 +71,14 @@ | ||
| 77 | 71 | ); |
| 78 | 72 | } |
| 79 | 73 | |
| 80 | 74 | /** |
| 81 | - * Replace the "for" attribute for captcha field so it matches the response ID. | |
| 75 | + * Modify the captcha field label so it is not orphaned. | |
| 82 | 76 | * |
| 77 | + * The label is omitted when the label position is set to "none". | |
| 78 | + * When the label is visible it is rendered as a <span> instead of a <label>, | |
| 79 | + * since the captcha response input is inside an iframe and cannot be referenced. | |
| 80 | + * | |
| 83 | 81 | * @param array $args |
| 84 | 82 | * @param string $html |
| 85 | 83 | * |
| 86 | 84 | * @return string |
| @@ -85,10 +83,19 @@ | ||
| 85 | 83 | * |
| 86 | 84 | * @return string |
| 87 | 85 | */ |
| 88 | 86 | protected function before_replace_html_shortcodes( $args, $html ) { |
| 89 | - $settings = FrmCaptchaFactory::get_settings_object(); | |
| 90 | - return str_replace( ' for="field_[key]"', ' for="' . esc_attr( $settings->token_field ) . '"', $html ); | |
| 87 | + if ( 'none' === FrmField::get_option( $this->field, 'label' ) ) { | |
| 88 | + // Fully strip the label for a CAPTCHA if it is set to hidden. | |
| 89 | + return preg_replace( '~\s*<label\b[^>]*for="field_\[key\]"[^>]*>.*?</label>\s*~s', '', $html ); | |
| 90 | + } | |
| 91 | + | |
| 92 | + // Convert a CAPTCHA label to a span to prevent an orphaned label issue in WAVE. | |
| 93 | + return preg_replace( | |
| 94 | + '~<label\b([^>]*?)\s*for="field_\[key\]"([^>]*?)>(.*?)</label>~s', | |
| 95 | + '<span$1$2>$3</span>', | |
| 96 | + $html | |
| 97 | + ); | |
| 91 | 98 | } |
| 92 | 99 | |
| 93 | 100 | /** |
| 94 | 101 | * @param array $args |
| @@ -96,14 +103,13 @@ | ||
| 96 | 103 | * |
| 97 | 104 | * @return string |
| 98 | 105 | */ |
| 99 | 106 | public function front_field_input( $args, $shortcode_atts ) { |
| 100 | - $frm_settings = FrmAppHelper::get_settings(); | |
| 101 | - | |
| 102 | 107 | if ( ! self::should_show_captcha() ) { |
| 103 | 108 | return ''; |
| 104 | 109 | } |
| 105 | 110 | |
| 111 | + $frm_settings = FrmAppHelper::get_settings(); | |
| 106 | 112 | $settings = FrmCaptchaFactory::get_settings_object(); |
| 107 | 113 | $div_attributes = array( |
| 108 | 114 | 'id' => $args['html_id'], |
| 109 | 115 | 'class' => $this->class_prefix( $frm_settings ) . $this->captcha_class( $frm_settings ), |
| @@ -118,11 +124,10 @@ | ||
| 118 | 124 | } |
| 119 | 125 | } |
| 120 | 126 | |
| 121 | 127 | $div_attributes = $settings->add_front_end_element_attributes( $div_attributes, $this->field ); |
| 122 | - $html = '<div ' . FrmAppHelper::array_to_html_params( $div_attributes ) . '></div>'; | |
| 123 | 128 | |
| 124 | - return $html; | |
| 129 | + return '<div ' . FrmAppHelper::array_to_html_params( $div_attributes ) . '></div>'; | |
| 125 | 130 | } |
| 126 | 131 | |
| 127 | 132 | /** |
| 128 | 133 | * @since 6.25 |
| @@ -148,11 +153,9 @@ | ||
| 148 | 153 | * |
| 149 | 154 | * @return void |
| 150 | 155 | */ |
| 151 | 156 | protected function load_field_scripts( $args ) { |
| 152 | - $api_js_url = $this->api_url(); | |
| 153 | - | |
| 154 | - wp_register_script( 'captcha-api', $api_js_url, array( 'formidable' ), '3', true ); | |
| 157 | + wp_register_script( 'captcha-api', $this->api_url(), array( 'formidable' ), '3', true ); | |
| 155 | 158 | wp_enqueue_script( 'captcha-api' ); |
| 156 | 159 | } |
| 157 | 160 | |
| 158 | 161 | /** |
| @@ -199,11 +202,9 @@ | ||
| 199 | 202 | |
| 200 | 203 | /** |
| 201 | 204 | * @param string $api_js_url |
| 202 | 205 | */ |
| 203 | - $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url ); | |
| 204 | - | |
| 205 | - return $api_js_url; | |
| 206 | + return apply_filters( 'frm_recaptcha_js_url', $api_js_url ); | |
| 206 | 207 | } |
| 207 | 208 | |
| 208 | 209 | /** |
| 209 | 210 | * @since 6.0 |
| @@ -211,11 +212,10 @@ | ||
| 211 | 212 | * @return string |
| 212 | 213 | */ |
| 213 | 214 | protected function hcaptcha_api_url() { |
| 214 | 215 | $api_js_url = 'https://js.hcaptcha.com/1/api.js'; |
| 216 | + $lang = $this->get_captcha_language(); | |
| 215 | 217 | |
| 216 | - $lang = $this->get_captcha_language(); | |
| 217 | - | |
| 218 | 218 | if ( $lang ) { |
| 219 | 219 | // Language might be in the format of en-US, fr-FR, etc. In that case, we need to extract the first part to comply with the hcaptcha api request format. |
| 220 | 220 | $lang_parts = explode( '-', $lang ); |
| 221 | 221 | $api_js_url .= '?hl=' . $lang_parts[0]; |
| @@ -229,11 +229,9 @@ | ||
| 229 | 229 | * @since 6.0 |
| 230 | 230 | * |
| 231 | 231 | * @param string $api_js_url |
| 232 | 232 | */ |
| 233 | - $api_js_url = apply_filters( 'frm_hcaptcha_js_url', $api_js_url ); | |
| 234 | - | |
| 235 | - return $api_js_url; | |
| 233 | + return apply_filters( 'frm_hcaptcha_js_url', $api_js_url ); | |
| 236 | 234 | } |
| 237 | 235 | |
| 238 | 236 | /** |
| 239 | 237 | * @since 6.8.4 |
| @@ -252,16 +250,14 @@ | ||
| 252 | 250 | */ |
| 253 | 251 | $api_js_url = apply_filters( 'frm_turnstile_js_url', $api_js_url ); |
| 254 | 252 | |
| 255 | 253 | // Prevent render=explicit from happening twice in case someone patched |
| 256 | - // the double rendering issue using the frm_turnstile_js_url hook. | |
| 257 | - $api_js_url = str_replace( | |
| 254 | + // The double rendering issue using the frm_turnstile_js_url hook. | |
| 255 | + return str_replace( | |
| 258 | 256 | '&render=explicit&render=explicit', |
| 259 | 257 | '&render=explicit', |
| 260 | 258 | $api_js_url |
| 261 | 259 | ); |
| 262 | - | |
| 263 | - return $api_js_url; | |
| 264 | 260 | } |
| 265 | 261 | |
| 266 | 262 | /** |
| 267 | 263 | * @param FrmSettings $frm_settings |
| @@ -304,9 +300,9 @@ | ||
| 304 | 300 | */ |
| 305 | 301 | protected function validate_against_api( $args ) { |
| 306 | 302 | $errors = array(); |
| 307 | 303 | $frm_settings = FrmAppHelper::get_settings(); |
| 308 | - $resp = $this->send_api_check( $frm_settings ); | |
| 304 | + $resp = $this->send_api_check(); | |
| 309 | 305 | $response = json_decode( wp_remote_retrieve_body( $resp ), true ); |
| 310 | 306 | |
| 311 | 307 | if ( is_wp_error( $resp ) ) { |
| 312 | 308 | $error_string = $resp->get_error_message(); |
| @@ -318,31 +314,32 @@ | ||
| 318 | 314 | if ( ! is_array( $response ) ) { |
| 319 | 315 | return $errors; |
| 320 | 316 | } |
| 321 | 317 | |
| 322 | - if ( $frm_settings->active_captcha === 'recaptcha' ) { | |
| 323 | - if ( 'v3' === $frm_settings->re_type && array_key_exists( 'score', $response ) ) { | |
| 324 | - $threshold = floatval( $frm_settings->re_threshold ); | |
| 325 | - $score = floatval( $response['score'] ); | |
| 318 | + if ( $frm_settings->active_captcha === 'recaptcha' && 'v3' === $frm_settings->re_type && array_key_exists( 'score', $response ) ) { | |
| 319 | + $threshold = floatval( $frm_settings->re_threshold ); | |
| 320 | + $score = floatval( $response['score'] ); | |
| 326 | 321 | |
| 327 | - $this->set_score( $score ); | |
| 322 | + $this->set_score( $score ); | |
| 328 | 323 | |
| 329 | - if ( $score < $threshold ) { | |
| 330 | - $response['success'] = false; | |
| 331 | - } | |
| 324 | + if ( $score < $threshold ) { | |
| 325 | + $response['success'] = false; | |
| 332 | 326 | } |
| 333 | 327 | } |
| 334 | 328 | |
| 335 | - if ( isset( $response['success'] ) && ! $response['success'] ) { | |
| 336 | - // What happens when the CAPTCHA was entered incorrectly | |
| 337 | - $invalid_message = FrmField::get_option( $this->field, 'invalid' ); | |
| 329 | + if ( ! isset( $response['success'] ) || $response['success'] ) { | |
| 330 | + return $errors; | |
| 331 | + } | |
| 338 | 332 | |
| 339 | - if ( $invalid_message === __( 'The reCAPTCHA was not entered correctly', 'formidable' ) ) { | |
| 340 | - $invalid_message = ''; | |
| 341 | - } | |
| 342 | - $errors[ 'field' . $args['id'] ] = ( $invalid_message === '' ? $frm_settings->re_msg : $invalid_message ); | |
| 333 | + // What happens when the CAPTCHA was entered incorrectly | |
| 334 | + $invalid_message = FrmField::get_option( $this->field, 'invalid' ); | |
| 335 | + | |
| 336 | + if ( $invalid_message === __( 'The reCAPTCHA was not entered correctly', 'formidable' ) ) { | |
| 337 | + $invalid_message = ''; | |
| 343 | 338 | } |
| 344 | 339 | |
| 340 | + $errors[ 'field' . $args['id'] ] = $invalid_message === '' ? $frm_settings->re_msg : $invalid_message; | |
| 341 | + | |
| 345 | 342 | return $errors; |
| 346 | 343 | } |
| 347 | 344 | |
| 348 | 345 | /** |
| @@ -415,18 +412,16 @@ | ||
| 415 | 412 | if ( FrmAppHelper::is_admin() || $is_hidden_field ) { |
| 416 | 413 | return false; |
| 417 | 414 | } |
| 418 | 415 | |
| 419 | - // don't require the captcha if it shouldn't be shown | |
| 416 | + // Don't require the captcha if it shouldn't be shown | |
| 420 | 417 | return self::should_show_captcha(); |
| 421 | 418 | } |
| 422 | 419 | |
| 423 | 420 | /** |
| 424 | - * @param FrmSettings $frm_settings | |
| 425 | - * | |
| 426 | 421 | * @return array|WP_Error |
| 427 | 422 | */ |
| 428 | - protected function send_api_check( $frm_settings ) { | |
| 423 | + protected function send_api_check() { | |
| 429 | 424 | $captcha_settings = FrmCaptchaFactory::get_settings_object(); |
| 430 | 425 | $arg_array = array( |
| 431 | 426 | 'body' => array( |
| 432 | 427 | 'secret' => $captcha_settings->secret, |
| @@ -444,9 +439,9 @@ | ||
| 444 | 439 | * @since 6.0 |
| 445 | 440 | * |
| 446 | 441 | * @param array $values |
| 447 | 442 | * |
| 448 | - * @return array $values | |
| 443 | + * @return array Values. | |
| 449 | 444 | */ |
| 450 | 445 | public static function update_field_name( $values ) { |
| 451 | 446 | if ( $values['type'] === 'captcha' ) { |
| 452 | 447 | $name = $values['name']; |
| @@ -456,16 +451,6 @@ | ||
| 456 | 451 | } |
| 457 | 452 | } |
| 458 | 453 | |
| 459 | 454 | return $values; |
| 460 | - } | |
| 461 | - | |
| 462 | - /** | |
| 463 | - * @param FrmSettings $frm_settings | |
| 464 | - * | |
| 465 | - * @return string | |
| 466 | - */ | |
| 467 | - protected function captcha_size( $frm_settings ) { | |
| 468 | - _deprecated_function( __METHOD__, '6.8.4' ); | |
| 469 | - return 'normal'; | |
| 470 | 455 | } |
| 471 | 456 | } |