为了账号安全,请及时绑定邮箱和手机立即绑定

如果之前在 WooCommerce 上购买过产品,请避免访客购买

如果之前在 WooCommerce 上购买过产品,请避免访客购买

PHP
侃侃无极 2023-08-26 17:30:01
由于各种原因,网上商店需要允许访客订单,但如果电子邮件已注册,则将数据保存到现有用户。但是,一个产品(父变量产品)不应该购买两次。在这种情况下,客户应该返回结帐页面并收到该产品已购买的通知。到目前为止,我有以下代码(不完整):add_action('woocommerce_checkout_process', function () {    if (!is_user_logged_in() && $_POST['billing_email'] && $_POST['createaccount'] == 1) {        $user = get_user_by('email', $_POST['billing_email']);        $order = wc_get_order( $order_id );        $items = $order->get_items();        foreach ( $items as $item ) {    $product_id = $item->get_product_id();        if (!empty($user)){            if (wc_customer_bought_product($user->user_email,$user->ID,$product_id))            return false;        wp_set_current_user($user->ID);        }        if (!empty($user)) {        if (wc_customer_bought_product($user->user_email,$user->ID,$product_id))             return true;        exit;    }    else{        ///guest, continue    }}}});但这只给出了内部服务器错误。任何人?
查看完整描述

1 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

首先,您可以使用wc_customer_bought_product()中的以下增强条件函数(基于与 相同的源代码 ,而不是使用。此功能将处理您的可变产品情况。 wc_customer_bought_product()

// Conditional function( stackOverFlow answer: https://stackoverflow.com/a/46217461/3730754 )

function has_bought_items( $user_var = 0,  $product_ids = 0 ) {

    global $wpdb;

    

    // Based on user ID (registered users)

    if ( is_numeric( $user_var) ) { 

        $meta_key     = '_customer_user';

        $meta_value   = $user_var == 0 ? (int) get_current_user_id() : (int) $user_var;

    } 

    // Based on billing email (Guest users)

    else { 

        $meta_key     = '_billing_email';

        $meta_value   = sanitize_email( $user_var );

    }

    

    $paid_statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );

    $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-" . implode( "','wc-", $paid_statuses ) . "' )

        AND pm.meta_key = '$meta_key'

        AND pm.meta_value = '$meta_value'

        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;

}

您还无法获取订单或订单商品...相反,您将检查购物车商品。


然后这是您重新访问的代码,用于按照要求处理所有类型的客户和可变产品:


add_action('woocommerce_checkout_process', 'wc_action_checkout_process' );

function wc_action_checkout_process() {

    $user_id = get_current_user_id();


    // 1. - For logged in users

    if( $user_id > 0 ) {

        $user_var = $user_id;

    }

    // 2. - For others

    else {

        if ( isset($_POST['billing_email']) && ! empty($_POST['billing_email']) ) {

            $email = sanitize_email( $_POST['billing_email'] );

            $user  = get_user_by( 'email', $email );


            // 2.a - When a user exist for the billing email return an error notice

            if ( is_a($user, 'WP_User') ) {

                wc_add_notice( sprintf( __('The email "%s" is already registered for "%s" user name. Please login.'), $email, $user->user_login ), 'error' );

            }

            // 2.b - User doesn't exits (real "guest")

            else {

                $user_var = $email;

            }

        }

    }


    // Loop through cart items to check products

    foreach ( WC()->cart->get_cart() as $cart_item ) {

        if ( has_bought_items( $user_var,  $cart_item['product_id'] ) ) {

            wc_add_notice( sprintf( __('You have already purchased "%s" product before. You can only purchase it once.'), $cart_item['data']->get_name() ), 'error' );

        }

    }

}

代码位于活动子主题(或活动主题)的functions.php 文件中。经过测试并有效。




查看完整回答
反对 回复 2023-08-26
  • 1 回答
  • 0 关注
  • 84 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信