PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 3.06.06
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v3.06.06
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 +55 -223 6.5.33.06.06 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 /**
7 4 * @since 3.0
8 5 */
@@ -14,29 +11,18 @@
14 11 */
15 12 protected $type = 'captcha';
16 13
17 14 /**
18 - * @return string
15 + * @var bool
16 + * @since 3.0
19 17 */
20 - protected function include_form_builder_file() {
21 - return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
22 - }
18 + protected $has_for_label = false;
23 19
24 20 /**
25 - * Returns the image name for a captcha.
26 - *
27 21 * @return string
28 22 */
29 - public static function get_captcha_image_name() {
30 - $frm_settings = FrmAppHelper::get_settings();
31 - $active_captcha = $frm_settings->active_captcha;
32 - if ( $active_captcha === 'recaptcha' && $frm_settings->re_type === 'v3' ) {
33 - $image_name = 'recaptcha_v3';
34 - } else {
35 - $image_name = $active_captcha;
36 - }
37 -
38 - return $image_name;
23 + protected function include_form_builder_file() {
24 + return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
39 25 }
40 26
41 27 /**
42 28 * @return array
@@ -42,12 +28,12 @@
42 28 * @return array
43 29 */
44 30 protected function field_settings_for_type() {
45 31 return array(
46 - 'required' => false,
47 - 'invalid' => true,
48 - 'captcha_size' => true,
49 - 'default' => false,
32 + 'required' => false,
33 + 'invalid' => true,
34 + 'default_blank' => false,
35 + 'captcha_size' => true,
50 36 );
51 37 }
52 38
53 39 /**
@@ -54,9 +40,8 @@
54 40 * @return array
55 41 */
56 42 protected function new_field_settings() {
57 43 $frm_settings = FrmAppHelper::get_settings();
58 -
59 44 return array(
60 45 'invalid' => $frm_settings->re_msg,
61 46 );
62 47 }
@@ -80,39 +65,23 @@
80 65 *
81 66 * @return string
82 67 */
83 68 protected function before_replace_html_shortcodes( $args, $html ) {
84 - $frm_settings = FrmAppHelper::get_settings();
85 - $replace_response = $frm_settings->active_captcha === 'recaptcha' ? 'g-recaptcha-response' : 'h-captcha-response';
86 - $replaced_for = str_replace( ' for="field_[key]"', ' for="' . $replace_response . '"', $html );
87 -
88 - return $replaced_for;
69 + return str_replace( ' for="field_[key]"', ' for="g-recaptcha-response"', $html );
89 70 }
90 71
91 - /**
92 - * @return string
93 - */
94 72 public function front_field_input( $args, $shortcode_atts ) {
95 73 $frm_settings = FrmAppHelper::get_settings();
96 - if ( ! self::should_show_captcha() ) {
74 + if ( empty( $frm_settings->pubkey ) ) {
97 75 return '';
98 76 }
99 77
100 - $class_prefix = $this->class_prefix( $frm_settings );
101 - $captcha_class = $this->captcha_class( $frm_settings );
102 - $captcha_size = $this->captcha_size( $frm_settings );
78 + $class_prefix = $this->class_prefix();
79 + $captcha_size = $this->captcha_size();
103 80 $allow_mutiple = $frm_settings->re_multi;
104 81
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 ) {
82 + $html = '<div id="' . esc_attr( $args['html_id'] ) . '" class="' . esc_attr( $class_prefix ) . 'g-recaptcha" data-sitekey="' . esc_attr( $frm_settings->pubkey ) . '" data-size="' . esc_attr( $captcha_size ) . '" data-theme="' . esc_attr( $this->field['captcha_theme'] ) . '"';
83 + if ( $captcha_size == 'invisible' && ! $allow_mutiple ) {
115 84 $html .= ' data-callback="frmAfterRecaptcha"';
116 85 }
117 86 $html .= '></div>';
118 87
@@ -118,33 +87,19 @@
118 87
119 88 return $html;
120 89 }
121 90
122 - /**
123 - * @return void
124 - */
125 91 protected function load_field_scripts( $args ) {
126 92 $api_js_url = $this->api_url();
127 93
128 - wp_register_script( 'captcha-api', $api_js_url, array( 'formidable' ), '3', true );
129 - wp_enqueue_script( 'captcha-api' );
94 + wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), '3', true );
95 + wp_enqueue_script( 'recaptcha-api' );
130 96 }
131 97
132 98 protected function api_url() {
133 - $frm_settings = FrmAppHelper::get_settings();
134 - if ( $frm_settings->active_captcha === 'recaptcha' ) {
135 - return $this->recaptcha_api_url( $frm_settings );
136 - }
137 -
138 - return $this->hcaptcha_api_url();
139 - }
140 -
141 - /**
142 - * @param FrmSettings $frm_settings
143 - */
144 - protected function recaptcha_api_url( $frm_settings ) {
145 99 $api_js_url = 'https://www.google.com/recaptcha/api.js?';
146 100
101 + $frm_settings = FrmAppHelper::get_settings();
147 102 $allow_mutiple = $frm_settings->re_multi;
148 103 if ( $allow_mutiple ) {
149 104 $api_js_url .= '&onload=frmRecaptcha&render=explicit';
150 105 }
@@ -153,212 +108,89 @@
153 108 if ( ! empty( $lang ) ) {
154 109 $api_js_url .= '&hl=' . $lang;
155 110 }
156 111
157 - $api_js_url = apply_filters( 'frm_recaptcha_js_url', $api_js_url );
158 -
159 - return $api_js_url;
112 + return apply_filters( 'frm_recaptcha_js_url', $api_js_url );
160 113 }
161 114
162 - protected function hcaptcha_api_url() {
163 - $api_js_url = 'https://js.hcaptcha.com/1/api.js';
164 -
165 - /**
166 - * Allows updating hcaptcha js api url.
167 - *
168 - * @since 6.0
169 - *
170 - * @param string $api_js_url
171 - */
172 - $api_js_url = apply_filters( 'frm_hcaptcha_js_url', $api_js_url );
173 -
174 - return $api_js_url;
175 - }
176 -
177 - /**
178 - * @param FrmSettings $frm_settings
179 - *
180 - * @return string
181 - *
182 - * @psalm-return ''|'frm-'
183 - */
184 - protected function class_prefix( $frm_settings ) {
185 - if ( $this->allow_multiple( $frm_settings ) && $frm_settings->active_captcha === 'recaptcha' ) {
115 + protected function class_prefix() {
116 + if ( $this->allow_multiple() ) {
186 117 $class_prefix = 'frm-';
187 118 } else {
188 119 $class_prefix = '';
189 120 }
190 -
191 121 return $class_prefix;
192 122 }
193 123
194 - /**
195 - * @param FrmSettings $frm_settings
196 - *
197 - * @return string
198 - *
199 - * @psalm-return 'g-recaptcha'|'h-captcha'
200 - */
201 - protected function captcha_class( $frm_settings ) {
202 - return $frm_settings->active_captcha === 'recaptcha' ? 'g-recaptcha' : 'h-captcha';
203 - }
204 -
205 - protected function allow_multiple( $frm_settings ) {
124 + protected function allow_multiple() {
125 + $frm_settings = FrmAppHelper::get_settings();
206 126 return $frm_settings->re_multi;
207 127 }
208 128
209 - /**
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 - }
129 + protected function captcha_size() {
218 130 // for reverse compatibility
219 - return $this->field['captcha_size'] === 'default' ? 'normal' : $this->field['captcha_size'];
131 + $frm_settings = FrmAppHelper::get_settings();
132 + $captcha_size = ( $this->field['captcha_size'] == 'default' ) ? 'normal' : $this->field['captcha_size'];
133 + return ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $captcha_size;
220 134 }
221 135
222 - /**
223 - * @since 4.07
224 - * @param array $args
225 - * @return array
226 - */
227 - protected function validate_against_api( $args ) {
228 - $errors = array();
229 - $frm_settings = FrmAppHelper::get_settings();
230 - $resp = $this->send_api_check( $frm_settings );
231 - $response = json_decode( wp_remote_retrieve_body( $resp ), true );
136 + public function validate( $args ) {
137 + $errors = array();
232 138
233 - if ( is_wp_error( $resp ) ) {
234 - $error_string = $resp->get_error_message();
235 - $errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your captcha', 'formidable' );
236 - $errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
139 + if ( ! $this->should_validate() ) {
237 140 return $errors;
238 141 }
239 142
240 - if ( ! is_array( $response ) ) {
143 + if ( ! isset( $_POST['g-recaptcha-response'] ) ) {
144 + // If captcha is missing, check if it was already verified
145 + if ( ! isset( $_POST['recaptcha_checked'] ) || ! wp_verify_nonce( $_POST['recaptcha_checked'], 'frm_ajax' ) ) {
146 + // There was no captcha submitted
147 + $errors[ 'field' . $args['id'] ] = __( 'The captcha is missing from this form', 'formidable' );
148 + }
241 149 return $errors;
242 150 }
243 151
244 - if ( $frm_settings->active_captcha === 'recaptcha' ) {
245 - if ( 'v3' === $frm_settings->re_type && array_key_exists( 'score', $response ) ) {
246 - $threshold = floatval( $frm_settings->re_threshold );
247 - $score = floatval( $response['score'] );
152 + $frm_settings = FrmAppHelper::get_settings();
248 153
249 - $this->set_score( $score );
154 + $resp = $this->send_api_check( $frm_settings );
155 + $response = json_decode( wp_remote_retrieve_body( $resp ), true );
250 156
251 - if ( $score < $threshold ) {
252 - $response['success'] = false;
253 - }
254 - }
255 - }
256 -
257 157 if ( isset( $response['success'] ) && ! $response['success'] ) {
258 158 // What happens when the CAPTCHA was entered incorrectly
259 159 $invalid_message = FrmField::get_option( $this->field, 'invalid' );
260 - if ( $invalid_message === __( 'The reCAPTCHA was not entered correctly', 'formidable' ) ) {
261 - $invalid_message = '';
262 - }
263 - $errors[ 'field' . $args['id'] ] = ( $invalid_message === '' ? $frm_settings->re_msg : $invalid_message );
160 + $errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message );
161 + } elseif ( is_wp_error( $resp ) ) {
162 + $error_string = $resp->get_error_message();
163 + $errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your recaptcha', 'formidable' );
164 + $errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
264 165 }
265 166
266 167 return $errors;
267 168 }
268 169
269 - /**
270 - * @param float $score
271 - * @return void
272 - */
273 - private function set_score( $score ) {
274 - global $frm_vars;
275 - if ( ! isset( $frm_vars['captcha_scores'] ) ) {
276 - $frm_vars['captcha_scores'] = array();
170 + protected function should_validate() {
171 + $is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, stripslashes_deep( $_POST ) ); // WPCS: CSRF ok.
172 + if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
173 + return false;
277 174 }
278 - $form_id = is_object( $this->field ) ? $this->field->form_id : $this->field['form_id'];
279 - if ( ! isset( $frm_vars['captcha_scores'][ $form_id ] ) ) {
280 - $frm_vars['captcha_scores'][ $form_id ] = $score;
281 - }
282 - }
283 175
284 - /**
285 - * @param array $args
286 - * @return array
287 - */
288 - public function validate( $args ) {
289 - if ( ! $this->should_validate() ) {
290 - return array();
291 - }
292 -
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.
296 - return array( 'field' . $args['id'] => __( 'The captcha is missing from this form', 'formidable' ) );
297 - }
298 -
299 - return $this->validate_against_api( $args );
300 - }
301 -
302 - /**
303 - * @since 4.07
304 - * @return bool
305 - */
306 - public static function should_show_captcha() {
307 176 $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 );
313 - }
314 -
315 - /**
316 - * @return bool
317 - */
318 - protected function should_validate() {
319 - $is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
320 - if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
177 + if ( empty( $frm_settings->pubkey ) ) {
178 + // don't require the captcha if it shouldn't be shown
321 179 return false;
322 180 }
323 181
324 - // don't require the captcha if it shouldn't be shown
325 - return self::should_show_captcha();
182 + return true;
326 183 }
327 184
328 - /**
329 - * @param FrmSettings $frm_settings
330 - */
331 185 protected function send_api_check( $frm_settings ) {
332 - $captcha_settings = new FrmFieldCaptchaSettings( $frm_settings );
333 -
334 186 $arg_array = array(
335 - 'body' => array(
336 - 'secret' => $captcha_settings->secret,
337 - 'response' => FrmAppHelper::get_param( $captcha_settings->token_field, '', 'post', 'sanitize_text_field' ),
187 + 'body' => array(
188 + 'secret' => $frm_settings->privkey,
189 + 'response' => $_POST['g-recaptcha-response'], // WPCS: CSRF ok.
338 190 'remoteip' => FrmAppHelper::get_ip_address(),
339 191 ),
340 192 );
341 193
342 - return wp_remote_post( $captcha_settings->endpoint, $arg_array );
343 - }
344 -
345 - /**
346 - * Updates field name in page builder to the currently activated captcha if it is set to the default.
347 - *
348 - * @since 6.0
349 - *
350 - * @param array $values
351 - *
352 - * @return array $values
353 - */
354 - public static function update_field_name( $values ) {
355 - if ( $values['type'] === 'captcha' ) {
356 - $name = $values['name'];
357 - if ( in_array( $name, array( __( 'reCAPTCHA', 'formidable' ), __( 'hCaptcha', 'formidable' ) ), true ) ) {
358 - $values['name'] = __( 'Captcha', 'formidable' );
359 - }
360 - }
361 -
362 - return $values;
194 + return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array );
363 195 }
364 196 }