检查用户是否在WooCommerce中购买了特定产品

问题描述 投票:6回答:4

我需要检查客户是否早些时候在WooCommerce中购买了特定产品。

情况是这样:除非客户较早购买了产品“ a”或“ b”,否则客户将无法购买产品“ c”,“ d”,“ e”。

如果客户较早购买了产品“ a”或“ b”,则激活产品“ c”,“ d”和“ e”的购买按钮,并允许他们购买。

[如果他们以前没有购买过“ a”或“ b”,将不允许他们购买“ c”,“ d”,“ e”,并且取消了购买按钮。

我该如何实现?

谢谢。

php wordpress woocommerce product orders
4个回答
9
投票

处理多个产品ID的更简化的改进代码版本in HERE

更新 (Woocommerce 3+的兼容性)

是的,如果当前客户已经购买了特定定义的产品ID,则可以编写一个条件函数返回“ true”。 此代码位于您的活动子主题或主题的function.php文件中

这里是条件函数:

function has_bought_items() {
    $bought = false;

    // Set HERE ine the array your specific target product IDs
    $prod_arr = array( '21', '67' );

    // Get all customer orders
    $customer_orders = get_posts( array(
        'numberposts' => -1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => 'shop_order', // WC orders post type
        'post_status' => 'wc-completed' // Only orders with status "completed"
    ) );
    foreach ( $customer_orders as $customer_order ) {
        // Updated compatibility with WooCommerce 3+
        $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
        $order = wc_get_order( $customer_order );

        // Iterating through each current customer products bought in the order
        foreach ($order->get_items() as $item) {
            // WC 3+ compatibility
            if ( version_compare( WC_VERSION, '3.0', '<' ) ) 
                $product_id = $item['product_id'];
            else
                $product_id = $item->get_product_id();

            // Your condition related to your 2 specific products Ids
            if ( in_array( $product_id, $prod_arr ) ) 
                $bought = true;
        }
    }
    // return "true" if one the specifics products have been bought before by customer
    return $bought;
}

此代码已经过测试并且可以正常工作。


用法:例如,您可以在以前复制到活动子主题或主题的某些WooCommerce templates中使用它:

  • 与[add-to-cart按钮相关的商店页面的模板为loop/add-to-cart.php
  • loop/add-to-cart.php
  • 按钮相关的产品页面的模板位于add-to-cart中,具体取决于您的产品类型。
这里是您可以在这些模板中使用的示例

(上方):

single-product/add-to-cart folder
这里是

完整的应用示例

[商店页面上的single-product/add-to-cart按钮模板:// Replace the numbers by your special restricted products IDs $restricted_products = array( '20', '32', '75' ); // compatibility with WC +3 $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id; // customer has NOT already bought a specific product for this restricted products if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) { // Displaying an INACTIVE add-to-cart button (With a custom text, style and without the link). // (AND optionally) an explicit message for example. // ALL OTHER PRODUCTS OR RESTRICTED PRODUCTS IF COSTUMER HAS ALREADY BOUGHT SPECIAL PRODUCTS } else { // place for normal Add-To-Cart button code here }

您将使用活动子主题或主题的add-to-cart

文件中的<?php /** * Loop Add to Cart * * This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * @see https://docs.woocommerce.com/document/template-structure/ * @author WooThemes * @package WooCommerce/Templates * @version 2.5.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; } global $product; // Replace the numbers by your special restricted products IDs $restricted_products = array( '37', '53', '70' ); // compatibility with WC +3 $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id; if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) { echo '<a class="button greyed_button">' . __("Disabled", "your_theme_slug") . '</a>'; echo '<br><span class="greyed_button-message">' . __("Your message goes here…", "your_theme_slug") . '</span>'; } else { echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>', esc_url( $product->add_to_cart_url() ), esc_attr( isset( $quantity ) ? $quantity : 1 ), esc_attr( $product_id ), esc_attr( $product->get_sku() ), esc_attr( isset( $class ) ? $class : 'button' ), esc_html( $product->add_to_cart_text() ) ), $product ); } 类来设置非活动按钮的样式。与greyed_button类的消息相同。

5
投票

[2020更新: 现在通过帐单电子邮件处理来宾用户。

新版本紧凑,轻便,更快并且与woocommerce的所有版本兼容((从2.4及更高版本开始)

这是一个新的增强的轻量级条件函数,部分基于内置的woocommerce函数style.css源代码。

有2个可选参数:

    greyed_button-message将允许您:
    • 指定已定义的用户ID
    • ((当当前登录的用户不使用时)
或计费电子邮件
  • 对于来宾用户;
  • wc_customer_bought_product
  • ((array)
  • 将允许指定一个或多个要检查的产品ID] 这里是代码:

    wc_customer_bought_product

    代码在您的活动子主题(或主题)的function.php文件中,或者在任何插件文件中。

    此代码已经在WooCommerce 3+上进行了测试,并且可以正常工作(它也可以在以前的版本上工作。)>


    用法示例:

    示例1

    (已登录客户):检测当前用户是否购买了已定义的产品之一。[[(产品ID必须是数组)
    $user_var
    示例2

    (对于已定义的[[用户ID]]检测已定义的用户是否购买了其中一个已定义的产品((需要在数组中设置产品ID)] >>

    $product_ids如果未定义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 = $value == 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; } 并且当前用户未登录,则此函数将返回// Define the targeted Products IDs $product_ids = array( 38, 41, 85, 95 ); if( has_bought_items( '', $product_ids ) ) echo "<p>You have already purchased one of this products</p>"; else echo "<p>You have not yet purchased one of this products</p>";

    示例3

    (对于[guest用户]用户)检测

    guest用户

    是否已从其计费电子邮件购买了其中一种定义的产品// Define the user ID $user_id = 85; // Define the targeted Products IDs $product_ids = array( 38, 41, 85, 95 ); if( has_bought_items( $user_id, $product_ids ) ) echo "<p>This user have already purchased one of this products</p>"; else echo "<p>This user have not yet purchased one of this products</p>"; 如果未定义$user_id并且当前用户未登录,则此函数将返回false示例4
    (已登录客户)
    :检测

    当前用户

    是否已经购买了商品
    // Define guest Billing email (string) $user_email = '[email protected]'; // Define the targeted Products IDs $product_ids = array( 38, 41, 85, 95 ); if( has_bought_items( $user_email, $product_ids ) ) echo "<p>This user have already purchased one of this products</p>"; else echo "<p>This user have not yet purchased one of this products</p>";

    示例5 (定义用户ID

    )-检测所定义的用户是否已经购物
    $user_id

    现在,如果用户ID等于0并且当前用户未登录,则此函数将返回false(如果未为访客用户定义帐单电子邮件)

    在这种情况下,也可以使用内置的woocommerce功能if( has_bought_items() ) echo '<p>You have already made a purchase</p>'; else echo '<p>Welcome, for your first purchase you will get a discount of 10%</p>';

    请参见功能用法// Define the user ID $user_id = 85; if( has_bought_items( $user_id ) ) echo '<p>customer have already made a purchase</p>'; else echo '<p>Customer with 0 purshases</p>';

    4
    投票
    我会这样做;

    这不会进行任何woocommerce模板修改,而仅使用过滤器false


    2
    投票

    检查客户是否已经带来了当前产品ID,在2.6 +版本中,woocommerce实现了功能wc_customer_bought_product以检查客户是否已经带来了产品,我以前从未使用过它,但是基于您的文档可以创建一个如下所示的函数来检查产品ID的数组(如果其中一个已经被带入);

    here

    以下是我用来检查客户是否已经带入特定产品ID的先前方法,因此尽管我创建的功能不是ID数组,您仍可以使用这些功能中的任何一个>

      woocommerce_is_purchasable
    1. 现在,我们可以检查产品ID是否已带,我们可以简单地在wc_customer_bought_product上添加一个过滤器以创建我们自己的条件,下面的此函数只是您要实现的目标的简单示例,

    仅更改了function cmk_check_product_brought( $ids=array() ) {
        if ( ! $ids ) return false;
        foreach ( $ids as $product => $id ) {
            if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $id ) ) {
                return true;
            }
        }
    }
    function cmk_product_ordered( $id ) {
        // Get All order of current user
        $orders = get_posts( array(
            'numberposts' => -1,
            'meta_key'    => '_customer_user',
            'meta_value'  => get_current_user_id(),
            'post_type'   => wc_get_order_types( 'view-orders' ),
            'post_status' => array_keys( wc_get_order_statuses() )
        ) );
    
        if ( !$orders ) return false; // return if no order found
    
        $all_ordered_product = array(); // store all products ordered by ID in an array
    
        foreach ( $orders as $order => $data ) { // Loop through each order
            $order_data = new WC_Order( $data->ID ); // create new object for each order
            foreach ( $order_data->get_items() as $key => $item ) {  // loop through each order item
                // store in array with product ID as key and order date a value
                $all_ordered_product[ $item['product_id'] ] = $data->post_date; 
            }
        }
        // check if defined ID is found in array
        if ( isset( $all_ordered_product[ $id ] ) ) return true;
        else return false;
    }
    值。 

    woocommerce_is_purchasable

    并且应该将产品设置为不可购买(添加到购物车按钮将自动隐藏)。现在,如果您要为非购买产品添加消息,则可以简单地使用$required_purchased的相同条件,添加消息并将其简单地挂在$conditional_purchase或要显示的任何位置。        
    © www.soinside.com 2019 - 2024. All rights reserved.