Completed
Pull Request — master (#801)
by
unknown
18:24
created

user-functions.php ➔ give_new_user_notification()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 53
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 4
Bugs 0 Features 1
Metric Value
cc 3
eloc 32
c 4
b 0
f 1
nc 2
nop 2
dl 0
loc 53
rs 9.5797
ccs 0
cts 22
cp 0
crap 12

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     http://opensource.org/licenses/gpl-2.0.php 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 Purchases
21
 *
22
 * Retrieves a list of all purchases 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 purchases to retrieve
28
 * @param bool $pagination
29
 * @param string $status
30
 *
31
 * @return bool|object List of all user purchases
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
		} else if ( 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_purchases_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_purchases_args', $args ) );
83
84
	// No purchases
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 purchased 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 purchased
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 purchased 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 product purchased 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 Purchases
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       $user_id int - the ID of the user to check
175
 *
176
 * @return      bool - true if has purchased, 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 purchase
185
	}
186
187
	return false; // User has never purchased anything
188
}
189
190
191
/**
192
 * Get Purchase Status for User
193
 *
194
 * Retrieves the purchase count and the total amount spent for a specific user
195
 *
196
 * @access      public
197
 * @since       1.0
198
 *
199
 * @param       $user int|string - 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
	return (array) apply_filters( 'give_purchase_stats_by_user', $stats, $user );
229
}
230
231
232
/**
233
 * Count number of purchases of a donor
234
 *
235
 * Returns total number of purchases a donor has made
236
 *
237
 * @access      public
238
 * @since       1.0
239
 *
240
 * @param       $user mixed - ID or email
241
 *
242
 * @return      int - the total number of purchases
243
 */
244
function give_count_purchases_of_customer( $user = null ) {
245
246
	//Logged in?
247 3
	if ( empty( $user ) ) {
248 1
		$user = get_current_user_id();
249 1
	}
250
251
	//Email access?
252 3
	if ( empty( $user ) && Give()->email_access->token_email ) {
253
		$user = Give()->email_access->token_email;
254
	}
255
256
257 3
	$stats = ! empty( $user ) ? give_get_purchase_stats_by_user( $user ) : false;
258
259 3
	return isset( $stats['purchases'] ) ? $stats['purchases'] : 0;
260
}
261
262
/**
263
 * Calculates the total amount spent by a user
264
 *
265
 * @access      public
266
 * @since       1.0
267
 *
268
 * @param       $user mixed - ID or email
269
 *
270
 * @return      float - the total amount the user has spent
271
 */
272
function give_purchase_total_of_user( $user = null ) {
273
274 3
	$stats = give_get_purchase_stats_by_user( $user );
275
276 3
	return $stats['total_spent'];
277
}
278
279
280
/**
281
 * Validate a potential username
282
 *
283
 * @access      public
284
 * @since       1.0
285
 *
286
 * @param       $username string - the username to validate
287
 *
288
 * @return      bool
289
 */
290
function give_validate_username( $username ) {
291 1
	$sanitized = sanitize_user( $username, false );
292 1
	$valid     = ( $sanitized == $username );
293
294 1
	return (bool) apply_filters( 'give_validate_username', $valid, $username );
295
}
296
297
298
/**
299
 * Looks up purchases by email that match the registering user
300
 *
301
 * This is for users that purchased as a guest and then came
302
 * back and created an account.
303
 *
304
 * @access      public
305
 * @since       1.0
306
 *
307
 * @param       $user_id INT - the new user's ID
308
 *
309
 * @return      void
310
 */
311
function give_add_past_purchases_to_new_user( $user_id ) {
312
313 32
	$email = get_the_author_meta( 'user_email', $user_id );
314
315 32
	$payments = give_get_payments( array( 's' => $email ) );
316
317 32
	if ( $payments ) {
318
		foreach ( $payments as $payment ) {
319
			if ( intval( give_get_payment_user_id( $payment->ID ) ) > 0 ) {
320
				continue;
321
			} // This payment already associated with an account
322
323
			$meta                    = give_get_payment_meta( $payment->ID );
324
			$meta['user_info']       = maybe_unserialize( $meta['user_info'] );
325
			$meta['user_info']['id'] = $user_id;
326
			$meta['user_info']       = $meta['user_info'];
327
328
			// Store the updated user ID in the payment meta
329
			give_update_payment_meta( $payment->ID, '_give_payment_meta', $meta );
330
			give_update_payment_meta( $payment->ID, '_give_payment_user_id', $user_id );
331
		}
332
	}
333
334 32
}
335
336
add_action( 'user_register', 'give_add_past_purchases_to_new_user' );
337
338
339
/**
340
 * Counts the total number of donors.
341
 *
342
 * @access        public
343
 * @since         1.0
344
 * @return        int - The total number of donors.
345
 */
346
function give_count_total_customers() {
347
	return Give()->customers->count();
348
}
349
350
351
/**
352
 * Returns the saved address for a donor
353
 *
354
 * @access        public
355
 * @since         1.0
356
 * @return        array - The donor's address, if any
357
 */
358
function give_get_donor_address( $user_id = 0 ) {
359
	if ( empty( $user_id ) ) {
360
		$user_id = get_current_user_id();
361
	}
362
363
	$address = get_user_meta( $user_id, '_give_user_address', true );
364
365
	if ( ! isset( $address['line1'] ) ) {
366
		$address['line1'] = '';
367
	}
368
369
	if ( ! isset( $address['line2'] ) ) {
370
		$address['line2'] = '';
371
	}
372
373
	if ( ! isset( $address['city'] ) ) {
374
		$address['city'] = '';
375
	}
376
377
	if ( ! isset( $address['zip'] ) ) {
378
		$address['zip'] = '';
379
	}
380
381
	if ( ! isset( $address['country'] ) ) {
382
		$address['country'] = '';
383
	}
384
385
	if ( ! isset( $address['state'] ) ) {
386
		$address['state'] = '';
387
	}
388
389
	return $address;
390
}
391
392
/**
393
 * Give New User Notification
394
 *
395
 * Sends the new user notification email when a user registers within the donation form
396
 *
397
 * @access        public
398
 * @since         1.0
399
 *
400
 * @param int $user_id
401
 * @param array $user_data
402
 *
403
 * @return        void
404
 */
405
function give_new_user_notification( $user_id = 0, $user_data = array() ) {
406
407
	if ( empty( $user_id ) || empty( $user_data ) ) {
408
		return;
409
	}
410
	$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
411
412
	/* translators: %s: site name */
413
	$message  = sprintf( esc_html__( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
414
	/* translators: %s: user login */
415
	$message .= sprintf( esc_html__( 'Username: %s' ), $user_data['user_login'] ) . "\r\n\r\n";
416
	/* translators: %s: user email */
417
	$message .= sprintf( esc_html__( 'E-mail: %s' ), $user_data['user_email'] ) . "\r\n";
418
419
	@wp_mail(
420
		get_option( 'admin_email' ),
421
		sprintf(
422
			/* translators: %s: site name */
423
			esc_html__( '[%s] New User Registration' ),
424
			$blogname
425
		),
426
		$message
427
	);
428
429
	/* translators: %s: user login */
430
	$message  = sprintf(
431
		esc_html__( 'Username: %s' ),
432
		$user_data['user_login']
433
	) . "\r\n";
434
435
	/* translators: %s: paswword */
436
	$message .= sprintf(
437
		esc_html__( 'Password: %s' ),
438
		esc_html__( '[Password entered during donation]', 'give' )
439
	) . "\r\n";
440
441
	$message .= sprintf(
442
		'<a href="%1$s">%2$s</a>',
443
		wp_login_url(),
444
		esc_html__( 'Click Here to Login', 'give' )
445
	) . "\r\n";
446
447
	wp_mail(
448
		$user_data['user_email'],
449
		sprintf(
450
			/* translators: %s: site name */
451
			esc_html__( '[%s] Your username and password' ),
452
			$blogname
453
		),
454
		$message
455
	);
456
457
}
458
459
add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
460