สร้างผลิตภัณฑ์ให้ซื้อเพียงครั้งเดียวหรือไม่หากมีการซื้อสินค้าจากหมวดหมู่ผลิตภัณฑ์เฉพาะใน Woocommerce

ใน woocommerce ฉันแค่ใช้ผลิตภัณฑ์ง่ายๆ และฉันมีผลิตภัณฑ์พิเศษ "แพ็คเกจทดลองใช้ฟรี" จากหมวดหมู่ผลิตภัณฑ์ "A" ซึ่งฉันยินดี:

  1. ให้ลูกค้าซื้อ "แพ็คเกจทดลองใช้ฟรี" นี้เพียงครั้งเดียว
  2. หากลูกค้าซื้อผลิตภัณฑ์อื่นจากหมวดหมู่ผลิตภัณฑ์เดียวกัน "A" ก่อน ลูกค้าจะไม่สามารถซื้อ "แพ็คเกจทดลองใช้ฟรี" นี้อีกต่อไป

ซึ่งหมายความว่าลูกค้าสามารถรับ "แพ็คเกจทดลองใช้ฟรี" ได้เฉพาะในกรณีที่เป็นการซื้อผลิตภัณฑ์ประเภท "A" ครั้งแรกเท่านั้น

ดูเหมือนว่ารหัสของฉันจะทำงานไม่ถูกต้อง และทำงานได้เฉพาะจุดที่ 1 เท่านั้น

ปัญหาอีกประการหนึ่งคือหากผู้ใช้สั่งซื้อเสร็จสิ้น ครั้งถัดไปที่ผู้ใช้เปิดตะกร้าสินค้าจะแสดงข้อความแปลก ๆ: "คุณไม่สามารถเลือกผลิตภัณฑ์นี้อีกต่อไป คุณซื้อแพ็คเกจนี้แล้ว" มันเหมือนกับปัญหาแคชของ Woocommerce หรือ บางสิ่งบางอย่าง…

นี่คือรหัสของฉันจนถึงตอนนี้:

function sv_disable_repeat_purchase( $purchasable, $product ) {
    $non_purchasable = 190;

    $product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id;

    if ( $product_id != $non_purchasable ) {
        $purchasable = true;
    }

    if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product_id ) ) {
        $purchasable = false;
    }

    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }

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

ความช่วยเหลือใด ๆ ที่ชื่นชม


person iKamy    schedule 26.03.2019    source แหล่งที่มา


คำตอบ (2)


อัปเดต 2

อ้างอิงจาก "ตรวจสอบว่าลูกค้าได้ซื้อผลิตภัณฑ์เฉพาะในรหัสคำตอบของ WooCommerce" หรือไม่ สิ่งต่อไปนี้จะป้องกันการซื้อจากผลิตภัณฑ์ "แพ็คเกจทดลอง" หากมีการซื้อไปแล้วครั้งหนึ่ง หรือหากมีผลิตภัณฑ์ใด ๆ สำหรับ มีการซื้อหมวดหมู่ผลิตภัณฑ์ที่กำหนด "A" แล้ว

รหัสจริงของคุณล้าสมัยตั้งแต่ Woocommerce 3 และมีข้อผิดพลาดบางประการ...

ฉันใช้ฟังก์ชันตามเงื่อนไขที่กำหนดเองซึ่งได้รับแรงบันดาลใจจาก wc_customer_bought_product() ซอร์สโค้ด< /a> เพื่อตรวจสอบว่าลูกค้าสามารถซื้อผลิตภัณฑ์ "ทดลองใช้ฟรี" ได้หรือไม่ ฟังก์ชันนี้จะตรวจสอบรหัสผลิตภัณฑ์หรือหมวดหมู่ผลิตภัณฑ์ด้วย:

function has_bought_items( $user_id = 0, $product_ids = 0, $categories_slugs = '' ) {
    global $wpdb;
    $customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
    $statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );

    if ( is_array( $product_ids ) ) {
        $product_ids = implode(',', $product_ids);
    }

    if ( $product_ids !=  ( 0 || '' ) ) {
        $query_in = "IN ($product_ids)";
    }
    else {
        $categories = is_array( $categories_slugs ) ? implode("','", $categories_slugs) : $categories_slugs;

        $query_in = "IN (
        SELECT DISTINCT products.ID  FROM {$wpdb->prefix}posts AS products
        INNER JOIN {$wpdb->prefix}term_relationships as term_rel
            ON products.ID = term_rel.object_id
        INNER JOIN {$wpdb->prefix}term_taxonomy as term_tax
            ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id
        INNER JOIN {$wpdb->prefix}terms as terms
            ON term_tax.term_taxonomy_id = terms.term_id
        WHERE products.post_status = 'publish'
        AND term_tax.taxonomy = 'product_cat'
        AND terms.slug IN ('$categories')
        )";
    }

    // Count the number of products
    $product_count_query = $wpdb->get_var( "
        SELECT DISTINCT COUNT(orders.ID)
        FROM {$wpdb->prefix}posts AS orders
        INNER JOIN {$wpdb->prefix}postmeta AS order_meta
            ON orders.ID = order_meta.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items
            ON orders.ID = order_items.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
            ON order_items.order_item_id = order_itemmeta.order_item_id
        WHERE orders.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
        AND order_meta.meta_key = '_customer_user'
        AND order_meta.meta_value = $customer_id
        AND order_itemmeta.meta_key IN ( '_product_id', '_variation_id' )
        AND order_itemmeta.meta_value $query_in
    " );

    // Return a boolean value if count is higher than 0
    return $product_count_query > 0 ? true : false;
}

รหัสที่คุณเยี่ยมชมอีกครั้งโดยใช้ฟังก์ชันตามเงื่อนไขที่กำหนดเองด้านบน:

// add_filter( 'woocommerce_variation_is_purchasable', 'trial_package_purchasable_once', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'trial_package_purchasable_once', 10, 2 );
function trial_package_purchasable_once( $purchasable, $product ) {
    // HERE set the free trial product Id to be purchased only once (can be an array of Ids too)
    $free_trial_id = 50;

    // HERE set the specific product category SLUG (could be an array of slugs too)
    $categories = array('lettering'); // Only slug terms

        if ( $product->get_id() == $free_trial_id ) {
            // Check if any item of the specific product category has already been purchased once
            if ( has_bought_items( get_current_user_id(), '', $categories ) ) {
                return false;
            }
            // Check if the free trial product has already been purchased once
            elseif ( has_bought_items( get_current_user_id(), $free_trial_id ) ) {
                return false;
            }
        }
    }

    return $purchasable;
}

รหัสอยู่ในไฟล์ function.php ของธีมลูกที่ใช้งานอยู่ (หรือธีมที่ใช้งานอยู่) ทดสอบแล้วใช้งานได้


ในการจัดการ ID คำหมวดหมู่ผลิตภัณฑ์แทน Term Slugs ให้ใช้ฟังก์ชันตามเงื่อนไขต่อไปนี้แทน:

// For Product category(ies) Id(s)
function has_bought_items( $user_id = 0, $product_ids = 0, $categories_ids = '' ) {
    global $wpdb;
    $customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
    $statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );

    if ( is_array( $product_ids ) ) {
        $product_ids = implode(',', $product_ids);
    }

    if ( $product_ids !=  ( 0 || '' ) ) {
        $query_in = "IN ($product_ids)";
    }
    else {
        $categories = is_array( $categories_ids ) ? implode(',', $categories_ids) : $categories_ids;

        $query_in = "IN (
        SELECT DISTINCT products.ID  FROM {$wpdb->prefix}posts AS products
        INNER JOIN {$wpdb->prefix}term_relationships as term_rel
            ON products.ID = term_rel.object_id
        INNER JOIN {$wpdb->prefix}term_taxonomy as term_tax
            ON term_rel.term_taxonomy_id = term_tax.term_taxonomy_id
        INNER JOIN {$wpdb->prefix}terms as terms
            ON term_tax.term_taxonomy_id = terms.term_id
        WHERE products.post_status = 'publish'
        AND term_tax.taxonomy = 'product_cat'
        AND terms.term_id IN ($categories)
        )";
    }

    // Count the number of products
    $product_count_query = $wpdb->get_var( "
        SELECT DISTINCT COUNT(orders.ID)
        FROM {$wpdb->prefix}posts AS orders
        INNER JOIN {$wpdb->prefix}postmeta AS order_meta
            ON orders.ID = order_meta.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items
            ON orders.ID = order_items.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
            ON order_items.order_item_id = order_itemmeta.order_item_id
        WHERE orders.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
        AND order_meta.meta_key = '_customer_user'
        AND order_meta.meta_value = $customer_id
        AND order_itemmeta.meta_key IN ( '_product_id', '_variation_id' )
        AND order_itemmeta.meta_value $query_in
    " );

    // Return a boolean value if count is higher than 0
    return $product_count_query > 0 ? true : false;
}

เป็นทางเลือกที่ดีกว่าสำหรับภาษาต่างประเทศที่มีอักขระพิเศษ

person LoicTheAztec    schedule 26.03.2019
comment
มันใช้งานไม่ได้ ตอนแรกฉันซื้อแพ็คเกจ $20 จากนั้นฉันพยายามซื้อแพ็คเกจฟรี และฉันก็ทำได้! - person iKamy; 26.03.2019
comment
จริงๆ แล้วมันทำอะไรได้บ้าง มันช่วยให้คุณซื้ออะไรก็ได้ ทันทีที่คุณซื้อแพ็คเกจฟรี คุณจะไม่สามารถซื้ออย่างอื่นได้อีก! สิ่งที่ฉันต้องการคือสิ่งนี้ เฉพาะในกรณีที่คุณสั่งซื้อแพ็คเกจฟรีเป็นการซื้อเริ่มต้น คุณสามารถซื้อได้ แต่ถ้าคุณทำอย่างนั้น คุณไม่สามารถซื้อได้อีกและถ้าคุณซื้ออะไรนอกเหนือจากแพ็คเกจฟรี คุณจะไม่สามารถเลือกแพ็คเกจฟรีได้อีก - person iKamy; 26.03.2019
comment
เมื่อซื้อแพ็กเกจฟรีไม่เพียงแต่ไม่ให้ซื้อหมวดเดียวกันเท่านั้น แต่ยังไม่ให้ซื้อซ้ำอีกด้วย! ปุ่มเพิ่มลงตะกร้าจะหายไปอย่างสมบูรณ์ในทุกสิ่ง! - person iKamy; 26.03.2019
comment
อืม ดูเหมือนว่าโค้ดจะต้องได้รับผลตอบแทนบางอย่างในแต่ละกรณี - person iKamy; 26.03.2019
comment
มันทำงานได้อย่างสมบูรณ์แบบ ปัญหาเดียวคือทากหมวดหมู่ของฉันไม่ใช่ภาษาอังกฤษ ดังนั้นจึงตรวจไม่พบเลย ... - person iKamy; 27.03.2019
comment
ฉันได้เพิ่มฟังก์ชันตามเงื่อนไขการแทนที่ใหม่ในตอนท้ายซึ่งจะตรวจสอบรหัสคำศัพท์ของหมวดหมู่ ซึ่งควรใช้กับภาษาต่างประเทศทั้งหมดที่มีอักขระพิเศษ - person LoicTheAztec; 27.03.2019
comment
เฮ้เพื่อน เมื่อเร็ว ๆ นี้เราได้เปลี่ยนหมวดหมู่บางหมวดหมู่ของเราเพื่อวัตถุประสงค์ในการทำ SEO มีวิธีใดบ้างที่ฟังก์ชันนี้ has_bought_items( $user_id = 0, $product_ids = 0, $categories_slugs = '' ) มีการเปลี่ยนแปลงในลักษณะที่ทำงานกับ CATEGORY NAME เช่น has_term () การทำงาน ?? เพราะทากของเราไม่ใช่ภาษาอังกฤษและใช้ได้เฉพาะกับทากภาษาอังกฤษเท่านั้น - person iKamy; 23.05.2019
comment
ในฟังก์ชันแรก ให้แทนที่ AND terms.slug IN ($categories) ด้วย AND terms.name IN ($categories) … หรือในฟังก์ชันสุดท้าย AND terms.term_id IN ($categories) ด้วย AND terms.name IN ($categories) - person LoicTheAztec; 23.05.2019

person    schedule
comment
รหัสผลิตภัณฑ์ไปไหน ?! - person iKamy; 26.03.2019