Your code attempt contains multiple mistakes, so some remarks:
- The
woocommerce_new_order
will be executed on newly created order event, and is therefore 'too late' for your question
- Use the
woocommerce_check_cart_items
action hook instead
$order->billing_phone
is since WooCommerce 3.0 replaced with $order->get_billing_phone()
but does not apply in this case. This is because the $order
object is only known after the order is placed, we will use WC()->session->get( 'customer' )
instead
- You mention that the username is based on a phone number, but your question is about "only for guests". Guests do not have a username
- In your code attempt you only check for 1 product ID (916), while order(s) usually consist of several different products
- The
wc_customer_bought_product()
function only applies to users with an account. So we will have to use/write of a custom function, which is based on the existing wc_customer_bought_product()
function
- Use
wp_safe_redirect()
vs wp_redirect()
So you get:
function has_bought_items_by_phone_number( $phone_number, $product_ids ) {
global $wpdb;
$product_ids = is_array( $product_ids ) ? implode( ',', $product_ids ) : $product_ids;
$line_meta_value = $product_ids != 0 ? 'AND woim.meta_value IN (' . $product_ids . ')' : 'AND woim.meta_value != 0';
// Count the number of products
$count = $wpdb->get_var( "
SELECT COUNT(p.ID) FROM {$wpdb->prefix}posts AS p
INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
WHERE p.post_status IN ( 'wc-processing' )
AND pm.meta_key = '_billing_phone'
AND pm.meta_value = '$phone_number'
AND woim.meta_key IN ( '_product_id', '_variation_id' ) $line_meta_value
" );
// Return true if count is higher than 0 (or false)
return $count > 0 ? true : false;
}
function action_woocommerce_check_cart_items() {
// Only for guests
if ( is_user_logged_in() ) return;
// Get session
$customer = WC()->session->get( 'customer' );
// NOT empty phone field
if ( ! empty( $customer['phone'] ) ) {
// Sanatize
$phone_number = wc_sanitize_phone_number( $customer['phone'] );
// WC Cart NOT null
if ( ! is_null( WC()->cart ) ) {
// Initialize (do not change)
$product_ids = array();
// Loop through cart contents
foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
// Get product ID and push to array
$product_ids[] = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
}
// NOT empty
if ( ! empty ( $product_ids ) ) {
// Call function, and if true
if ( has_bought_items_by_phone_number( $phone_number, $product_ids ) ) {
// Performs a safe redirect
wp_safe_redirect( 'https://yoursite.com/custom-url-1' );
exit;
}
}
}
}
}
add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10 );
Note 1) to apply this action (the redirect) only after they click place order button on checkout page would require using the woocommerce_checkout_process
hook opposite the woocommerce_check_cart_items
hook.
Because with my current answer, this will only happen in certain cases, if the phone number is not (yet) known.
However, the redirect would then display an error message and not be executed. So if you still want this, you should replace the redirect by displaying a message, which then contains the link to the page
Note 2) my answer will be applied to ALL products, to only apply this to specific products:
Replace:
if ( ! is_null( WC()->cart ) ) {
// Initialize (do not change)
$product_ids = array();
// Loop through cart contents
foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
// Get product ID and push to array
$product_ids[] = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
}
With:
// WC Cart NOT null
if ( ! is_null( WC()->cart ) ) {
// Specific product IDs
$specific_product_ids = array( 30, 823, 53, 57 );
// Initialize (do not change)
$product_ids = array();
// Loop through cart contents
foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
// Get product ID
$product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
// Checks if a value exists in an array
if ( in_array( $product_id, $specific_product_ids ) ) {
// Push to array
$product_ids[] = $product_id;
}
}
Note 3) the has_bought_items_by_phone_number()
function is based on Check if a user has purchased specific products in WooCommerce answer code