Issues (4296)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/user-functions.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * User Functions
4
 *
5
 * Functions related to users / donors
6
 *
7
 * @package     Give
8
 * @subpackage  Functions
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
11
 * @since       1.0
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Get Users Donations
21
 *
22
 * Retrieves a list of all donations by a specific user.
23
 *
24
 * @param int    $user       User ID or email address.
25
 * @param int    $number     Number of donations to retrieve.
26
 * @param bool   $pagination Enable/Disable Pagination.
27
 * @param string $status     Donation Status.
28
 *
29
 * @since  1.0
30
 *
31
 * @return bool|array List of all user donations.
32
 */
33
function give_get_users_donations( $user = 0, $number = 20, $pagination = false, $status = 'complete' ) {
34
35 1
	if ( empty( $user ) ) {
36 1
		$user = get_current_user_id();
37 1
	}
38
39 1
	if ( 0 === $user && ! Give()->email_access->token_exists ) {
40 1
		return false;
41
	}
42
43 1
	$status = ( 'complete' === $status ) ? 'publish' : $status;
44
	$paged = 1;
45 1
46
	if ( $pagination ) {
47
		if ( get_query_var( 'paged' ) ) {
48
			$paged = get_query_var( 'paged' );
49
		} elseif ( get_query_var( 'page' ) ) {
50
			$paged = get_query_var( 'page' );
51
		}
52
	}
53
54
	$args = apply_filters( 'give_get_users_donations_args', array(
55 1
		'user'    => $user,
56 1
		'number'  => $number,
57 1
		'status'  => $status,
58 1
		'orderby' => 'date',
59
	) );
60 1
61
	if ( $pagination ) {
62 1
		$args['page'] = $paged;
63
	} else {
64
		$args['nopaging'] = true;
0 ignored issues
show
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
65
	}
66
67
	$by_user_id = is_numeric( $user ) ? true : false;
68 1
	$donor   = new Give_Donor( $user, $by_user_id );
69
70
	if ( ! empty( $donor->payment_ids ) ) {
71
72 1
		unset( $args['user'] );
73 1
		$args['post__in'] = array_map( 'absint', explode( ',', $donor->payment_ids ) );
74
75 1
	}
76
77 1
	$donations = give_get_payments( apply_filters( 'give_get_users_donations_args', $args ) );
78 1
79
	// No donations.
80 1
	if ( ! $donations ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $donations of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
81
		return false;
82 1
	}
83
84
	return $donations;
85 1
}
86
87
/**
88
 * Get Users Donations
89 1
 *
90
 * Returns a list of unique donation forms given to by a specific user.
91
 *
92
 * @param int    $user   User ID or email address
93
 * @param string $status Donation Status.
94
 *
95
 * @since 1.0
96
 *
97
 * @return bool|object List of unique forms donated by user
98
 */
99
function give_get_users_completed_donations( $user = 0, $status = 'complete' ) {
0 ignored issues
show
The parameter $status 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...
100
	if ( empty( $user ) ) {
101
		$user = get_current_user_id();
102
	}
103
104
	if ( empty( $user ) ) {
105 1
		return false;
106
	}
107
108
	$by_user_id = is_numeric( $user ) ? true : false;
109 1
110
	$donor = new Give_Donor( $user, $by_user_id );
111
112
	if ( empty( $donor->payment_ids ) ) {
113 1
		return false;
114
	}
115 1
116
	// Get all the items donated.
117 1
	$payment_ids    = array_reverse( explode( ',', $donor->payment_ids ) );
118
	$limit_payments = apply_filters( 'give_users_completed_donations_payments', 50 );
119
	if ( ! empty( $limit_payments ) ) {
120
		$payment_ids = array_slice( $payment_ids, 0, $limit_payments );
121
	}
122 1
	$donation_data = array();
123 1
	foreach ( $payment_ids as $payment_id ) {
124 1
		$donation_data[] = give_get_payment_meta( $payment_id );
125 1
	}
126 1
127 1
	if ( empty( $donation_data ) ) {
128 1
		return false;
129 1
	}
130 1
131
	// Grab only the post ids "form_id" of the forms donated on this order.
132 1
	$completed_donations_ids = array();
133
	foreach ( $donation_data as $donation_meta ) {
134
		$completed_donations_ids[] = isset( $donation_meta['form_id'] ) ? $donation_meta['form_id'] : '';
135
	}
136
137 32
	if ( empty( $completed_donations_ids ) ) {
138 1
		return false;
139 1
	}
140 1
141
	// Only include each donation once.
142 1
	$form_ids = array_unique( $completed_donations_ids );
143
144
	// Make sure we still have some products and a first item.
145
	if ( empty( $form_ids ) || ! isset( $form_ids[0] ) ) {
146
		return false;
147 1
	}
148
149
	$post_type = get_post_type( $form_ids[0] );
150 1
151
	$args = apply_filters( 'give_get_users_completed_donations_args', array(
152
		'include'        => $form_ids,
153
		'post_type'      => $post_type,
154 1
		'posts_per_page' => - 1,
155
	) );
156 1
157 1
	return apply_filters( 'give_users_completed_donations_list', get_posts( $args ) );
158 1
}
159
160 1
161
/**
162 1
 * Has donations
163
 *
164
 * Checks to see if a user has donated to at least one form.
165
 *
166
 * @param int $user_id The ID of the user to check.
167
 *
168
 * @access public
169
 * @since  1.0
170
 *
171
 * @return bool True if has donated, false other wise.
172
 */
173
function give_has_donations( $user_id = null ) {
174
	if ( empty( $user_id ) ) {
175
		$user_id = get_current_user_id();
176
	}
177
178
	if ( give_get_users_donations( $user_id, 1 ) ) {
179 1
		return true; // User has at least one donation.
180
	}
181
182
	// User has never donated anything.
183 1
	return false;
184 1
}
185
186
187
/**
188
 * Get Donation Status for User.
189
 *
190
 * Retrieves the donation count and the total amount spent for a specific user.
191
 *
192
 * @param int|string $user The ID or email of the donor to retrieve stats for.
193
 *
194
 * @access public
195
 * @since  1.0
196
 *
197
 * @return array
198
 */
199
function give_get_donation_stats_by_user( $user = '' ) {
200
201
	$field = '';
202
203
	if ( is_email( $user ) ) {
204
		$field = 'email';
205 5
	} elseif ( is_numeric( $user ) ) {
206
		$field = 'user_id';
207
	}
208
209 5
	$stats    = array();
210
	$donor = Give()->donors->get_donor_by( $field, $user );
211 5
212
	if ( $donor ) {
213 5
		$donor = new Give_Donor( $donor->id );
214
		$stats['purchases']   = absint( $donor->purchase_count );
215 5
		$stats['total_spent'] = give_maybe_sanitize_amount( $donor->get_total_donation_amount() );
216 5
	}
217
218 5
	/**
219
	 * Filter the donation stats.
220 5
	 *
221
	 * @since 1.7
222 5
	 */
223 5
	$stats = (array) apply_filters( 'give_donation_stats_by_user', $stats, $user );
224
225 5
	return $stats;
226
}
227
228 5
229
/**
230
 * Count number of donations of a donor.
231
 *
232
 * Returns total number of donations a donor has made.
233
 *
234
 * @param int|string $user The ID or email of the donor.
235
 *
236
 * @access public
237
 * @since  1.0
238
 *
239
 * @return int The total number of donations.
240
 */
241
function give_count_donations_of_donor( $user = null ) {
242
243
	// Logged in?
244
	if ( empty( $user ) ) {
245
		$user = get_current_user_id();
246
	}
247 3
248 1
	// Email access?
249 1
	if ( empty( $user ) && Give()->email_access->token_email ) {
250
		$user = Give()->email_access->token_email;
251
	}
252 3
253
	$stats = ! empty( $user ) ? give_get_donation_stats_by_user( $user ) : false;
254
255
	return isset( $stats['purchases'] ) ? $stats['purchases'] : 0;
256
}
257 3
258
/**
259 3
 * Calculates the total amount spent by a user.
260
 *
261
 * @param int|string $user The ID or email of the donor.
262
 *
263
 * @access public
264
 * @since  1.0
265
 *
266
 * @return float The total amount the user has spent
267
 */
268
function give_donation_total_of_user( $user = null ) {
269
270
	$stats = give_get_donation_stats_by_user( $user );
271
272
	return $stats['total_spent'];
273
}
274 3
275
276 3
/**
277
 * Validate a potential username.
278
 *
279
 * @param string $username The username to validate.
280
 * @param int    $form_id  Donation Form ID.
281
 *
282
 * @since 1.0
283
 *
284
 * @return bool
285
 */
286
function give_validate_username( $username, $form_id = 0 ) {
287
	$valid = true;
288
289
	// Validate username.
290
	if ( ! empty( $username ) ) {
291 1
292 1
		// Sanitize username.
293
		$sanitized_user_name = sanitize_user( $username, false );
294 1
295
		// We have an user name, check if it already exists.
296
		if ( username_exists( $username ) ) {
297
			// Username already registered.
298
			give_set_error( 'username_unavailable', __( 'Username already taken.', 'give' ) );
299
			$valid = false;
300
301
			// Check if it's valid.
302
		} elseif ( $sanitized_user_name !== $username ) {
303
			// Invalid username.
304
			if ( is_multisite() ) {
305
				give_set_error( 'username_invalid', __( 'Invalid username. Only lowercase letters (a-z) and numbers are allowed.', 'give' ) );
306
				$valid = false;
307
			} else {
308
				give_set_error( 'username_invalid', __( 'Invalid username.', 'give' ) );
309
				$valid = false;
310
			}
311
		}
312
	} else {
313 32
		// Username is empty.
314
		give_set_error( 'username_empty', __( 'Enter a username.', 'give' ) );
315 32
		$valid = false;
316
317 32
		// Check if guest checkout is disable for form.
318
		if ( $form_id && give_logged_in_only( $form_id ) ) {
319
			give_set_error( 'registration_required', __( 'You must register or login to complete your donation.', 'give' ) );
320
			$valid = false;
321
		}
322
	}
323
324
	/**
325
	 * Filter the username validation result.
326
	 *
327
	 * @param bool   $valid    Username is valid or not.
328
	 * @param string $username Username to check.
329
	 * @param bool   $form_id  Donation Form ID.
330
	 *
331
	 * @since 1.8
332
	 */
333
	$valid = (bool) apply_filters( 'give_validate_username', $valid, $username, $form_id );
334 32
335
	return $valid;
336
}
337
338
339
/**
340
 * Validate user email.
341
 *
342
 * @param string $email                User email.
343
 * @param bool   $registering_new_user Flag to check user register or not.
344
 *
345
 * @since 1.8
346
 *
347
 * @return bool
348
 */
349
function give_validate_user_email( $email, $registering_new_user = false ) {
350
	$valid = true;
351
352
	if ( empty( $email ) ) {
353
		// No email.
354
		give_set_error( 'email_empty', __( 'Enter an email.', 'give' ) );
355
		$valid = false;
356
357
	} elseif ( email_exists( $email ) ) {
358
		// Email already exists.
359
		give_set_error( 'email_exists', __( 'Email already exists.', 'give' ) );
360
		$valid = false;
361
362
	} elseif ( ! is_email( $email ) ) {
363
		// Validate email.
364
		give_set_error( 'email_invalid', __( 'Invalid email.', 'give' ) );
365
		$valid = false;
366
367
	} elseif ( $registering_new_user ) {
368
369
		// If donor email is not primary.
370
		if ( ! email_exists( $email ) && give_donor_email_exists( $email ) && give_is_additional_email( $email ) ) {
371
			// Check if email exists.
372
			give_set_error( 'email_used', __( 'The email address provided is already active for another user.', 'give' ) );
373
			$valid = false;
374
		}
375
	}
376
377
	/**
378
	 * Filter the email validation result.
379
	 *
380
	 * @param bool   $valid                Email is valid or not.
381
	 * @param string $email                Email to check.
382
	 * @param bool   $registering_new_user Registering New or Existing User.
383
	 *
384
	 * @since 1.8
385
	 */
386
	$valid = (bool) apply_filters( 'give_validate_user_email', $valid, $email, $registering_new_user );
387
388
	return $valid;
389
}
390
391
/**
392
 * Validate password.
393
 *
394
 * @param string $password             Password to Validate.
395
 * @param string $confirm_password     Password to Confirm Validation.
396
 * @param bool   $registering_new_user Registering New or Existing User.
397
 *
398
 * @since 1.8
399
 *
400
 * @return bool
401
 */
402
function give_validate_user_password( $password = '', $confirm_password = '', $registering_new_user = false ) {
403
	$valid = true;
404
405
	// Passwords Validation For New Donors Only.
406
	if ( $registering_new_user ) {
407
		// Password or confirmation missing.
408
		if ( ! $password ) {
409
			// The password is invalid.
410
			give_set_error( 'password_empty', __( 'Enter a password.', 'give' ) );
411
			$valid = false;
412
		} elseif ( ! $confirm_password ) {
413
			// Confirmation password is invalid.
414
			give_set_error( 'confirmation_empty', __( 'Enter the password confirmation.', 'give' ) );
415
			$valid = false;
416
		}
417
	}
418
	// Passwords Validation For New Donors as well as Existing Donors.
419
	if ( $password || $confirm_password ) {
420
		if ( strlen( $password ) < 6 || strlen( $confirm_password ) < 6 ) {
421
			// Seems Weak Password.
422
			give_set_error( 'password_weak', __( 'Passwords should have at least 6 characters.', 'give' ) );
423
			$valid = false;
424
		}
425
		if ( $password && $confirm_password ) {
426
			// Verify confirmation matches.
427
			if ( $password !== $confirm_password ) {
428
				// Passwords do not match.
429
				give_set_error( 'password_mismatch', __( 'Passwords you entered do not match. Please try again.', 'give' ) );
430
				$valid = false;
431
			}
432
		}
433
	}
434
435
	/**
436
	 * Filter the password validation result.
437
	 *
438
	 * @param bool   $valid                Password is Valid or not.
439
	 * @param string $password             Password to check validation.
440
	 * @param string $confirm_password     Password to confirm validation.
441
	 * @param bool   $registering_new_user Registering New or Existing User.
442
	 *
443
	 * @since 1.8
444
	 */
445
	$valid = (bool) apply_filters( 'give_validate_user_email', $valid, $password, $confirm_password, $registering_new_user );
446
447
	return $valid;
448
}
449
450
/**
451
 * Counts the total number of donors.
452
 *
453
 * @access public
454
 * @since  1.0
455
 *
456
 * @return int The total number of donors.
457
 */
458
function give_count_total_donors() {
459
	return Give()->donors->count();
460
}
461
462
/**
463
 * Returns the saved address for a donor
464
 *
465
 * @access public
466
 * @since  1.0
467
 *
468
 * @param int/null $donor_id Donor ID.
0 ignored issues
show
The doc-type int/null could not be parsed: Unknown type name "int/null" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
469
 * @param array    $args donor args.
470
 *
471
 * @return array The donor's address, if any
472
 */
473
function give_get_donor_address( $donor_id = null, $args = array() ) {
474
	if ( empty( $donor_id ) ) {
475
		$donor_id = get_current_user_id();
476
	}
477
478
	$address         = array();
479
	$args            = wp_parse_args(
480
		$args,
481
		array(
482
			'address_type' => 'billing',
483
		)
484
	);
485
	$default_address = array(
486
		'line1'   => '',
487
		'line2'   => '',
488
		'city'    => '',
489
		'state'   => '',
490
		'country' => '',
491
		'zip'     => '',
492
	);
493
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
494
495
	// Backward compatibility for user id param.
496
	$by_user_id = get_user_by( 'id', $donor_id ) ? true : false;
497
498
	// Backward compatibility.
499 View Code Duplication
	if ( ! give_has_upgrade_completed( 'v20_upgrades_user_address' ) && $by_user_id ) {
0 ignored issues
show
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...
500
		return wp_parse_args(
501
			(array) get_user_meta( $donor_id, '_give_user_address', true ),
0 ignored issues
show
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
502
			$default_address
503
		);
504
	}
505
506
	$donor = new Give_Donor( $donor_id, $by_user_id );
507
508
	if (
509
		! $donor->id ||
510
		empty( $donor->address ) ||
511
		! array_key_exists( $args['address_type'], $donor->address )
512
	) {
513
		return $default_address;
514
	}
515
516
	switch ( true ) {
517
		case is_string( end( $donor->address[ $args['address_type'] ] ) ):
518
			$address = wp_parse_args( $donor->address[ $args['address_type'] ], $default_address );
519
			break;
520
521 View Code Duplication
		case is_array( end( $donor->address[ $args['address_type'] ] ) ):
0 ignored issues
show
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...
522
			$address = wp_parse_args( array_shift( $donor->address[ $args['address_type'] ] ), $default_address );
523
			break;
524
	}
525
526
	return $address;
527
}
528
529
/**
530
 * Give New User Notification
531
 *
532
 * Sends the new user notification email when a user registers within the donation form
533
 *
534
 * @param int   $donation_id   Donation ID.
535
 * @param array $donation_data An Array of Donation Data.
536
 *
537
 * @access public
538
 * @since  1.0
539
 *
540
 * @return void
541
 */
542
function give_new_user_notification( $donation_id = 0, $donation_data = array() ) {
543
	// Bailout.
544
	if (
545
		empty( $donation_id )
546
		|| empty( $donation_data )
547
		|| ! isset( $_POST['give_create_account'] )
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
548
		|| 'on' !== give_clean( $_POST['give_create_account'] )
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
549
	) {
550
		return;
551
	}
552
553
	// For backward compatibility
554
	$user = get_user_by( 'ID', $donation_data['user_info']['id'] );
555
556
	$donation_data['user_info'] = array_merge(
557
		$donation_data['user_info'],
558
		array(
559
			'user_id'    => $donation_data['user_info']['id'],
560
			'user_first' => $donation_data['user_info']['first_name'],
561
			'user_last'  => $donation_data['user_info']['last_name'],
562
			'user_email' => $donation_data['user_info']['email'],
563
			'user_login' => $user->user_login,
564
		)
565
	);
566
567
	do_action( 'give_new-donor-register_email_notification', $donation_data['user_info']['id'], $donation_data['user_info'], $donation_id );
568
	do_action( 'give_donor-register_email_notification', $donation_data['user_info']['id'], $donation_data['user_info'], $donation_id );
569
}
570
571
add_action( 'give_insert_payment', 'give_new_user_notification', 10, 2 );
572
573
574
/**
575
 * Get Donor Name By
576
 *
577
 * Retrieves the donor name based on the id and the name of the user or donation
578
 *
579
 * @param int    $id   The ID of donation or donor.
580
 * @param string $from From will be a string to be passed as donation or donor.
581
 *
582
 * @access public
583
 * @since  1.8.9
584
 *
585
 * @return string
586
 */
587
function give_get_donor_name_by( $id = 0, $from = 'donation' ) {
588
589
	// ID shouldn't be empty.
590
	if ( empty( $id ) ) {
591
		return '';
592
	}
593
594
	$name         = '';
595
	$title_prefix = '';
596
597
	switch ( $from ) {
598
599
		case 'donation':
600
			$title_prefix  = give_get_meta( $id, '_give_payment_donor_title_prefix', true );
601
			$first_name    = give_get_meta( $id, '_give_donor_billing_first_name', true );
602
			$last_name     = give_get_meta( $id, '_give_donor_billing_last_name', true );
603
604
			$name = "{$first_name} {$last_name}";
605
606
			break;
607
608
		case 'donor':
609
			$name         = Give()->donors->get_column( 'name', $id );
610
			$title_prefix = Give()->donor_meta->get_meta( $id, '_give_donor_title_prefix', true );
611
612
			break;
613
614
	}
615
616
	// If title prefix is set then prepend it to name.
617
	$name = give_get_donor_name_with_title_prefixes( $title_prefix, $name );
618
619
	return $name;
620
621
}
622
623
/**
624
 * Checks whether the given donor email exists in users as well as additional_email of donors.
625
 *
626
 * @param string $email Donor Email.
627
 *
628
 * @since 1.8.9
629
 *
630
 * @return boolean  The user's ID on success, and false on failure.
631
 */
632
function give_donor_email_exists( $email ) {
633
	if ( Give()->donors->get_donor_by( 'email', $email ) ) {
634
		return true;
635
	}
636
	return false;
637
}
638
639
/**
640
 * This function will check whether the donor email is primary or additional.
641
 *
642
 * @param string $email Donor Email.
643
 *
644
 * @since 1.8.13
645
 *
646
 * @return bool
647
 */
648
function give_is_additional_email( $email ) {
649
	global $wpdb;
650
651
	$meta_table = Give()->donor_meta->table_name;
652
	$meta_type  = Give()->donor_meta->meta_type;
653
	$donor_id   = $wpdb->get_var( $wpdb->prepare( "SELECT {$meta_type}_id FROM {$meta_table} WHERE meta_key = 'additional_email' AND meta_value = %s LIMIT 1", $email ) );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
654
655
	if ( empty( $donor_id ) ) {
656
		return false;
657
	}
658
659
	return true;
660
}
661