Add message below shipping methods based on taxonomy terms in WooCommerce

Viewed 55

I'd like to add a custom message below the available shipping methods in the cart, but only if ALL products in the cart have a tag named 'express'.

Therefore I use this snippet:

add_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate', 20, 2 );
function action_after_shipping_rate ( $method, $index ) {
    if( 'flat_rate:1' === $method->id ) {        
        echo __("<p>Arriving on your chosen date between 9am - 1pm Perfect for business addresses & special occasions</p>");
     }
    if( 'flat_rate:2' === $method->id ) {
        echo __("<p>Arriving on your chosen date between 9am - 7pm Perfect for residential addresses</p>");
    }
}

add_filter( 'woocommerce_shipping_details', 'hide_shipping_details', 10, 2 );
function hide_shipping_details( $rates, $package ) {

    $terms = array( 'express' ); 
    $taxonomy = 'product_tag';

    $found = false;

    foreach( $package['contents'] as $cart_item ) {
        if ( !has_term( $terms, $taxonomy, $cart_item['product_id'] ) ){
            $found = true;
            break;
        }
    }
    
    if ( $found === false ) {
        remove_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate', 20, 2 );
    }
}

But right now, the custom message remains if 1 or 2 products have the tag 'express' but not ALL products. Can someone help me solve this problem?

1 Answers

No need to call from one hook to another, while you can just loop through all the products in cart in the woocommerce_after_shipping_rate hook

So you get:

function action_woocommerce_after_shipping_rate( $method, $index ) {
    // Settings
    $terms = array( 'express', 'tag-1' ); 
    $taxonomy = 'product_tag';

    // Initialize
    $flag = false;

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        // Checks if the current product has NOT any of given terms
        if ( ! has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
            $flag = true;
            break;
        }
    }

    // When false
    if ( ! $flag ) {
        // Compare
        if ( $method->get_id() === 'flat_rate:1' ) {
            $text = 'My text 1';
        } elseif ( $method->get_id() === 'flat_rate:3' ) {
            $text = 'My text 2';
        } elseif ( $method->get_id() === 'local_pickup:1' ) {
            $text = 'My text 3';
        }

        // When isset
        if ( isset( $text ) ) {
            // Output
            echo '<p>' . sprintf( __( '%s', 'woocommerce' ), $text ) . '</p>';
        }
    }
}
add_action( 'woocommerce_after_shipping_rate', 'action_woocommerce_after_shipping_rate', 10, 2 );
Related