如果未选择 XX 国家并且结帐页面上的购物车包含 WooCommerce 中的特定产品,则禁用下订单按钮并显示消息

Disable place order button and display message if XX country NOT selected and cart on checkout page contains particular product in WooCommerce

有人知道如何处理这种情况吗? 我想在选择非XX country并包含特定产品(不可交付给国外)时在结帐页面中显示通知消息,并禁用位置订单按钮。

我可以使用 Jquery,但无法访问“下订单”按钮,因为每次我更改帐单地址时都会通过 AJAX 刷​​新其表单。这是我到目前为止所取得的成就:

add_action( 'woocommerce_checkout_before_customer_details', 'display_shipping_notice' );
function display_shipping_notice() {
    echo '<div class="shipping-notice woocommerce-error" role="alert" style="display:none">We cannot ship this product to your country. Please remove it from the cart to continue!</div>';
    
}


add_action( 'woocommerce_after_checkout_form', 'show_shipping_notice_js' );
function show_shipping_notice_js(){
    ?>
    <script>
        jQuery(function($){
            var countryCode  = 'LV', // Set the country code (That will display the message)
                countryField = 'select#billing_country'; // The Field selector to target
            
            function showHideShippingNotice( countryCode, countryField ){
                if( $(countryField).val() !== countryCode && $('.shop_table tr').hasClass('id-27733')){
                    $('.shipping-notice').show();                   
                    $('.woocommerce-checkout-payment').hide();
                    
                }
                else {
                    $('.shipping-notice').hide();
                    $('.woocommerce-checkout-payment').show();
                }
            }

            // On Ready (after DOM is loaded)
            showHideShippingNotice( countryCode, countryField );

            // On billing country change (Live event)
            $('form.checkout').on('change', countryField, function() {
                showHideShippingNotice( countryCode, countryField );
            });
        });
    </script>
    <?php
}

function cart_item_class( $class, $values, $values_key ) {
    if ( isset( $values[ 'product_id' ] ) ) {
        $class .= ' id-' . $values[ 'product_id' ];
    }
    return $class;
}
add_filter( 'woocommerce_cart_item_class', 'cart_item_class', 10, 3 );

不需要使用 jQuery 或 AJAX,也不需要通过 HTML div 显示自定义消息,因为这可以通过wc_add_notice() 和 WooCommerce 挂钩。

换句话说,利用相反的 WooCommerce 功能自行创建。


如果您只想在结帐页面上执行此检查,您可以使用 woocommerce_order_button_html 钩子:

function filter_woocommerce_order_button_text( $button ) {        
    // The targeted product ids
    $targeted_ids = array( 30, 815 );

    // Flag
    $found = false;

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( array_intersect( $targeted_ids, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
            $found = true;
            break;
        }
    }

    // True
    if ( $found ) {
        // Get billing country
        $billing_country = WC()->customer->get_billing_country();
    
        // Multiple country codes can be added, separated by a comma
        $countries = array( 'BE', 'LV' );
    
        // Checks if a value NOT exists in an array
        if ( ! in_array( $billing_country, $countries ) ) {
            $style  = 'style="background:Silver !important; color:white !important; cursor: not-allowed !important; text-align:center;"';
            $text   = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) );
            $button = '<a class="button"' . $style . '>' . $text . '</a>';
            
            // Clear all other notices          
            wc_clear_notices();
            
            // Notice
            wc_add_notice( __( 'We cannot ship this product to your country. Please remove it from the cart to continue!', 'woocommerce' ), 'error' ); 
        }
    }
    
    return $button;
}
add_filter( 'woocommerce_order_button_html', 'filter_woocommerce_order_button_text', 10, 1 );

对于购物车和结帐页面的组合,您可以使用 woocommerce_check_cart_items 挂钩:

function action_woocommerce_check_cart_items() {        
    // The targeted product ids
    $targeted_ids = array( 30, 815 );

    // Flag
    $found = false;

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( array_intersect( $targeted_ids, array( $cart_item['product_id'], $cart_item['variation_id'] ) ) ) {
            $found = true;
            break;
        }
    }

    // True
    if ( $found ) {
        // Get billing country
        $billing_country = WC()->customer->get_billing_country();
        
        // Multiple country codes can be added, separated by a comma
        $countries = array( 'BE', 'LV' );
    
        // Checks if a value NOT exists in an array
        if ( ! in_array( $billing_country, $countries ) ) {
            // Notice
            wc_add_notice( __( 'We cannot ship this product to your country. Please remove it from the cart to continue!', 'woocommerce' ), 'error' ); 
            
            // 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 );