WooCommerce: Cart price override with text

2019-02-14 03:40发布

问题:

We have a bunch of products with either:

  • No price
  • Zero price

We made them purchasable with the built-in hook but the cart still displays them as having a 0 price during checkout.

We'd like the cart & checkout summary to display "Special order" or any other text, but it seems WooCommerce invalidates text-based prices.

Tried this : WooCommerce: Add product to cart with price override?

The above works fine with a number override, but when tried with a text override it defaults back to displaying a 0 price.

Why? These products are built-to-order and the shop admin will update price after talking to customer/supplier.

回答1:

You need to filter the strings that display the price and subtotal in the cart. The link you mentioned discussed changing the actual price. In your case the price is $0 until you set an actual price later on. There are probably filters for the cart totals too, but this should be a start:

add_filter( 'woocommerce_cart_item_price', 'so_38057349_cart_item_price', 10, 3 );
function so_38057349_cart_item_price( $price, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $price = __( 'Special Order', 'yourtheme' );
    }

    return $price;
}


add_filter( 'woocommerce_cart_item_subtotal', 'so_38057349_cart_item_subtotal', 10, 3 );
function so_38057349_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}


add_filter( 'woocommerce_order_formatted_line_subtotal', 'so_38057349_order_item_subtotal', 10, 3 );
function so_38057349_order_item_subtotal( $subtotal, $item, $order ) {

    if ( isset( $item[ 'line_subtotal' ] ) && $item[ 'line_subtotal' ] == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}

Of course, this will also apply to any product with a 0 price and maybe not only the ones you have configured to be custom built, so you may need more conditional logic than I've supplied here.

To follow up on your comment.... woocommerce_order_amount_total is the numerical total and not the displayed html. You can see the functions being called in the cart-totals.php template.

function so_38057349_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart ) { 
    if( $cart->subtotal == 0 ){
        $cart_subtotal = __( 'Order subtotal to be determined', 'yourtheme' ); 
    }
    return $cart_subtotal; 
}; 
add_filter( 'woocommerce_cart_subtotal', 'so_38057349_woocommerce_cart_subtotal', 10, 3 ); 


// define the woocommerce_order_amount_total callback 
function so_38057349_woocommerce_order_amount_total( $order_total ) { 
    if( WC()->cart->get_total() == 0 ){
        $order_total = __( 'Order total to be determined', 'yourtheme' ); 
    }
    return $order_total; 
}; 
add_filter( 'woocommerce_cart_totals_order_total_html', 'so_38057349_woocommerce_order_amount_total' ); 

Updated screenshot:



回答2:

expanding on Helga's answer, here's the full code that changes the prices to 'to be determined' on cart pages, checkout pages and order confirmation emails too. Text kept different so people can spot where each filter goes.

    add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price, $cart_item, $cart_item_key ) {
    if ( $cart_item[ 'data' ]->price == 0 ) {
        $price = __( 'Special Order', 'yourtheme' );
    }
    return $price;
}

add_filter( 'woocommerce_cart_item_subtotal', 'filter_cart_item_subtotal', 10, 3 );
function filter_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {
    if ( $cart_item[ 'data' ]->price == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }
    return $subtotal;
}

add_filter( 'woocommerce_cart_subtotal', 'filter_woocommerce_cart_subtotal', 10, 3 ); 
function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $instance ) { 
    $cart_subtotal = __( 'To be determined 4', 'yourtheme' ); 
    return $cart_subtotal; 
}; 


add_filter( 'woocommerce_order_formatted_line_subtotal', 'filter_order_item_subtotal', 10, 3 );
function filter_order_item_subtotal( $subtotal, $item, $order ) {
    if ( isset( $item[ 'line_subtotal' ] ) && $item[ 'line_subtotal' ] == 0 ) {
        $subtotal = __( 'To be determined 2', 'yourtheme' );
    }
    return $subtotal;
}

add_filter( 'woocommerce_order_subtotal_to_display', 'filter_woocommerce_order_subtotal_to_display', 10, 3 ); 
function filter_woocommerce_order_subtotal_to_display( $subtotal, $compound, $instance ) { 
        $subtotal = __( 'To be determined 6', 'yourtheme' );
    return $subtotal; 
};

add_filter( 'woocommerce_get_formatted_order_total', 'filter_woocommerce_get_formatted_order_total', 10, 2 ); 
function filter_woocommerce_get_formatted_order_total( $formatted_total, $instance ) { 
        $formatted_total = __( 'To be determined 8', 'yourtheme' );
    return $formatted_total; 
};