2013-08-09 16:11:15 +00:00
< ? php
/**
2015-11-03 13:53:50 +00:00
* WooCommerce Customer Functions
2013-08-09 16:11:15 +00:00
*
* Functions for customers .
*
2018-03-08 21:26:56 +00:00
* @ package WooCommerce / Functions
* @ version 2.2 . 0
2013-08-09 16:11:15 +00:00
*/
2018-03-08 21:26:56 +00:00
defined ( 'ABSPATH' ) || exit ;
2013-08-09 16:11:15 +00:00
/**
2015-11-03 13:31:20 +00:00
* Prevent any user who cannot 'edit_posts' ( subscribers , customers etc ) from seeing the admin bar .
2013-08-09 16:11:15 +00:00
*
2017-07-17 10:10:52 +00:00
* Note : get_option ( 'woocommerce_lock_down_admin' , true ) is a deprecated option here for backwards compatibility . Defaults to true .
2013-08-09 16:11:15 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param bool $show_admin_bar If should display admin bar .
2013-08-09 16:11:15 +00:00
* @ return bool
*/
2013-11-25 12:52:53 +00:00
function wc_disable_admin_bar ( $show_admin_bar ) {
2017-11-19 13:17:37 +00:00
if ( apply_filters ( 'woocommerce_disable_admin_bar' , true ) && ! ( current_user_can ( 'edit_posts' ) || current_user_can ( 'manage_woocommerce' ) ) ) {
2013-08-09 16:11:15 +00:00
$show_admin_bar = false ;
}
return $show_admin_bar ;
}
2018-03-08 21:26:56 +00:00
add_filter ( 'show_admin_bar' , 'wc_disable_admin_bar' , 10 , 1 ); // phpcs:ignore WordPress.VIP.AdminBarRemoval.RemovalDetected
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
if ( ! function_exists ( 'wc_create_new_customer' ) ) {
/**
* Create a new customer .
*
2019-02-20 19:18:43 +00:00
* @ param string $email Customer email .
2016-04-18 18:30:57 +00:00
* @ param string $username Customer username .
* @ param string $password Customer password .
2019-02-20 19:18:43 +00:00
* @ param array $args List of arguments to pass to `wp_insert_user()` .
2016-04-18 18:30:57 +00:00
* @ return int | WP_Error Returns WP_Error on failure , Int ( user ID ) on success .
*/
2019-02-20 19:18:43 +00:00
function wc_create_new_customer ( $email , $username = '' , $password = '' , $args = array () ) {
2016-04-18 18:30:57 +00:00
if ( empty ( $email ) || ! is_email ( $email ) ) {
return new WP_Error ( 'registration-error-invalid-email' , __ ( 'Please provide a valid email address.' , 'woocommerce' ) );
}
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
if ( email_exists ( $email ) ) {
2020-06-22 15:57:28 +00:00
return new WP_Error ( 'registration-error-email-exists' , apply_filters ( 'woocommerce_registration_error_email_exists' , __ ( 'An account is already registered with your email address. <a href="#" class="showlogin">Please log in.</a>' , 'woocommerce' ), $email ) );
2016-04-18 18:30:57 +00:00
}
2013-08-09 16:11:15 +00:00
2019-03-26 11:09:37 +00:00
if ( 'yes' === get_option ( 'woocommerce_registration_generate_username' , 'yes' ) && empty ( $username ) ) {
$username = wc_create_new_customer_username ( $email , $args );
}
2013-08-09 16:11:15 +00:00
2019-03-26 11:09:37 +00:00
$username = sanitize_user ( $username );
2013-08-09 16:11:15 +00:00
2019-03-26 11:09:37 +00:00
if ( empty ( $username ) || ! validate_username ( $username ) ) {
return new WP_Error ( 'registration-error-invalid-username' , __ ( 'Please enter a valid account username.' , 'woocommerce' ) );
}
2013-08-09 16:11:15 +00:00
2019-03-26 11:09:37 +00:00
if ( username_exists ( $username ) ) {
return new WP_Error ( 'registration-error-username-exists' , __ ( 'An account is already registered with that username. Please choose another.' , 'woocommerce' ) );
2014-02-11 19:57:15 +00:00
}
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
// Handle password creation.
2018-05-25 10:53:27 +00:00
$password_generated = false ;
2016-04-18 18:30:57 +00:00
if ( 'yes' === get_option ( 'woocommerce_registration_generate_password' ) && empty ( $password ) ) {
$password = wp_generate_password ();
$password_generated = true ;
2018-05-25 10:53:27 +00:00
}
if ( empty ( $password ) ) {
2016-04-18 18:30:57 +00:00
return new WP_Error ( 'registration-error-missing-password' , __ ( 'Please enter an account password.' , 'woocommerce' ) );
2013-08-09 16:11:15 +00:00
}
2016-04-18 18:30:57 +00:00
// Use WP_Error to handle registration errors.
$errors = new WP_Error ();
2014-04-02 02:45:25 +00:00
2016-04-18 18:30:57 +00:00
do_action ( 'woocommerce_register_post' , $username , $email , $errors );
2014-04-02 02:45:25 +00:00
2016-04-18 18:30:57 +00:00
$errors = apply_filters ( 'woocommerce_registration_errors' , $errors , $username , $email );
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
if ( $errors -> get_error_code () ) {
return $errors ;
}
2013-08-09 16:11:15 +00:00
2018-03-08 21:26:56 +00:00
$new_customer_data = apply_filters (
2019-01-21 12:38:40 +00:00
'woocommerce_new_customer_data' ,
2019-02-20 19:18:43 +00:00
array_merge (
$args ,
array (
'user_login' => $username ,
'user_pass' => $password ,
'user_email' => $email ,
'role' => 'customer' ,
)
2018-03-08 21:26:56 +00:00
)
);
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
$customer_id = wp_insert_user ( $new_customer_data );
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
if ( is_wp_error ( $customer_id ) ) {
2019-04-23 21:52:22 +00:00
return $customer_id ;
2016-04-18 18:30:57 +00:00
}
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
do_action ( 'woocommerce_created_customer' , $customer_id , $new_customer_data , $password_generated );
2013-08-09 16:11:15 +00:00
2016-04-18 18:30:57 +00:00
return $customer_id ;
2014-02-11 19:57:15 +00:00
}
2013-08-09 16:11:15 +00:00
}
2019-03-26 11:09:37 +00:00
/**
* Create a unique username for a new customer .
*
* @ since 3.6 . 0
* @ param string $email New customer email address .
* @ param array $new_user_args Array of new user args , maybe including first and last names .
2019-03-27 12:22:15 +00:00
* @ param string $suffix Append string to username to make it unique .
2019-03-26 11:09:37 +00:00
* @ return string Generated username .
*/
2019-05-09 20:08:15 +00:00
function wc_create_new_customer_username ( $email , $new_user_args = array (), $suffix = '' ) {
2019-03-26 11:09:37 +00:00
$username_parts = array ();
if ( isset ( $new_user_args [ 'first_name' ] ) ) {
$username_parts [] = sanitize_user ( $new_user_args [ 'first_name' ], true );
}
if ( isset ( $new_user_args [ 'last_name' ] ) ) {
$username_parts [] = sanitize_user ( $new_user_args [ 'last_name' ], true );
}
// Remove empty parts.
$username_parts = array_filter ( $username_parts );
// If there are no parts, e.g. name had unicode chars, or was not provided, fallback to email.
if ( empty ( $username_parts ) ) {
$email_parts = explode ( '@' , $email );
$email_username = $email_parts [ 0 ];
// Exclude common prefixes.
if ( in_array (
$email_username ,
array (
'sales' ,
'hello' ,
'mail' ,
'contact' ,
'info' ,
),
true
) ) {
// Get the domain part.
$email_username = $email_parts [ 1 ];
}
$username_parts [] = sanitize_user ( $email_username , true );
}
2019-05-09 20:27:51 +00:00
$username = wc_strtolower ( implode ( '.' , $username_parts ) );
2019-03-26 11:09:37 +00:00
if ( $suffix ) {
$username .= $suffix ;
}
2019-05-09 19:56:47 +00:00
/**
* WordPress 4.4 - filters the list of blacklisted usernames .
*
* @ since 3.7 . 0
* @ param array $usernames Array of blacklisted usernames .
*/
$illegal_logins = ( array ) apply_filters ( 'illegal_user_logins' , array () );
2019-05-09 20:04:27 +00:00
// Stop illegal logins and generate a new random username.
2019-05-09 19:56:47 +00:00
if ( in_array ( strtolower ( $username ), array_map ( 'strtolower' , $illegal_logins ), true ) ) {
$new_args = array ();
/**
2019-05-09 20:02:47 +00:00
* Filter generated customer username .
2019-05-09 19:56:47 +00:00
*
* @ since 3.7 . 0
2019-05-09 20:01:30 +00:00
* @ param string $username Generated username .
* @ param string $email New customer email address .
* @ param array $new_user_args Array of new user args , maybe including first and last names .
* @ param string $suffix Append string to username to make it unique .
2019-05-09 19:56:47 +00:00
*/
2019-05-09 20:01:30 +00:00
$new_args [ 'first_name' ] = apply_filters (
'woocommerce_generated_customer_username' ,
'woo_user_' . zeroise ( wp_rand ( 0 , 9999 ), 4 ),
$email ,
$new_user_args ,
$suffix
);
2019-05-09 19:56:47 +00:00
return wc_create_new_customer_username ( $email , $new_args , $suffix );
}
2019-03-26 11:09:37 +00:00
if ( username_exists ( $username ) ) {
2019-03-27 12:22:15 +00:00
// Generate something unique to append to the username in case of a conflict with another user.
$suffix = '-' . zeroise ( wp_rand ( 0 , 9999 ), 4 );
return wc_create_new_customer_username ( $email , $new_user_args , $suffix );
2019-03-26 11:09:37 +00:00
}
2019-05-09 20:02:47 +00:00
/**
* Filter new customer username .
*
* @ since 3.7 . 0
* @ param string $username Customer username .
* @ param string $email New customer email address .
* @ param array $new_user_args Array of new user args , maybe including first and last names .
* @ param string $suffix Append string to username to make it unique .
*/
return apply_filters ( 'woocommerce_new_customer_username' , $username , $email , $new_user_args , $suffix );
2019-03-26 11:09:37 +00:00
}
2013-08-09 16:11:15 +00:00
/**
2015-11-03 13:31:20 +00:00
* Login a customer ( set auth cookie and set global user object ) .
2013-08-09 16:11:15 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param int $customer_id Customer ID .
2013-08-09 16:11:15 +00:00
*/
2013-11-25 12:52:53 +00:00
function wc_set_customer_auth_cookie ( $customer_id ) {
2019-02-04 15:48:59 +00:00
wp_set_current_user ( $customer_id );
2013-09-04 10:26:19 +00:00
wp_set_auth_cookie ( $customer_id , true );
2019-02-04 15:48:59 +00:00
// Update session.
WC () -> session -> init_session_cookie ();
2013-08-09 16:11:15 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Get past orders ( by email ) and update them .
2013-08-09 16:11:15 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param int $customer_id Customer ID .
2013-11-27 18:20:31 +00:00
* @ return int
2013-08-09 16:11:15 +00:00
*/
2013-11-25 12:52:53 +00:00
function wc_update_new_customer_past_orders ( $customer_id ) {
2016-03-09 16:11:05 +00:00
$linked = 0 ;
$complete = 0 ;
$customer = get_user_by ( 'id' , absint ( $customer_id ) );
2018-03-08 21:26:56 +00:00
$customer_orders = wc_get_orders (
array (
'limit' => - 1 ,
'customer' => array ( array ( 0 , $customer -> user_email ) ),
'return' => 'ids' ,
)
);
2013-08-09 16:11:15 +00:00
2016-03-09 16:11:05 +00:00
if ( ! empty ( $customer_orders ) ) {
2014-02-11 19:51:10 +00:00
foreach ( $customer_orders as $order_id ) {
2017-11-20 06:44:42 +00:00
$order = wc_get_order ( $order_id );
if ( ! $order ) {
continue ;
}
$order -> set_customer_id ( $customer -> ID );
$order -> save ();
if ( $order -> has_downloadable_item () ) {
$data_store = WC_Data_Store :: load ( 'customer-download' );
$data_store -> delete_by_order_id ( $order -> get_id () );
wc_downloadable_product_permissions ( $order -> get_id (), true );
}
2013-08-09 16:11:15 +00:00
2015-09-15 22:56:59 +00:00
do_action ( 'woocommerce_update_new_customer_past_order' , $order_id , $customer );
2014-12-04 13:09:37 +00:00
if ( get_post_status ( $order_id ) === 'wc-completed' ) {
2015-09-15 22:56:59 +00:00
$complete ++ ;
2014-05-30 15:14:24 +00:00
}
2013-08-09 16:11:15 +00:00
2015-09-15 22:56:59 +00:00
$linked ++ ;
2014-02-11 19:51:10 +00:00
}
2014-12-04 13:09:37 +00:00
}
2013-08-09 16:11:15 +00:00
2014-02-11 19:51:10 +00:00
if ( $complete ) {
update_user_meta ( $customer_id , 'paying_customer' , 1 );
update_user_meta ( $customer_id , '_order_count' , '' );
update_user_meta ( $customer_id , '_money_spent' , '' );
}
2013-08-09 16:11:15 +00:00
2014-02-11 19:51:10 +00:00
return $linked ;
2013-08-09 16:11:15 +00:00
}
/**
2019-04-19 18:21:17 +00:00
* Order payment completed - This is a paying customer .
2013-08-09 16:11:15 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param int $order_id Order ID .
2013-08-09 16:11:15 +00:00
*/
2013-11-25 12:52:53 +00:00
function wc_paying_customer ( $order_id ) {
2016-06-22 12:06:02 +00:00
$order = wc_get_order ( $order_id );
$customer_id = $order -> get_customer_id ();
2013-08-09 16:11:15 +00:00
2017-01-19 19:16:43 +00:00
if ( $customer_id > 0 && 'shop_order_refund' !== $order -> get_type () ) {
2016-12-15 15:07:48 +00:00
$customer = new WC_Customer ( $customer_id );
2019-07-10 22:36:43 +00:00
if ( ! $customer -> get_is_paying_customer () ) {
$customer -> set_is_paying_customer ( true );
$customer -> save ();
}
2013-08-09 16:11:15 +00:00
}
}
2019-04-19 18:21:17 +00:00
add_action ( 'woocommerce_payment_complete' , 'wc_paying_customer' );
2013-11-25 12:52:53 +00:00
add_action ( 'woocommerce_order_status_completed' , 'wc_paying_customer' );
2013-08-09 16:11:15 +00:00
/**
2015-11-14 16:25:09 +00:00
* Checks if a user ( by email or ID or both ) has bought an item .
2017-11-01 15:48:46 +00:00
*
* @ param string $customer_email Customer email to check .
* @ param int $user_id User ID to check .
* @ param int $product_id Product ID to check .
2013-08-09 16:11:15 +00:00
* @ return bool
*/
2013-11-25 12:52:53 +00:00
function wc_customer_bought_product ( $customer_email , $user_id , $product_id ) {
2013-08-09 16:11:15 +00:00
global $wpdb ;
2017-11-01 15:48:46 +00:00
$result = apply_filters ( 'woocommerce_pre_customer_bought_product' , null , $customer_email , $user_id , $product_id );
2017-10-30 17:20:55 +00:00
if ( null !== $result ) {
return $result ;
}
2019-01-21 12:38:40 +00:00
$transient_name = 'wc_customer_bought_product_' . md5 ( $customer_email . $user_id );
$transient_version = WC_Cache_Helper :: get_transient_version ( 'orders' );
$transient_value = get_transient ( $transient_name );
2015-03-27 13:17:54 +00:00
2019-01-21 12:38:40 +00:00
if ( isset ( $transient_value [ 'value' ], $transient_value [ 'version' ] ) && $transient_value [ 'version' ] === $transient_version ) {
$result = $transient_value [ 'value' ];
} else {
2018-10-29 14:15:22 +00:00
$customer_data = array ( $user_id );
2013-08-09 16:11:15 +00:00
2015-03-27 13:17:54 +00:00
if ( $user_id ) {
$user = get_user_by ( 'id' , $user_id );
2015-01-19 02:25:32 +00:00
2015-03-27 13:17:54 +00:00
if ( isset ( $user -> user_email ) ) {
$customer_data [] = $user -> user_email ;
}
2015-01-19 02:25:32 +00:00
}
2013-08-09 16:11:15 +00:00
2015-03-27 13:17:54 +00:00
if ( is_email ( $customer_email ) ) {
$customer_data [] = $customer_email ;
}
2013-08-09 16:11:15 +00:00
2015-05-19 05:01:53 +00:00
$customer_data = array_map ( 'esc_sql' , array_filter ( array_unique ( $customer_data ) ) );
2016-11-03 11:27:03 +00:00
$statuses = array_map ( 'esc_sql' , wc_get_is_paid_statuses () );
2015-03-27 13:08:24 +00:00
2018-03-08 21:26:56 +00:00
if ( count ( $customer_data ) === 0 ) {
2015-03-27 13:17:54 +00:00
return false ;
}
2013-08-09 16:11:15 +00:00
2018-10-29 14:15:22 +00:00
$result = $wpdb -> get_col (
"
SELECT im . meta_value FROM { $wpdb -> posts } AS p
INNER JOIN { $wpdb -> postmeta } AS pm ON p . ID = pm . post_id
INNER JOIN { $wpdb -> prefix } woocommerce_order_items AS i ON p . ID = i . order_id
INNER JOIN { $wpdb -> prefix } woocommerce_order_itemmeta AS im ON i . order_item_id = im . order_item_id
WHERE p . post_status IN ( 'wc-" . implode( "' , 'wc-", $statuses ) . "' )
AND pm . meta_key IN ( '_billing_email' , '_customer_user' )
AND im . meta_key IN ( '_product_id' , '_variation_id' )
AND im . meta_value != 0
AND pm . meta_value IN ( '" . implode( "' , '", $customer_data ) . "' )
"
); // WPCS: unprepared SQL ok.
2015-11-14 16:25:09 +00:00
$result = array_map ( 'absint' , $result );
2015-10-07 17:59:02 +00:00
2019-01-21 12:38:40 +00:00
$transient_value = array (
'version' => $transient_version ,
'value' => $result ,
);
set_transient ( $transient_name , $transient_value , DAY_IN_SECONDS * 30 );
2015-03-27 13:17:54 +00:00
}
2018-03-08 21:26:56 +00:00
return in_array ( absint ( $product_id ), $result , true );
2013-09-06 14:37:38 +00:00
}
2018-10-15 14:48:16 +00:00
/**
* Checks if the current user has a role .
*
2018-10-15 15:21:04 +00:00
* @ param string $role The role .
2018-10-15 14:48:16 +00:00
* @ return bool
*/
function wc_current_user_has_role ( $role ) {
return wc_user_has_role ( wp_get_current_user (), $role );
}
/**
* Checks if a user has a role .
*
* @ param int | \WP_User $user The user .
* @ param string $role The role .
* @ return bool
*/
function wc_user_has_role ( $user , $role ) {
2018-10-15 15:21:04 +00:00
if ( ! is_object ( $user ) ) {
$user = get_userdata ( $user );
}
2018-10-15 15:38:13 +00:00
2018-10-15 15:21:04 +00:00
if ( ! $user || ! $user -> exists () ) {
return false ;
}
2018-10-15 14:48:16 +00:00
2018-10-15 15:21:04 +00:00
return in_array ( $role , $user -> roles , true );
2018-10-15 14:48:16 +00:00
}
2013-09-06 14:37:38 +00:00
/**
2015-11-03 13:31:20 +00:00
* Checks if a user has a certain capability .
2013-09-06 14:37:38 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param array $allcaps All capabilities .
* @ param array $caps Capabilities .
* @ param array $args Arguments .
2018-11-20 13:50:46 +00:00
*
* @ return array The filtered array of all capabilities .
2013-09-06 14:37:38 +00:00
*/
2013-11-25 12:52:53 +00:00
function wc_customer_has_capability ( $allcaps , $caps , $args ) {
2014-02-11 19:57:15 +00:00
if ( isset ( $caps [ 0 ] ) ) {
switch ( $caps [ 0 ] ) {
2018-03-08 21:26:56 +00:00
case 'view_order' :
$user_id = intval ( $args [ 1 ] );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $args [ 2 ] );
2013-09-06 14:37:38 +00:00
2018-03-08 21:26:56 +00:00
if ( $order && $user_id === $order -> get_user_id () ) {
2014-02-11 19:57:15 +00:00
$allcaps [ 'view_order' ] = true ;
}
2018-03-08 21:26:56 +00:00
break ;
case 'pay_for_order' :
$user_id = intval ( $args [ 1 ] );
2014-02-11 19:57:15 +00:00
$order_id = isset ( $args [ 2 ] ) ? $args [ 2 ] : null ;
2013-11-28 15:22:05 +00:00
2014-02-11 19:57:15 +00:00
// When no order ID, we assume it's a new order
2018-03-08 21:26:56 +00:00
// and thus, customer can pay for it.
2014-02-11 19:57:15 +00:00
if ( ! $order_id ) {
$allcaps [ 'pay_for_order' ] = true ;
break ;
}
2013-09-06 14:37:38 +00:00
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $order_id );
2017-04-12 12:46:14 +00:00
2018-03-08 21:26:56 +00:00
if ( $order && ( $user_id === $order -> get_user_id () || ! $order -> get_user_id () ) ) {
2014-02-11 19:57:15 +00:00
$allcaps [ 'pay_for_order' ] = true ;
}
2018-03-08 21:26:56 +00:00
break ;
case 'order_again' :
$user_id = intval ( $args [ 1 ] );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $args [ 2 ] );
2013-09-06 14:37:38 +00:00
2018-03-08 21:26:56 +00:00
if ( $order && $user_id === $order -> get_user_id () ) {
2014-02-11 19:57:15 +00:00
$allcaps [ 'order_again' ] = true ;
}
2018-03-08 21:26:56 +00:00
break ;
case 'cancel_order' :
$user_id = intval ( $args [ 1 ] );
2014-08-15 12:29:21 +00:00
$order = wc_get_order ( $args [ 2 ] );
2013-09-06 14:37:38 +00:00
2018-03-08 21:26:56 +00:00
if ( $order && $user_id === $order -> get_user_id () ) {
2014-02-11 19:57:15 +00:00
$allcaps [ 'cancel_order' ] = true ;
}
2018-03-08 21:26:56 +00:00
break ;
case 'download_file' :
$user_id = intval ( $args [ 1 ] );
2014-02-11 19:57:15 +00:00
$download = $args [ 2 ];
2013-09-06 16:38:06 +00:00
2018-03-08 21:26:56 +00:00
if ( $download && $user_id === $download -> get_user_id () ) {
2014-02-11 19:57:15 +00:00
$allcaps [ 'download_file' ] = true ;
}
2018-03-08 21:26:56 +00:00
break ;
2014-02-11 19:57:15 +00:00
}
2014-02-11 19:51:10 +00:00
}
2014-02-11 19:57:15 +00:00
return $allcaps ;
2013-09-06 14:37:38 +00:00
}
2014-02-11 19:57:15 +00:00
add_filter ( 'user_has_cap' , 'wc_customer_has_capability' , 10 , 3 );
2014-04-23 13:18:17 +00:00
2019-01-21 16:02:28 +00:00
/**
* Safe way of allowing shop managers restricted capabilities that will remove
* access to the capabilities if WooCommerce is deactivated .
*
* @ since 3.5 . 4
* @ param bool [] $allcaps Array of key / value pairs where keys represent a capability name and boolean values
* represent whether the user has that capability .
* @ param string [] $caps Required primitive capabilities for the requested capability .
* @ param array $args Arguments that accompany the requested capability check .
* @ param WP_User $user The user object .
* @ return bool []
*/
function wc_shop_manager_has_capability ( $allcaps , $caps , $args , $user ) {
if ( wc_user_has_role ( $user , 'shop_manager' ) ) {
2019-02-20 19:30:46 +00:00
// @see wc_modify_map_meta_cap, which limits editing to customers.
2019-01-21 16:02:28 +00:00
$allcaps [ 'edit_users' ] = true ;
}
return $allcaps ;
}
add_filter ( 'user_has_cap' , 'wc_shop_manager_has_capability' , 10 , 4 );
2014-04-23 13:18:17 +00:00
/**
2015-11-03 13:31:20 +00:00
* Modify the list of editable roles to prevent non - admin adding admin users .
2018-03-08 21:26:56 +00:00
*
* @ param array $roles Roles .
2014-04-23 13:18:17 +00:00
* @ return array
*/
2016-08-27 04:47:24 +00:00
function wc_modify_editable_roles ( $roles ) {
2018-10-15 21:53:29 +00:00
if ( is_multisite () && is_super_admin () ) {
return $roles ;
}
2018-10-15 14:48:16 +00:00
if ( ! wc_current_user_has_role ( 'administrator' ) ) {
2016-08-27 03:23:21 +00:00
unset ( $roles [ 'administrator' ] );
2018-09-14 19:31:43 +00:00
2018-10-15 15:15:53 +00:00
if ( wc_current_user_has_role ( 'shop_manager' ) ) {
$shop_manager_editable_roles = apply_filters ( 'woocommerce_shop_manager_editable_roles' , array ( 'customer' ) );
return array_intersect_key ( $roles , array_flip ( $shop_manager_editable_roles ) );
}
2018-09-14 19:31:43 +00:00
}
2018-10-10 16:56:37 +00:00
2016-07-11 14:56:35 +00:00
return $roles ;
2014-04-23 13:18:17 +00:00
}
add_filter ( 'editable_roles' , 'wc_modify_editable_roles' );
/**
2017-07-17 10:10:52 +00:00
* Modify capabilities to prevent non - admin users editing admin users .
2014-04-23 13:18:17 +00:00
*
* $args [ 0 ] will be the user being edited in this case .
2014-05-28 17:05:19 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param array $caps Array of caps .
* @ param string $cap Name of the cap we are checking .
* @ param int $user_id ID of the user being checked against .
* @ param array $args Arguments .
2014-04-23 13:18:17 +00:00
* @ return array
*/
function wc_modify_map_meta_cap ( $caps , $cap , $user_id , $args ) {
2018-10-15 21:52:47 +00:00
if ( is_multisite () && is_super_admin () ) {
return $caps ;
}
2014-04-23 13:18:17 +00:00
switch ( $cap ) {
2018-03-08 21:26:56 +00:00
case 'edit_user' :
case 'remove_user' :
case 'promote_user' :
case 'delete_user' :
2014-08-27 18:18:44 +00:00
if ( ! isset ( $args [ 0 ] ) || $args [ 0 ] === $user_id ) {
2014-04-23 13:18:17 +00:00
break ;
} else {
2018-10-15 15:15:53 +00:00
if ( ! wc_current_user_has_role ( 'administrator' ) ) {
if ( wc_user_has_role ( $args [ 0 ], 'administrator' ) ) {
2018-09-14 19:31:43 +00:00
$caps [] = 'do_not_allow' ;
2018-10-16 12:11:36 +00:00
} elseif ( wc_current_user_has_role ( 'shop_manager' ) ) {
// Shop managers can only edit customer info.
2019-12-20 17:21:08 +00:00
$userdata = get_userdata ( $args [ 0 ] );
2018-10-15 15:15:53 +00:00
$shop_manager_editable_roles = apply_filters ( 'woocommerce_shop_manager_editable_roles' , array ( 'customer' ) );
if ( property_exists ( $userdata , 'roles' ) && ! empty ( $userdata -> roles ) && ! array_intersect ( $userdata -> roles , $shop_manager_editable_roles ) ) {
$caps [] = 'do_not_allow' ;
}
}
2018-09-14 19:08:36 +00:00
}
2014-04-23 13:18:17 +00:00
}
2018-03-08 21:26:56 +00:00
break ;
2014-04-23 13:18:17 +00:00
}
return $caps ;
}
2014-05-28 17:05:19 +00:00
add_filter ( 'map_meta_cap' , 'wc_modify_map_meta_cap' , 10 , 4 );
/**
2016-06-29 11:06:03 +00:00
* Get customer download permissions from the database .
2014-05-28 17:05:19 +00:00
*
2018-03-08 21:26:56 +00:00
* @ param int $customer_id Customer / User ID .
2014-05-28 17:05:19 +00:00
* @ return array
*/
2016-06-29 11:06:03 +00:00
function wc_get_customer_download_permissions ( $customer_id ) {
2016-11-18 17:13:02 +00:00
$data_store = WC_Data_Store :: load ( 'customer-download' );
return apply_filters ( 'woocommerce_permission_list' , $data_store -> get_downloads_for_customer ( $customer_id ), $customer_id );
2016-06-29 11:06:03 +00:00
}
/**
* Get customer available downloads .
*
2018-03-08 21:26:56 +00:00
* @ param int $customer_id Customer / User ID .
2016-06-29 11:06:03 +00:00
* @ return array
*/
function wc_get_customer_available_downloads ( $customer_id ) {
2014-05-28 17:05:19 +00:00
$downloads = array ();
$_product = null ;
$order = null ;
$file_number = 0 ;
2018-03-08 21:26:56 +00:00
// Get results from valid orders only.
2016-06-29 11:06:03 +00:00
$results = wc_get_customer_download_permissions ( $customer_id );
2014-05-28 17:05:19 +00:00
if ( $results ) {
foreach ( $results as $result ) {
2018-03-08 21:26:56 +00:00
$order_id = intval ( $result -> order_id );
if ( ! $order || $order -> get_id () !== $order_id ) {
// New order.
$order = wc_get_order ( $order_id );
2014-05-28 17:05:19 +00:00
$_product = null ;
}
2018-03-08 21:26:56 +00:00
// Make sure the order exists for this download.
2015-02-18 10:04:19 +00:00
if ( ! $order ) {
continue ;
}
2018-03-08 21:26:56 +00:00
// Check if downloads are permitted.
2014-05-28 17:05:19 +00:00
if ( ! $order -> is_download_permitted () ) {
continue ;
}
2015-01-21 12:21:42 +00:00
$product_id = intval ( $result -> product_id );
2018-03-08 21:26:56 +00:00
if ( ! $_product || $_product -> get_id () !== $product_id ) {
// New product.
2014-05-28 17:05:19 +00:00
$file_number = 0 ;
2015-01-21 12:21:42 +00:00
$_product = wc_get_product ( $product_id );
2014-05-28 17:05:19 +00:00
}
2018-03-08 21:26:56 +00:00
// Check product exists and has the file.
2014-05-28 17:05:19 +00:00
if ( ! $_product || ! $_product -> exists () || ! $_product -> has_file ( $result -> download_id ) ) {
continue ;
}
$download_file = $_product -> get_file ( $result -> download_id );
2015-03-27 13:08:24 +00:00
2017-03-06 22:45:03 +00:00
// Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files.
2014-05-28 17:05:19 +00:00
$download_name = apply_filters (
'woocommerce_downloadable_product_name' ,
2017-07-11 12:45:35 +00:00
$download_file [ 'name' ],
2014-05-28 17:05:19 +00:00
$_product ,
$result -> download_id ,
$file_number
);
$downloads [] = array (
2018-03-08 21:26:56 +00:00
'download_url' => add_query_arg (
2014-08-19 10:01:55 +00:00
array (
2015-01-21 12:21:42 +00:00
'download_file' => $product_id ,
2014-08-19 10:01:55 +00:00
'order' => $result -> order_key ,
2018-03-08 21:26:56 +00:00
'email' => rawurlencode ( $result -> user_email ),
2016-08-27 01:46:45 +00:00
'key' => $result -> download_id ,
2014-08-19 10:01:55 +00:00
),
home_url ( '/' )
),
2018-03-08 21:26:56 +00:00
'download_id' => $result -> download_id ,
'product_id' => $_product -> get_id (),
'product_name' => $_product -> get_name (),
'product_url' => $_product -> is_visible () ? $_product -> get_permalink () : '' , // Since 3.3.0.
'download_name' => $download_name ,
'order_id' => $order -> get_id (),
'order_key' => $order -> get_order_key (),
'downloads_remaining' => $result -> downloads_remaining ,
'access_expires' => $result -> access_expires ,
'file' => array (
2017-03-06 22:45:03 +00:00
'name' => $download_file -> get_name (),
'file' => $download_file -> get_file (),
),
2014-05-28 17:05:19 +00:00
);
$file_number ++ ;
}
}
2016-10-11 14:36:03 +00:00
return apply_filters ( 'woocommerce_customer_available_downloads' , $downloads , $customer_id );
2014-05-28 17:05:19 +00:00
}
2015-01-12 17:09:42 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get total spent by customer .
2018-03-08 21:26:56 +00:00
*
* @ param int $user_id User ID .
2015-01-12 17:09:42 +00:00
* @ return string
*/
function wc_get_customer_total_spent ( $user_id ) {
2016-10-14 14:11:10 +00:00
$customer = new WC_Customer ( $user_id );
return $customer -> get_total_spent ();
2015-01-12 17:09:42 +00:00
}
/**
2015-11-03 13:31:20 +00:00
* Get total orders by customer .
2018-03-08 21:26:56 +00:00
*
* @ param int $user_id User ID .
2015-01-12 17:09:42 +00:00
* @ return int
*/
function wc_get_customer_order_count ( $user_id ) {
2016-10-14 14:11:10 +00:00
$customer = new WC_Customer ( $user_id );
return $customer -> get_order_count ();
2015-01-12 17:09:42 +00:00
}
2015-10-05 20:38:20 +00:00
/**
2018-10-29 14:16:07 +00:00
* Reset _customer_user on orders when a user is deleted .
2018-03-08 21:26:56 +00:00
*
* @ param int $user_id User ID .
2015-10-05 20:38:20 +00:00
*/
function wc_reset_order_customer_id_on_deleted_user ( $user_id ) {
global $wpdb ;
2018-03-08 21:26:56 +00:00
$wpdb -> update (
2019-01-21 12:38:40 +00:00
$wpdb -> postmeta ,
array (
'meta_value' => 0 ,
),
array (
2018-03-08 21:26:56 +00:00
'meta_key' => '_customer_user' ,
'meta_value' => $user_id ,
)
); // WPCS: slow query ok.
2015-10-05 20:38:20 +00:00
}
2015-10-13 21:13:31 +00:00
add_action ( 'deleted_user' , 'wc_reset_order_customer_id_on_deleted_user' );
2015-10-09 16:22:56 +00:00
/**
2015-11-03 13:31:20 +00:00
* Get review verification status .
2018-03-08 21:26:56 +00:00
*
* @ param int $comment_id Comment ID .
2015-10-09 16:22:56 +00:00
* @ return bool
*/
function wc_review_is_from_verified_owner ( $comment_id ) {
$verified = get_comment_meta ( $comment_id , 'verified' , true );
2018-06-06 11:16:43 +00:00
return '' === $verified ? WC_Comments :: add_comment_purchase_verification ( $comment_id ) : ( bool ) $verified ;
2015-10-09 16:22:56 +00:00
}
2015-10-26 17:38:44 +00:00
/**
2015-11-03 13:31:20 +00:00
* Disable author archives for customers .
2015-10-26 17:38:44 +00:00
*
* @ since 2.5 . 0
*/
function wc_disable_author_archives_for_customers () {
2017-05-15 09:54:06 +00:00
global $author ;
2015-10-26 17:38:44 +00:00
if ( is_author () ) {
$user = get_user_by ( 'id' , $author );
2017-06-09 14:18:35 +00:00
if ( user_can ( $user , 'customer' ) && ! user_can ( $user , 'edit_posts' ) ) {
2019-08-14 02:57:05 +00:00
wp_safe_redirect ( wc_get_page_permalink ( 'shop' ) );
exit ;
2015-10-26 17:38:44 +00:00
}
}
}
add_action ( 'template_redirect' , 'wc_disable_author_archives_for_customers' );
2016-02-10 11:56:13 +00:00
/**
2016-02-10 16:47:37 +00:00
* Hooks into the `profile_update` hook to set the user last updated timestamp .
2016-02-10 11:56:13 +00:00
*
2016-01-20 20:13:17 +00:00
* @ since 2.6 . 0
* @ param int $user_id The user that was updated .
* @ param array $old The profile fields pre - change .
2016-02-10 11:56:13 +00:00
*/
function wc_update_profile_last_update_time ( $user_id , $old ) {
wc_set_user_last_update_time ( $user_id );
}
add_action ( 'profile_update' , 'wc_update_profile_last_update_time' , 10 , 2 );
/**
2016-02-10 16:47:37 +00:00
* Hooks into the update user meta function to set the user last updated timestamp .
2016-02-10 11:56:13 +00:00
*
2016-01-20 20:13:17 +00:00
* @ since 2.6 . 0
* @ param int $meta_id ID of the meta object that was changed .
* @ param int $user_id The user that was updated .
* @ param string $meta_key Name of the meta key that was changed .
* @ param string $_meta_value Value of the meta that was changed .
2016-02-10 11:56:13 +00:00
*/
function wc_meta_update_last_update_time ( $meta_id , $user_id , $meta_key , $_meta_value ) {
2016-02-10 16:21:33 +00:00
$keys_to_track = apply_filters ( 'woocommerce_user_last_update_fields' , array ( 'first_name' , 'last_name' ) );
2018-06-05 12:31:05 +00:00
$update_time = in_array ( $meta_key , $keys_to_track , true ) ? true : false ;
$update_time = 'billing_' === substr ( $meta_key , 0 , 8 ) ? true : $update_time ;
$update_time = 'shipping_' === substr ( $meta_key , 0 , 9 ) ? true : $update_time ;
2016-02-10 16:21:33 +00:00
if ( $update_time ) {
wc_set_user_last_update_time ( $user_id );
2016-02-10 11:56:13 +00:00
}
}
2016-02-10 16:47:37 +00:00
add_action ( 'update_user_meta' , 'wc_meta_update_last_update_time' , 10 , 4 );
2016-02-10 11:56:13 +00:00
/**
2016-02-10 16:47:37 +00:00
* Sets a user ' s " last update " time to the current timestamp .
2016-02-10 11:56:13 +00:00
*
2016-01-20 20:13:17 +00:00
* @ since 2.6 . 0
* @ param int $user_id The user to set a timestamp for .
2016-02-10 11:56:13 +00:00
*/
function wc_set_user_last_update_time ( $user_id ) {
2017-03-10 04:58:53 +00:00
update_user_meta ( $user_id , 'last_update' , gmdate ( 'U' ) );
2016-02-10 11:56:13 +00:00
}
2016-01-20 20:13:17 +00:00
/**
* Get customer saved payment methods list .
*
* @ since 2.6 . 0
2018-03-08 21:26:56 +00:00
* @ param int $customer_id Customer ID .
2016-01-20 20:13:17 +00:00
* @ return array
*/
function wc_get_customer_saved_methods_list ( $customer_id ) {
return apply_filters ( 'woocommerce_saved_payment_methods_list' , array (), $customer_id );
}
2016-03-01 23:07:05 +00:00
/**
* Get info about customer ' s last order .
*
* @ since 2.6 . 0
* @ param int $customer_id Customer ID .
2018-01-10 18:39:35 +00:00
* @ return WC_Order | bool Order object if successful or false .
2016-03-01 23:07:05 +00:00
*/
function wc_get_customer_last_order ( $customer_id ) {
2018-01-10 18:39:35 +00:00
$customer = new WC_Customer ( $customer_id );
2016-03-01 23:07:05 +00:00
2018-01-10 18:39:35 +00:00
return $customer -> get_last_order ();
2016-03-01 23:07:05 +00:00
}
2017-10-09 18:20:22 +00:00
/**
* Add support for searching by display_name .
*
* @ since 3.2 . 0
* @ param array $search_columns Column names .
* @ return array
*/
function wc_user_search_columns ( $search_columns ) {
$search_columns [] = 'display_name' ;
return $search_columns ;
}
add_filter ( 'user_search_columns' , 'wc_user_search_columns' );
2018-04-13 14:07:38 +00:00
/**
* When a user is deleted in WordPress , delete corresponding WooCommerce data .
*
* @ param int $user_id User ID being deleted .
*/
function wc_delete_user_data ( $user_id ) {
global $wpdb ;
// Clean up sessions.
$wpdb -> delete (
$wpdb -> prefix . 'woocommerce_sessions' ,
array (
'session_key' => $user_id ,
)
);
// Revoke API keys.
$wpdb -> delete (
$wpdb -> prefix . 'woocommerce_api_keys' ,
array (
'user_id' => $user_id ,
)
);
// Clean up payment tokens.
$payment_tokens = WC_Payment_Tokens :: get_customer_tokens ( $user_id );
foreach ( $payment_tokens as $payment_token ) {
$payment_token -> delete ();
}
}
add_action ( 'delete_user' , 'wc_delete_user_data' );
2018-04-30 14:38:45 +00:00
/**
* Store user agents . Used for tracker .
*
* @ since 3.0 . 0
* @ param string $user_login User login .
* @ param int | object $user User .
*/
function wc_maybe_store_user_agent ( $user_login , $user ) {
if ( 'yes' === get_option ( 'woocommerce_allow_tracking' , 'no' ) && user_can ( $user , 'manage_woocommerce' ) ) {
$admin_user_agents = array_filter ( ( array ) get_option ( 'woocommerce_tracker_ua' , array () ) );
$admin_user_agents [] = wc_get_user_agent ();
update_option ( 'woocommerce_tracker_ua' , array_unique ( $admin_user_agents ) );
}
}
add_action ( 'wp_login' , 'wc_maybe_store_user_agent' , 10 , 2 );
/**
* Update logic triggered on login .
*
* @ since 3.4 . 0
* @ param string $user_login User login .
* @ param object $user User .
*/
function wc_user_logged_in ( $user_login , $user ) {
wc_update_user_last_active ( $user -> ID );
2018-06-22 11:39:21 +00:00
update_user_meta ( $user -> ID , '_woocommerce_load_saved_cart_after_login' , 1 );
2018-04-30 14:38:45 +00:00
}
add_action ( 'wp_login' , 'wc_user_logged_in' , 10 , 2 );
/**
* Update when the user was last active .
*
* @ since 3.4 . 0
*/
function wc_current_user_is_active () {
if ( ! is_user_logged_in () ) {
return ;
}
wc_update_user_last_active ( get_current_user_id () );
}
add_action ( 'wp' , 'wc_current_user_is_active' , 10 );
/**
* Set the user last active timestamp to now .
*
* @ since 3.4 . 0
* @ param int $user_id User ID to mark active .
*/
function wc_update_user_last_active ( $user_id ) {
if ( ! $user_id ) {
return ;
}
2019-12-20 17:23:05 +00:00
update_user_meta ( $user_id , 'wc_last_active' , ( string ) strtotime ( date ( 'Y-m-d' , time () ) ) );
2018-04-30 14:38:45 +00:00
}
2019-03-26 13:56:06 +00:00
/**
* Translate WC roles using the woocommerce textdomain .
*
* @ since 3.7 . 0
* @ param string $translation Translated text .
* @ param string $text Text to translate .
* @ param string $context Context information for the translators .
* @ param string $domain Text domain . Unique identifier for retrieving translated strings .
* @ return string
*/
function wc_translate_user_roles ( $translation , $text , $context , $domain ) {
2019-07-08 21:38:03 +00:00
// translate_user_role() only accepts a second parameter starting in WP 5.2.
if ( version_compare ( get_bloginfo ( 'version' ), '5.2' , '<' ) ) {
return $translation ;
}
2019-03-26 14:08:14 +00:00
if ( 'User role' === $context && 'default' === $domain && in_array ( $text , array ( 'Shop manager' , 'Customer' ), true ) ) {
2019-03-26 13:56:06 +00:00
return translate_user_role ( $text , 'woocommerce' );
}
2019-07-08 21:38:03 +00:00
2019-03-26 13:56:06 +00:00
return $translation ;
}
add_filter ( 'gettext_with_context' , 'wc_translate_user_roles' , 10 , 4 );