Completed
Push — master ( 1e8296...316c10 )
by Devin
37:55 queued 17:58
created

process-donation.php ➔ give_process_donation_form()   D

Complexity

Conditions 12
Paths 194

Size

Total Lines 136
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 51
nc 194
nop 0
dl 0
loc 136
rs 4.6933
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 26 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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_purchase_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 );
49
50
	$is_ajax = isset( $_POST['give_ajax'] );
51
52
	// Process the login form
53
	if ( isset( $_POST['give_login_submit'] ) ) {
54
		give_process_form_login();
55
	}
56
57
	// Validate the user
58
	$user = give_get_purchase_form_user( $valid_data );
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'] ) ? (float) apply_filters( 'give_donation_total', give_sanitize_amount( give_format_amount( $_POST['give-amount'] ) ) ) : '0.00';
103
	$purchase_key = strtolower( md5( $user['user_email'] . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) );
104
105
	// Setup donation information
106
	$purchase_data = array(
107
		'price'        => $price,
108
		'purchase_key' => $purchase_key,
109
		'user_email'   => $user['user_email'],
110
		'date'         => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
111
		'user_info'    => stripslashes_deep( $user_info ),
112
		'post_data'    => $_POST,
113
		'gateway'      => $valid_data['gateway'],
114
		'card_info'    => $valid_data['cc_info'],
115
	);
116
117
	// Add the user data for hooks
118
	$valid_data['user'] = $user;
119
120
	/**
121
	 * Fires before donation form gateway.
122
	 *
123
	 * Allow you to hook to donation form before the gateway.
124
	 *
125
	 * @since 1.0
126
	 *
127
	 * @param array      $_POST      Array of variables passed via the HTTP POST.
128
	 * @param array      $user_info  Array containing basic user information.
129
	 * @param bool|array $valid_data Validate fields.
130
	 */
131
	do_action( 'give_checkout_before_gateway', $_POST, $user_info, $valid_data );
132
133
	// Sanity check for price
134
	if ( ! $purchase_data['price'] ) {
135
		// Revert to manual
136
		$purchase_data['gateway'] = 'manual';
137
		$_POST['give-gateway']    = 'manual';
138
	}
139
140
	/**
141
	 * Allow the purchase data to be modified before it is sent to the gateway
142
	 *
143
	 * @since 1.7
144
	 */
145
	$purchase_data = apply_filters( 'give_donation_data_before_gateway', $purchase_data, $valid_data );
146
147
	// Setup the data we're storing in the donation session
148
	$session_data = $purchase_data;
149
150
	// Make sure credit card numbers are never stored in sessions
151
	unset( $session_data['card_info']['card_number'] );
152
	unset( $session_data['post_data']['card_number'] );
153
154
	// Used for showing data to non logged-in users after donation, and for other plugins needing donation data.
155
	give_set_purchase_session( $session_data );
156
157
	// Send info to the gateway for payment processing
158
	give_send_to_gateway( $purchase_data['gateway'], $purchase_data );
159
	give_die();
160
161
}
162
163
add_action( 'give_purchase', 'give_process_donation_form' );
164
add_action( 'wp_ajax_give_process_donation', 'give_process_donation_form' );
165
add_action( 'wp_ajax_nopriv_give_process_donation', 'give_process_donation_form' );
166
167
168
/**
169
 * Verify that when a logged in user makes a donation that the email address used doesn't belong to a different customer
170
 *
171
 * @since  1.7
172
 *
173
 * @param  array $valid_data Validated data submitted for the purchase
174
 * @param  array $post       Additional $_POST data submitted
175
 *
176
 * @return void
177
 */
178
function give_checkout_check_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...
179
180
	// Verify that the email address belongs to this customer.
181
	if ( is_user_logged_in() ) {
182
183
		$email    = $valid_data['logged_in_user']['user_email'];
184
		$customer = new Give_Customer( get_current_user_id(), true );
185
186
		// If this email address is not registered with this customer, see if it belongs to any other customer
187
		if ( $email !== $customer->email && ( is_array( $customer->emails ) && ! in_array( $email, $customer->emails ) ) ) {
188
			$found_customer = new Give_Customer( $email );
189
190
			if ( $found_customer->id > 0 ) {
191
				give_set_error( 'give-customer-email-exists', sprintf( esc_html__( 'The email address %s is already in use.', 'give' ), $email ) );
192
			}
193
		}
194
	}
195
}
196
197
add_action( 'give_checkout_error_checks', 'give_checkout_check_existing_email', 10, 2 );
198
199
/**
200
 * Process the checkout login form
201
 *
202
 * @access      private
203
 * @since       1.0
204
 * @return      void
205
 */
206
function give_process_form_login() {
207
208
	$is_ajax = isset( $_POST['give_ajax'] );
209
210
	$user_data = give_purchase_form_validate_user_login();
211
212
	if ( give_get_errors() || $user_data['user_id'] < 1 ) {
213
		if ( $is_ajax ) {
214
			/**
215
			 * Fires when AJAX sends back errors from the donation form.
216
			 *
217
			 * @since 1.0
218
			 */
219
			do_action( 'give_ajax_donation_errors' );
220
			give_die();
221
		} else {
222
			wp_redirect( $_SERVER['HTTP_REFERER'] );
223
			exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_process_form_login() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
224
		}
225
	}
226
227
	give_log_user_in( $user_data['user_id'], $user_data['user_login'], $user_data['user_pass'] );
228
229
	if ( $is_ajax ) {
230
		echo 'success';
231
		give_die();
232
	} else {
233
		wp_redirect( $_SERVER['HTTP_REFERER'] );
234
	}
235
}
236
237
add_action( 'wp_ajax_give_process_donation_login', 'give_process_form_login' );
238
add_action( 'wp_ajax_nopriv_give_process_donation_login', 'give_process_form_login' );
239
240
/**
241
 * Donation Form Validate Fields
242
 *
243
 * @access      private
244
 * @since       1.0
245
 * @return      bool|array
246
 */
247
function give_purchase_form_validate_fields() {
248
249
	// Check if there is $_POST
250
	if ( empty( $_POST ) ) {
251
		return false;
252
	}
253
254
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
255
256
	// Start an array to collect valid data
257
	$valid_data = array(
258
		'gateway'          => give_purchase_form_validate_gateway(), // Gateway fallback (amount is validated here)
259
		'need_new_user'    => false,     // New user flag
260
		'need_user_login'  => false,     // Login user flag
261
		'logged_user_data' => array(),   // Logged user collected data
262
		'new_user_data'    => array(),   // New user collected data
263
		'login_user_data'  => array(),   // Login user collected data
264
		'guest_user_data'  => array(),   // Guest user collected data
265
		'cc_info'          => give_purchase_form_validate_cc(),// Credit card info
266
	);
267
268
	// Validate Honeypot First
269
	if ( ! empty( $_POST['give-honeypot'] ) ) {
270
		give_set_error( 'invalid_honeypot', esc_html__( 'Honeypot field detected. Go away bad bot!', 'give' ) );
271
	}
272
273
	// Validate agree to terms
274
	if ( give_is_terms_enabled( $form_id ) ) {
275
		give_purchase_form_validate_agree_to_terms();
276
	}
277
278
	if ( is_user_logged_in() ) {
279
		// Collect logged in user data
280
		$valid_data['logged_in_user'] = give_purchase_form_validate_logged_in_user();
281
	} elseif ( isset( $_POST['give-purchase-var'] ) && $_POST['give-purchase-var'] == 'needs-to-register' ) {
282
		// Set new user registration as required
283
		$valid_data['need_new_user'] = true;
284
		// Validate new user data
285
		$valid_data['new_user_data'] = give_purchase_form_validate_new_user();
286
		// Check if login validation is needed
287
	} elseif ( isset( $_POST['give-purchase-var'] ) && $_POST['give-purchase-var'] == 'needs-to-login' ) {
288
		// Set user login as required
289
		$valid_data['need_user_login'] = true;
290
		// Validate users login info
291
		$valid_data['login_user_data'] = give_purchase_form_validate_user_login();
292
	} else {
293
		// Not registering or logging in, so setup guest user data
294
		$valid_data['guest_user_data'] = give_purchase_form_validate_guest_user();
295
	}
296
297
	// Return collected data
298
	return $valid_data;
299
}
300
301
/**
302
 * Donation Form Validate Gateway
303
 *
304
 * Validate the gateway and donation amount
305
 *
306
 * @access      private
307
 * @since       1.0
308
 * @return      string
309
 */
310
function give_purchase_form_validate_gateway() {
311
312
	$form_id = isset( $_REQUEST['give-form-id'] ) ? $_REQUEST['give-form-id'] : 0;
313
	$amount  = isset( $_REQUEST['give-amount'] ) ? give_sanitize_amount( $_REQUEST['give-amount'] ) : 0;
314
	$gateway = give_get_default_gateway( $form_id );
315
316
	// Check if a gateway value is present
317
	if ( ! empty( $_REQUEST['give-gateway'] ) ) {
318
319
		$gateway = sanitize_text_field( $_REQUEST['give-gateway'] );
320
321
		// Is amount being donated in LIVE mode 0.00? If so, error:
322
		if ( $amount == 0 && ! give_is_test_mode() ) {
323
324
			give_set_error( 'invalid_donation_amount', esc_html__( 'Please insert a valid donation amount.', 'give' ) );
325
326
		} //Check for a minimum custom amount
327
		elseif ( ! give_verify_minimum_price() ) {
328
			// translators: %s: minimum donation amount.
329
			give_set_error(
330
				'invalid_donation_minimum',
331
				sprintf(
332
					/* translators: %s: minimum donation amount */
333
					esc_html__( 'This form has a minimum donation amount of %s.', 'give' ),
334
					give_currency_filter( give_format_amount( give_get_form_minimum_price( $form_id ) ) )
335
				)
336
			);
337
338
		} //Is this test mode zero donation? Let it through but set to manual gateway.
339
		elseif ( $amount == 0 && give_is_test_mode() ) {
340
341
			$gateway = 'manual';
342
343
		} //Check if this gateway is active.
344
		elseif ( ! give_is_gateway_active( $gateway ) ) {
345
346
			give_set_error( 'invalid_gateway', esc_html__( 'The selected payment gateway is not enabled.', 'give' ) );
347
348
		}
349
	}
350
351
	return $gateway;
352
353
}
354
355
/**
356
 * Donation Form Validate Minimum Donation Amount
357
 *
358
 * @access      private
359
 * @since       1.3.6
360
 * @return      bool
361
 */
362
function give_verify_minimum_price() {
363
364
	$amount          = give_sanitize_amount( $_REQUEST['give-amount'] );
365
	$form_id         = isset( $_REQUEST['give-form-id'] ) ? $_REQUEST['give-form-id'] : 0;
366
	$price_id        = isset( $_REQUEST['give-price-id'] ) ? $_REQUEST['give-price-id'] : 0;
367
	$variable_prices = give_has_variable_prices( $form_id );
368
369
	if ( $variable_prices && ! empty( $price_id ) ) {
370
371
		$price_level_amount = give_get_price_option_amount( $form_id, $price_id );
372
373
		if ( $price_level_amount == $amount ) {
374
			return true;
375
		}
376
	}
377
378
	$minimum = give_get_form_minimum_price( $form_id );
379
380
	if ( $minimum > $amount ) {
381
		return false;
382
	}
383
384
	return true;
385
}
386
387
/**
388
 * Donation form validate agree to "Terms and Conditions".
389
 *
390
 * @access      private
391
 * @since       1.0
392
 * @return      void
393
 */
394
function give_purchase_form_validate_agree_to_terms() {
395
	// Validate agree to terms.
396
	if ( ! isset( $_POST['give_agree_to_terms'] ) || $_POST['give_agree_to_terms'] != 1 ) {
397
		// User did not agree.
398
		give_set_error( 'agree_to_terms', apply_filters( 'give_agree_to_terms_text', esc_html__( 'You must agree to the terms and conditions.', 'give' ) ) );
399
	}
400
}
401
402
/**
403
 * Donation Form Required Fields.
404
 *
405
 * @access      private
406
 * @since       1.0
407
 *
408
 * @param       $form_id
409
 *
410
 * @return      array
411
 */
412
function give_get_required_fields( $form_id ) {
413
414
	$payment_mode = give_get_chosen_gateway( $form_id );
415
416
	$required_fields = array(
417
		'give_email' => array(
418
			'error_id'      => 'invalid_email',
419
			'error_message' => esc_html__( 'Please enter a valid email address.', 'give' ),
420
		),
421
		'give_first' => array(
422
			'error_id'      => 'invalid_first_name',
423
			'error_message' => esc_html__( 'Please enter your first name.', 'give' ),
424
		),
425
	);
426
427
	$require_address = give_require_billing_address( $payment_mode );
428
429
	if ( $require_address ) {
430
		$required_fields['card_address']    = array(
431
			'error_id'      => 'invalid_card_address',
432
			'error_message' => esc_html__( 'Please enter your primary billing address.', 'give' ),
433
		);
434
		$required_fields['card_zip']        = array(
435
			'error_id'      => 'invalid_zip_code',
436
			'error_message' => esc_html__( 'Please enter your zip / postal code.', 'give' ),
437
		);
438
		$required_fields['card_city']       = array(
439
			'error_id'      => 'invalid_city',
440
			'error_message' => esc_html__( 'Please enter your billing city.', 'give' ),
441
		);
442
		$required_fields['billing_country'] = array(
443
			'error_id'      => 'invalid_country',
444
			'error_message' => esc_html__( 'Please select your billing country.', 'give' ),
445
		);
446
		$required_fields['card_state']      = array(
447
			'error_id'      => 'invalid_state',
448
			'error_message' => esc_html__( 'Please enter billing state / province.', 'give' ),
449
		);
450
	}
451
452
	/**
453
	 * Filters the donation form required field.
454
	 *
455
	 * @since 1.7
456
	 */
457
	$required_fields = apply_filters( 'give_donation_form_required_fields', $required_fields, $form_id );
458
459
	return $required_fields;
460
461
}
462
463
/**
464
 * Check if the Billing Address is required
465
 *
466
 * @since  1.0.1
467
 *
468
 * @param string $payment_mode
469
 *
470
 * @return mixed|void
471
 */
472
function give_require_billing_address( $payment_mode ) {
473
474
	$return = false;
475
476
	if ( isset( $_POST['billing_country'] ) || did_action( "give_{$payment_mode}_cc_form" ) || did_action( 'give_cc_form' ) ) {
477
		$return = true;
478
	}
479
480
	// Let payment gateways and other extensions determine if address fields should be required.
481
	return apply_filters( 'give_require_billing_address', $return );
482
483
}
484
485
/**
486
 * Donation Form Validate Logged In User
487
 *
488
 * @access      private
489
 * @since       1.0
490
 * @return      array
491
 */
492
function give_purchase_form_validate_logged_in_user() {
493
	global $user_ID;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
494
495
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
496
497
	// Start empty array to collect valid user data.
498
	$valid_user_data = array(
499
		// Assume there will be errors.
500
		'user_id' => - 1,
501
	);
502
503
	// Verify there is a user_ID.
504
	if ( $user_ID > 0 ) {
505
		// Get the logged in user data.
506
		$user_data = get_userdata( $user_ID );
507
508
		// Loop through required fields and show error messages.
509
		foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
510
			if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
511
				give_set_error( $value['error_id'], $value['error_message'] );
512
			}
513
		}
514
515
		// Verify data.
516
		if ( $user_data ) {
517
			// Collected logged in user data.
518
			$valid_user_data = array(
519
				'user_id'    => $user_ID,
520
				'user_email' => isset( $_POST['give_email'] ) ? sanitize_email( $_POST['give_email'] ) : $user_data->user_email,
521
				'user_first' => isset( $_POST['give_first'] ) && ! empty( $_POST['give_first'] ) ? sanitize_text_field( $_POST['give_first'] ) : $user_data->first_name,
522
				'user_last'  => isset( $_POST['give_last'] ) && ! empty( $_POST['give_last'] ) ? sanitize_text_field( $_POST['give_last'] ) : $user_data->last_name,
523
			);
524
525
			if ( ! is_email( $valid_user_data['user_email'] ) ) {
526
				give_set_error( 'email_invalid', esc_html__( 'Invalid email.', 'give' ) );
527
			}
528
		} else {
529
			// Set invalid user error.
530
			give_set_error( 'invalid_user', esc_html__( 'The user information is invalid.', 'give' ) );
531
		}
532
	}
533
534
	// Return user data.
535
	return $valid_user_data;
536
}
537
538
/**
539
 * Donate Form Validate New User
540
 *
541
 * @access      private
542
 * @since       1.0
543
 * @return      array
544
 */
545
function give_purchase_form_validate_new_user() {
546
	// Default user data.
547
	$default_user_data = array(
548
		'give-form-id'           => '',
549
		'user_id'                => - 1, // Assume there will be errors.
550
		'user_first'             => '',
551
		'user_last'              => '',
552
		'give_user_login'        => false,
553
		'give_email'             => false,
554
		'give_user_pass'         => false,
555
		'give_user_pass_confirm' => false,
556
	);
557
558
	// Get user data.
559
	$user_data = wp_parse_args( array_map( 'trim', give_clean( $_POST ) ), $default_user_data );
560
	$registering_new_user = false;
561
	$form_id              = absint( $user_data['give-form-id'] );
562
563
	// Start an empty array to collect valid user data.
564
	$valid_user_data = array(
565
		// Assume there will be errors.
566
		'user_id'    => - 1,
567
568
		// Get first name.
569
		'user_first' => $user_data['give_first'],
570
571
		// Get last name.
572
		'user_last'  => $user_data['give_last'],
573
	);
574
575
	// Loop through required fields and show error messages.
576
	foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
577
		if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
578
			give_set_error( $value['error_id'], $value['error_message'] );
579
		}
580
	}
581
582
	// Check if we have an username to register.
583
	if( give_validate_username( $user_data['give_user_login'] ) ) {
584
		$registering_new_user = true;
585
		$valid_user_data['user_login'] = $user_data['give_user_login'];
586
	}
587
588
	// Check if we have an email to verify.
589
	if( give_validate_user_email( $user_data['give_email'], $registering_new_user ) ) {
590
		$valid_user_data['user_email'] = $user_data['give_email'];
591
	}
592
593
	// Check password.
594
	if( give_validate_user_password( $user_data['give_user_pass'],  $user_data['give_user_pass_confirm'], $registering_new_user)){
595
		// All is good to go.
596
		$valid_user_data['user_pass'] = $user_data['give_user_pass'];
597
	}
598
599
	return $valid_user_data;
600
}
601
602
/**
603
 * Donation Form Validate User Login
604
 *
605
 * @access      private
606
 * @since       1.0
607
 * @return      array
608
 */
609
function give_purchase_form_validate_user_login() {
610
611
	// Start an array to collect valid user data.
612
	$valid_user_data = array(
613
		// Assume there will be errors
614
		'user_id' => - 1,
615
	);
616
617
	// Username.
618
	if ( ! isset( $_POST['give_user_login'] ) || $_POST['give_user_login'] == '' ) {
619
		give_set_error( 'must_log_in', esc_html__( 'You must register or login to complete your donation.', 'give' ) );
620
621
		return $valid_user_data;
622
	}
623
624
	// Get the user by login.
625
	$user_data = get_user_by( 'login', strip_tags( $_POST['give_user_login'] ) );
626
627
	// Check if user exists.
628
	if ( $user_data ) {
629
		// Get password.
630
		$user_pass = isset( $_POST['give_user_pass'] ) ? $_POST['give_user_pass'] : false;
631
632
		// Check user_pass.
633
		if ( $user_pass ) {
634
			// Check if password is valid.
635
			if ( ! wp_check_password( $user_pass, $user_data->user_pass, $user_data->ID ) ) {
636
				// Incorrect password.
637
				give_set_error(
638
					'password_incorrect',
639
					sprintf(
640
						'%1$s <a href="%2$s">%3$s</a>',
641
						esc_html__( 'The password you entered is incorrect.', 'give' ),
642
						wp_lostpassword_url( "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ),
643
						esc_html__( 'Reset Password', 'give' )
644
					)
645
				);
646
				// All is correct.
647
			} else {
648
				// Repopulate the valid user data array.
649
				$valid_user_data = array(
650
					'user_id'    => $user_data->ID,
651
					'user_login' => $user_data->user_login,
652
					'user_email' => $user_data->user_email,
653
					'user_first' => $user_data->first_name,
654
					'user_last'  => $user_data->last_name,
655
					'user_pass'  => $user_pass,
656
				);
657
			}
658
		} else {
659
			// Empty password.
660
			give_set_error( 'password_empty', esc_html__( 'Enter a password.', 'give' ) );
661
		}
662
	} else {
663
		// No username.
664
		give_set_error( 'username_incorrect', esc_html__( 'The username you entered does not exist.', 'give' ) );
665
	}
666
667
	return $valid_user_data;
668
}
669
670
/**
671
 * Donation Form Validate Guest User
672
 *
673
 * @access  private
674
 * @since   1.0
675
 * @return  array
676
 */
677
function give_purchase_form_validate_guest_user() {
678
679
	$form_id = isset( $_POST['give-form-id'] ) ? $_POST['give-form-id'] : '';
680
681
	// Start an array to collect valid user data.
682
	$valid_user_data = array(
683
		// Set a default id for guests.
684
		'user_id' => 0,
685
	);
686
687
	// Show error message if user must be logged in.
688
	if ( give_logged_in_only( $form_id ) ) {
689
		give_set_error( 'logged_in_only', esc_html__( 'You must be logged in to donate.', 'give' ) );
690
	}
691
692
	// Get the guest email.
693
	$guest_email = isset( $_POST['give_email'] ) ? $_POST['give_email'] : false;
694
695
	// Check email.
696
	if ( $guest_email && strlen( $guest_email ) > 0 ) {
697
		// Validate email.
698
		if ( ! is_email( $guest_email ) ) {
699
			// Invalid email.
700
			give_set_error( 'email_invalid', esc_html__( 'Invalid email.', 'give' ) );
701
		} else {
702
			// All is good to go.
703
			$valid_user_data['user_email'] = $guest_email;
704
705
			// Get user_id from donor if exist.
706
			$donor = new Give_Customer( $guest_email );
707
			if ( $donor->id && $donor->user_id ) {
708
				$valid_user_data['user_id'] = $donor->user_id;
709
			}
710
		}
711
	} else {
712
		// No email.
713
		give_set_error( 'email_empty', esc_html__( 'Enter an email.', 'give' ) );
714
	}
715
716
	// Loop through required fields and show error messages.
717
	foreach ( give_get_required_fields( $form_id ) as $field_name => $value ) {
718
		if ( in_array( $value, give_get_required_fields( $form_id ) ) && empty( $_POST[ $field_name ] ) ) {
719
			give_set_error( $value['error_id'], $value['error_message'] );
720
		}
721
	}
722
723
	return $valid_user_data;
724
}
725
726
/**
727
 * Register And Login New User
728
 *
729
 * @param array $user_data
730
 *
731
 * @access  private
732
 * @since   1.0
733
 * @return  integer
734
 */
735
function give_register_and_login_new_user( $user_data = array() ) {
736
	// Verify the array.
737
	if ( empty( $user_data ) ) {
738
		return - 1;
739
	}
740
741
	if ( give_get_errors() ) {
742
		return - 1;
743
	}
744
745
	$user_args = apply_filters( 'give_insert_user_args', array(
746
		'user_login'      => isset( $user_data['user_login'] ) ? $user_data['user_login'] : '',
747
		'user_pass'       => isset( $user_data['user_pass'] ) ? $user_data['user_pass'] : '',
748
		'user_email'      => isset( $user_data['user_email'] ) ? $user_data['user_email'] : '',
749
		'first_name'      => isset( $user_data['user_first'] ) ? $user_data['user_first'] : '',
750
		'last_name'       => isset( $user_data['user_last'] ) ? $user_data['user_last'] : '',
751
		'user_registered' => date( 'Y-m-d H:i:s' ),
752
		'role'            => get_option( 'default_role' ),
753
	), $user_data );
754
755
	// Insert new user.
756
	$user_id = wp_insert_user( $user_args );
757
758
	// Validate inserted user.
759
	if ( is_wp_error( $user_id ) ) {
760
		return - 1;
761
	}
762
763
	// Allow themes and plugins to filter the user data.
764
	$user_data = apply_filters( 'give_insert_user_data', $user_data, $user_args );
765
766
	/**
767
	 * Fires after inserting user.
768
	 *
769
	 * @since 1.0
770
	 *
771
	 * @param int   $user_id   User id.
772
	 * @param array $user_data Array containing user data.
773
	 */
774
	do_action( 'give_insert_user', $user_id, $user_data );
775
776
	// Login new user.
777
	give_log_user_in( $user_id, $user_data['user_login'], $user_data['user_pass'] );
778
779
	// Return user id.
780
	return $user_id;
781
}
782
783
/**
784
 * Get Donation Form User
785
 *
786
 * @param array $valid_data
787
 *
788
 * @access  private
789
 * @since   1.0
790
 * @return  array
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|array<string,array|false>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
791
 */
792
function give_get_purchase_form_user( $valid_data = array() ) {
793
794
	// Initialize user.
795
	$user    = false;
796
	$is_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
797
798
	if ( $is_ajax ) {
799
		// Do not create or login the user during the ajax submission (check for errors only).
800
		return true;
801
	} elseif ( is_user_logged_in() ) {
802
		// Set the valid user as the logged in collected data.
803
		$user = $valid_data['logged_in_user'];
804
	} elseif ( $valid_data['need_new_user'] === true || $valid_data['need_user_login'] === true ) {
805
		// New user registration.
806
		if ( $valid_data['need_new_user'] === true ) {
807
			// Set user.
808
			$user = $valid_data['new_user_data'];
809
			// Register and login new user.
810
			$user['user_id'] = give_register_and_login_new_user( $user );
811
			// User login
812
		} elseif ( $valid_data['need_user_login'] === true && ! $is_ajax ) {
813
814
			/*
815
			 * The login form is now processed in the give_process_purchase_login() function.
816
			 * This is still here for backwards compatibility.
817
			 * This also allows the old login process to still work if a user removes the checkout login submit button.
818
			 *
819
			 * 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.
820
			 */
821
822
			// Set user.
823
			$user = $valid_data['login_user_data'];
824
			// Login user.
825
			give_log_user_in( $user['user_id'], $user['user_login'], $user['user_pass'] );
826
		}
827
	}
828
829
	// Check guest checkout.
830
	if ( false === $user && false === give_logged_in_only( $_POST['give-form-id'] ) ) {
831
		// Set user
832
		$user = $valid_data['guest_user_data'];
833
	}
834
835
	// Verify we have an user.
836
	if ( false === $user || empty( $user ) ) {
837
		// Return false.
838
		return false;
839
	}
840
841
	// Get user first name.
842
	if ( ! isset( $user['user_first'] ) || strlen( trim( $user['user_first'] ) ) < 1 ) {
843
		$user['user_first'] = isset( $_POST['give_first'] ) ? strip_tags( trim( $_POST['give_first'] ) ) : '';
844
	}
845
846
	// Get user last name.
847
	if ( ! isset( $user['user_last'] ) || strlen( trim( $user['user_last'] ) ) < 1 ) {
848
		$user['user_last'] = isset( $_POST['give_last'] ) ? strip_tags( trim( $_POST['give_last'] ) ) : '';
849
	}
850
851
	// Get the user's billing address details.
852
	$user['address']            = array();
853
	$user['address']['line1']   = ! empty( $_POST['card_address'] ) ? sanitize_text_field( $_POST['card_address'] ) : false;
854
	$user['address']['line2']   = ! empty( $_POST['card_address_2'] ) ? sanitize_text_field( $_POST['card_address_2'] ) : false;
855
	$user['address']['city']    = ! empty( $_POST['card_city'] ) ? sanitize_text_field( $_POST['card_city'] ) : false;
856
	$user['address']['state']   = ! empty( $_POST['card_state'] ) ? sanitize_text_field( $_POST['card_state'] ) : false;
857
	$user['address']['country'] = ! empty( $_POST['billing_country'] ) ? sanitize_text_field( $_POST['billing_country'] ) : false;
858
	$user['address']['zip']     = ! empty( $_POST['card_zip'] ) ? sanitize_text_field( $_POST['card_zip'] ) : false;
859
860
	if ( empty( $user['address']['country'] ) ) {
861
		$user['address'] = false;
862
	} // Country will always be set if address fields are present.
863
864
	if ( ! empty( $user['user_id'] ) && $user['user_id'] > 0 && ! empty( $user['address'] ) ) {
865
		// Store the address in the user's meta so the donation form can be pre-populated with it on return purchases.
866
		update_user_meta( $user['user_id'], '_give_user_address', $user['address'] );
867
	}
868
869
	// Return valid user.
870
	return $user;
871
}
872
873
/**
874
 * Validates the credit card info
875
 *
876
 * @access  private
877
 * @since   1.0
878
 * @return  array
879
 */
880
function give_purchase_form_validate_cc() {
881
882
	$card_data = give_get_purchase_cc_info();
883
884
	// Validate the card zip.
885
	if ( ! empty( $card_data['card_zip'] ) ) {
886
		if ( ! give_purchase_form_validate_cc_zip( $card_data['card_zip'], $card_data['card_country'] ) ) {
887
			give_set_error( 'invalid_cc_zip', esc_html__( 'The zip / postal code you entered for your billing address is invalid.', 'give' ) );
888
		}
889
	}
890
891
	// Ensure no spaces.
892
	if ( ! empty( $card_data['card_number'] ) ) {
893
		$card_data['card_number'] = str_replace( '+', '', $card_data['card_number'] ); // no "+" signs
894
		$card_data['card_number'] = str_replace( ' ', '', $card_data['card_number'] ); // No spaces
895
	}
896
897
	// This should validate card numbers at some point too.
898
	return $card_data;
899
}
900
901
/**
902
 * Get Credit Card Info
903
 *
904
 * @access  private
905
 * @since   1.0
906
 * @return  array
907
 */
908
function give_get_purchase_cc_info() {
909
	$cc_info                   = array();
910
	$cc_info['card_name']      = isset( $_POST['card_name'] ) ? sanitize_text_field( $_POST['card_name'] ) : '';
911
	$cc_info['card_number']    = isset( $_POST['card_number'] ) ? sanitize_text_field( $_POST['card_number'] ) : '';
912
	$cc_info['card_cvc']       = isset( $_POST['card_cvc'] ) ? sanitize_text_field( $_POST['card_cvc'] ) : '';
913
	$cc_info['card_exp_month'] = isset( $_POST['card_exp_month'] ) ? sanitize_text_field( $_POST['card_exp_month'] ) : '';
914
	$cc_info['card_exp_year']  = isset( $_POST['card_exp_year'] ) ? sanitize_text_field( $_POST['card_exp_year'] ) : '';
915
	$cc_info['card_address']   = isset( $_POST['card_address'] ) ? sanitize_text_field( $_POST['card_address'] ) : '';
916
	$cc_info['card_address_2'] = isset( $_POST['card_address_2'] ) ? sanitize_text_field( $_POST['card_address_2'] ) : '';
917
	$cc_info['card_city']      = isset( $_POST['card_city'] ) ? sanitize_text_field( $_POST['card_city'] ) : '';
918
	$cc_info['card_state']     = isset( $_POST['card_state'] ) ? sanitize_text_field( $_POST['card_state'] ) : '';
919
	$cc_info['card_country']   = isset( $_POST['billing_country'] ) ? sanitize_text_field( $_POST['billing_country'] ) : '';
920
	$cc_info['card_zip']       = isset( $_POST['card_zip'] ) ? sanitize_text_field( $_POST['card_zip'] ) : '';
921
922
	// Return cc info
923
	return $cc_info;
924
}
925
926
/**
927
 * Validate zip code based on country code
928
 *
929
 * @since  1.0
930
 *
931
 * @param int    $zip
932
 * @param string $country_code
933
 *
934
 * @return bool|mixed|void
935
 */
936
function give_purchase_form_validate_cc_zip( $zip = 0, $country_code = '' ) {
937
	$ret = false;
938
939
	if ( empty( $zip ) || empty( $country_code ) ) {
940
		return $ret;
941
	}
942
943
	$country_code = strtoupper( $country_code );
944
945
	$zip_regex = array(
946
		'AD' => 'AD\d{3}',
947
		'AM' => '(37)?\d{4}',
948
		'AR' => '^([A-Z]{1}\d{4}[A-Z]{3}|[A-Z]{1}\d{4}|\d{4})$',
949
		'AS' => '96799',
950
		'AT' => '\d{4}',
951
		'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})$',
952
		'AX' => '22\d{3}',
953
		'AZ' => '\d{4}',
954
		'BA' => '\d{5}',
955
		'BB' => '(BB\d{5})?',
956
		'BD' => '\d{4}',
957
		'BE' => '^[1-9]{1}[0-9]{3}$',
958
		'BG' => '\d{4}',
959
		'BH' => '((1[0-2]|[2-9])\d{2})?',
960
		'BM' => '[A-Z]{2}[ ]?[A-Z0-9]{2}',
961
		'BN' => '[A-Z]{2}[ ]?\d{4}',
962
		'BR' => '\d{5}[\-]?\d{3}',
963
		'BY' => '\d{6}',
964
		'CA' => '^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$',
965
		'CC' => '6799',
966
		'CH' => '^[1-9][0-9][0-9][0-9]$',
967
		'CK' => '\d{4}',
968
		'CL' => '\d{7}',
969
		'CN' => '\d{6}',
970
		'CR' => '\d{4,5}|\d{3}-\d{4}',
971
		'CS' => '\d{5}',
972
		'CV' => '\d{4}',
973
		'CX' => '6798',
974
		'CY' => '\d{4}',
975
		'CZ' => '\d{3}[ ]?\d{2}',
976
		'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',
977
		'DK' => '^([D-d][K-k])?( |-)?[1-9]{1}[0-9]{3}$',
978
		'DO' => '\d{5}',
979
		'DZ' => '\d{5}',
980
		'EC' => '([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?',
981
		'EE' => '\d{5}',
982
		'EG' => '\d{5}',
983
		'ES' => '^([1-9]{2}|[0-9][1-9]|[1-9][0-9])[0-9]{3}$',
984
		'ET' => '\d{4}',
985
		'FI' => '\d{5}',
986
		'FK' => 'FIQQ 1ZZ',
987
		'FM' => '(9694[1-4])([ \-]\d{4})?',
988
		'FO' => '\d{3}',
989
		'FR' => '^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$',
990
		'GE' => '\d{4}',
991
		'GF' => '9[78]3\d{2}',
992
		'GL' => '39\d{2}',
993
		'GN' => '\d{3}',
994
		'GP' => '9[78][01]\d{2}',
995
		'GR' => '\d{3}[ ]?\d{2}',
996
		'GS' => 'SIQQ 1ZZ',
997
		'GT' => '\d{5}',
998
		'GU' => '969[123]\d([ \-]\d{4})?',
999
		'GW' => '\d{4}',
1000
		'HM' => '\d{4}',
1001
		'HN' => '(?:\d{5})?',
1002
		'HR' => '\d{5}',
1003
		'HT' => '\d{4}',
1004
		'HU' => '\d{4}',
1005
		'ID' => '\d{5}',
1006
		'IE' => '((D|DUBLIN)?([1-9]|6[wW]|1[0-8]|2[024]))?',
1007
		'IL' => '\d{5}',
1008
		'IN' => '^[1-9][0-9][0-9][0-9][0-9][0-9]$', // india
1009
		'IO' => 'BBND 1ZZ',
1010
		'IQ' => '\d{5}',
1011
		'IS' => '\d{3}',
1012
		'IT' => '^(V-|I-)?[0-9]{5}$',
1013
		'JO' => '\d{5}',
1014
		'JP' => '\d{3}-\d{4}',
1015
		'KE' => '\d{5}',
1016
		'KG' => '\d{6}',
1017
		'KH' => '\d{5}',
1018
		'KR' => '\d{3}[\-]\d{3}',
1019
		'KW' => '\d{5}',
1020
		'KZ' => '\d{6}',
1021
		'LA' => '\d{5}',
1022
		'LB' => '(\d{4}([ ]?\d{4})?)?',
1023
		'LI' => '(948[5-9])|(949[0-7])',
1024
		'LK' => '\d{5}',
1025
		'LR' => '\d{4}',
1026
		'LS' => '\d{3}',
1027
		'LT' => '\d{5}',
1028
		'LU' => '\d{4}',
1029
		'LV' => '\d{4}',
1030
		'MA' => '\d{5}',
1031
		'MC' => '980\d{2}',
1032
		'MD' => '\d{4}',
1033
		'ME' => '8\d{4}',
1034
		'MG' => '\d{3}',
1035
		'MH' => '969[67]\d([ \-]\d{4})?',
1036
		'MK' => '\d{4}',
1037
		'MN' => '\d{6}',
1038
		'MP' => '9695[012]([ \-]\d{4})?',
1039
		'MQ' => '9[78]2\d{2}',
1040
		'MT' => '[A-Z]{3}[ ]?\d{2,4}',
1041
		'MU' => '(\d{3}[A-Z]{2}\d{3})?',
1042
		'MV' => '\d{5}',
1043
		'MX' => '\d{5}',
1044
		'MY' => '\d{5}',
1045
		'NC' => '988\d{2}',
1046
		'NE' => '\d{4}',
1047
		'NF' => '2899',
1048
		'NG' => '(\d{6})?',
1049
		'NI' => '((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?',
1050
		'NL' => '^[1-9][0-9]{3}\s?([a-zA-Z]{2})?$',
1051
		'NO' => '\d{4}',
1052
		'NP' => '\d{5}',
1053
		'NZ' => '\d{4}',
1054
		'OM' => '(PC )?\d{3}',
1055
		'PF' => '987\d{2}',
1056
		'PG' => '\d{3}',
1057
		'PH' => '\d{4}',
1058
		'PK' => '\d{5}',
1059
		'PL' => '\d{2}-\d{3}',
1060
		'PM' => '9[78]5\d{2}',
1061
		'PN' => 'PCRN 1ZZ',
1062
		'PR' => '00[679]\d{2}([ \-]\d{4})?',
1063
		'PT' => '\d{4}([\-]\d{3})?',
1064
		'PW' => '96940',
1065
		'PY' => '\d{4}',
1066
		'RE' => '9[78]4\d{2}',
1067
		'RO' => '\d{6}',
1068
		'RS' => '\d{5}',
1069
		'RU' => '\d{6}',
1070
		'SA' => '\d{5}',
1071
		'SE' => '^(s-|S-){0,1}[0-9]{3}\s?[0-9]{2}$',
1072
		'SG' => '\d{6}',
1073
		'SH' => '(ASCN|STHL) 1ZZ',
1074
		'SI' => '\d{4}',
1075
		'SJ' => '\d{4}',
1076
		'SK' => '\d{3}[ ]?\d{2}',
1077
		'SM' => '4789\d',
1078
		'SN' => '\d{5}',
1079
		'SO' => '\d{5}',
1080
		'SZ' => '[HLMS]\d{3}',
1081
		'TC' => 'TKCA 1ZZ',
1082
		'TH' => '\d{5}',
1083
		'TJ' => '\d{6}',
1084
		'TM' => '\d{6}',
1085
		'TN' => '\d{4}',
1086
		'TR' => '\d{5}',
1087
		'TW' => '\d{3}(\d{2})?',
1088
		'UA' => '\d{5}',
1089
		'UK' => '^(GIR|[A-Z]\d[A-Z\d]??|[A-Z]{2}\d[A-Z\d]??)[ ]??(\d[A-Z]{2})$',
1090
		'US' => '^\d{5}([\-]?\d{4})?$',
1091
		'UY' => '\d{5}',
1092
		'UZ' => '\d{6}',
1093
		'VA' => '00120',
1094
		'VE' => '\d{4}',
1095
		'VI' => '008(([0-4]\d)|(5[01]))([ \-]\d{4})?',
1096
		'WF' => '986\d{2}',
1097
		'YT' => '976\d{2}',
1098
		'YU' => '\d{5}',
1099
		'ZA' => '\d{4}',
1100
		'ZM' => '\d{5}',
1101
	);
1102
1103
	if ( ! isset( $zip_regex[ $country_code ] ) || preg_match( '/' . $zip_regex[ $country_code ] . '/i', $zip ) ) {
1104
		$ret = true;
1105
	}
1106
1107
	return apply_filters( 'give_is_zip_valid', $ret, $zip, $country_code );
1108
}
1109
1110
1111
/**
1112
 * Auto set correct donation level id on basis of amount.
1113
 *
1114
 * 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.
1115
 *
1116
 * @param array $valid_data
1117
 * @param array $data
1118
 *
1119
 * @return bool
1120
 */
1121
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...
1122
	/* @var Give_Donate_Form $form */
1123
	$form = new Give_Donate_Form( $data['give-form-id'] );
1124
1125
	$donation_level_matched = false;
1126
1127
	if ( $form->is_multi_type_donation_form() ) {
1128
1129
		// Bailout.
1130
		if ( ! ( $variable_prices = $form->get_prices() ) ) {
1131
			return false;
1132
		}
1133
1134
		// Sanitize donation amount.
1135
		$data['give-amount'] = give_sanitize_amount( $data['give-amount'] );
1136
1137
		// Get number of decimals.
1138
		$default_decimals = give_get_price_decimals();
1139
1140
		if ( $data['give-amount'] === give_sanitize_amount( give_get_price_option_amount( $data['give-form-id'], $data['give-price-id'] ), $default_decimals ) ) {
1141
			return true;
1142
		}
1143
1144
		// Find correct donation level from all donation levels.
1145
		foreach ( $variable_prices as $variable_price ) {
1146
			// Sanitize level amount.
1147
			$variable_price['_give_amount'] = give_sanitize_amount( $variable_price['_give_amount'], $default_decimals );
1148
1149
			// Set first match donation level ID.
1150
			if ( $data['give-amount'] === $variable_price['_give_amount'] ) {
1151
				$_POST['give-price-id'] = $variable_price['_give_id']['level_id'];
1152
				$donation_level_matched = true;
1153
				break;
1154
			}
1155
		}
1156
1157
		// If donation amount is not find in donation levels then check if form has custom donation feature enable or not.
1158
		// If yes then set price id to custom if amount is greater then custom minimum amount (if any).
1159
		if (
1160
			! $donation_level_matched
1161
			&& ( give_is_setting_enabled( get_post_meta( $data['give-form-id'], '_give_custom_amount', true ) ) )
1162
		) {
1163
			// Sanitize custom minimum amount.
1164
			$custom_minimum_amount = give_sanitize_amount( get_post_meta( $data['give-form-id'], '_give_custom_amount_minimum', true ), $default_decimals );
1165
1166
			if ( $data['give-amount'] >= $custom_minimum_amount ) {
1167
				$_POST['give-price-id'] = 'custom';
1168
				$donation_level_matched = true;
1169
			}
1170
		}
1171
	}
1172
1173
	return ( $donation_level_matched ? true : false );
1174
}
1175
1176
add_action( 'give_checkout_error_checks', 'give_validate_multi_donation_form_level', 10, 2 );
1177