-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathrecaptcha-woo.php
437 lines (392 loc) · 15.7 KB
/
recaptcha-woo.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
<?php
/**
* Plugin Name: reCAPTCHA for WooCommerce
* Description: Add Google reCAPTCHA to your WooCommerce Checkout, Login, and Registration Forms.
* Version: 1.4.1
* Author: Elliot Sowersby, RelyWP
* Author URI: https://www.relywp.com
* License: GPLv3 or later
* Text Domain: recaptcha-woo
*
* WC requires at least: 3.4
* WC tested up to: 9.4.3
**/
include( plugin_dir_path( __FILE__ ) . 'admin-options.php');
/**
* On activate redirect to settings page
*/
register_activation_hook(__FILE__, function () {
add_option('rcfwc_do_activation_redirect', true);
add_option('rcfwc_tested', 'no');
});
add_action('admin_init', function () {
if (get_option('rcfwc_do_activation_redirect', false)) {
delete_option('rcfwc_do_activation_redirect');
exit( wp_redirect("options-general.php?page=recaptcha-woo%2Fadmin-options.php") );
}
});
/**
* Compatible with HPOS
*/
add_action( 'before_woocommerce_init', function() {
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
}
} );
// Plugin List - Settings Link
add_filter( 'plugin_action_links', 'rcfwc_settings_link_plugin', 10, 5 );
function rcfwc_settings_link_plugin( $actions, $plugin_file )
{
static $plugin;
if (!isset($plugin))
$plugin = plugin_basename(__FILE__);
if ($plugin == $plugin_file) {
$settings = array('settings' => '<a href="options-general.php?page=recaptcha-woo%2Fadmin-options.php">' . __('Settings', 'General') . '</a>');
$actions = array_merge($settings, $actions);
}
return $actions;
}
// Enqueue recaptcha script only on account or checkout page
if(get_option('rcfwc_scripts_all', true)) {
add_action("wp_enqueue_scripts", "rcfwc_script_enqueue");
}
function rcfwc_script_enqueue() {
wp_enqueue_script( 'rcfwc-js', plugins_url( '/js/rcfwc.js', __FILE__ ), array('jquery'), '1.0', array('strategy' => 'defer'));
wp_enqueue_script( 'recaptcha', 'https://www.google.com/recaptcha/api.js?explicit&hl=' . get_locale(), array(), null, array('strategy' => 'defer'));
}
add_action("wp_enqueue_scripts", "rcfwc_script");
function rcfwc_script() {
if( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
if ( is_checkout() || is_account_page() ) {
rcfwc_script_enqueue();
}
}
}
// Enqueue recaptcha script on login
add_action("login_enqueue_scripts", "rcfwc_script_login");
function rcfwc_script_login() {
rcfwc_script_enqueue();
}
// Field
function rcfwc_field() {
$key = esc_attr( get_option('rcfwc_key') );
$secret = esc_attr( get_option('rcfwc_secret') );
$theme = esc_attr( get_option('rcfwc_theme') );
if($key && $secret) {
?>
<div class="g-recaptcha" <?php if($theme == "dark") { ?>data-theme="dark" <?php } ?>data-sitekey="<?php echo $key; ?>"></div>
<br/>
<?php
}
}
// Field WP Admin
function rcfwc_field_admin() {
$key = esc_attr( get_option('rcfwc_key') );
$secret = esc_attr( get_option('rcfwc_secret') );
$theme = esc_attr( get_option('rcfwc_theme') );
if($key && $secret) {
?>
<div style="margin-left: -15px;" class="g-recaptcha" <?php if($theme == "dark") { ?>data-theme="dark" <?php } ?>data-sitekey="<?php echo $key; ?>"></div>
<br/>
<?php
}
}
// Field Checkout
function rcfwc_field_checkout($checkout) {
$key = esc_attr( get_option('rcfwc_key') );
$secret = esc_attr( get_option('rcfwc_secret') );
$theme = esc_attr( get_option('rcfwc_theme') );
$guest = esc_attr( get_option('rcfwc_guest_only') );
if(get_option('rcfwc_woo_checkout_pos') == "afterpay") {
echo "<br/>";
}
if( !$guest || ( $guest && !is_user_logged_in() ) ) {
if($key && $secret) {
?>
<div class="g-recaptcha" <?php if($theme == "dark") { ?>data-theme="dark" <?php } ?>data-sitekey="<?php echo $key; ?>"></div>
<br/>
<?php
}
}
}
// Field Checkout block
function rcfwc_field_checkout_block() {
$key = esc_attr( get_option('rcfwc_key') );
$secret = esc_attr( get_option('rcfwc_secret') );
$theme = esc_attr( get_option('rcfwc_theme') );
$guest = esc_attr( get_option('rcfwc_guest_only') );
?>
<?php if ( !$guest || ( $guest && !is_user_logged_in() ) ) {
if($key && $secret) {
?>
<div class="g-recaptcha" <?php if($theme == "dark") { ?>data-theme="dark" <?php } ?>data-sitekey="<?php echo $key; ?>"></div>
<br/>
<?php
}
} ?>
<?php
return;
}
function rcfwc_render_post_block($block_content) {
ob_start();
echo $block_content;
rcfwc_field_checkout_block();
$block_content = ob_get_contents();
ob_end_clean();
return $block_content;
}
function rcfwc_render_pre_block($block_content) {
ob_start();
rcfwc_field_checkout_block();
echo $block_content;
$block_content = ob_get_contents();
ob_end_clean();
return $block_content;
}
// Check the reCAPTCHA on submit.
function rcfwc_recaptcha_check($token = null) {
if ( isset( $token ) ) {
$postdata = $token;
} else {
$postdata = "";
if(isset($_POST['g-recaptcha-response'])) {
$postdata = sanitize_text_field( $_POST['g-recaptcha-response'] );
}
}
$key = esc_attr( get_option('rcfwc_key') );
$secret = esc_attr( get_option('rcfwc_secret') );
$guest = esc_attr( get_option('rcfwc_guest_only') );
if($key && $secret) {
$verify = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$postdata );
$verify = wp_remote_retrieve_body( $verify );
$response = json_decode($verify);
$results['success'] = $response->success;
foreach($response as $key => $val){
if($key == 'error-codes')
foreach($val as $key => $error_val){
$results['error_code'] = $error_val;
}
}
return $results;
} else {
return false;
}
}
if(!empty(get_option('rcfwc_key')) && !empty(get_option('rcfwc_secret'))) {
// WP Login Check
if(get_option('rcfwc_login')) {
if(get_option('rcfwc_tested') == 'yes') {
add_action('login_form','rcfwc_field_admin');
add_action('authenticate', 'rcfwc_wp_login_check', 21, 1);
function rcfwc_wp_login_check($user){
// Start session
if (!session_id()) { session_start(); }
// Only run if $user exists
if(!isset($user->ID)) { return $user; }
// Check skip
if(defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST) { return $user; } // Skip XMLRPC
if(defined( 'REST_REQUEST' ) && REST_REQUEST) { return $user; } // Skip REST API
if(isset($_POST['woocommerce-login-nonce']) && wp_verify_nonce(sanitize_text_field($_POST['woocommerce-login-nonce']), 'woocommerce-login')) { return $user; } // Skip Woo
if(is_wp_error($user) && isset($user->errors['empty_username']) && isset($user->errors['empty_password']) ) {return $user; } // Skip Errors
// Check if already validated
if(isset($_SESSION['rcfwc_login_checked']) && wp_verify_nonce( sanitize_text_field($_SESSION['rcfwc_login_checked']), 'rcfwc_login_check' )) {
return $user;
}
if(stripos($_SERVER["REQUEST_URI"], strrchr(wp_login_url(), '/')) !== false) { // Check if WP login page
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$user = new WP_Error( 'authentication_failed', __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) );
} else {
$nonce = wp_create_nonce( 'rcfwc_login_check' );
$_SESSION['rcfwc_login_checked'] = $nonce;
}
}
return $user;
}
}
}
// Clear session on login
add_action('wp_login', 'rcfwc_wp_login_clear', 10, 2);
function rcfwc_wp_login_clear($user_login, $user) {
if(isset($_SESSION['rcfwc_login_checked'])) { unset($_SESSION['rcfwc_login_checked']); }
}
// WP Register Check
if(get_option('rcfwc_register')) {
add_action('register_form','rcfwc_field_admin');
add_action('registration_errors', 'rcfwc_wp_register_check', 10, 3);
function rcfwc_wp_register_check($errors, $sanitized_user_login, $user_email) {
if(defined( 'XMLRPC_REQUEST')) { return $errors; } // Skip XMLRPC
if(defined( 'REST_REQUEST')) { return $errors; } // Skip REST API
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$errors->add( 'rcfwc_error', sprintf('<strong>%s</strong>: %s',__( 'ERROR', 'recaptcha-woo' ), __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) ) );
}
return $errors;
}
}
// WP Reset Check
if(get_option('rcfwc_woo_reset')) {
if(!is_admin()) {
add_action('lostpassword_form','rcfwc_field_admin');
add_action('lostpassword_post','rcfwc_wp_reset_check', 10, 1);
function rcfwc_wp_reset_check($validation_errors) {
if(stripos($_SERVER["REQUEST_URI"], strrchr(wp_login_url(), '/')) !== false) { // Check if WP login page
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$validation_errors->add( 'rcfwc_error', __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) );
}
}
}
}
}
if( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
// Woo Checkout
if( get_option('rcfwc_key') && get_option('rcfwc_woo_checkout') ) {
if(empty(get_option('rcfwc_woo_checkout_pos')) || get_option('rcfwc_woo_checkout_pos') == "beforepay") {
add_action('woocommerce_review_order_before_payment', 'rcfwc_field_checkout', 10);
add_filter('render_block_woocommerce/checkout-payment-block', 'rcfwc_render_pre_block', 999, 1); // Before Payment block.
} elseif(get_option('rcfwc_woo_checkout_pos') == "afterpay") {
add_action('woocommerce_review_order_after_payment', 'rcfwc_field_checkout', 10);
add_filter('render_block_woocommerce/checkout-payment-block', 'rcfwc_render_post_block', 999, 1); // After Payment block.
} elseif(get_option('rcfwc_woo_checkout_pos') == "beforebilling") {
add_action('woocommerce_before_checkout_billing_form', 'rcfwc_field_checkout', 10);
add_filter('render_block_woocommerce/checkout-contact-information-block', 'rcfwc_render_pre_block', 999, 1); // Before Contact Information block.
} elseif(get_option('rcfwc_woo_checkout_pos') == "afterbilling") {
add_action('woocommerce_after_checkout_billing_form', 'rcfwc_field_checkout', 10);
add_filter('render_block_woocommerce/checkout-shipping-methods-block', 'rcfwc_render_pre_block', 999, 1); // Before Shipping Methods block.
} elseif(get_option('rcfwc_woo_checkout_pos') == "beforesubmit") {
add_action('woocommerce_review_order_before_submit', 'rcfwc_field_checkout', 10);
add_filter('render_block_woocommerce/checkout-actions-block', 'rcfwc_render_pre_block', 999, 1); // Before Actions block, not sure if this option is still supported.
}
add_action('woocommerce_checkout_process', 'rcfwc_checkout_check');
add_action('woocommerce_store_api_checkout_update_order_from_request', 'rcfwc_checkout_block_check', 10, 2);
add_action('woocommerce_loaded', 'rcfwc_register_endpoint_data');
function rcfwc_register_endpoint_data() {
woocommerce_store_api_register_endpoint_data(
array(
'endpoint' => 'checkout',
'namespace' => 'rcfwc',
'schema_callback' => function() {
return array(
'token' => array(
'description' => __( 'reCaptcha token.', 'recaptcha-woo' ),
'type' => 'string',
'context' => array()
),
);
},
)
);
}
function rcfwc_checkout_check() {
// Skip if reCAPTCHA disabled for payment method
$skip = 0;
if ( isset( $_POST['payment_method'] ) ) {
$chosen_payment_method = sanitize_text_field( $_POST['payment_method'] );
// Retrieve the selected payment methods from the rcfwc_selected_payment_methods option
$selected_payment_methods = get_option('rcfwc_selected_payment_methods', array());
if(is_array($selected_payment_methods)) {
// Check if the chosen payment method is in the selected payment methods array
if ( in_array( $chosen_payment_method, $selected_payment_methods, true ) ) {
$skip = 1;
}
}
}
// Check if guest only enabled
$guest = esc_attr( get_option('rcfwc_guest_only') );
// Check
if( !$skip && (!$guest || ( $guest && !is_user_logged_in() )) ) {
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
wc_add_notice( __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ), 'error');
}
}
}
function rcfwc_checkout_block_check($order, $request) {
// Skip if reCAPTCHA disabled for payment method
$skip = 0;
if ( $request->get_method() === 'POST' ) {
if ( $request->get_param( 'payment_method' ) !== null ) {
$chosen_payment_method = sanitize_text_field( $request->get_param( 'payment_method' ) );
// Retrieve the selected payment methods from the rcfwc_selected_payment_methods option
$selected_payment_methods = get_option('rcfwc_selected_payment_methods', array());
if(is_array($selected_payment_methods)) {
// Check if the chosen payment method is in the selected payment methods array
if ( in_array( $chosen_payment_method, $selected_payment_methods, true ) ) {
return $order;
}
}
}
// Check if guest only enabled
$guest = esc_attr( get_option('rcfwc_guest_only') );
if ( !$guest || ( $guest && !is_user_logged_in() ) ) {
$extensions = $request->get_param( 'extensions' );
if ( empty( $extensions ) ) {
throw new \Exception( __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ));
}
$value = $extensions[ 'rcfwc' ];
if ( empty( $value ) ) {
throw new \Exception( __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ));
}
$token = $value['token'];
$check = rcfwc_recaptcha_check($token);
$success = $check['success'];
if ( !$success ) {
throw new \Exception( __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ));
}
}
}
return $order;
}
}
// Woo Login
if(get_option('rcfwc_woo_login')) {
add_action('woocommerce_login_form','rcfwc_field');
add_action('authenticate', 'rcfwc_woo_login_check', 21, 1);
function rcfwc_woo_login_check($user){
if(defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST) { return $user; } // Skip XMLRPC
if(defined( 'REST_REQUEST' ) && REST_REQUEST) { return $user; } // Skip REST API
if(isset($_POST['woocommerce-login-nonce'])) {
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$user = new WP_Error( 'authentication_failed', __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) );
}
}
return $user;
}
}
// Woo Register
if(get_option('rcfwc_woo_register')) {
add_action('woocommerce_register_form','rcfwc_field');
add_action('woocommerce_register_post', 'rcfwc_woo_register_check', 10, 3);
function rcfwc_woo_register_check($username, $email, $validation_errors) {
if(!is_checkout()) {
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$validation_errors->add( 'rcfwc_error', __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) );
}
}
}
}
// Woo Reset
if(get_option('rcfwc_woo_reset')) {
add_action('woocommerce_lostpassword_form','rcfwc_field');
add_action('lostpassword_post','rcfwc_woo_reset_check', 10, 1);
function rcfwc_woo_reset_check($validation_errors) {
if(isset($_POST['woocommerce-lost-password-nonce'])) {
$check = rcfwc_recaptcha_check();
$success = $check['success'];
if($success != true) {
$validation_errors->add( 'rcfwc_error', __( 'Please complete the reCAPTCHA to verify that you are not a robot.', 'recaptcha-woo' ) );
}
}
}
}
}
}