避免在WooCommerce购物车中多次显示自定义通知

时间:2019-05-24 01:58:53

标签: php wordpress woocommerce cart notice

我正在为一家非营利组织工作,人们可以从他们那里订购信息小册子。小册子可以单独订购,也可以打包订购。该产品包已设置为ID为 1076 的一种产品。

当客户订购包装时,他们只能自己订购包装。

我将代码清除购物车中的所有其他产品,并在将包装添加到购物车时仅留下包装。然后,当包装在购物车中时,它将禁用所有产品的“添加到购物车”按钮。最后,当人们单击灰色的“添加到购物车”按钮时,它会更改弹出错误消息。

如何确保wc_print_notice()仅在购物车页面中输出一次通知?

这是我到目前为止的代码(它是从多个来源拼凑而成的,因此效率可能很低)

// Remove conditionally cart items based on a specific product (item)
    function remove_cart_items_conditionally( $cart ) {
    // HERE define your specific product ID
    $specific_product_id = 1076; 

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $cart_items  = $cart->get_cart(); // Cart items array
    $items_count = count($cart_items); // Different cart items count

    // Continue if cart has at least 2 different cart items
    if ( $items_count < 2 )
        return;

    $last_item    = end($cart_items); // Last cart item data array
    $is_last_item = false; // Initializing

    // Check if the specific product is the last added item
    if ( in_array($specific_product_id, array( $last_item['product_id'], $last_item['variation_id'] ) ) ) {
        $is_last_item = true;
    }

    // Loop through cart items
    foreach ( $cart_items as $cart_item_key => $cart_item ) {
        // Remove all others cart items when specific product ID is the last added to cart
        if ( ! in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) && $is_last_item ) {
            $cart->remove_cart_item( $cart_item_key );
            wc_print_notice( 'Individual resources have been removed as the full pack already contains all the resources', 'notice' );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'remove_cart_items_conditionally', 10, 1 );

// Disable the add to cart button if specified product is in the cart
function disable_add_to_cart_if_product_is_in_cart ( $is_purchasable, $product ){

    $specific_product_id = 1076;

    // Loop through cart items checking if the product is already in cart
    foreach ( WC()->cart->get_cart() as $cart_item ){
        if ( in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
            return false;

        }
    }
    return $is_purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'disable_add_to_cart_if_product_is_in_cart', 10, 2 );

// Change disabled add to cart button popup message to something relevant
function customizing_product_variation_message( $translated_text, $untranslated_text, $domain )
{
    if ( in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
        if ($untranslated_text == 'Sorry, this product is unavailable. Please choose a different combination.') {
        $translated_text = __( 'The full pack in the cart already contains this resource', $domain );
        }
    }
    return $translated_text;
}
add_filter( 'gettext', 'customizing_product_variation_message', 10, 3 );

我的代码是通过以下答案线程制作的:

Remove conditionally Woocommerce cart items based on a specific product

Disable Woocommerce add to cart button if the product is already in cart

Customizing product variations message on single product pages

2 个答案:

答案 0 :(得分:0)

您正在循环中使用wc_print_notice,因此它将显示与循环计数一样多的时间。为了克服这个问题,请尝试使用以下代码。

替换这段代码。此代码将默认禁用通知调用。只有在执行循环并删除购物车项目时,它才会启用通知呼叫。

// Loop through cart items
    foreach ( $cart_items as $cart_item_key => $cart_item ) {
        // Remove all others cart items when specific product ID is the last added to cart
        if ( ! in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) && $is_last_item ) {
            $cart->remove_cart_item( $cart_item_key );
            wc_print_notice( 'Individual resources have been removed as the full pack already contains all the resources', 'notice' );
        }
    }

通过这段代码,让我知道结果。

// Loop through cart items
    $enable_notice = false;
    foreach ( $cart_items as $cart_item_key => $cart_item ) {
        // Remove all others cart items when specific product ID is the last added to cart
        if ( ! in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) && $is_last_item ) {
            $cart->remove_cart_item( $cart_item_key );
            $enable_notice = true;
        }
    }
    if($enable_notice){
        wc_print_notice( 'Individual resources have been removed as the full pack already contains all the resources', 'notice' );    
    }

答案 1 :(得分:0)

为避免在woocommerce_before_calculate_totals钩子上出现重复的提示,请尝试以下已更改的钩子函数:

// Remove conditionally cart items based on a specific product (item)
add_action( 'woocommerce_before_calculate_totals', 'remove_cart_items_conditionally', 10, 1 );
function remove_cart_items_conditionally( $cart ) {
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_user_logged_in() )
        return;

    // Avoid hook to be triggered twice
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return; 

    $specific_product_id = 1076; // <=== HERE define your specific product ID

    $cart_items  = $cart->get_cart(); // Cart items array
    $items_count = count($cart_items); // Different cart items count

    // Continue if cart has at least 2 different cart items
    if ( $items_count < 2 )
        return;

    $last_item    = end($cart_items); // Last cart item data array
    $is_last_item = false; // Initializing

    // Check if the specific product is the last added item
    if ( in_array($specific_product_id, array( $last_item['product_id'], $last_item['variation_id'] ) ) ) {
        $is_last_item = true;
    }

    // Loop through cart items
    foreach ( $cart_items as $cart_item_key => $cart_item ) {
        // Remove all others cart items when specific product ID is the last added to cart
        if ( ! in_array($specific_product_id, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) && $is_last_item ) {
            $cart->remove_cart_item( $cart_item_key );
            $message_notice = __('Individual resources have been removed as the full pack already contains all the resources');
        }
    }

    // Conditionally display a custom notice
    if( isset( $message_notice ) && ! empty( $message_notice ) ) {
        wc_clear_notices(); // Remove previous notices
        if( is_cart() ) {
            wc_print_notice( $message_notice, 'notice' );
        } else {
            wc_add_notice( $message_notice, 'notice' );
        }
    }
}

我已经测试了具有店面主题的代码,并且可以正常工作……购物车页面(不再有迷你购物车中的内容)中不再存在重复的通知。现在,根据您的主题和woocommerce定制,这可能会有不同的行为。