如何在 WooCommerce 结帐期间向之前购买订单状态为“正在处理”的产品的客户显示自定义消息

问题描述 投票:0回答:3

我想在结帐页面上显示一条消息,通知客户他们过去购买过此产品(他们即将购买的产品),但此消息仅应在满足这些条件时运行。

  1. 客户必须登录
  2. 用户角色是管理员或客户
  3. 之前购买的产品仍应具有“正在处理”的订单状态。

到目前为止,我已经能够使前 2 个条件正常工作:

function user_logged_in_product_already_bought() {

    global $woocommerce;

    if ( ! is_user_logged_in() ) return;
            

    $items = $woocommerce->cart->get_cart();

    $has_bought = false;

    foreach($items as $item => $values) { 
        if ( wc_customer_bought_product( '', get_current_user_id(), $values['data']->get_id() ) ) {
            $has_bought = true;
            break;
        }
    } 


    
    $user = wp_get_current_user();
$allowed_roles = array( 'administrator', 'customer' );
if ( array_intersect( $allowed_roles, $user->roles ) ) {
    
    if( $has_bought ){
        wc_print_notice( "You purchased this in the past. Buy again?", 'success' );
    }
}
        


}
add_action( 'woocommerce_before_checkout_form', 'user_logged_in_product_already_bought' );

注意:我使用

foreach
的原因是用户一次只能购买一件产品(购物车中不能有超过一个预约产品)

但我不知道如何处理第三个条件。有什么建议吗?

php wordpress woocommerce checkout orders
3个回答
2
投票

您的前两个步骤确实有效,对于第三步,您将必须使用仅检查订单状态“正在处理”的自定义函数。

这个自定义功能的优点是,与遍历所有现有订单相比,它更快更轻。

所以你得到:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    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 = '_customer_user'
        AND pm.meta_value = '$user_id'
        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_before_checkout_form() {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Initialize
            $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'];
            }
            
            // Call function, and if true
            if ( has_bought_items( $user->ID, $product_ids ) ) {
                // Notice
                wc_print_notice( __( 'You purchased this in the past. Buy again?', 'woocommerce' ), 'success' );
            }
        }
    }
}
add_action( 'woocommerce_before_checkout_form', 'action_woocommerce_before_checkout_form' );

结果:一般消息


可选:您可以使用 woocommerce_checkout_cart_item_quantity

 挂钩
,而不是显示一般消息,而是针对每个产品单独显示此消息

所以你会得到:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    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 = '_customer_user'
        AND pm.meta_value = '$user_id'
        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 filter_woocommerce_checkout_cart_item_quantity( $item_qty, $cart_item, $cart_item_key ) {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Initialize
    $message = '';
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // Get product id
        $product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
        
        // Call function, and if true
        if ( has_bought_items( $user->ID, $product_id ) ) {
            $message = '<p>' . __( 'You purchased this in the past. Buy again?', 'woocommerce' ) . '</p>';
        }
    }

    // Return
    return $item_qty . $message;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'filter_woocommerce_checkout_cart_item_quantity', 10, 3 );

结果:按产品单独显示


注意:

has_bought_items()
功能基于检查用户是否在WooCommerce中购买了特定产品答案代码

相关: 如果用户之前购买过产品,则在 WooCommerce 购物车页面上的产品名称下方显示消息


1
投票

根据这篇文章

您可以按如下方式实现这样的登录:

$customer_orders = get_posts( array(
    'numberposts' => -1,
    'meta_key'    => '_customer_user',
    'meta_value'  =>  $user->ID,
    'post_type'   => wc_get_order_types(),
    'post_status' => array_keys( wc_get_is_paid_statuses() ),
) );

// LOOP THROUGH ORDERS AND GET PRODUCT IDS
if ( ! $customer_orders ) return;

$product_ids = array();
foreach($items as $item) { 
   foreach ( $customer_orders as $customer_order ) {
       $order = wc_get_order( $customer_order->ID );
       $orderItems = $order->get_items();
       foreach ( $orderItems as $orderItem ) {
          if ($orderItem->get_product_id() == $item->get_product_id() )
             $has_bought = true;
             break;
       }
   }
} 

1
投票

关于第三点,您可以使用

wc_get_orders()

轻松获得客户处理订单
$user              = wp_get_current_user();
$processing_orders = wc_get_orders(
    array(
       'customer' => $user->ID,
       'status'   => 'wc-processing',
    )
);

您可以查看加工订单是否为空。 您可以循环查看订单产品以获取每个产品的详细信息。

foreach ( $processing_orders as $p_order ) {
   $order_products = $p_order->get_items();
   foreach ( $order_products as $product_item ) {
      $product_id = $product_item->get_id();
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.