PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.4
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.4
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
formidable / classes / models / fields / FrmFieldCaptcha.php

FrmFieldCaptcha.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 5.4, at classes/models/fields/FrmFieldCaptcha.php

247 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 /**
7 * @since 3.0
8 */
9 class FrmFieldCaptcha extends FrmFieldType {
10
11 /**
12 * @var string
13 * @since 3.0
14 */
15 protected $type = 'captcha';
16
17 /**
18 * @return string
19 */
20 protected function include_form_builder_file() {
21 return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php';
22 }
23
24 /**
25 * @return array
26 */
27 protected function field_settings_for_type() {
28 return array(
29 'required' => false,
30 'invalid' => true,
31 'captcha_size' => true,
32 'default' => false,
33 );
34 }
35
36 /**
37 * @return array
38 */
39 protected function new_field_settings() {
40 $frm_settings = FrmAppHelper::get_settings();
41
42 return array(
43 'invalid' => $frm_settings->re_msg,
44 );
45 }
46
47 /**
48 * @return array
49 */
50 protected function extra_field_opts() {
51 return array(
52 'label' => 'none',
53 'captcha_size' => 'normal',
54 'captcha_theme' => 'light',
55 );
56 }
57
58 /**
59 * Remove the "for" attribute for captcha
60 *
61 * @param array $args
62 * @param string $html
63 *
64 * @return string
65 */
66 protected function before_replace_html_shortcodes( $args, $html ) {
67 return str_replace( ' for="field_[key]"', ' for="g-recaptcha-response"', $html );
68 }
69
70 public function front_field_input( $args, $shortcode_atts ) {
71 $frm_settings = FrmAppHelper::get_settings();
72 if ( empty( $frm_settings->pubkey ) ) {
73 return '';
74 }
75
76 $class_prefix = $this->class_prefix();
77 $captcha_size = $this->captcha_size();
78 $allow_mutiple = $frm_settings->re_multi;
79
80 $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'] ) . '"';
81 if ( $captcha_size == 'invisible' && ! $allow_mutiple ) {
82 $html .= ' data-callback="frmAfterRecaptcha"';
83 }
84 $html .= '></div>';
85
86 return $html;
87 }
88
89 protected function load_field_scripts( $args ) {
90 $api_js_url = $this->api_url();
91
92 wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), '3', true );
93 wp_enqueue_script( 'recaptcha-api' );
94 }
95
96 protected function api_url() {
97 $api_js_url = 'https://www.google.com/recaptcha/api.js?';
98
99 $frm_settings = FrmAppHelper::get_settings();
100 $allow_mutiple = $frm_settings->re_multi;
101 if ( $allow_mutiple ) {
102 $api_js_url .= '&onload=frmRecaptcha&render=explicit';
103 }
104
105 $lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field );
106 if ( ! empty( $lang ) ) {
107 $api_js_url .= '&hl=' . $lang;
108 }
109
110 return apply_filters( 'frm_recaptcha_js_url', $api_js_url );
111 }
112
113 protected function class_prefix() {
114 if ( $this->allow_multiple() ) {
115 $class_prefix = 'frm-';
116 } else {
117 $class_prefix = '';
118 }
119
120 return $class_prefix;
121 }
122
123 protected function allow_multiple() {
124 $frm_settings = FrmAppHelper::get_settings();
125
126 return $frm_settings->re_multi;
127 }
128
129 /**
130 * @return string
131 */
132 protected function captcha_size() {
133 $frm_settings = FrmAppHelper::get_settings();
134 if ( in_array( $frm_settings->re_type, array( 'invisible', 'v3' ), true ) ) {
135 return 'invisible';
136 }
137 // for reverse compatibility
138 return $this->field['captcha_size'] === 'default' ? 'normal' : $this->field['captcha_size'];
139 }
140
141 /**
142 * @since 4.07
143 * @param array $args
144 * @return array
145 */
146 protected function validate_against_api( $args ) {
147 $errors = array();
148 $frm_settings = FrmAppHelper::get_settings();
149 $resp = $this->send_api_check( $frm_settings );
150 $response = json_decode( wp_remote_retrieve_body( $resp ), true );
151
152 if ( is_wp_error( $resp ) ) {
153 $error_string = $resp->get_error_message();
154 $errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your recaptcha', 'formidable' );
155 $errors[ 'field' . $args['id'] ] .= ' ' . $error_string;
156 return $errors;
157 }
158
159 if ( ! is_array( $response ) ) {
160 return $errors;
161 }
162
163 if ( 'v3' === $frm_settings->re_type && array_key_exists( 'score', $response ) ) {
164 $threshold = floatval( $frm_settings->re_threshold );
165 $score = floatval( $response['score'] );
166
167 $this->set_score( $score );
168
169 if ( $score < $threshold ) {
170 $response['success'] = false;
171 }
172 }
173
174 if ( isset( $response['success'] ) && ! $response['success'] ) {
175 // What happens when the CAPTCHA was entered incorrectly
176 $invalid_message = FrmField::get_option( $this->field, 'invalid' );
177 $errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message );
178 }
179
180 return $errors;
181 }
182
183 /**
184 * @param float $score
185 * @return void
186 */
187 private function set_score( $score ) {
188 global $frm_vars;
189 if ( ! isset( $frm_vars['captcha_scores'] ) ) {
190 $frm_vars['captcha_scores'] = array();
191 }
192 $form_id = is_object( $this->field ) ? $this->field->form_id : $this->field['form_id'];
193 if ( ! isset( $frm_vars['captcha_scores'][ $form_id ] ) ) {
194 $frm_vars['captcha_scores'][ $form_id ] = $score;
195 }
196 }
197
198 /**
199 * @param array $args
200 * @return array
201 */
202 public function validate( $args ) {
203 if ( ! $this->should_validate() ) {
204 return array();
205 }
206
207 // phpcs:ignore WordPress.Security.NonceVerification.Missing
208 if ( ! isset( $_POST['g-recaptcha-response'] ) ) {
209 // There was no captcha submitted.
210 return array( 'field' . $args['id'] => __( 'The captcha is missing from this form', 'formidable' ) );
211 }
212
213 return $this->validate_against_api( $args );
214 }
215
216 /**
217 * @since 4.07
218 * @return bool
219 */
220 private function should_show_captcha() {
221 $frm_settings = FrmAppHelper::get_settings();
222 return ! empty( $frm_settings->pubkey );
223 }
224
225 protected function should_validate() {
226 $is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
227 if ( FrmAppHelper::is_admin() || $is_hidden_field ) {
228 return false;
229 }
230
231 // don't require the captcha if it shouldn't be shown
232 return $this->should_show_captcha();
233 }
234
235 protected function send_api_check( $frm_settings ) {
236 $arg_array = array(
237 'body' => array(
238 'secret' => $frm_settings->privkey,
239 'response' => FrmAppHelper::get_param( 'g-recaptcha-response', '', 'post', 'sanitize_text_field' ),
240 'remoteip' => FrmAppHelper::get_ip_address(),
241 ),
242 );
243
244 return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array );
245 }
246 }
247