如何通过以访客身份将产品添加到购物车并在结账时登录来避免在 WooCommerce 中再次购买相同的产品 [英] How to avoid buying the same product again in WooCommerce by adding products to the cart as a guest and logging in during checkout

查看:24
本文介绍了如何通过以访客身份将产品添加到购物车并在结账时登录来避免在 WooCommerce 中再次购买相同的产品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 WooCommerce + Tutor LMS Pro.WooCommerce shop_page 和产品页面被隐藏,WP 搜索结果相同(使用 functions.php 中的片段).用户不能购买多个相同的产品(课程)——这在 WooCommerce 中很容易设置.购买产品的唯一预期方法是通过 Tutor 课程页面.

I have WooCommerce + Tutor LMS Pro. WooCommerce shop_page and product pages are hidden, same for the WP search results (using a snippet in functions.php). Users can’t purchase more than one of the same product (course) – this is easily set up in WooCommerce. The only intended method of purchasing a product is through a Tutor course page.

在测试期间,我发现了一种方法客户仍然可以购买过去已经购买的产品(这对于终身访问课程没有意义)——只需添加以访客身份将产品放入购物车,然后登录.

During the testing I found a way how customers still can buy products already purchased in the past (which doesn’t make sense for a lifetime access to a course) – simply by adding products into the cart as a visitor and logging in after.

我不想强迫用户创建新帐户将课程添加到购物车,因为购买过程将不再是无缝和直接的.

I don't want to force users creating new account to add courses to the cart because the buying process won't be seamless and straightforward anymore.

我尝试了以下解决方案:

I tried these solutions:

解决方案 A (/child-theme/functions.php)

Solution A (/child-theme/functions.php)

add_filter( 'woocommerce_add_cart_item_data', 'woo_check_not_bought_before' );

function woo_check_not_bought_before( $cart_item_data ) {

    global $woocommerce;

    // Some MYSQL to check if product was bought before

    if ($bought_before == 'true') {       
         $woocommerce->cart->empty_cart();
    }

    // Echo some text to explain why you can only buy the product once

    return $cart_item_data;
}

解决方案 B (/child-theme/loop/add-to-cart.php)

Solution B (/child-theme/loop/add-to-cart.php)

  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

  global $product;
  $current_user = wp_get_current_user();

 if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id)) {
    echo 'Purchased';
    }
   else
   {
   echo apply_filters( 'woocommerce_loop_add_to_cart_link',
  sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-product_sku="%s" class="button          %s product_type_%s">%s</a>',
    esc_url( $product->add_to_cart_url() ),
    esc_attr( $product->id ),
    esc_attr( $product->get_sku() ),
    $product->is_purchasable() ? 'add_to_cart_button' : '',
    esc_attr( $product->product_type ),
    esc_html( $product->add_to_cart_text() )
),
$product );
  } 

这些都不适用于所描述的问题.他们限制仅从 woo 产品页面将产品添加到购物车.以访客身份通过 Tutor 课程页面添加产品,但仍然可以登录和购买.

None of those work for the described issue. They restrict adding products to the cart from the woo product pages only. Adding product via Tutor course page as a visitor, logging in and buying after is still possible though.

解决方案C.phpsme)/(/child-thea)/

/**
 * Disables repeat purchase for products / variations
 * 
 * @param bool $purchasable true if product can be purchased
 * @param \WC_Product $product the WooCommerce product
 * @return bool $purchasable the updated is_purchasable check
 */
function sv_disable_repeat_purchase( $purchasable, $product ) {

    // Don't run on parents of variations,
    // function will already check variations separately
    if ( $product->is_type( 'variable' ) ) {
        return $purchasable;
    }

    // Get the ID for the current product (passed in)
    $product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id; 

    // return false if the customer has bought the product / variation
    if ( wc_customer_bought_product( get_current_user()->user_email, get_current_user_id(), $product_id ) ) {
        $purchasable = false;
    }

    // Double-check for variations: if parent is not purchasable, then variation is not
    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }

    return $purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'sv_disable_repeat_purchase', 10, 2 );


/**
 * Shows a "purchase disabled" message to the customer
 */
function sv_purchase_disabled_message() {

    // Get the current product to see if it has been purchased
    global $product;

    if ( $product->is_type( 'variable' ) ) {

        foreach ( $product->get_children() as $variation_id ) {
            // Render the purchase restricted message if it has been purchased
            if ( wc_customer_bought_product( get_current_user()->user_email, get_current_user_id(), $variation_id ) ) {
                sv_render_variation_non_purchasable_message( $product, $variation_id );
            }
        }

    } else {
        if ( wc_customer_bought_product( get_current_user()->user_email, get_current_user_id(), $product->id ) ) {
            echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message">You\'ve already purchased this product! It can only be purchased once.</div></div>';
        }
    }
}
add_action( 'woocommerce_single_product_summary', 'sv_purchase_disabled_message', 31 );


/**
 * Generates a "purchase disabled" message to the customer for specific variations
 * 
 * @param \WC_Product $product the WooCommerce product
 * @param int $no_repeats_id the id of the non-purchasable product
 */
function sv_render_variation_non_purchasable_message( $product, $no_repeats_id ) {

    // Double-check we're looking at a variable product
    if ( $product->is_type( 'variable' ) && $product->has_child() ) {
        $variation_purchasable = true;
        foreach ( $product->get_available_variations() as $variation ) {
            // only show this message for non-purchasable variations matching our ID
            if ( $no_repeats_id === $variation['variation_id'] ) {
                $variation_purchasable = false; 
                echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message js-variation-' . sanitize_html_class( $variation['variation_id'] ) . '">You\'ve already purchased this product! It can only be purchased once.</div></div>';
            }
        }
    }

    if ( ! $variation_purchasable ) {
        wc_enqueue_js("
            jQuery('.variations_form')
                .on( 'woocommerce_variation_select_change', function( event ) {
                    jQuery('.wc-nonpurchasable-message').hide();
                })
                .on( 'found_variation', function( event, variation ) {
                    jQuery('.wc-nonpurchasable-message').hide();
                    if ( ! variation.is_purchasable ) {
                        jQuery( '.wc-nonpurchasable-message.js-variation-' + variation.variation_id ).show();
                    }
                })
            .find( '.variations select' ).change();
        ");
    }
} 

这似乎是最先进的,通过客户 ID 和电子邮件检查过去的购买.使用这个,即使我以没有任何购买历史记录的用户身份登录,我也会收到错误"消息.我该如何解决这个问题?

This one seems to be most advanced, checking for the past purchase by customer ID and email. Using this one I get the 'error' message even if I log in as a user without any purchase history. How can I fix this to work?

解决方案 D

也许最简单的方法是每次登录后自动清除购物车.不确定它是否会导致其他问题(例如,无法为没有帐户的新人购买课程).我也没有找到关于这个的任何片段.

Maybe the simpliest one would be clearing the cart automatically after every login. Not sure if it won’t cause another issues though (e.g. being impossible to purchase a course for newcomers without an account). I also didn't find any snippets on this one.

推荐答案

为了避免一个用户在 WooCommerce 中重复购买相同的产品,首先你可以使用 woocommerce_add_to_cart_validation 过滤钩>

To avoid re-buying the same product by one user in WooCommerce, first of all you can use the woocommerce_add_to_cart_validation filter hook

function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
    // Retrieve the current user object
    $current_user = wp_get_current_user();
    
    // Check for variantions, if you don't want this, delete this code line
    $product_id = $variation_id > 0 ? $variation_id : $product_id;
    
    // Checks if a user (by email or ID or both) has bought an item
    if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id ) ) {
        // Display an error message
        wc_add_notice( __( 'My custom error message', 'woocommerce' ), 'error' );
        
        $passed = false;
    }

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );

但是,这可以通过将产品作为访问者添加到购物车然后登录来规避.为避免这种情况,请使用 woocommerce_check_cart_items 钩子,这将阻止结帐.

However, this can be circumvented by adding products as a visitor to the cart and then logging in. To avoid this use the woocommerce_check_cart_items hook, which will prevent checkout.

function action_woocommerce_check_cart_items() {
    // Retrieve the current user object
    $current_user = wp_get_current_user();
    
    // Initialize
    $flag = false;
    
    // Loop through cart items
    foreach( WC()->cart->get_cart() as $cart_item ) {
        // Check for variantions
        $product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
        
        // Checks if a user (by email or ID or both) has bought an item
        if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id ) ) {
            // Flag becomes true
            $flag = true;
            
            // Break loop
            break;
        }
    }
    
    // True
    if ( $flag ) {
        // Clear all other notices          
        wc_clear_notices();

        // Avoid checkout display an error notice
        wc_add_notice( __( 'My custom error message', 'woocommerce' ), 'error' );
        
        // Optional: remove proceed to checkout button
        remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );   
    }
}   
add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );

这篇关于如何通过以访客身份将产品添加到购物车并在结账时登录来避免在 WooCommerce 中再次购买相同的产品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆