Woocommerce - Display Lowest Price on Category (Archive) Page Only - php

I'm trying to display the lowest price instead of the price range on the category pages while continuing to display the price range on the individual product pages.
I found this answer from someone else's question:
add_filter('woocommerce_variable_price_html', 'custom_variation_price', 10, 2);
function custom_variation_price( $price, $product ) {
$price = '';
if ( !$product->min_variation_price || $product->min_variation_price !== $product->max_variation_price ) {
$price .= '<span class="from">' . _x('From', 'min_price', 'woocommerce') . ' </span>';
$price .= woocommerce_price($product->get_price());
}
return $price;
}
And it works, but when I put the code in functions.php, it applies to the whole site. I only want it to apply to the category pages.
Also, when I use this code, items with only one price end up with no price being displayed.
What can I do?
Here's a screenshot of what I mean:
Screenshot of current category page

If I got you right then you just need to display the minimal price whenever there's a range of prices. So basically you need to change the $price's HTML only if product's minimal price is set (if it's not set then the product has a single price and no change is needed). I also included the check for whether it's a category page. Here's the code:
add_filter('woocommerce_variable_price_html', 'custom_variation_price', 10, 2);
function custom_variation_price( $price, $product ) {
if ( ! empty($product->min_variation_price) && is_product_category() ) {
$price = '<span class="from">' . _x('From', 'min_price', 'woocommerce') . ' </span>';
$price .= woocommerce_price($product->get_price());
}
return $price;
}

Related

How to add an icon in the product page of WooCommerce ONLY after the price

I added the following code after doing some research online on how to do this, the issue is that, this code adds an icon to both the product page of a product as well as the mini overview of the other products, which isn't what I want, I want to have the icon showing only on all product pages alone.
Seeking some assistance on how to achieve this.
I'm trying to get
What I want to remove.
add_filter( 'woocommerce_get_price_html', 'prepend_append_icon_to_price', 10, 2 );
function prepend_append_icon_to_price( $price, $product ) {
$price .= '<span style="float:right"><i class="fas fa-shipping-fast"></i></span> ';
return $price;
}
add_filter('woocommerce_get_price_html', 'prepend_append_icon_to_price', 10, 2);
function prepend_append_icon_to_price($price, $product) {
if (is_product()) {
$price .= '<span style="float:right"><i class="fas fa-shipping-fast"></i></span> ';
}
return $price;
}
You can use is_product() woocommerce conditional tag for check is a single product page

WooCommerce wc_price( $price ) & variations & headache

I'm having beginner problems with some PHP...
I'd like to change the price label on a variable product depending on whether a product variation is rented or sold. Each product has both options.
I've realised that the product's post title includes the text 'rent' or 'buy' depending on the variation.
So I have butchered some code found here to try and display a different label depending on the results of the products post title. Currently looks like this (but doesn't work!), have a feeling that this is totally the wrong approach, can anyone help?
function sv_change_product_html( $price_html, $product ) {
$is_rental = get_post_meta( $product->id, 'post_title' );
$price = $product->get_regular_price();
if (strpos($is_rental, "Rent") !== false) {
$price_html = '<span class="amount">' . wc_price( $price ) . ' per week</span>';
}
else
{
$price_html = '<span class="amount">' . wc_price( $price ) . ' buy today</span>';
}
return $price_html;
}
Probably a better approach would be to check for the accompanying product attribute which stores the values on bases which you have your variations ('rent'/'buy') and then carry out your business from there as this approach seems hacky and can fail if the store owner decides to change the way they name their products in future.
Also, you can get product properties like name ($product->get_name()), attribute ($product->get_attribute(<attr_name>)), etc., using the methods provided in the WooCommerce classes (Product/Product Variation)
Also, is your function hooked to the right filter?

(Woocommerce) Add Words to Prices Display Everywhere but the Cart and Checkout Pages

I would like to add something before the price products category/ single-procut page only. I use this code as example:
function cw_change_product_price_display( $price ) {
$price .= ' Starts At';
return $price;
}
add_filter( 'woocommerce_get_price_html', 'cw_change_product_price_display' );
But it shows up as "RM49.00 Starts At"
I need the words to be before the price. How do I achieve this?
I really need help on this.
You just need to append it before the price html. And you can check for single product page using is_product() and category page using is_product_category().
function cw_change_product_price_display( $price ) {
if ( is_product() || is_product_category() ) {
return 'Starts At ' . $price;
}
return $price;
}
The code:
$price .= ' Starts At';
is shorthand for:
$price = $price . ' Starts At';
So, output of RM49.00 Starts At is entirely expected.
This is a common motif in many programming languages (but certainly not all). For example, you will see things like:
count += 4
which means:
count = count + 4
You will also see *=, /=, -=, etc.

Add a text under item name based on checkbox custom field in Woocommerce checkout

I have a custom function that checks if a checkbox is checked and if so, it adds 'with vat relief' next to the price. If it isn't checked, it adds 'inc vat' next to the price. That works fine and my code is:
add_filter( 'woocommerce_get_price_html', 'conditional_price_suffix', 20, 2 );
function conditional_price_suffix( $price, $product ) {
$isTaxRelefe = get_post_meta($product->id, 'disability_exemption', true);
if ($isTaxRelefe == 'yes')
$price .= ' ' . __('with vat relief');
else $price .= ' ' . __('inc vat');
return $price;
}
What I need to do now is add another function targeting the checkout page that says if the checkbox is checked show some text underneath the product title but I'm struggling. My initial thought was to edit the /checkout/review-order so I added an if else statement to output something next to the product title is. I added:
$isTaxRelefe = get_post_meta($product->id, 'disability_exemption', true);
if ($isTaxRelefe == 'yes') {
$content .= 'VAT RELIEF AVAILABLE';
}
but this does nothing, I have tried various variations, changing to echo statements etc. but no luck. I'm sure I am just writing this incorrectly. Can anyone advise? What I'm not very up on are WordPress functions as in if I could write one to target the checkout page only, Im not sure how it determines where to output your. an if else statement seemed like the obvious choice but not having any luck.
Your code is a bit outdated and you should use $product->get_id() since Woocommerce 3 in your first function instead of $product->id in the get_post_meta() function.
You can also use instead the WC_Data method get_meta() from the product object directly.
Below is your revisited code with the additional hooked function that will display conditionally "VAT RELIEF AVAILABLE" text under the product title in checkout page: (without overriding the template review-order.php)
add_filter( 'woocommerce_get_price_html', 'conditional_price_suffix', 20, 2 );
function conditional_price_suffix( $price, $product ) {
if ( $product->get_meta('disability_exemption') === 'yes')
$price .= ' ' . __('with vat relief');
else
$price .= ' ' . __('inc vat');
return $price;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'custom_text_below_checkout_product_title', 20, 3 );
function custom_text_below_checkout_product_title( $quantity_html, $cart_item, $cart_item_key ){
if ( $cart_item['data']->get_meta('disability_exemption') === 'yes' )
$quantity_html .= '<br>' . __('VAT RELIEF AVAILABLE');
return $quantity_html;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.

Bulk Updating Woocommerce Variation Prices

I'm trying to update woocommerce variation prices with a php/mysql script outside of wordpress.
I have a script that updates the _price and _regular_price value of one product_variation of a product in wp_postmeta table.
If I have more than one variation the correct price of the variation is displayed on the webpage - but the the price / price range coming from woocommerce`s price.php is not updated.
However, if I have only this one variation, the price in the table is updated, but not at all on the rendered webpage.
I also tried to edit the prices of the product itself. But: I still get the old price on the rendered webpage.
Basically I now have the same new price in these fields:
in product-variation -> postmeta: _price, _regular_price
and in product -> postmeta: _price, _regular_price, _min_variation_price, _max_variation_price, _min_variation_regular_price, _max_variation_regular_price
I couldn't find any other fields with a price - I'm stuck...
Did I miss anything? Is there any other table/field to be updated?
Thanks for your help!
-EDIT-
Maybe this helps: Apparently when having only one Variation my price is rendered with echo $product->get_price_html(); instead of echo $value['price_html'];. So where is the price used in $product->get_price_html(); stored?
OK after some digging around and thanks to #helgatheviking who pointed me in the right direction I tried this:
included wp-load.php in script
called WC_Product_Variable::sync( $post_id );
-> unfortunately this didn't work for me. I just put it here because I think this is the right approach - hopefully it helps someone else.
What actually helped me was including this in my functions.php:
// Display Price For Variable Product With Same Variations Prices
add_filter('woocommerce_available_variation', function ($value, $object = null, $variation = null) {
if ($value['price_html'] == '') {
$value['price_html'] = '<span class="price">' . $variation->get_price_html() . '</span>';
}
return $value;
}, 10, 3);
// Hook into price html
add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html', 100, 2 );
function wpa83367_price_html( $price, $product ){
WC_Product_Variable::sync( $product->id );
$myPrice = $product->min_variation_price;
$priceFormat = str_replace(utf8_encode('.'), ",", $myPrice);
return '<span class="amount">from ' . $priceFormat . ' €</span>';
}
Please use the following script to bulk update the product variations.
Click here for full code. https://www.pearlbells.co.uk/bulk-update-product-variation-price-woocommerce/
function getExistingProducts($updatedPrices,$skuArray) {
$loop = new WP_Query(array('post_type' => array('product', 'product_variation'), 'posts_per_page' => -1));
while ($loop->have_posts()) : $loop->the_post();
$id = get_the_ID();
$product = wc_get_product( $id );
$sku = get_post_meta($id, '_sku', true);
if( in_array( $sku, $skuArray ) ) {
$attributes = $product->get_attributes();
$attributes['medium-quantity-price']['value'] = $updatedPrices[$sku][4];
$attributes['low-quantity-price']['value'] = $updatedPrices[$sku][3];
$attributes['v-low-quantity-price']['value'] = $updatedPrices[$sku][2];
update_post_meta( $id,'_product_attributes',$attributes);
echo ' Update Sku : '.$sku.' '.PHP_EOL;
}
endwhile;
}

Categories