Completed
Push — issues/611 ( 661115...758b1c )
by Ravinder
21:11
created

includes/user-functions.php (3 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
 * @since  1.0
25
 *
26
 * @param int    $user   User ID or email address
27
 * @param int    $number Number of donations to retrieve
28
 * @param bool   $pagination
29
 * @param string $status
30
 *
31
 * @return bool|object List of all user donations
0 ignored issues
show
Should the return type not be false|array?

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...
32
 */
33
function give_get_users_purchases( $user = 0, $number = 20, $pagination = false, $status = 'complete' ) {
34
35
	if ( empty( $user ) ) {
36
		$user = get_current_user_id();
37
	}
38
39
	if ( 0 === $user && ! Give()->email_access->token_exists ) {
40
		return false;
41
	}
42
43
	$status = $status === 'complete' ? 'publish' : $status;
44
45
	if ( $pagination ) {
46
		if ( get_query_var( 'paged' ) ) {
47
			$paged = get_query_var( 'paged' );
48
		} elseif ( get_query_var( 'page' ) ) {
49
			$paged = get_query_var( 'page' );
50
		} else {
51
			$paged = 1;
52
		}
53
	}
54
55
	$args = apply_filters( 'give_get_users_donations_args', array(
56
		'user'    => $user,
57
		'number'  => $number,
58
		'status'  => $status,
59
		'orderby' => 'date',
60
	) );
61
62
	if ( $pagination ) {
63
64
		$args['page'] = $paged;
65
66
	} else {
67
68
		$args['nopaging'] = true;
69
70
	}
71
72
	$by_user_id = is_numeric( $user ) ? true : false;
73
	$customer   = new Give_Customer( $user, $by_user_id );
74
75
	if ( ! empty( $customer->payment_ids ) ) {
76
77
		unset( $args['user'] );
78
		$args['post__in'] = array_map( 'absint', explode( ',', $customer->payment_ids ) );
79
80
	}
81
82
	$purchases = give_get_payments( apply_filters( 'give_get_users_donations_args', $args ) );
83
84
	// No donations
85
	if ( ! $purchases ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $purchases 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...
86
		return false;
87
	}
88
89
	return $purchases;
90
}
91
92
/**
93
 * Get Users Donations
94
 *
95
 * Returns a list of unique donation forms given to by a specific user
96
 *
97
 * @since  1.0
98
 *
99
 * @param int    $user User ID or email address
100
 * @param string $status
101
 *
102
 * @return bool|object List of unique forms donated by user
103
 */
104
function give_get_users_completed_donations( $user = 0, $status = 'complete' ) {
105
	if ( empty( $user ) ) {
106
		$user = get_current_user_id();
107
	}
108
109
	if ( empty( $user ) ) {
110
		return false;
111
	}
112
113
	$by_user_id = is_numeric( $user ) ? true : false;
114
115
	$customer = new Give_Customer( $user, $by_user_id );
116
117
	if ( empty( $customer->payment_ids ) ) {
118
		return false;
119
	}
120
121
	// Get all the items donated
122
	$payment_ids    = array_reverse( explode( ',', $customer->payment_ids ) );
123
	$limit_payments = apply_filters( 'give_users_completed_donations_payments', 50 );
124
	if ( ! empty( $limit_payments ) ) {
125
		$payment_ids = array_slice( $payment_ids, 0, $limit_payments );
126
	}
127
	$donation_data = array();
128
	foreach ( $payment_ids as $payment_id ) {
129
		$donation_data[] = give_get_payment_meta( $payment_id );
130
	}
131
132
	if ( empty( $donation_data ) ) {
133
		return false;
134
	}
135
136
	// Grab only the post ids "form_id" of the forms donated on this order
137
	$completed_donations_ids = array();
138
	foreach ( $donation_data as $purchase_meta ) {
139
		$completed_donations_ids[] = isset( $purchase_meta['form_id'] ) ? $purchase_meta['form_id'] : '';
140
	}
141
142
	if ( empty( $completed_donations_ids ) ) {
143
		return false;
144
	}
145
146
	// Only include each donation once
147
	$form_ids = array_unique( $completed_donations_ids );
148
149
	// Make sure we still have some products and a first item
150
	if ( empty( $form_ids ) || ! isset( $form_ids[0] ) ) {
151
		return false;
152
	}
153
154
	$post_type = get_post_type( $form_ids[0] );
155
156
	$args = apply_filters( 'give_get_users_completed_donations_args', array(
157
		'include'        => $form_ids,
158
		'post_type'      => $post_type,
159
		'posts_per_page' => - 1,
160
	) );
161
162
	return apply_filters( 'give_users_completed_donations_list', get_posts( $args ) );
163
}
164
165
166
/**
167
 * Has donations
168
 *
169
 * Checks to see if a user has donated to at least one form.
170
 *
171
 * @access      public
172
 * @since       1.0
173
 *
174
 * @param       int $user_id The ID of the user to check.
175
 *
176
 * @return      bool True if has donated, false other wise.
177
 */
178
function give_has_purchases( $user_id = null ) {
179
	if ( empty( $user_id ) ) {
180
		$user_id = get_current_user_id();
181
	}
182
183
	if ( give_get_users_purchases( $user_id, 1 ) ) {
184
		return true; // User has at least one donation
185
	}
186
187
	return false; // User has never donated anything
188
}
189
190
191
/**
192
 * Get Donation Status for User
193
 *
194
 * Retrieves the donation count and the total amount spent for a specific user
195
 *
196
 * @access      public
197
 * @since       1.0
198
 *
199
 * @param       int|string $user The ID or email of the donor to retrieve stats for
200
 *
201
 * @return      array
202
 */
203
function give_get_purchase_stats_by_user( $user = '' ) {
204
205
	if ( is_email( $user ) ) {
206
207
		$field = 'email';
208
209
	} elseif ( is_numeric( $user ) ) {
210
211
		$field = 'user_id';
212
213
	}
214
215
	$stats    = array();
216
	$customer = Give()->customers->get_customer_by( $field, $user );
217
218
	if ( $customer ) {
219
220
		$customer = new Give_Customer( $customer->id );
221
222
		$stats['purchases']   = absint( $customer->purchase_count );
223
		$stats['total_spent'] = give_sanitize_amount( $customer->purchase_value );
224
225
	}
226
227
	/**
228
	 * Filter the donation stats
229
	 *
230
	 * @since 1.7
231
	 */
232
	$stats = (array) apply_filters( 'give_donation_stats_by_user', $stats, $user );
233
234
	return $stats;
235
}
236
237
238
/**
239
 * Count number of donations of a donor
240
 *
241
 * Returns total number of donations a donor has made
242
 *
243
 * @access      public
244
 * @since       1.0
245
 *
246
 * @param       int|string $user The ID or email of the donor.
247
 *
248
 * @return      int The total number of donations
249
 */
250
function give_count_purchases_of_customer( $user = null ) {
251
252
	// Logged in?
253
	if ( empty( $user ) ) {
254
		$user = get_current_user_id();
255
	}
256
257
	// Email access?
258
	if ( empty( $user ) && Give()->email_access->token_email ) {
259
		$user = Give()->email_access->token_email;
260
	}
261
262
	$stats = ! empty( $user ) ? give_get_purchase_stats_by_user( $user ) : false;
263
264
	return isset( $stats['purchases'] ) ? $stats['purchases'] : 0;
265
}
266
267
/**
268
 * Calculates the total amount spent by a user
269
 *
270
 * @access      public
271
 * @since       1.0
272
 *
273
 * @param       int|string $user The ID or email of the donor.
274
 *
275
 * @return      float The total amount the user has spent
276
 */
277
function give_purchase_total_of_user( $user = null ) {
278
279
	$stats = give_get_purchase_stats_by_user( $user );
280
281
	return $stats['total_spent'];
282
}
283
284
285
/**
286
 * Validate a potential username
287
 *
288
 * @since 1.0
289
 *
290
 * @param string $username The username to validate.
291
 * @param int    $form_id
292
 *
293
 * @return bool
294
 */
295
function give_validate_username( $username, $form_id = 0 ) {
296
	$valid = true;
297
298
	// Validate username.
299
	if ( ! empty( $username ) ) {
300
301
		// Sanitize username.
302
		$sanitized_user_name = sanitize_user( $username, false );
303
304
		// We have an user name, check if it already exists.
305
		if ( username_exists( $username ) ) {
306
			// Username already registered.
307
			give_set_error( 'username_unavailable', esc_html__( 'Username already taken.', 'give' ) );
308
			$valid = false;
309
310
			// Check if it's valid.
311
		} elseif ( $sanitized_user_name !== $username ) {
312
			// Invalid username.
313
			if ( is_multisite() ) {
314
				give_set_error( 'username_invalid', esc_html__( 'Invalid username. Only lowercase letters (a-z) and numbers are allowed.', 'give' ) );
315
				$valid = false;
316
			} else {
317
				give_set_error( 'username_invalid', esc_html__( 'Invalid username.', 'give' ) );
318
				$valid = false;
319
			}
320
		}
321
	} else {
322
		// Username is empty.
323
		give_set_error( 'username_empty', esc_html__( 'Enter a username.', 'give' ) );
324
		$valid = false;
325
326
		// Check if guest checkout is disable for form.
327
		if ( $form_id && give_logged_in_only( $form_id ) ) {
328
			give_set_error( 'registration_required', esc_html__( 'You must register or login to complete your donation.', 'give' ) );
329
			$valid = false;
330
		}
331
	}
332
333
	/**
334
	 * Filter the username validation result.
335
	 *
336
	 * @since 1.8
337
	 *
338
	 * @param bool   $valid
339
	 * @param string $username
340
	 * @param bool   $form_id
341
	 */
342
	$valid = (bool) apply_filters( 'give_validate_username', $valid, $username, $form_id );
343
344
	return $valid;
345
}
346
347
348
/**
349
 * Validate user email.
350
 *
351
 * @since 1.8
352
 *
353
 * @param string $email                User email.
354
 * @param bool   $registering_new_user Flag to check user register or not.
355
 *
356
 * @return bool
357
 */
358
function give_validate_user_email( $email, $registering_new_user = false ) {
359
	$valid = true;
360
361
	if ( empty( $email ) ) {
362
		// No email.
363
		give_set_error( 'email_empty', esc_html__( 'Enter an email.', 'give' ) );
364
		$valid = false;
365
366
	} elseif ( ! is_email( $email ) ) {
367
		// Validate email.
368
		give_set_error( 'email_invalid', esc_html__( 'Invalid email.', 'give' ) );
369
		$valid = false;
370
371
	} elseif ( $registering_new_user && email_exists( $email ) ) {
372
		// Check if email exists.
373
		give_set_error( 'email_used', esc_html__( 'The email already active for another user.', 'give' ) );
374
		$valid = false;
375
	}
376
377
	/**
378
	 * Filter the email validation result.
379
	 *
380
	 * @since 1.8
381
	 *
382
	 * @param bool   $valid
383
	 * @param string $email
384
	 * @param bool   $registering_new_user
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
 * @since 1.8
395
 *
396
 * @param string $password
397
 * @param string $confirm_password
398
 * @param bool   $registering_new_user
399
 *
400
 * @return bool
401
 */
402
function give_validate_user_password( $password = '', $confirm_password = '', $registering_new_user = false ) {
403
	$valid = true;
404
405
	if ( $password && $confirm_password ) {
406
		// Verify confirmation matches.
407
		if ( $password != $confirm_password ) {
408
			// Passwords do not match
409
			give_set_error( 'password_mismatch', esc_html__( 'Passwords don\'t match.', 'give' ) );
410
			$valid = false;
411
		}
412
	} elseif ( $registering_new_user ) {
413
		// Password or confirmation missing.
414
		if ( ! $password ) {
415
			// The password is invalid.
416
			give_set_error( 'password_empty', esc_html__( 'Enter a password.', 'give' ) );
417
			$valid = false;
418
		} elseif ( ! $confirm_password ) {
419
			// Confirmation password is invalid.
420
			give_set_error( 'confirmation_empty', esc_html__( 'Enter the password confirmation.', 'give' ) );
421
			$valid = false;
422
		}
423
	}
424
425
	/**
426
	 * Filter the password validation result.
427
	 *
428
	 * @since 1.8
429
	 *
430
	 * @param bool   $valid
431
	 * @param string $password
432
	 * @param string $confirm_password
433
	 * @param bool   $registering_new_user
434
	 */
435
	$valid = (bool) apply_filters( 'give_validate_user_email', $valid, $password, $confirm_password, $registering_new_user );
436
437
	return $valid;
438
}
439
440
441
/**
442
 * Looks up donations by email that match the registering user
443
 *
444
 * This is for users that donated as a guest and then came
445
 * back and created an account.
446
 *
447
 * @access      public
448
 * @since       1.0
449
 *
450
 * @param       int $user_id The new user's ID.
451
 *
452
 * @return      void
453
 */
454
function give_add_past_purchases_to_new_user( $user_id ) {
455
456
	$email = get_the_author_meta( 'user_email', $user_id );
457
458
	$payments = give_get_payments( array( 's' => $email ) );
459
460
	if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments 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...
461
		foreach ( $payments as $payment ) {
462
			if ( intval( give_get_payment_user_id( $payment->ID ) ) > 0 ) {
463
				continue;
464
			} // This payment already associated with an account
465
466
			$meta                    = give_get_payment_meta( $payment->ID );
467
			$meta['user_info']       = maybe_unserialize( $meta['user_info'] );
468
			$meta['user_info']['id'] = $user_id;
469
			$meta['user_info']       = $meta['user_info'];
470
471
			// Store the updated user ID in the payment meta
472
			give_update_payment_meta( $payment->ID, '_give_payment_meta', $meta );
473
			give_update_payment_meta( $payment->ID, '_give_payment_user_id', $user_id );
474
		}
475
	}
476
477
}
478
479
add_action( 'user_register', 'give_add_past_purchases_to_new_user' );
480
481
482
/**
483
 * Counts the total number of donors.
484
 *
485
 * @access        public
486
 * @since         1.0
487
 *
488
 * @return        int The total number of donors.
489
 */
490
function give_count_total_customers() {
491
	return Give()->customers->count();
492
}
493
494
495
/**
496
 * Returns the saved address for a donor
497
 *
498
 * @access        public
499
 * @since         1.0
500
 *
501
 * @param         int $user_id The donor ID.
502
 *
503
 * @return        array The donor's address, if any
504
 */
505
function give_get_donor_address( $user_id = 0 ) {
506
	if ( empty( $user_id ) ) {
507
		$user_id = get_current_user_id();
508
	}
509
510
	$address = get_user_meta( $user_id, '_give_user_address', true );
511
512
	if ( ! isset( $address['line1'] ) ) {
513
		$address['line1'] = '';
514
	}
515
516
	if ( ! isset( $address['line2'] ) ) {
517
		$address['line2'] = '';
518
	}
519
520
	if ( ! isset( $address['city'] ) ) {
521
		$address['city'] = '';
522
	}
523
524
	if ( ! isset( $address['zip'] ) ) {
525
		$address['zip'] = '';
526
	}
527
528
	if ( ! isset( $address['country'] ) ) {
529
		$address['country'] = '';
530
	}
531
532
	if ( ! isset( $address['state'] ) ) {
533
		$address['state'] = '';
534
	}
535
536
	return $address;
537
}
538
539
/**
540
 * Give New User Notification
541
 *
542
 * Sends the new user notification email when a user registers within the donation form
543
 *
544
 * @access        public
545
 * @since         1.0
546
 *
547
 * @param int   $user_id
548
 * @param array $user_data
549
 *
550
 * @return        void
551
 */
552
function give_new_user_notification( $user_id = 0, $user_data = array() ) {
553
554
	if ( empty( $user_id ) || empty( $user_data ) ) {
555
		return;
556
	}
557
558
	do_action( 'give_new-donor-register_email_notification', $user_id, $user_data );
559
	do_action( 'give_donor-register_email_notification', $user_id, $user_data );
560
}
561
562
add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
563