3

I am looking for a way to replace €0,00 price for a WooCommerce (version 3.3.x) product with text, like 'Based on contract'. Preferably visible in the webshop and emails. Because of recent changes in WooCommerce the existing snippets aren't working anymore, like:

add_filter('woocommerce_get_price_html', 'changeFreePriceNotice', 10, 2);

function changeFreePriceNotice($price, $product) {
    if ( $price == wc_price( 0.00 ) )
        return 'FREE';
    else
        return $price;
}

Or

<?php
// Do not copy the opening <?php tag above
// Customize the Free! price output
add_filter( 'woocommerce_variable_free_price_html','wsm_custom_free_price' );
add_filter( 'woocommerce_free_price_html', 'wsm_custom_free_price' );
add_filter( 'woocommerce_variation_free_price_html', 'wsm_custom_free_price' );
function wsm_custom_free_price( $price ) {
    // Edit content between single quotes below to desired output
    return 'Prepaid Inventory';
}

Or

function my_wc_custom_get_price_html( $price, $product ) {
    if ( $product->get_price() == 0 ) {
        if ( $product->is_on_sale() && $product->get_regular_price() ) {
            $regular_price = wc_get_price_to_display( $product, array( 'qty' => 1, 'price' => $product->get_regular_price() ) );

            $price = wc_format_price_range( $regular_price, __( 'Free!', 'woocommerce' ) );
        } else {
            $price = '<span class="amount">' . __( 'Free!', 'woocommerce' ) . '</span>';
        }
    }

    return $price;
}

add_filter( 'woocommerce_get_price_html', 'my_wc_custom_get_price_html', 10, 2 );
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Sjors
  • 301
  • 4
  • 14

1 Answers1

6

Here is the correct way to do it on Woocommerce 3+ (tested on WooCommerce 3.3.x and 3.5+ too):

// Product displayed prices
add_filter( 'woocommerce_get_price_html', 'free_price_custom_label', 20, 2 );
function free_price_custom_label( $price, $product ) {
    if ( is_shop() || is_product_category() || is_product_tag() || is_product() ) {
        // HERE your custom free price label
        $free_label = '<span class="amount">' . __('Based on contract') . '</span>';

        if( $product->is_type('variable') )
        {
            $price_min  = wc_get_price_to_display( $product, array( 'price' => $product->get_variation_price('min') ) );
            $price_max  = wc_get_price_to_display( $product, array( 'price' => $product->get_variation_price('max') ) );

            if( $price_min != $price_max ){
                if( $price_min == 0 && $price_max > 0 )
                    $price = wc_price( $price_max );
                elseif( $price_min > 0 && $price_max == 0 )
                    $price = wc_price( $price_min );
                else
                    $price = wc_format_price_range( $price_min, $price_max );
            } else {
                if( $price_min > 0 )
                    $price = wc_price( $price_min);
                else
                    $price = $free_label;
            }
        }
        elseif( $product->is_on_sale() )
        {
            $regular_price = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) );
            $sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
            if( $sale_price > 0 )
                $price = wc_format_sale_price( $regular_price, $sale_price );
            else
                $price = $free_label;
        }
        else
        {
            $active_price = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) );
            if( $active_price > 0 )
                $price = wc_price($active_price);
            else
                $price = $free_label;
        }
    }
    return $price;
}

// Product variation displayed prices
add_filter( 'woocommerce_variable_price_html', 'free_variation_price_custom_label', 20, 2 );
function free_variation_price_custom_label( $price, $product ) {
    // HERE your custom free price label
    $free_label = '<span class="amount">' . __('Based on contract') . '</span>';

    if( $product->is_on_sale() )
    {
        $regular_price = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) );
        $sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
        if( $sale_price > 0 )
            $price = wc_format_sale_price( $regular_price, $sale_price );
        else
            $price = $free_label;
    }
    else
    {
        $active_price = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) );
        if( $active_price > 0 )
            $price = wc_price($active_price);
        else
            $price = $free_label;
    }
    return $price;
}

// Cart items displayed prices and line item subtotal
add_filter( 'woocommerce_cart_item_subtotal', 'free_cart_item_price_custom_label', 20, 3 );
add_filter( 'woocommerce_cart_item_price', 'free_cart_item_price_custom_label', 20, 3 );
function free_cart_item_price_custom_label( $price, $cart_item, $cart_item_key ) {
    // HERE your custom free price label
    $free_label = '<span class="amount">' . __('Based on contract') . '</span>';

    if( $cart_item['data']->get_price() > 0 )
        return $price;
    else
        return $free_label;
}

// Order items displayed prices (and also email notifications)
add_filter( 'woocommerce_order_formatted_line_subtotal', 'free_order_item_price_custom_label', 20, 3 );
function free_order_item_price_custom_label( $subtotal, $item, $order ) {
    // HERE your custom free price label
    $free_label = '<span class="amount">' . __('Based on contract') . '</span>';

    if( $order->get_line_subtotal( $item ) > 0 )
        return $subtotal;
    else
        return $free_label;
}

This code goes on function.php file of your active child theme (or theme). Tested and works.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you so much Loic! It works prefectly! The only items that are still visible as zero are the sub totals and totals in the shopping cart, checkout page and emails. Is it possible to also change those items? – Sjors Mar 12 '18 at 21:14
  • @Sjors Your question was about replacing the product / items displayed prices by a custom text… Change cart and order totals is another thing and I am not really sure that you can replace zero value by a custom text everywhere. – LoicTheAztec Mar 12 '18 at 21:23