Aaron T
Aaron T

Reputation: 73

What is the proper way to override a php function / file containted in the includes / abstracts folder when using woocommerce?

What is the proper way to override a php file in the includes folder when using woocommerce?

As an example of one of the many things I want to change: "I think sale prices being wrapped in <del></del> is silly(<span> or <div> would be better for what i want), and I want to change the layout anyways so I want to alter the code

/**
 * Functions for getting parts of a price, in html, used by get_price_html.
 *
 * @param  mixed $from String or float to wrap with 'from' text
 * @param  mixed $to String or float to wrap with 'to' text
 * @return string
 */
public function get_price_html_from_to( $from, $to ) {
    return '<del>' . ( ( is_numeric( $from ) ) ? wc_price( $from ) : $from ) . '</del> <ins>' . ( ( is_numeric( $to ) ) ? wc_price( $to ) : $to ) . '</ins>';
}

in file

plugins/woocommerce/includes/abstracts/abstract-wc-product.php

I could just alter it in this file, but I know that is the incorrect way of doing it, and that it would get overwritten by the next woo update also.

So what is the CORRECT way to alter this code?

Upvotes: 1

Views: 1600

Answers (3)

helgatheviking
helgatheviking

Reputation: 26319

If the price is greater than 0, you can change the value of the price html via the woocommerce_sale_price_html filter. Or if the price is 0, you can target the woocommerce_free_sale_price_html filter. See the get_price_html() method in the WC_Product abstract.

Here's the relevant bit if the price is greater than 0:

if ( $this->is_on_sale() && $this->get_regular_price() ) {

    $price .= $this->get_price_html_from_to( $display_regular_price, $display_price ) . $this->get_price_suffix();

    $price = apply_filters( 'woocommerce_sale_price_html', $price, $this );

} 

So you could filter the html and instead of using WC's default get_price_html_from_to method you could create your own function with your own custom markup, like so:

add_filter( 'woocommerce_sale_price_html', 'so_26002687_sale_price_html', 10, 2);

function so_26002687_sale_price_html( $html, $product ){

    $tax_display_mode      = get_option( 'woocommerce_tax_display_shop' );
    $display_price  = $tax_display_mode == 'incl' ? $product->get_price_including_tax() : $product->get_price_excluding_tax();
    $display_regular_price = $tax_display_mode == 'incl' ? $product->get_price_including_tax( 1, $product->get_regular_price() ) : $product->get_price_excluding_tax( 1, $product->get_regular_price() );

    $html = so_26002687_get_price_html_from_to( $display_regular_price, $display_price ) . $product->get_price_suffix();

    return $html;

}

function so_26002687_get_price_html_from_to( $from, $to ) {
    return '<span class="from">' . ( ( is_numeric( $from ) ) ? wc_price( $from ) : $from ) . '</span> <span class="to">' . ( ( is_numeric( $to ) ) ? wc_price( $to ) : $to ) . '</span>';
}

Then I'd repeat the process for woocommerce_free_sale_price_html.

Upvotes: 2

TML
TML

Reputation: 12966

Make your own class that implements the WC_Product 'abstract' class, and make sure your products are registered as that type, so that the WC_Product_Factory gives you back instances of that class, instead of WC_Product; e.g.

class WC_Product_Your_Type extends WC_Product {
  public function get_price_html_from_to( $from, $to ) {
    return '<span>' . ( ( is_numeric( $from ) ) ? wc_price( $from ) : $from ) . '</span> <div>' . ( ( is_numeric( $to ) ) ? wc_price( $to ) : $to ) . '</div>';
  }
}

Upvotes: 0

tfrascaroli
tfrascaroli

Reputation: 1219

I guess you could create your own file, and include/require it AFTER you include the original one from woocommerce. In your file you redefine the functions you need to by doing:

bool runkit_function_redefine ( string $funcname , string $arglist , string $code );

It's your best bet I think, allthough it's a bit obscure.

$funcname is the name of the function you want to redefine.

$arglist is the new argument list (in string format!).

$codeis the new code (again, in string format).

Hope it helps.

Further info: Redefine PHP manuals

Upvotes: 0

Related Questions