I’m not sure if this is possible, but it feels like it should be.
I have a list of products that I wish to display via two different archives (set by another plugin) where I can control the products displayed by listing categories with the shortcode. The different archives need to have different prices showing for the same products and sometimes to not list specific products within a category.
So what I’ve done is setup categories (which are filterable on the front end and as such display their name) with the same name but different slugs for each archive page and then added each product to both categories with the same name so they show up in each archive.
The problem is I need to increase the base price of almost all of the products in one archive by 0.50 and I can’t figure out a way of doing it. I can achieve the correct result visually like this:
function bbloomer_alter_price_display( $price_html, $product ) {
global $wp_query;
$slug = basename(get_permalink($wp_query->post->ID));
// Only if not null
if ( '' === $product->get_price() ) return $price_html;
// If on specifc archive page
if ( $slug == "eathere" ) {
$orig_price = wc_get_price_to_display( $product );
$price_html = wc_price( $orig_price + 0.50 );
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'bbloomer_alter_price_display', 9999, 2 );
But obviously, this only updates the visual price, and as soon as it’s added to the cart and checkout it just shows the base price, unaltered.
I know that you’re supposed to update the cart separately with a hook like woocommerce_before_calculate_totals
but I can’t figure out how to apply the logic that it has to have come from this archive to have the modified price.
This code works for the category they’re in:
add_filter( 'woocommerce_product_get_price', 'custom_sale_price_for_category', 10, 2 );
function custom_sale_price_for_category( $price, $product ) {
//Get all product categories for the current product
$terms = wp_get_post_terms( $product->get_id(), 'product_cat' );
foreach ( $terms as $term ) {
$categories[] = $term->slug;
}
if ( ! empty( $categories ) && in_array( 'eathere-burgers', $categories, true ) ) {
$price *= ( 1 + 0.50 );
}
return $price;
}
But this will then affect the prices across the site regardless of which archive page they’re on. If I add that it should only affect the archive page via the slug as in the first example then they appear correctly in the archive but again don’t change in the cart of checkout.
I’m really stuck on how to get this working without duplicating the entire product list and adjusting the price. It feels like this should be possible with a simple bit of code but WooCommerce’s hooks and filters are so dense in their functionality I’m finding it hard to figure out.
2
Answers
I don’t know if the logic is correct or not but you can try with Session Variable in ‘woocommerce_product_get_price’ filter to store value of archive
Now get the same session variable value on cart/checkout Hook ‘woocommerce_before_calculate_totals’ & don’t forgot to
session_start();
& get value of$_SESSION["archive"]
in this hook to check archive slug & update the price according to that.In your code assign slug value to session variable in if & elseif statement based on which archive page you are on
on Cart/Checkout page compare the value of archive page slug with Session variable slug value & based on that update the price of the product
Sometimes it may give error in that case you need to start_session(); before assigning value to session