Test Failed
Branch master (049c7e)
by Devin
12:45 queued 07:50
created

process-donation.php ➔ give_get_required_fields()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 67
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 33
nc 4
nop 1
dl 0
loc 67
rs 8.8076
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Process Donation
4
 *
5
 * @package     Give
6
 * @subpackage  Functions
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Process Donation Form
19
 *
20
 * Handles the donation form process.
21
 *
22
 * @access      private
23
 * @since       1.0
24
 * @return      false|null
25
 */
26
function give_process_donation_form() {
27
28
	/**
29
	 * Fires before processing the donation form.
30
	 *
31
	 * @since 1.0
32
	 */
33
	do_action( 'give_pre_process_donation' );
34
35
	// Validate the form $_POST data
36
	$valid_data = give_donation_form_validate_fields();
37
38
	/**
39
	 * Fires after validating donation form fields.
40
	 *
41
	 * Allow you to hook to donation form errors.
42
	 *
43
	 * @since 1.0
44
	 *
45
	 * @param bool|array $valid_data Validate fields.
46
	 * @param array $_POST Array of variables passed via the HTTP POST.
47
	 */
48
	do_action( 'give_checkout_error_checks', $valid_data, $_POST );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
49
50
	$is_ajax = isset( $_POST['give_ajax'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
51
52
	// Process the login form
53
	if ( isset( $_POST['give_login_submit'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
54
		give_process_form_login();
55
	}
56
57
	// Validate the user
58
	$user = give_get_donation_form_user( $valid_data );
0 ignored issues
show
Security Bug introduced by
It seems like $valid_data defined by give_donation_form_validate_fields() on line 36 can also be of type false; however, give_get_donation_form_user() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
59
60
	if ( false === $valid_data || give_get_errors() || ! $user ) {
61
		if ( $is_ajax ) {
62
			/**
63
			 * Fires when AJAX sends back errors from the donation form.
64
			 *
65
			 * @since 1.0
66
			 */
67
			do_action( 'give_ajax_donation_errors' );
68
			give_die();
69
		} else {
70
			return false;
71
		}
72
	}
73
74
	// If AJAX send back success to proceed with form submission
75
	if ( $is_ajax ) {
76
		echo 'success';
77
		give_die();
78
	}
79
80
	// After AJAX: Setup session if not using php_sessions
81
	if ( ! Give()->session->use_php_sessions() ) {
82
		// Double-check that set_cookie is publicly accessible;
83
		// we're using a slightly modified class-wp-sessions.php
84
		$session_reflection = new ReflectionMethod( 'WP_Session', 'set_cookie' );
85
		if ( $session_reflection->isPublic() ) {
86
			// Manually set the cookie.
87
			Give()->session->init()->set_cookie();
0 ignored issues
show
Bug introduced by
The method set_cookie cannot be called on Give()->session->init() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
88
		}
89
	}
90
91
	// Setup user information
92
	$user_info = array(
93
		'id'         => $user['user_id'],
94
		'email'      => $user['user_email'],
95
		'first_name' => $user['user_first'],
96
		'last_name'  => $user['user_last'],
97
		'address'    => $user['address'],
98
	);
99
100
	$auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
101
102
	$price        = isset( $_POST['give-amount'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
103
		(float) apply_filters( 'give_donation_total', give_maybe_sanitize_amount( $_POST['give-amount'] ) ) :
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
104
		'0.00';
105
	$purchase_key = strtolower( md5( $user['user_email'] . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) );
106
107
	// Setup donation information
108
	$donation_data = array(
109
		'price'        => $price,
110
		'purchase_key' => $purchase_key,
111
		'user_email'   => $user['user_email'],
112
		'date'         => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
113
		'user_info'    => stripslashes_deep( $user_info ),
114
		'post_data'    => $_POST,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
115
		'gateway'      => $valid_data['gateway'],
116
		'card_info'    => $valid_data['cc_info'],
117
	);
118
119
	// Add the user data for hooks
120
	$valid_data['user'] = $user;
121
122
	/**
123
	 * Fires before donation form gateway.
124
	 *
125
	 * Allow you to hook to donation form before the gateway.
126
	 *
127
	 * @since 1.0
128
	 *
129
	 * @param array $_POST Array of variables passed via the HTTP POST.
130
	 * @param array $user_info Array containing basic user information.
131
	 * @param bool|array $valid_data Validate fields.
132
	 */
133
	do_action( 'give_checkout_before_gateway', $_POST, $user_info, $valid_data );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
134
135
	// Sanity check for price
136
	if ( ! $donation_data['price'] ) {
137
		// Revert to manual
138
		$donation_data['gateway'] = 'manual';
139
		$_POST['give-gateway']    = 'manual';
140
	}
141
142
	/**
143
	 * Allow the donation data to be modified before it is sent to the gateway.
144
	 *
145
	 * @since 1.7
146
	 */
147
	$donation_data = apply_filters( 'give_donation_data_before_gateway', $donation_data, $valid_data );
148
149
	// Setup the data we're storing in the donation session
150
	$session_data = $donation_data;
151
152
	// Make sure credit card numbers are never stored in sessions
153
	unset( $session_data['card_info']['card_number'] );
154
	unset( $session_data['post_data']['card_number'] );
155
156
	// Used for showing data to non logged-in users after donation, and for other plugins needing donation data.
157
	give_set_purchase_session( $session_data );
158
159
	// Send info to the gateway for payment processing
160
	give_send_to_gateway( $donation_data['gateway'], $donation_data );
161
	give_die();
162
163
}
164
165
add_action( 'give_purchase', 'give_process_donation_form' );
166
add_action( 'wp_ajax_give_process_donation', 'give_process_donation_form' );
167
add_action( 'wp_ajax_nopriv_give_process_donation', 'give_process_donation_form' );
168
169
170
/**
171
 * Verify that when a logged in user makes a donation that the email address used doesn't belong to a different customer.
172
 *
173
 * @since  1.7
174
 *
175
 * @param  array $valid_data Validated data submitted for the donation.
176
 * @param  array $post Additional $_POST data submitted
177
 *
178
 * @return void
179
 */
180
function give_check_logged_in_user_for_existing_email( $valid_data, $post ) {
0 ignored issues
show
Unused Code introduced by
The parameter $post is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
181
182
	// Verify that the email address belongs to this customer.
183
	if ( is_user_logged_in() ) {
184
185
		$submitted_email    = $valid_data['logged_in_user']['user_email'];
186
		$customer = new Give_Donor( get_current_user_id(), true );
187
188
		// If this email address is not registered with this customer, see if it belongs to any other customer
189
		if (
190
			$submitted_email !== $customer->email
191
			&& ( is_array( $customer->emails ) && ! in_array( $submitted_email, $customer->emails ) )
192
		) {
193
			$found_customer = new Give_Donor( $submitted_email );
194
195
			if ( $found_customer->id > 0 ) {
196
				give_set_error( 'give-customer-email-exists', sprintf( __( 'You are logged in as %1$s, and are submitting a donation as %2$s, which is an existing donor. To ensure that the email address is tied to the correct donor, please submit this donation from a logged-out browser, or choose another email address.' ,'give' ), $customer->email, $submitted_email ) );
197
			}
198
		}
199
	}
200
}
201
202
add_action( 'give_checkout_error_checks', 'give_check_logged_in_user_for_existing_email', 10, 2 );
203
204
/**
205
 * Process the checkout login form
206
 *
207
 * @access      private
208
 * @since       1.0
209
 * @return      void
210
 */
211
function give_process_form_login() {
212
	$is_ajax = isset( $_POST['give_ajax'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
213
214
	$user_data = give_donation_form_validate_user_login();
215
216
	if ( give_get_errors() || $user_data['user_id'] < 1 ) {
217
		if ( $is_ajax ) {
218
			/**
219
			 * Fires when AJAX sends back errors from the donation form.
220
			 *
221
			 * @since 1.0
222
			 */
223
			ob_start();
224
				do_action( 'give_ajax_donation_errors' );
225
				$message = ob_get_contents();
226
			ob_end_clean();
227
			wp_send_json_error( $message );
228
		} else {
229
			wp_redirect( $_SERVER['HTTP_REFERER'] );
0 ignored issues
show
introduced by
Detected usage of a non-validated input variable: $_SERVER
Loading history...
230
			exit;
231
		}
232
	}
233
234
	give_log_user_in( $user_data['user_id'], $user_data['user_login'], $user_data['user_pass'] );
235
236
	if ( $is_ajax ) {
237
		$message = Give()->notices->print_frontend_notice(
238
			sprintf(
239
				/* translators: %s: user first name */
240
				esc_html__( 'Welcome %s! You have successfully logged into your account.', 'give' ),
241
				( ! empty( $user_data['user_first'] ) ) ? $user_data['user_first'] : $user_data['user_login']
242
			),
243
			false,
244
			'success'
245
		);
246
247
		wp_send_json_success( $message );
248
	} else {
249
		wp_redirect( $_SERVER['HTTP_REFERER'] );
0 ignored issues
show
introduced by
Detected usage of a non-validated input variable: $_SERVER
Loading history...
250
	}
251
}
252
253
add_action( 'wp_ajax_give_process_donation_login', 'give_process_form_login' );
254
add_action( 'wp_ajax_nopriv_give_process_donation_login', 'give_process_form_login' );
255
256
/**
257
 * Donation Form Validate Fields.
258
 *
259
 * @access      private
260
 * @since       1.0
261
 * @return      bool|array
262
 */
263
function give_donation_form_validate_fields() {
264
265
	// Check if there is $_POST
266
	if ( empty( $_POST ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
267
		return false;
268
	}
269
270
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
271
272
	// Start an array to collect valid data
273
	$valid_data = array(
274
		'gateway'          => give_donation_form_validate_gateway(), // Gateway fallback (amount is validated here)
275
		'need_new_user'    => false,     // New user flag
276
		'need_user_login'  => false,     // Login user flag
277
		'logged_user_data' => array(),   // Logged user collected data
278
		'new_user_data'    => array(),   // New user collected data
279
		'login_user_data'  => array(),   // Login user collected data
280
		'guest_user_data'  => array(),   // Guest user collected data
281
		'cc_info'          => give_donation_form_validate_cc(),// Credit card info
282
	);
283
284
	// Validate Honeypot First
285
	if ( ! empty( $_POST['give-honeypot'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
286
		give_set_error( 'invalid_honeypot', esc_html__( 'Honeypot field detected. Go away bad bot!', 'give' ) );
287
	}
288
289
	// Validate agree to terms
290
	if ( give_is_terms_enabled( $form_id ) ) {
291
		give_donation_form_validate_agree_to_terms();
292
	}
293
294
	// Stop processing donor registration, if donor registration is optional and donor can do guest checkout.
295
	// If registration form username field is empty that means donor do not want to registration instead want guest checkout.
296
	if (
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
297
		! give_logged_in_only( $form_id )
298
		&& isset( $_POST['give-purchase-var'] )
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
299
		&& $_POST['give-purchase-var'] == 'needs-to-register'
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
300
		&& empty( $_POST['give_user_login'] )
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
301
	) {
302
		unset( $_POST['give-purchase-var'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
303
	}
304
305
	if ( is_user_logged_in() ) {
306
		// Collect logged in user data.
307
		$valid_data['logged_in_user'] = give_donation_form_validate_logged_in_user();
308
	} elseif ( isset( $_POST['give-purchase-var'] ) && $_POST['give-purchase-var'] == 'needs-to-register' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
309
		// Set new user registration as required.
310
		$valid_data['need_new_user'] = true;
311
		// Validate new user data.
312
		$valid_data['new_user_data'] = give_donation_form_validate_new_user();
313
		// Check if login validation is needed.
314
	} elseif ( isset( $_POST['give-purchase-var'] ) && $_POST['give-purchase-var'] == 'needs-to-login' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
315
		// Set user login as required.
316
		$valid_data['need_user_login'] = true;
317
		// Validate users login info.
318
		$valid_data['login_user_data'] = give_donation_form_validate_user_login();
319
	} else {
320
		// Not registering or logging in, so setup guest user data.
321
		$valid_data['guest_user_data'] = give_donation_form_validate_guest_user();
322
	}
323
324
	// Return collected data.
325
	return $valid_data;
326
}
327
328
/**
329
 * Donation Form Validate Gateway
330
 *
331
 * Validate the gateway and donation amount.
332
 *
333
 * @access      private
334
 * @since       1.0
335
 * @return      string
336
 */
337
function give_donation_form_validate_gateway() {
338
339
	$form_id = isset( $_REQUEST['give-form-id'] ) ? $_REQUEST['give-form-id'] : 0;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
340
	$amount  = isset( $_REQUEST['give-amount'] ) ? give_maybe_sanitize_amount( $_REQUEST['give-amount'] ) : 0;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
341
	$gateway = give_get_default_gateway( $form_id );
342
343
	// Check if a gateway value is present.
344
	if ( ! empty( $_REQUEST['give-gateway'] ) ) {
345
346
		$gateway = sanitize_text_field( $_REQUEST['give-gateway'] );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
347
348
		// Is amount being donated in LIVE mode 0.00? If so, error:
349
		if ( $amount == 0 && ! give_is_test_mode() ) {
0 ignored issues
show
introduced by
Found "== 0". Use Yoda Condition checks, you must
Loading history...
350
351
			give_set_error( 'invalid_donation_amount', __( 'Please insert a valid donation amount.', 'give' ) );
352
353
		} // End if().
354
		elseif ( ! give_verify_minimum_price() ) {
355
			// translators: %s: minimum donation amount.
356
			give_set_error(
357
				'invalid_donation_minimum',
358
				sprintf(
359
					/* translators: %s: minimum donation amount */
360
					__( 'This form has a minimum donation amount of %s.', 'give' ),
361
					give_currency_filter( give_format_amount( give_get_form_minimum_price( $form_id ), array( 'sanitize' => false ) ) )
362
				)
363
			);
364
365
		} //Is this test mode zero donation? Let it through but set to manual gateway.
366
		elseif ( $amount == 0 && give_is_test_mode() ) {
0 ignored issues
show
introduced by
Found "== 0". Use Yoda Condition checks, you must
Loading history...
367
368
			$gateway = 'manual';
369
370
		} //Check if this gateway is active.
371
		elseif ( ! give_is_gateway_active( $gateway ) ) {
372
373
			give_set_error( 'invalid_gateway', __( 'The selected payment gateway is not enabled.', 'give' ) );
374
375
		}
376
	}
377
378
	return $gateway;
379
380
}
381
382
/**
383
 * Donation Form Validate Minimum Donation Amount
384
 *
385
 * @access      private
386
 * @since       1.3.6
387
 * @return      bool
388
 */
389
function give_verify_minimum_price() {
390
391
	$amount          = give_maybe_sanitize_amount( $_REQUEST['give-amount'] );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
392
	$form_id         = isset( $_REQUEST['give-form-id'] ) ? $_REQUEST['give-form-id'] : 0;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
393
	$price_id        = isset( $_REQUEST['give-price-id'] ) ? $_REQUEST['give-price-id'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
394
	$variable_prices = give_has_variable_prices( $form_id );
395
396
	if ( $variable_prices && in_array( $price_id, give_get_variable_price_ids( $form_id ) ) ) {
397
398
		$price_level_amount = give_get_price_option_amount( $form_id, $price_id );
399
400
		if ( $price_level_amount == $amount ) {
401
			return true;
402
		}
403
	}
404
405
	if ( give_get_form_minimum_price( $form_id ) > $amount ) {
406
		return false;
407
	}
408
409
	return true;
410
}
411
412
/**
413
 * Donation form validate agree to "Terms and Conditions".
414
 *
415
 * @access      private
416
 * @since       1.0
417
 * @return      void
418
 */
419
function give_donation_form_validate_agree_to_terms() {
420
	// Validate agree to terms.
421
	if ( ! isset( $_POST['give_agree_to_terms'] ) || $_POST['give_agree_to_terms'] != 1 ) {
0 ignored issues
show
introduced by
Found "!= 1". Use Yoda Condition checks, you must
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
422
		// User did not agree.
423
		give_set_error( 'agree_to_terms', apply_filters( 'give_agree_to_terms_text', __( 'You must agree to the terms and conditions.', 'give' ) ) );
424
	}
425
}
426
427
/**
428
 * Donation Form Required Fields.
429
 *
430
 * @access      private
431
 * @since       1.0
432
 *
433
 * @param       $form_id
434
 *
435
 * @return      array
436
 */
437
function give_get_required_fields( $form_id ) {
438
439
	$payment_mode = give_get_chosen_gateway( $form_id );
440
441
	$required_fields = array(
442
		'give_email' => array(
443
			'error_id'      => 'invalid_email',
444
			'error_message' => __( 'Please enter a valid email address.', 'give' ),
445
		),
446
		'give_first' => array(
447
			'error_id'      => 'invalid_first_name',
448
			'error_message' => __( 'Please enter your first name.', 'give' ),
449
		),
450
	);
451
452
	$require_address = give_require_billing_address( $payment_mode );
453
454
	if ( $require_address ) {
455
		$required_fields['card_address']    = array(
456
			'error_id'      => 'invalid_card_address',
457
			'error_message' => __( 'Please enter your primary billing address.', 'give' ),
458
		);
459
		$required_fields['card_zip']        = array(
460
			'error_id'      => 'invalid_zip_code',
461
			'error_message' => __( 'Please enter your zip / postal code.', 'give' ),
462
		);
463
		$required_fields['card_city']       = array(
464
			'error_id'      => 'invalid_city',
465
			'error_message' => __( 'Please enter your billing city.', 'give' ),
466
		);
467
		$required_fields['billing_country'] = array(
468
			'error_id'      => 'invalid_country',
469
			'error_message' => __( 'Please select your billing country.', 'give' ),
470
		);
471
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
472
473
		$required_fields['card_state']      = array(
474
			'error_id'      => 'invalid_state',
475
			'error_message' => __( 'Please enter billing state / province / County.', 'give' ),
476
		);
477
478
		// Check if billing country alredy exists.
479
		if ( ! empty( $_POST['billing_country'] ) ) {
480
			// Get the value from $_POST.
481
			$country = sanitize_text_field( $_POST['billing_country'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
482
483
			// Get the country list that does not required any states init.
484
			$states_country = give_states_not_required_country_list();
485
486
			// Check if states is empty or not.
487
			if ( array_key_exists( $country, $states_country ) ) {
488
				// If states is empty remove the required feilds of state in billing cart.
489
				unset( $required_fields['card_state'] );
490
			}
491
		}
492
	}
493
494
	/**
495
	 * Filters the donation form required field.
496
	 *
497
	 * @since 1.7
498
	 */
499
	$required_fields = apply_filters( 'give_donation_form_required_fields', $required_fields, $form_id );
500
501
	return $required_fields;
502
503
}
504
505
/**
506
 * Check if the Billing Address is required
507
 *
508
 * @since  1.0.1
509
 *
510
 * @param string $payment_mode
511
 *
512
 * @return bool
513
 */
514
function give_require_billing_address( $payment_mode ) {
515
516
	$return = false;
517
518
	if ( isset( $_POST['billing_country'] ) || did_action( "give_{$payment_mode}_cc_form" ) || did_action( 'give_cc_form' ) ) {
519
		$return = true;
520
	}
521
522
	// Let payment gateways and other extensions determine if address fields should be required.
523
	return apply_filters( 'give_require_billing_address', $return );
524
525
}
526
527
/**
528
 * Donation Form Validate Logged In User.
529
 *
530
 * @access      private
531
 * @since       1.0
532
 * @return      array
533
 */
534
function give_donation_form_validate_logged_in_user() {
535
	global $user_ID;
536
537
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
538
539
	// Start empty array to collect valid user data.
540
	$valid_user_data = array(
541
		// Assume there will be errors.
542
		'user_id' => - 1,
543
	);
544
545
	// Verify there is a user_ID.
546
	if ( $user_ID > 0 ) {
547
		// Get the logged in user data.
548
		$user_data = get_userdata( $user_ID );
549
550
		// Loop through required fields and show error messages.
551 View Code Duplication
		foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
552
			if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
553
				give_set_error( $value['error_id'], $value['error_message'] );
554
			}
555
		}
556
557
		// Verify data.
558
		if ( $user_data ) {
559
			// Collected logged in user data.
560
			$valid_user_data = array(
561
				'user_id'    => $user_ID,
562
				'user_email' => isset( $_POST['give_email'] ) ? sanitize_email( $_POST['give_email'] ) : $user_data->user_email,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
563
				'user_first' => isset( $_POST['give_first'] ) && ! empty( $_POST['give_first'] ) ? sanitize_text_field( $_POST['give_first'] ) : $user_data->first_name,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
564
				'user_last'  => isset( $_POST['give_last'] ) && ! empty( $_POST['give_last'] ) ? sanitize_text_field( $_POST['give_last'] ) : $user_data->last_name,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
565
			);
566
567
			if ( ! is_email( $valid_user_data['user_email'] ) ) {
568
				give_set_error( 'email_invalid', esc_html__( 'Invalid email.', 'give' ) );
569
			}
570
		} else {
571
			// Set invalid user error.
572
			give_set_error( 'invalid_user', esc_html__( 'The user information is invalid.', 'give' ) );
573
		}
574
	}
575
576
	// Return user data.
577
	return $valid_user_data;
578
}
579
580
/**
581
 * Donate Form Validate New User
582
 *
583
 * @access      private
584
 * @since       1.0
585
 * @return      array
586
 */
587
function give_donation_form_validate_new_user() {
588
	// Default user data.
589
	$default_user_data = array(
590
		'give-form-id'           => '',
591
		'user_id'                => - 1, // Assume there will be errors.
592
		'user_first'             => '',
593
		'user_last'              => '',
594
		'give_user_login'        => false,
595
		'give_email'             => false,
596
		'give_user_pass'         => false,
597
		'give_user_pass_confirm' => false,
598
	);
599
600
	// Get user data.
601
	$user_data            = wp_parse_args( array_map( 'trim', give_clean( $_POST ) ), $default_user_data );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
602
	$registering_new_user = false;
603
	$form_id              = absint( $user_data['give-form-id'] );
604
605
	// Start an empty array to collect valid user data.
606
	$valid_user_data = array(
607
		// Assume there will be errors.
608
		'user_id'    => - 1,
609
610
		// Get first name.
611
		'user_first' => $user_data['give_first'],
612
613
		// Get last name.
614
		'user_last'  => $user_data['give_last'],
615
	);
616
617
	// Loop through required fields and show error messages.
618 View Code Duplication
	foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
619
		if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
620
			give_set_error( $value['error_id'], $value['error_message'] );
621
		}
622
	}
623
624
	// Check if we have an username to register.
625
	if ( give_validate_username( $user_data['give_user_login'] ) ) {
626
		$registering_new_user          = true;
627
		$valid_user_data['user_login'] = $user_data['give_user_login'];
628
	}
629
630
	// Check if we have an email to verify.
631
	if ( give_validate_user_email( $user_data['give_email'], $registering_new_user ) ) {
632
		$valid_user_data['user_email'] = $user_data['give_email'];
633
	}
634
635
	// Check password.
636
	if ( give_validate_user_password( $user_data['give_user_pass'], $user_data['give_user_pass_confirm'], $registering_new_user ) ) {
637
		// All is good to go.
638
		$valid_user_data['user_pass'] = $user_data['give_user_pass'];
639
	}
640
641
	return $valid_user_data;
642
}
643
644
/**
645
 * Donation Form Validate User Login
646
 *
647
 * @access      private
648
 * @since       1.0
649
 * @return      array
650
 */
651
function give_donation_form_validate_user_login() {
652
653
	// Start an array to collect valid user data.
654
	$valid_user_data = array(
655
		// Assume there will be errors.
656
		'user_id' => - 1,
657
	);
658
659
	// Username.
660
	if ( ! isset( $_POST['give_user_login'] ) || $_POST['give_user_login'] == '' ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
661
		give_set_error( 'must_log_in', __( 'You must register or login to complete your donation.', 'give' ) );
662
663
		return $valid_user_data;
664
	}
665
666
	// Get the user by login.
667
	$user_data = get_user_by( 'login', strip_tags( $_POST['give_user_login'] ) );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
668
669
	// Check if user exists.
670
	if ( $user_data ) {
671
		// Get password.
672
		$user_pass = isset( $_POST['give_user_pass'] ) ? $_POST['give_user_pass'] : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
673
674
		// Check user_pass.
675
		if ( $user_pass ) {
676
			// Check if password is valid.
677
			if ( ! wp_check_password( $user_pass, $user_data->user_pass, $user_data->ID ) ) {
678
				// Incorrect password.
679
				give_set_error(
680
					'password_incorrect',
681
					sprintf(
682
						'%1$s <a href="%2$s">%3$s</a>',
683
						__( 'The password you entered is incorrect.', 'give' ),
684
						wp_lostpassword_url( "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ),
685
						__( 'Reset Password', 'give' )
686
					)
687
				);
688
				// All is correct.
689
			} else {
690
				// Repopulate the valid user data array.
691
				$valid_user_data = array(
692
					'user_id'    => $user_data->ID,
693
					'user_login' => $user_data->user_login,
694
					'user_email' => $user_data->user_email,
695
					'user_first' => $user_data->first_name,
696
					'user_last'  => $user_data->last_name,
697
					'user_pass'  => $user_pass,
698
				);
699
			}
700
		} else {
701
			// Empty password.
702
			give_set_error( 'password_empty', __( 'Enter a password.', 'give' ) );
703
		}
704
	} else {
705
		// No username.
706
		give_set_error( 'username_incorrect', __( 'The username you entered does not exist.', 'give' ) );
707
	}// End if().
708
709
	return $valid_user_data;
710
}
711
712
/**
713
 * Donation Form Validate Guest User
714
 *
715
 * @access  private
716
 * @since   1.0
717
 * @return  array
718
 */
719
function give_donation_form_validate_guest_user() {
720
721
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
722
723
	// Start an array to collect valid user data.
724
	$valid_user_data = array(
725
		// Set a default id for guests.
726
		'user_id' => 0,
727
	);
728
729
	// Show error message if user must be logged in.
730
	if ( give_logged_in_only( $form_id ) ) {
731
		give_set_error( 'logged_in_only', __( 'You must be logged in to donate.', 'give' ) );
732
	}
733
734
	// Get the guest email.
735
	$guest_email = isset( $_POST['give_email'] ) ? $_POST['give_email'] : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
736
737
	// Check email.
738
	if ( $guest_email && strlen( $guest_email ) > 0 ) {
739
		// Validate email.
740
		if ( ! is_email( $guest_email ) ) {
741
			// Invalid email.
742
			give_set_error( 'email_invalid', __( 'Invalid email.', 'give' ) );
743
		} else {
744
			// All is good to go.
745
			$valid_user_data['user_email'] = $guest_email;
746
747
			// Get user_id from donor if exist.
748
			$donor = new Give_Donor( $guest_email );
749
			if ( $donor->id && $donor->user_id ) {
750
				$valid_user_data['user_id'] = $donor->user_id;
751
			}
752
		}
753
	} else {
754
		// No email.
755
		give_set_error( 'email_empty', __( 'Enter an email.', 'give' ) );
756
	}
757
758
	// Loop through required fields and show error messages.
759 View Code Duplication
	foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
760
		if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
761
			give_set_error( $value['error_id'], $value['error_message'] );
762
		}
763
	}
764
765
	return $valid_user_data;
766
}
767
768
/**
769
 * Register And Login New User
770
 *
771
 * @param array $user_data
772
 *
773
 * @access  private
774
 * @since   1.0
775
 * @return  integer
776
 */
777
function give_register_and_login_new_user( $user_data = array() ) {
778
	// Verify the array.
779
	if ( empty( $user_data ) ) {
780
		return - 1;
781
	}
782
783
	if ( give_get_errors() ) {
784
		return - 1;
785
	}
786
787
	$user_args = apply_filters( 'give_insert_user_args', array(
788
		'user_login'      => isset( $user_data['user_login'] ) ? $user_data['user_login'] : '',
789
		'user_pass'       => isset( $user_data['user_pass'] ) ? $user_data['user_pass'] : '',
790
		'user_email'      => isset( $user_data['user_email'] ) ? $user_data['user_email'] : '',
791
		'first_name'      => isset( $user_data['user_first'] ) ? $user_data['user_first'] : '',
792
		'last_name'       => isset( $user_data['user_last'] ) ? $user_data['user_last'] : '',
793
		'user_registered' => date( 'Y-m-d H:i:s' ),
794
		'role'            => get_option( 'default_role' ),
795
	), $user_data );
796
797
	// Insert new user.
798
	$user_id = wp_insert_user( $user_args );
799
800
	// Validate inserted user.
801
	if ( is_wp_error( $user_id ) ) {
802
		return - 1;
803
	}
804
805
	// Allow themes and plugins to filter the user data.
806
	$user_data = apply_filters( 'give_insert_user_data', $user_data, $user_args );
807
808
	/**
809
	 * Fires after inserting user.
810
	 *
811
	 * @since 1.0
812
	 *
813
	 * @param int $user_id User id.
814
	 * @param array $user_data Array containing user data.
815
	 */
816
	do_action( 'give_insert_user', $user_id, $user_data );
817
818
	// Login new user.
819
	give_log_user_in( $user_id, $user_data['user_login'], $user_data['user_pass'] );
820
821
	// Return user id.
822
	return $user_id;
823
}
824
825
/**
826
 * Get Donation Form User
827
 *
828
 * @param array $valid_data
829
 *
830
 * @access  private
831
 * @since   1.0
832
 * @return  array|bool
833
 */
834
function give_get_donation_form_user( $valid_data = array() ) {
835
836
	// Initialize user.
837
	$user    = false;
838
	$is_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
839
840
	if ( $is_ajax ) {
841
		// Do not create or login the user during the ajax submission (check for errors only).
842
		return true;
843
	} elseif ( is_user_logged_in() ) {
844
		// Set the valid user as the logged in collected data.
845
		$user = $valid_data['logged_in_user'];
846
	} elseif ( $valid_data['need_new_user'] === true || $valid_data['need_user_login'] === true ) {
0 ignored issues
show
introduced by
Found "=== true". Use Yoda Condition checks, you must
Loading history...
847
		// New user registration.
848
		if ( $valid_data['need_new_user'] === true ) {
0 ignored issues
show
introduced by
Found "=== true". Use Yoda Condition checks, you must
Loading history...
849
			// Set user.
850
			$user = $valid_data['new_user_data'];
851
			// Register and login new user.
852
			$user['user_id'] = give_register_and_login_new_user( $user );
853
			// User login
854
		} elseif ( $valid_data['need_user_login'] === true && ! $is_ajax ) {
0 ignored issues
show
introduced by
Found "=== true". Use Yoda Condition checks, you must
Loading history...
855
856
			/**
857
			 * The login form is now processed in the give_process_donation_login() function.
858
			 * This is still here for backwards compatibility.
859
			 * This also allows the old login process to still work if a user removes the checkout login submit button.
860
			 *
861
			 * This also ensures that the donor is logged in correctly if they click "Donation" instead of submitting the login form, meaning the donor is logged in during the donation process.
862
			 */
863
			// Set user.
864
			$user = $valid_data['login_user_data'];
865
			// Login user.
866
			give_log_user_in( $user['user_id'], $user['user_login'], $user['user_pass'] );
867
		}
868
	}
869
870
	// Check guest checkout.
871
	if ( false === $user && false === give_logged_in_only( $_POST['give-form-id'] ) ) {
872
		// Set user
873
		$user = $valid_data['guest_user_data'];
874
	}
875
876
	// Verify we have an user.
877
	if ( false === $user || empty( $user ) ) {
878
		// Return false.
879
		return false;
880
	}
881
882
	// Get user first name.
883 View Code Duplication
	if ( ! isset( $user['user_first'] ) || strlen( trim( $user['user_first'] ) ) < 1 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
884
		$user['user_first'] = isset( $_POST['give_first'] ) ? strip_tags( trim( $_POST['give_first'] ) ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
885
	}
886
887
	// Get user last name.
888 View Code Duplication
	if ( ! isset( $user['user_last'] ) || strlen( trim( $user['user_last'] ) ) < 1 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
889
		$user['user_last'] = isset( $_POST['give_last'] ) ? strip_tags( trim( $_POST['give_last'] ) ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
890
	}
891
892
	// Get the user's billing address details.
893
	$user['address']            = array();
894
	$user['address']['line1']   = ! empty( $_POST['card_address'] ) ? sanitize_text_field( $_POST['card_address'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
895
	$user['address']['line2']   = ! empty( $_POST['card_address_2'] ) ? sanitize_text_field( $_POST['card_address_2'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
896
	$user['address']['city']    = ! empty( $_POST['card_city'] ) ? sanitize_text_field( $_POST['card_city'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
897
	$user['address']['state']   = ! empty( $_POST['card_state'] ) ? sanitize_text_field( $_POST['card_state'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
898
	$user['address']['country'] = ! empty( $_POST['billing_country'] ) ? sanitize_text_field( $_POST['billing_country'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
899
	$user['address']['zip']     = ! empty( $_POST['card_zip'] ) ? sanitize_text_field( $_POST['card_zip'] ) : false;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
900
901
	if ( empty( $user['address']['country'] ) ) {
902
		$user['address'] = false;
903
	} // End if().
904
905
	if ( ! empty( $user['user_id'] ) && $user['user_id'] > 0 && ! empty( $user['address'] ) ) {
906
		// Store the address in the user's meta so the donation form can be pre-populated with it on return donation.
907
		update_user_meta( $user['user_id'], '_give_user_address', $user['address'] );
0 ignored issues
show
introduced by
update_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
908
	}
909
910
	// Return valid user.
911
	return $user;
912
}
913
914
/**
915
 * Validates the credit card info.
916
 *
917
 * @access  private
918
 * @since   1.0
919
 * @return  array
920
 */
921
function give_donation_form_validate_cc() {
922
923
	$card_data = give_get_donation_cc_info();
924
925
	// Validate the card zip.
926
	if ( ! empty( $card_data['card_zip'] ) ) {
927
		if ( ! give_donation_form_validate_cc_zip( $card_data['card_zip'], $card_data['card_country'] ) ) {
928
			give_set_error( 'invalid_cc_zip', __( 'The zip / postal code you entered for your billing address is invalid.', 'give' ) );
929
		}
930
	}
931
932
	// Ensure no spaces.
933
	if ( ! empty( $card_data['card_number'] ) ) {
934
		$card_data['card_number'] = str_replace( '+', '', $card_data['card_number'] ); // no "+" signs
935
		$card_data['card_number'] = str_replace( ' ', '', $card_data['card_number'] ); // No spaces
936
	}
937
938
	// This should validate card numbers at some point too.
939
	return $card_data;
940
}
941
942
/**
943
 * Get credit card info.
944
 *
945
 * @access  private
946
 * @since   1.0
947
 * @return  array
948
 */
949
function give_get_donation_cc_info() {
950
951
	$cc_info                   = array();
952
	$cc_info['card_name']      = isset( $_POST['card_name'] ) ? sanitize_text_field( $_POST['card_name'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
953
	$cc_info['card_number']    = isset( $_POST['card_number'] ) ? sanitize_text_field( $_POST['card_number'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
954
	$cc_info['card_cvc']       = isset( $_POST['card_cvc'] ) ? sanitize_text_field( $_POST['card_cvc'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
955
	$cc_info['card_exp_month'] = isset( $_POST['card_exp_month'] ) ? sanitize_text_field( $_POST['card_exp_month'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
956
	$cc_info['card_exp_year']  = isset( $_POST['card_exp_year'] ) ? sanitize_text_field( $_POST['card_exp_year'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
957
	$cc_info['card_address']   = isset( $_POST['card_address'] ) ? sanitize_text_field( $_POST['card_address'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
958
	$cc_info['card_address_2'] = isset( $_POST['card_address_2'] ) ? sanitize_text_field( $_POST['card_address_2'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
959
	$cc_info['card_city']      = isset( $_POST['card_city'] ) ? sanitize_text_field( $_POST['card_city'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
960
	$cc_info['card_state']     = isset( $_POST['card_state'] ) ? sanitize_text_field( $_POST['card_state'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
961
	$cc_info['card_country']   = isset( $_POST['billing_country'] ) ? sanitize_text_field( $_POST['billing_country'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
962
	$cc_info['card_zip']       = isset( $_POST['card_zip'] ) ? sanitize_text_field( $_POST['card_zip'] ) : '';
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
963
964
	// Return cc info.
965
	return $cc_info;
966
}
967
968
/**
969
 * Validate zip code based on country code
970
 *
971
 * @since  1.0
972
 *
973
 * @param int    $zip
974
 * @param string $country_code
975
 *
976
 * @return bool|mixed
977
 */
978
function give_donation_form_validate_cc_zip( $zip = 0, $country_code = '' ) {
979
	$ret = false;
980
981
	if ( empty( $zip ) || empty( $country_code ) ) {
982
		return $ret;
983
	}
984
985
	$country_code = strtoupper( $country_code );
986
987
	$zip_regex = array(
988
		'AD' => 'AD\d{3}',
989
		'AM' => '(37)?\d{4}',
990
		'AR' => '^([A-Z]{1}\d{4}[A-Z]{3}|[A-Z]{1}\d{4}|\d{4})$',
991
		'AS' => '96799',
992
		'AT' => '\d{4}',
993
		'AU' => '^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$',
994
		'AX' => '22\d{3}',
995
		'AZ' => '\d{4}',
996
		'BA' => '\d{5}',
997
		'BB' => '(BB\d{5})?',
998
		'BD' => '\d{4}',
999
		'BE' => '^[1-9]{1}[0-9]{3}$',
1000
		'BG' => '\d{4}',
1001
		'BH' => '((1[0-2]|[2-9])\d{2})?',
1002
		'BM' => '[A-Z]{2}[ ]?[A-Z0-9]{2}',
1003
		'BN' => '[A-Z]{2}[ ]?\d{4}',
1004
		'BR' => '\d{5}[\-]?\d{3}',
1005
		'BY' => '\d{6}',
1006
		'CA' => '^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$',
1007
		'CC' => '6799',
1008
		'CH' => '^[1-9][0-9][0-9][0-9]$',
1009
		'CK' => '\d{4}',
1010
		'CL' => '\d{7}',
1011
		'CN' => '\d{6}',
1012
		'CR' => '\d{4,5}|\d{3}-\d{4}',
1013
		'CS' => '\d{5}',
1014
		'CV' => '\d{4}',
1015
		'CX' => '6798',
1016
		'CY' => '\d{4}',
1017
		'CZ' => '\d{3}[ ]?\d{2}',
1018
		'DE' => '\b((?:0[1-46-9]\d{3})|(?:[1-357-9]\d{4})|(?:[4][0-24-9]\d{3})|(?:[6][013-9]\d{3}))\b',
1019
		'DK' => '^([D-d][K-k])?( |-)?[1-9]{1}[0-9]{3}$',
1020
		'DO' => '\d{5}',
1021
		'DZ' => '\d{5}',
1022
		'EC' => '([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?',
1023
		'EE' => '\d{5}',
1024
		'EG' => '\d{5}',
1025
		'ES' => '^([1-9]{2}|[0-9][1-9]|[1-9][0-9])[0-9]{3}$',
1026
		'ET' => '\d{4}',
1027
		'FI' => '\d{5}',
1028
		'FK' => 'FIQQ 1ZZ',
1029
		'FM' => '(9694[1-4])([ \-]\d{4})?',
1030
		'FO' => '\d{3}',
1031
		'FR' => '^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$',
1032
		'GE' => '\d{4}',
1033
		'GF' => '9[78]3\d{2}',
1034
		'GL' => '39\d{2}',
1035
		'GN' => '\d{3}',
1036
		'GP' => '9[78][01]\d{2}',
1037
		'GR' => '\d{3}[ ]?\d{2}',
1038
		'GS' => 'SIQQ 1ZZ',
1039
		'GT' => '\d{5}',
1040
		'GU' => '969[123]\d([ \-]\d{4})?',
1041
		'GW' => '\d{4}',
1042
		'HM' => '\d{4}',
1043
		'HN' => '(?:\d{5})?',
1044
		'HR' => '\d{5}',
1045
		'HT' => '\d{4}',
1046
		'HU' => '\d{4}',
1047
		'ID' => '\d{5}',
1048
		'IE' => '((D|DUBLIN)?([1-9]|6[wW]|1[0-8]|2[024]))?',
1049
		'IL' => '\d{5}',
1050
		'IN' => '^[1-9][0-9][0-9][0-9][0-9][0-9]$', // india
1051
		'IO' => 'BBND 1ZZ',
1052
		'IQ' => '\d{5}',
1053
		'IS' => '\d{3}',
1054
		'IT' => '^(V-|I-)?[0-9]{5}$',
1055
		'JO' => '\d{5}',
1056
		'JP' => '\d{3}-\d{4}',
1057
		'KE' => '\d{5}',
1058
		'KG' => '\d{6}',
1059
		'KH' => '\d{5}',
1060
		'KR' => '\d{3}[\-]\d{3}',
1061
		'KW' => '\d{5}',
1062
		'KZ' => '\d{6}',
1063
		'LA' => '\d{5}',
1064
		'LB' => '(\d{4}([ ]?\d{4})?)?',
1065
		'LI' => '(948[5-9])|(949[0-7])',
1066
		'LK' => '\d{5}',
1067
		'LR' => '\d{4}',
1068
		'LS' => '\d{3}',
1069
		'LT' => '\d{5}',
1070
		'LU' => '\d{4}',
1071
		'LV' => '\d{4}',
1072
		'MA' => '\d{5}',
1073
		'MC' => '980\d{2}',
1074
		'MD' => '\d{4}',
1075
		'ME' => '8\d{4}',
1076
		'MG' => '\d{3}',
1077
		'MH' => '969[67]\d([ \-]\d{4})?',
1078
		'MK' => '\d{4}',
1079
		'MN' => '\d{6}',
1080
		'MP' => '9695[012]([ \-]\d{4})?',
1081
		'MQ' => '9[78]2\d{2}',
1082
		'MT' => '[A-Z]{3}[ ]?\d{2,4}',
1083
		'MU' => '(\d{3}[A-Z]{2}\d{3})?',
1084
		'MV' => '\d{5}',
1085
		'MX' => '\d{5}',
1086
		'MY' => '\d{5}',
1087
		'NC' => '988\d{2}',
1088
		'NE' => '\d{4}',
1089
		'NF' => '2899',
1090
		'NG' => '(\d{6})?',
1091
		'NI' => '((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?',
1092
		'NL' => '^[1-9][0-9]{3}\s?([a-zA-Z]{2})?$',
1093
		'NO' => '\d{4}',
1094
		'NP' => '\d{5}',
1095
		'NZ' => '\d{4}',
1096
		'OM' => '(PC )?\d{3}',
1097
		'PF' => '987\d{2}',
1098
		'PG' => '\d{3}',
1099
		'PH' => '\d{4}',
1100
		'PK' => '\d{5}',
1101
		'PL' => '\d{2}-\d{3}',
1102
		'PM' => '9[78]5\d{2}',
1103
		'PN' => 'PCRN 1ZZ',
1104
		'PR' => '00[679]\d{2}([ \-]\d{4})?',
1105
		'PT' => '\d{4}([\-]\d{3})?',
1106
		'PW' => '96940',
1107
		'PY' => '\d{4}',
1108
		'RE' => '9[78]4\d{2}',
1109
		'RO' => '\d{6}',
1110
		'RS' => '\d{5}',
1111
		'RU' => '\d{6}',
1112
		'SA' => '\d{5}',
1113
		'SE' => '^(s-|S-){0,1}[0-9]{3}\s?[0-9]{2}$',
1114
		'SG' => '\d{6}',
1115
		'SH' => '(ASCN|STHL) 1ZZ',
1116
		'SI' => '\d{4}',
1117
		'SJ' => '\d{4}',
1118
		'SK' => '\d{3}[ ]?\d{2}',
1119
		'SM' => '4789\d',
1120
		'SN' => '\d{5}',
1121
		'SO' => '\d{5}',
1122
		'SZ' => '[HLMS]\d{3}',
1123
		'TC' => 'TKCA 1ZZ',
1124
		'TH' => '\d{5}',
1125
		'TJ' => '\d{6}',
1126
		'TM' => '\d{6}',
1127
		'TN' => '\d{4}',
1128
		'TR' => '\d{5}',
1129
		'TW' => '\d{3}(\d{2})?',
1130
		'UA' => '\d{5}',
1131
		'UK' => '^(GIR|[A-Z]\d[A-Z\d]??|[A-Z]{2}\d[A-Z\d]??)[ ]??(\d[A-Z]{2})$',
1132
		'US' => '^\d{5}([\-]?\d{4})?$',
1133
		'UY' => '\d{5}',
1134
		'UZ' => '\d{6}',
1135
		'VA' => '00120',
1136
		'VE' => '\d{4}',
1137
		'VI' => '008(([0-4]\d)|(5[01]))([ \-]\d{4})?',
1138
		'WF' => '986\d{2}',
1139
		'YT' => '976\d{2}',
1140
		'YU' => '\d{5}',
1141
		'ZA' => '\d{4}',
1142
		'ZM' => '\d{5}',
1143
	);
1144
1145
	if ( ! isset( $zip_regex[ $country_code ] ) || preg_match( '/' . $zip_regex[ $country_code ] . '/i', $zip ) ) {
1146
		$ret = true;
1147
	}
1148
1149
	return apply_filters( 'give_is_zip_valid', $ret, $zip, $country_code );
1150
}
1151
1152
1153
/**
1154
 * Auto set correct donation level id on basis of amount.
1155
 *
1156
 * Note: If amount does not match to donation level amount then level id will be auto select to first match level id on basis of amount.
1157
 *
1158
 * @param array $valid_data
1159
 * @param array $data
1160
 *
1161
 * @return bool
1162
 */
1163
function give_validate_multi_donation_form_level( $valid_data, $data ) {
0 ignored issues
show
Unused Code introduced by
The parameter $valid_data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1164
	/* @var Give_Donate_Form $form */
1165
	$form = new Give_Donate_Form( $data['give-form-id'] );
1166
1167
	$donation_level_matched = false;
1168
1169
	if ( $form->is_multi_type_donation_form() ) {
1170
1171
		// Bailout.
1172
		if ( ! ( $variable_prices = $form->get_prices() ) ) {
1173
			return false;
1174
		}
1175
1176
		// Sanitize donation amount.
1177
		$data['give-amount'] = give_maybe_sanitize_amount( $data['give-amount'] );
1178
1179
		if ( $data['give-amount'] === give_maybe_sanitize_amount( give_get_price_option_amount( $data['give-form-id'], $data['give-price-id'] ) ) ) {
1180
			return true;
1181
		}
1182
1183
		// Find correct donation level from all donation levels.
1184
		foreach ( $variable_prices as $variable_price ) {
1185
			// Sanitize level amount.
1186
			$variable_price['_give_amount'] = give_maybe_sanitize_amount( $variable_price['_give_amount'] );
1187
1188
			// Set first match donation level ID.
1189
			if ( $data['give-amount'] === $variable_price['_give_amount'] ) {
1190
				$_POST['give-price-id'] = $variable_price['_give_id']['level_id'];
1191
				$donation_level_matched = true;
1192
				break;
1193
			}
1194
		}
1195
1196
		// If donation amount is not find in donation levels then check if form has custom donation feature enable or not.
1197
		// If yes then set price id to custom if amount is greater then custom minimum amount (if any).
1198
		if (
1199
			! $donation_level_matched
1200
			&& ( give_is_setting_enabled( give_get_meta( $data['give-form-id'], '_give_custom_amount', true ) ) )
1201
		) {
1202
			// Sanitize custom minimum amount.
1203
			$custom_minimum_amount = give_maybe_sanitize_amount( give_get_meta( $data['give-form-id'], '_give_custom_amount_minimum', true ) );
1204
1205
			if ( $data['give-amount'] >= $custom_minimum_amount ) {
1206
				$_POST['give-price-id'] = 'custom';
1207
				$donation_level_matched = true;
1208
			}
1209
		}
1210
	}// End if().
1211
1212
	return ( $donation_level_matched ? true : false );
1213
}
1214
1215
add_action( 'give_checkout_error_checks', 'give_validate_multi_donation_form_level', 10, 2 );
1216