wc-user-functions.php ➔ wc_review_is_from_verified_owner()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
eloc 5
nc 2
nop 1
1
<?php
2
/**
3
 * WooCommerce Customer Functions
4
 *
5
 * Functions for customers.
6
 *
7
 * @author 		WooThemes
8
 * @category 	Core
9
 * @package 	WooCommerce/Functions
10
 * @version 	2.2.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit; // Exit if accessed directly
15
}
16
17
/**
18
 * Prevent any user who cannot 'edit_posts' (subscribers, customers etc) from seeing the admin bar.
19
 *
20
 * Note: get_option( 'woocommerce_lock_down_admin', true ) is a deprecated option here for backwards compat. Defaults to true.
21
 *
22
 * @access public
23
 * @param bool $show_admin_bar
24
 * @return bool
25
 */
26
function wc_disable_admin_bar( $show_admin_bar ) {
27
	if ( apply_filters( 'woocommerce_disable_admin_bar', get_option( 'woocommerce_lock_down_admin', 'yes' ) === 'yes' ) && ! ( current_user_can( 'edit_posts' ) || current_user_can( 'manage_woocommerce' ) ) ) {
28
		$show_admin_bar = false;
29
	}
30
31
	return $show_admin_bar;
32
}
33
add_filter( 'show_admin_bar', 'wc_disable_admin_bar', 10, 1 );
34
35
if ( ! function_exists( 'wc_create_new_customer' ) ) {
36
37
	/**
38
	 * Create a new customer.
39
	 *
40
	 * @param  string $email Customer email.
41
	 * @param  string $username Customer username.
42
	 * @param  string $password Customer password.
43
	 * @return int|WP_Error Returns WP_Error on failure, Int (user ID) on success.
44
	 */
45
	function wc_create_new_customer( $email, $username = '', $password = '' ) {
46
47
		// Check the email address.
48
		if ( empty( $email ) || ! is_email( $email ) ) {
49
			return new WP_Error( 'registration-error-invalid-email', __( 'Please provide a valid email address.', 'woocommerce' ) );
50
		}
51
52
		if ( email_exists( $email ) ) {
53
			return new WP_Error( 'registration-error-email-exists', __( 'An account is already registered with your email address. Please login.', 'woocommerce' ) );
54
		}
55
56
		// Handle username creation.
57
		if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) || ! empty( $username ) ) {
58
			$username = sanitize_user( $username );
59
60
			if ( empty( $username ) || ! validate_username( $username ) ) {
61
				return new WP_Error( 'registration-error-invalid-username', __( 'Please enter a valid account username.', 'woocommerce' ) );
62
			}
63
64
			if ( username_exists( $username ) ) {
65
				return new WP_Error( 'registration-error-username-exists', __( 'An account is already registered with that username. Please choose another.', 'woocommerce' ) );
66
			}
67
		} else {
68
			$username = sanitize_user( current( explode( '@', $email ) ), true );
69
70
			// Ensure username is unique.
71
			$append     = 1;
72
			$o_username = $username;
73
74
			while ( username_exists( $username ) ) {
75
				$username = $o_username . $append;
76
				$append++;
77
			}
78
		}
79
80
		// Handle password creation.
81
		if ( 'yes' === get_option( 'woocommerce_registration_generate_password' ) && empty( $password ) ) {
82
			$password           = wp_generate_password();
83
			$password_generated = true;
84
		} elseif ( empty( $password ) ) {
85
			return new WP_Error( 'registration-error-missing-password', __( 'Please enter an account password.', 'woocommerce' ) );
86
		} else {
87
			$password_generated = false;
88
		}
89
90
		// Use WP_Error to handle registration errors.
91
		$errors = new WP_Error();
92
93
		do_action( 'woocommerce_register_post', $username, $email, $errors );
94
95
		$errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $email );
96
97
		if ( $errors->get_error_code() ) {
98
			return $errors;
99
		}
100
101
		$new_customer_data = apply_filters( 'woocommerce_new_customer_data', array(
102
			'user_login' => $username,
103
			'user_pass'  => $password,
104
			'user_email' => $email,
105
			'role'       => 'customer',
106
		) );
107
108
		$customer_id = wp_insert_user( $new_customer_data );
109
110
		if ( is_wp_error( $customer_id ) ) {
111
			return new WP_Error( 'registration-error', '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Couldn&#8217;t register you&hellip; please contact us if you continue to have problems.', 'woocommerce' ) );
112
		}
113
114
		do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated );
115
116
		return $customer_id;
117
	}
118
}
119
120
/**
121
 * Login a customer (set auth cookie and set global user object).
122
 *
123
 * @param int $customer_id
124
 */
125
function wc_set_customer_auth_cookie( $customer_id ) {
126
	global $current_user;
127
128
	$current_user = get_user_by( 'id', $customer_id );
129
130
	wp_set_auth_cookie( $customer_id, true );
131
}
132
133
/**
134
 * Get past orders (by email) and update them.
135
 *
136
 * @param  int $customer_id
137
 * @return int
138
 */
139
function wc_update_new_customer_past_orders( $customer_id ) {
140
	$linked          = 0;
141
	$complete        = 0;
142
	$customer        = get_user_by( 'id', absint( $customer_id ) );
143
	$customer_orders = wc_get_orders( array(
144
		'limit'    => -1,
145
		'customer' => array( array( 0, $customer->user_email ) ),
146
		'return'   => 'ids',
147
	) );
148
149
	if ( ! empty( $customer_orders ) ) {
150
		foreach ( $customer_orders as $order_id ) {
0 ignored issues
show
Bug introduced by
The expression $customer_orders of type array|object<stdClass> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
151
			update_post_meta( $order_id, '_customer_user', $customer->ID );
152
153
			do_action( 'woocommerce_update_new_customer_past_order', $order_id, $customer );
154
155
			if ( get_post_status( $order_id ) === 'wc-completed' ) {
156
				$complete++;
157
			}
158
159
			$linked++;
160
		}
161
	}
162
163
	if ( $complete ) {
164
		update_user_meta( $customer_id, 'paying_customer', 1 );
165
		update_user_meta( $customer_id, '_order_count', '' );
166
		update_user_meta( $customer_id, '_money_spent', '' );
167
	}
168
169
	return $linked;
170
}
171
172
/**
173
 * Order Status completed - This is a paying customer.
174
 *
175
 * @access public
176
 * @param int $order_id
177
 */
178
function wc_paying_customer( $order_id ) {
179
	$order = wc_get_order( $order_id );
180
181
	if ( $order->user_id > 0 && 'refund' !== $order->order_type ) {
182
		update_user_meta( $order->user_id, 'paying_customer', 1 );
183
184
		$old_spent = absint( get_user_meta( $order->user_id, '_money_spent', true ) );
185
		update_user_meta( $order->user_id, '_money_spent', $old_spent + $order->order_total );
186
	}
187
	if ( $order->user_id > 0 && 'simple' === $order->order_type ) {
188
		$old_count = absint( get_user_meta( $order->user_id, '_order_count', true ) );
189
		update_user_meta( $order->user_id, '_order_count', $old_count + 1 );
190
	}
191
}
192
add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' );
193
194
/**
195
 * Checks if a user (by email or ID or both) has bought an item.
196
 * @param string $customer_email
197
 * @param int $user_id
198
 * @param int $product_id
199
 * @return bool
200
 */
201
function wc_customer_bought_product( $customer_email, $user_id, $product_id ) {
202
	global $wpdb;
203
204
	$transient_name = 'wc_cbp_' . md5( $customer_email . $user_id . WC_Cache_Helper::get_transient_version( 'orders' ) );
205
206
	if ( false === ( $result = get_transient( $transient_name ) ) ) {
207
		$customer_data = array( $user_id );
208
209
		if ( $user_id ) {
210
			$user = get_user_by( 'id', $user_id );
211
212
			if ( isset( $user->user_email ) ) {
213
				$customer_data[] = $user->user_email;
214
			}
215
		}
216
217
		if ( is_email( $customer_email ) ) {
218
			$customer_data[] = $customer_email;
219
		}
220
221
		$customer_data = array_map( 'esc_sql', array_filter( array_unique( $customer_data ) ) );
222
223
		if ( sizeof( $customer_data ) == 0 ) {
224
			return false;
225
		}
226
227
		$result = $wpdb->get_col( "
228
			SELECT im.meta_value FROM {$wpdb->posts} AS p
229
			INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
230
			INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
231
			INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
232
			WHERE p.post_status IN ( 'wc-completed', 'wc-processing' )
233
			AND pm.meta_key IN ( '_billing_email', '_customer_user' )
234
			AND im.meta_key IN ( '_product_id', '_variation_id' )
235
			AND im.meta_value != 0
236
			AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
237
		" );
238
		$result = array_map( 'absint', $result );
239
240
		set_transient( $transient_name, $result, DAY_IN_SECONDS * 30 );
241
	}
242
	return in_array( absint( $product_id ), $result );
243
}
244
245
/**
246
 * Checks if a user has a certain capability.
247
 *
248
 * @access public
249
 * @param array $allcaps
250
 * @param array $caps
251
 * @param array $args
252
 * @return bool
253
 */
254
function wc_customer_has_capability( $allcaps, $caps, $args ) {
255
	if ( isset( $caps[0] ) ) {
256
		switch ( $caps[0] ) {
257 View Code Duplication
			case 'view_order' :
0 ignored issues
show
Duplication introduced by
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...
258
				$user_id = $args[1];
259
				$order   = wc_get_order( $args[2] );
260
261
				if ( $order && $user_id == $order->user_id ) {
262
					$allcaps['view_order'] = true;
263
				}
264
			break;
265
			case 'pay_for_order' :
266
				$user_id  = $args[1];
267
				$order_id = isset( $args[2] ) ? $args[2] : null;
268
269
				// When no order ID, we assume it's a new order
270
				// and thus, customer can pay for it
271
				if ( ! $order_id ) {
272
					$allcaps['pay_for_order'] = true;
273
					break;
274
				}
275
276
				$order = wc_get_order( $order_id );
277
				if ( $user_id == $order->user_id || empty( $order->user_id ) ) {
278
					$allcaps['pay_for_order'] = true;
279
				}
280
			break;
281 View Code Duplication
			case 'order_again' :
0 ignored issues
show
Duplication introduced by
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...
282
				$user_id = $args[1];
283
				$order   = wc_get_order( $args[2] );
284
285
				if ( $user_id == $order->user_id ) {
286
					$allcaps['order_again'] = true;
287
				}
288
			break;
289 View Code Duplication
			case 'cancel_order' :
0 ignored issues
show
Duplication introduced by
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...
290
				$user_id = $args[1];
291
				$order   = wc_get_order( $args[2] );
292
293
				if ( $user_id == $order->user_id ) {
294
					$allcaps['cancel_order'] = true;
295
				}
296
			break;
297
			case 'download_file' :
298
				$user_id  = $args[1];
299
				$download = $args[2];
300
301
				if ( $user_id == $download->user_id ) {
302
					$allcaps['download_file'] = true;
303
				}
304
			break;
305
		}
306
	}
307
	return $allcaps;
308
}
309
add_filter( 'user_has_cap', 'wc_customer_has_capability', 10, 3 );
310
311
/**
312
 * Modify the list of editable roles to prevent non-admin adding admin users.
313
 * @param  array $roles
314
 * @return array
315
 */
316
function wc_modify_editable_roles( $roles ){
317
	if ( ! current_user_can( 'administrator' ) ) {
318
		unset( $roles[ 'administrator' ] );
319
	}
320
    return $roles;
321
}
322
add_filter( 'editable_roles', 'wc_modify_editable_roles' );
323
324
/**
325
 * Modify capabiltiies to prevent non-admin users editing admin users.
326
 *
327
 * $args[0] will be the user being edited in this case.
328
 *
329
 * @param  array $caps Array of caps
330
 * @param  string $cap Name of the cap we are checking
331
 * @param  int $user_id ID of the user being checked against
332
 * @param  array $args
333
 * @return array
334
 */
335
function wc_modify_map_meta_cap( $caps, $cap, $user_id, $args ) {
336
	switch ( $cap ) {
337
		case 'edit_user' :
338
		case 'remove_user' :
339
		case 'promote_user' :
340
		case 'delete_user' :
341
			if ( ! isset( $args[0] ) || $args[0] === $user_id ) {
342
				break;
343
			} else {
344
				if ( user_can( $args[0], 'administrator' ) && ! current_user_can( 'administrator' ) ) {
345
					$caps[] = 'do_not_allow';
346
				}
347
			}
348
		break;
349
	}
350
	return $caps;
351
}
352
add_filter( 'map_meta_cap', 'wc_modify_map_meta_cap', 10, 4 );
353
354
/**
355
 * Get customer available downloads.
356
 *
357
 * @param int $customer_id Customer/User ID
358
 * @return array
359
 */
360
function wc_get_customer_available_downloads( $customer_id ) {
361
	global $wpdb;
362
363
	$downloads   = array();
364
	$_product    = null;
365
	$order       = null;
366
	$file_number = 0;
367
368
	// Get results from valid orders only
369
	$results = apply_filters( 'woocommerce_permission_list', $wpdb->get_results( $wpdb->prepare( "
370
		SELECT permissions.*
371
		FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions as permissions
372
		WHERE user_id = %d
373
		AND permissions.order_id > 0
374
		AND
375
			(
376
				permissions.downloads_remaining > 0
377
				OR
378
				permissions.downloads_remaining = ''
379
			)
380
		AND
381
			(
382
				permissions.access_expires IS NULL
383
				OR
384
				permissions.access_expires >= %s
385
				OR
386
				permissions.access_expires = '0000-00-00 00:00:00'
387
			)
388
		ORDER BY permissions.order_id, permissions.product_id, permissions.permission_id;
389
		", $customer_id, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ), $customer_id );
390
391
	if ( $results ) {
392
		foreach ( $results as $result ) {
393
			if ( ! $order || $order->id != $result->order_id ) {
394
				// new order
395
				$order    = wc_get_order( $result->order_id );
396
				$_product = null;
397
			}
398
399
			// Make sure the order exists for this download
400
			if ( ! $order ) {
401
				continue;
402
			}
403
404
			// Downloads permitted?
405
			if ( ! $order->is_download_permitted() ) {
406
				continue;
407
			}
408
409
			$product_id = intval( $result->product_id );
410
411
			if ( ! $_product || $_product->id != $product_id ) {
412
				// new product
413
				$file_number = 0;
414
				$_product    = wc_get_product( $product_id );
415
			}
416
417
			// Check product exists and has the file
418
			if ( ! $_product || ! $_product->exists() || ! $_product->has_file( $result->download_id ) ) {
419
				continue;
420
			}
421
422
			$download_file = $_product->get_file( $result->download_id );
423
424
			// Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files
425
			$download_name = apply_filters(
426
				'woocommerce_downloadable_product_name',
427
				$_product->get_title() . ' &ndash; ' . $download_file['name'],
428
				$_product,
429
				$result->download_id,
430
				$file_number
431
			);
432
433
			$downloads[] = array(
434
				'download_url'        => add_query_arg(
435
					array(
436
						'download_file' => $product_id,
437
						'order'         => $result->order_key,
438
						'email'         => $result->user_email,
439
						'key'           => $result->download_id
440
					),
441
					home_url( '/' )
442
				),
443
				'download_id'         => $result->download_id,
444
				'product_id'          => $product_id,
445
				'download_name'       => $download_name,
446
				'order_id'            => $order->id,
447
				'order_key'           => $order->order_key,
448
				'downloads_remaining' => $result->downloads_remaining,
449
				'access_expires' 	  => $result->access_expires,
450
				'file'                => $download_file
451
			);
452
453
			$file_number++;
454
		}
455
	}
456
457
	return $downloads;
458
}
459
460
/**
461
 * Get total spent by customer.
462
 * @param  int $user_id
463
 * @return string
464
 */
465
function wc_get_customer_total_spent( $user_id ) {
466
	$spent = get_user_meta( $user_id, '_money_spent', true );
467
	if ( '' === $spent ) {
468
		global $wpdb;
469
470
		$spent = $wpdb->get_var( "SELECT SUM(meta2.meta_value)
471
			FROM $wpdb->posts as posts
472
473
			LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
474
			LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id
475
476
			WHERE   meta.meta_key       = '_customer_user'
477
			AND     meta.meta_value     = $user_id
478
			AND     posts.post_type     IN ('" . implode( "','", wc_get_order_types( 'reports' ) ) . "')
479
			AND     posts.post_status   IN ( 'wc-completed', 'wc-processing' )
480
			AND     meta2.meta_key      = '_order_total'
481
		" );
482
483
		update_user_meta( $user_id, '_money_spent', $spent );
484
	}
485
486
	return $spent;
487
}
488
489
/**
490
 * Get total orders by customer.
491
 * @param  int $user_id
492
 * @return int
493
 */
494
function wc_get_customer_order_count( $user_id ) {
495
	$count = get_user_meta( $user_id, '_order_count', true );
496
	if ( '' === $count ) {
497
		global $wpdb;
498
499
		$count = $wpdb->get_var( "SELECT COUNT(*)
500
			FROM $wpdb->posts as posts
501
502
			LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
503
504
			WHERE   meta.meta_key       = '_customer_user'
505
			AND     posts.post_type     IN ('" . implode( "','", wc_get_order_types( 'order-count' ) ) . "')
506
			AND     posts.post_status   IN ('" . implode( "','", array_keys( wc_get_order_statuses() ) )  . "')
507
			AND     meta_value          = $user_id
508
		" );
509
510
		update_user_meta( $user_id, '_order_count', absint( $count ) );
511
	}
512
513
	return absint( $count );
514
}
515
516
/**
517
 * Reset _customer_user on orders when a user is deleted.
518
 * @param int $user_id
519
 */
520
function wc_reset_order_customer_id_on_deleted_user( $user_id ) {
521
	global $wpdb;
522
523
	$wpdb->update( $wpdb->postmeta, array( 'meta_value' => 0 ), array( 'meta_key' => '_customer_user', 'meta_value' => $user_id ) );
524
}
525
526
add_action( 'deleted_user', 'wc_reset_order_customer_id_on_deleted_user' );
527
528
/**
529
 * Get review verification status.
530
 * @param  int $comment_id
531
 * @return bool
532
 */
533
function wc_review_is_from_verified_owner( $comment_id ) {
534
	$verified = get_comment_meta( $comment_id, 'verified', true );
535
536
	// If no "verified" meta is present, generate it (if this is a product review).
537
	if ( '' === $verified ) {
538
		$verified = WC_Comments::add_comment_purchase_verification( $comment_id );
539
	}
540
541
	return (bool) $verified;
542
}
543
544
/**
545
 * Disable author archives for customers.
546
 *
547
 * @since 2.5.0
548
 */
549
function wc_disable_author_archives_for_customers() {
550
	global $wp_query, $author;
551
552
	if ( is_author() ) {
553
		$user = get_user_by( 'id', $author );
554
555
		if ( isset( $user->roles[0] ) && 'customer' === $user->roles[0] ) {
556
			wp_redirect( wc_get_page_permalink( 'shop' ) );
557
		}
558
	}
559
}
560
561
add_action( 'template_redirect', 'wc_disable_author_archives_for_customers' );
562
563
/**
564
 * Hooks into the `profile_update` hook to set the user last updated timestamp.
565
 *
566
 * @since 2.6.0
567
 * @param int   $user_id The user that was updated.
568
 * @param array $old     The profile fields pre-change.
569
 */
570
function wc_update_profile_last_update_time( $user_id, $old ) {
0 ignored issues
show
Unused Code introduced by
The parameter $old 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...
571
	wc_set_user_last_update_time( $user_id );
572
}
573
574
add_action( 'profile_update', 'wc_update_profile_last_update_time', 10, 2 );
575
576
/**
577
 * Hooks into the update user meta function to set the user last updated timestamp.
578
 *
579
 * @since 2.6.0
580
 * @param int    $meta_id     ID of the meta object that was changed.
581
 * @param int    $user_id     The user that was updated.
582
 * @param string $meta_key    Name of the meta key that was changed.
583
 * @param string $_meta_value Value of the meta that was changed.
584
 */
585
function wc_meta_update_last_update_time( $meta_id, $user_id, $meta_key, $_meta_value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $meta_id 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...
Unused Code introduced by
The parameter $_meta_value 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...
586
	$keys_to_track = apply_filters( 'woocommerce_user_last_update_fields', array( 'first_name', 'last_name' ) );
587
	$update_time   = false;
588
	if ( in_array( $meta_key, $keys_to_track ) ) {
589
		$update_time = true;
590
	}
591
	if ( 'billing_' === substr( $meta_key, 0, 8 ) ) {
592
		$update_time = true;
593
	}
594
	if ( 'shipping_' === substr( $meta_key, 0, 9 ) ) {
595
		$update_time = true;
596
	}
597
598
	if ( $update_time ) {
599
		wc_set_user_last_update_time( $user_id );
600
	}
601
}
602
603
add_action( 'update_user_meta', 'wc_meta_update_last_update_time', 10, 4 );
604
605
/**
606
 * Sets a user's "last update" time to the current timestamp.
607
 *
608
 * @since 2.6.0
609
 * @param int $user_id The user to set a timestamp for.
610
 */
611
function wc_set_user_last_update_time( $user_id ) {
612
	update_user_meta( $user_id, 'last_update', time() );
613
}
614
615
/**
616
 * Get customer saved payment methods list.
617
 *
618
 * @since 2.6.0
619
 * @param int $customer_id
620
 * @return array
621
 */
622
function wc_get_customer_saved_methods_list( $customer_id ) {
623
	return apply_filters( 'woocommerce_saved_payment_methods_list', array(), $customer_id );
624
}
625
626
/**
627
 * Get info about customer's last order.
628
 *
629
 * @since 2.6.0
630
 * @param int $customer_id Customer ID.
631
 * @return WC_Order Order object if successful or false.
632
 */
633
function wc_get_customer_last_order( $customer_id ) {
634
	global $wpdb;
635
636
	$customer_id = absint( $customer_id );
637
638
	$id = $wpdb->get_var( "SELECT id
639
		FROM $wpdb->posts AS posts
640
		LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
641
		WHERE meta.meta_key = '_customer_user'
642
		AND   meta.meta_value = {$customer_id}
643
		AND   posts.post_type = 'shop_order'
644
		AND   posts.post_status IN ( '" . implode( "','", array_keys( wc_get_order_statuses() ) ) . "' )
645
		ORDER BY posts.ID DESC
646
	" );
647
648
	return wc_get_order( $id );
649
}
650
651
/**
652
 * Wrapper for @see get_avatar() which doesn't simply return
653
 * the URL so we need to pluck it from the HTML img tag.
654
 *
655
 * Kudos to https://github.com/WP-API/WP-API for offering a better solution.
656
 *
657
 * @since 2.6.0
658
 * @param string $email the customer's email.
659
 * @return string the URL to the customer's avatar.
660
 */
661 View Code Duplication
function wc_get_customer_avatar_url( $email ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in 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...
662
	$avatar_html = get_avatar( $email );
663
664
	// Get the URL of the avatar from the provided HTML.
665
	preg_match( '/src=["|\'](.+)[\&|"|\']/U', $avatar_html, $matches );
666
667
	if ( isset( $matches[1] ) && ! empty( $matches[1] ) ) {
668
		return esc_url_raw( $matches[1] );
669
	}
670
671
	return null;
672
}
673