|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* @since 3.0 |
|
5
|
|
|
*/ |
|
6
|
|
|
class FrmFieldCaptcha extends FrmFieldType { |
|
7
|
|
|
|
|
8
|
|
|
/** |
|
9
|
|
|
* @var string |
|
10
|
|
|
* @since 3.0 |
|
11
|
|
|
*/ |
|
12
|
|
|
protected $type = 'captcha'; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* @return string |
|
16
|
|
|
*/ |
|
17
|
|
|
protected function include_form_builder_file() { |
|
18
|
|
|
return FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/field-captcha.php'; |
|
19
|
|
|
} |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* @return array |
|
23
|
|
|
*/ |
|
24
|
|
|
protected function field_settings_for_type() { |
|
25
|
|
|
return array( |
|
26
|
|
|
'required' => false, |
|
27
|
|
|
'invalid' => true, |
|
28
|
|
|
'captcha_size' => true, |
|
29
|
|
|
'default' => false, |
|
30
|
|
|
); |
|
31
|
|
|
} |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* @return array |
|
35
|
|
|
*/ |
|
36
|
|
|
protected function new_field_settings() { |
|
37
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
38
|
|
|
|
|
39
|
|
|
return array( |
|
40
|
|
|
'invalid' => $frm_settings->re_msg, |
|
41
|
|
|
); |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* @return array |
|
46
|
|
|
*/ |
|
47
|
|
|
protected function extra_field_opts() { |
|
48
|
|
|
return array( |
|
49
|
|
|
'label' => 'none', |
|
50
|
|
|
'captcha_size' => 'normal', |
|
51
|
|
|
'captcha_theme' => 'light', |
|
52
|
|
|
); |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* Remove the "for" attribute for captcha |
|
57
|
|
|
* |
|
58
|
|
|
* @param array $args |
|
59
|
|
|
* @param string $html |
|
60
|
|
|
* |
|
61
|
|
|
* @return string |
|
62
|
|
|
*/ |
|
63
|
|
|
protected function before_replace_html_shortcodes( $args, $html ) { |
|
64
|
|
|
return str_replace( ' for="field_[key]"', ' for="g-recaptcha-response"', $html ); |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
public function front_field_input( $args, $shortcode_atts ) { |
|
68
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
69
|
|
|
if ( empty( $frm_settings->pubkey ) ) { |
|
70
|
|
|
return ''; |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
$class_prefix = $this->class_prefix(); |
|
74
|
|
|
$captcha_size = $this->captcha_size(); |
|
75
|
|
|
$allow_mutiple = $frm_settings->re_multi; |
|
76
|
|
|
|
|
77
|
|
|
$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'] ) . '"'; |
|
78
|
|
|
if ( $captcha_size == 'invisible' && ! $allow_mutiple ) { |
|
79
|
|
|
$html .= ' data-callback="frmAfterRecaptcha"'; |
|
80
|
|
|
} |
|
81
|
|
|
$html .= '></div>'; |
|
82
|
|
|
|
|
83
|
|
|
return $html; |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
protected function load_field_scripts( $args ) { |
|
87
|
|
|
$api_js_url = $this->api_url(); |
|
88
|
|
|
|
|
89
|
|
|
wp_register_script( 'recaptcha-api', $api_js_url, array( 'formidable' ), '3', true ); |
|
90
|
|
|
wp_enqueue_script( 'recaptcha-api' ); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
protected function api_url() { |
|
94
|
|
|
$api_js_url = 'https://www.google.com/recaptcha/api.js?'; |
|
95
|
|
|
|
|
96
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
97
|
|
|
$allow_mutiple = $frm_settings->re_multi; |
|
98
|
|
|
if ( $allow_mutiple ) { |
|
99
|
|
|
$api_js_url .= '&onload=frmRecaptcha&render=explicit'; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
$lang = apply_filters( 'frm_recaptcha_lang', $frm_settings->re_lang, $this->field ); |
|
103
|
|
|
if ( ! empty( $lang ) ) { |
|
104
|
|
|
$api_js_url .= '&hl=' . $lang; |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
return apply_filters( 'frm_recaptcha_js_url', $api_js_url ); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
protected function class_prefix() { |
|
111
|
|
|
if ( $this->allow_multiple() ) { |
|
112
|
|
|
$class_prefix = 'frm-'; |
|
113
|
|
|
} else { |
|
114
|
|
|
$class_prefix = ''; |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
return $class_prefix; |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
|
|
protected function allow_multiple() { |
|
121
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
122
|
|
|
|
|
123
|
|
|
return $frm_settings->re_multi; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
protected function captcha_size() { |
|
127
|
|
|
// for reverse compatibility |
|
128
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
129
|
|
|
$captcha_size = ( $this->field['captcha_size'] == 'default' ) ? 'normal' : $this->field['captcha_size']; |
|
130
|
|
|
|
|
131
|
|
|
return ( $frm_settings->re_type == 'invisible' ) ? 'invisible' : $captcha_size; |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* @since 4.07 |
|
136
|
|
|
* @param array $args |
|
137
|
|
|
* @return array |
|
138
|
|
|
*/ |
|
139
|
|
|
protected function validate_against_api( $args ) { |
|
140
|
|
|
$errors = array(); |
|
141
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
142
|
|
|
$resp = $this->send_api_check( $frm_settings ); |
|
143
|
|
|
$response = json_decode( wp_remote_retrieve_body( $resp ), true ); |
|
144
|
|
|
|
|
145
|
|
|
if ( isset( $response['success'] ) && ! $response['success'] ) { |
|
146
|
|
|
// What happens when the CAPTCHA was entered incorrectly |
|
147
|
|
|
$invalid_message = FrmField::get_option( $this->field, 'invalid' ); |
|
148
|
|
|
$errors[ 'field' . $args['id'] ] = ( $invalid_message == '' ? $frm_settings->re_msg : $invalid_message ); |
|
149
|
|
View Code Duplication |
} elseif ( is_wp_error( $resp ) ) { |
|
|
|
|
|
|
150
|
|
|
$error_string = $resp->get_error_message(); |
|
151
|
|
|
$errors[ 'field' . $args['id'] ] = __( 'There was a problem verifying your recaptcha', 'formidable' ); |
|
152
|
|
|
$errors[ 'field' . $args['id'] ] .= ' ' . $error_string; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
return $errors; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* @param array $args |
|
160
|
|
|
* @return array |
|
161
|
|
|
*/ |
|
162
|
|
|
public function validate( $args ) { |
|
163
|
|
|
if ( ! $this->should_validate() ) { |
|
164
|
|
|
return array(); |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
if ( ! isset( $_POST['g-recaptcha-response'] ) ) { |
|
168
|
|
|
// There was no captcha submitted. |
|
169
|
|
|
return array( 'field' . $args['id'] => __( 'The captcha is missing from this form', 'formidable' ) ); |
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
return $this->validate_against_api( $args ); |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* @since 4.07 |
|
177
|
|
|
* @return bool |
|
178
|
|
|
*/ |
|
179
|
|
|
private function should_show_captcha() { |
|
180
|
|
|
$frm_settings = FrmAppHelper::get_settings(); |
|
181
|
|
|
return ! empty( $frm_settings->pubkey ); |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
protected function should_validate() { |
|
185
|
|
|
$is_hidden_field = apply_filters( 'frm_is_field_hidden', false, $this->field, wp_unslash( $_POST ) ); // WPCS: CSRF ok. |
|
186
|
|
|
if ( FrmAppHelper::is_admin() || $is_hidden_field ) { |
|
187
|
|
|
return false; |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
// don't require the captcha if it shouldn't be shown |
|
191
|
|
|
return $this->should_show_captcha(); |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
protected function send_api_check( $frm_settings ) { |
|
195
|
|
|
$arg_array = array( |
|
196
|
|
|
'body' => array( |
|
197
|
|
|
'secret' => $frm_settings->privkey, |
|
198
|
|
|
'response' => FrmAppHelper::get_param( 'g-recaptcha-response', '', 'post', 'sanitize_text_field' ), |
|
199
|
|
|
'remoteip' => FrmAppHelper::get_ip_address(), |
|
200
|
|
|
), |
|
201
|
|
|
); |
|
202
|
|
|
|
|
203
|
|
|
return wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', $arg_array ); |
|
204
|
|
|
} |
|
205
|
|
|
} |
|
206
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.