Completed
Pull Request — master (#1412)
by Ravinder
17:25
created

user-functions.php ➔ give_validate_username()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 51
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 26.3215

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 6
nop 2
dl 0
loc 51
rs 6.9743
c 0
b 0
f 0
ccs 4
cts 15
cp 0.2667
crap 26.3215

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
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 33 and the first side effect is on line 16.

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
 * 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
32
 */
33
function give_get_users_purchases( $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 = $status === 'complete' ? 'publish' : $status;
44
45 1
	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 1
	$args = apply_filters( 'give_get_users_donations_args', array(
56 1
		'user'    => $user,
57 1
		'number'  => $number,
58 1
		'status'  => $status,
59
		'orderby' => 'date',
60 1
	) );
61
62 1
	if ( $pagination ) {
63
64
		$args['page'] = $paged;
0 ignored issues
show
Bug introduced by
The variable $paged does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
65
66
	} else {
67
68 1
		$args['nopaging'] = true;
69
70
	}
71
72 1
	$by_user_id = is_numeric( $user ) ? true : false;
73 1
	$customer   = new Give_Customer( $user, $by_user_id );
74
75 1
	if ( ! empty( $customer->payment_ids ) ) {
76
77 1
		unset( $args['user'] );
78 1
		$args['post__in'] = array_map( 'absint', explode( ',', $customer->payment_ids ) );
79
80 1
	}
81
82 1
	$purchases = give_get_payments( apply_filters( 'give_get_users_donations_args', $args ) );
83
84
	// No donations
85 1
	if ( ! $purchases ) {
86
		return false;
87
	}
88
89 1
	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' ) {
0 ignored issues
show
Unused Code introduced by
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...
105 1
	if ( empty( $user ) ) {
106
		$user = get_current_user_id();
107
	}
108
109 1
	if ( empty( $user ) ) {
110
		return false;
111
	}
112
113 1
	$by_user_id = is_numeric( $user ) ? true : false;
114
115 1
	$customer = new Give_Customer( $user, $by_user_id );
116
117 1
	if ( empty( $customer->payment_ids ) ) {
118
		return false;
119
	}
120
121
	// Get all the items donated
122 1
	$payment_ids    = array_reverse( explode( ',', $customer->payment_ids ) );
123 1
	$limit_payments = apply_filters( 'give_users_completed_donations_payments', 50 );
124 1
	if ( ! empty( $limit_payments ) ) {
125 1
		$payment_ids = array_slice( $payment_ids, 0, $limit_payments );
126 1
	}
127 1
	$donation_data = array();
128 1
	foreach ( $payment_ids as $payment_id ) {
129 1
		$donation_data[] = give_get_payment_meta( $payment_id );
130 1
	}
131
132 1
	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 32
	$completed_donations_ids = array();
138 1
	foreach ( $donation_data as $purchase_meta ) {
139 1
		$completed_donations_ids[] = isset( $purchase_meta['form_id'] ) ? $purchase_meta['form_id'] : '';
140 1
	}
141
142 1
	if ( empty( $completed_donations_ids ) ) {
143
		return false;
144
	}
145
146
	// Only include each donation once
147 1
	$form_ids = array_unique( $completed_donations_ids );
148
149
	// Make sure we still have some products and a first item
150 1
	if ( empty( $form_ids ) || ! isset( $form_ids[0] ) ) {
151
		return false;
152
	}
153
154 1
	$post_type = get_post_type( $form_ids[0] );
155
156 1
	$args = apply_filters( 'give_get_users_completed_donations_args', array(
157 1
		'include'        => $form_ids,
158 1
		'post_type'      => $post_type,
159
		'posts_per_page' => - 1,
160 1
	) );
161
162 1
	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 1
	if ( empty( $user_id ) ) {
180
		$user_id = get_current_user_id();
181
	}
182
183 1
	if ( give_get_users_purchases( $user_id, 1 ) ) {
184 1
		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 5
	if ( is_email( $user ) ) {
206
207
		$field = 'email';
208
209 5
	} elseif ( is_numeric( $user ) ) {
210
211 5
		$field = 'user_id';
212
213 5
	}
214
215 5
	$stats    = array();
216 5
	$customer = Give()->customers->get_customer_by( $field, $user );
0 ignored issues
show
Bug introduced by
The variable $field does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
217
218 5
	if ( $customer ) {
219
220 5
		$customer = new Give_Customer( $customer->id );
221
222 5
		$stats['purchases']   = absint( $customer->purchase_count );
223 5
		$stats['total_spent'] = give_sanitize_amount( $customer->purchase_value );
224
225 5
	}
226
227
	/**
228 5
	 * 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 3
 *
248 1
 * @return      int The total number of donations
249 1
 */
250
function give_count_purchases_of_customer( $user = null ) {
251
252 3
	// Logged in?
253
	if ( empty( $user ) ) {
254
		$user = get_current_user_id();
255
	}
256
257 3
	// Email access?
258
	if ( empty( $user ) && Give()->email_access->token_email ) {
259 3
		$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 3
 *
275
 * @return      float The total amount the user has spent
276 3
 */
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 1
 * @param int    $form_id
292 1
 *
293
 * @return bool
294 1
 */
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 32
			if ( is_multisite() ) {
314
				give_set_error( 'username_invalid', esc_html__( 'Invalid username. Only lowercase letters (a-z) and numbers are allowed.', 'give' ) );
315 32
				$valid = false;
316
			} else {
317 32
				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 an 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 32
	 * 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 ) {
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
	$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
558
559
	/* translators: %s: site name */
560
	$message = sprintf( esc_attr__( 'New user registration on your site %s:', 'give' ), $blogname ) . "\r\n\r\n";
561
	/* translators: %s: user login */
562
	$message .= sprintf( esc_attr__( 'Username: %s', 'give' ), $user_data['user_login'] ) . "\r\n\r\n";
563
	/* translators: %s: user email */
564
	$message .= sprintf( esc_attr__( 'E-mail: %s', 'give' ), $user_data['user_email'] ) . "\r\n";
565
566
	@wp_mail(
567
		get_option( 'admin_email' ),
568
		sprintf(
569
			/* translators: %s: site name */
570
			esc_attr__( '[%s] New User Registration', 'give' ),
571
			$blogname
572
		),
573
		$message
574
	);
575
576
	/* translators: %s: user login */
577
	$message = sprintf( esc_attr__( 'Username: %s', 'give' ), $user_data['user_login'] ) . "\r\n";
578
	/* translators: %s: paswword */
579
	$message .= sprintf( esc_attr__( 'Password: %s', 'give' ), esc_attr__( '[Password entered during donation]', 'give' ) ) . "\r\n";
580
581
	$message .= '<a href="' . wp_login_url() . '"> ' . esc_attr__( 'Click Here to Login &raquo;', 'give' ) . '</a>' . "\r\n";
582
583
	wp_mail(
584
		$user_data['user_email'],
585
		sprintf(
586
			/* translators: %s: site name */
587
			esc_attr__( '[%s] Your username and password', 'give' ),
588
			$blogname
589
		),
590
		$message
591
	);
592
593
}
594
595
add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
596