Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding "Sale" product category to products that are on sale in Woocommerce

As part of a WooCommerce site I want to have a sale page that lists sale items (with pagination and filtering). I think the best way to do this is to have a 'Sale' category that is added automatically to any posts that are part of the sale (as category pages allow for filtering and pagination automatically.

I have this code so far to programatically add the sale category to products when you save them:

function update_test( $product) { 
wp_set_object_terms($product, 'sale', 'product_cat', true );
}

add_action( 'save_post', 'update_test', 1, 2);`

However, I only want this to happen if a product is on sale (i.e has sale price set) so that saving posts that are not on sale does not add the sale category. I have tried several different things, but have had no luck. I tried this, but it didnt work:

function update_test( $product ) { 
if($product->is_on_sale()){
wp_set_object_terms($product, 'sale', 'product_cat', true );
}
}

add_action( 'save_post', 'update_test', 1, 2);`

but this just made my site freeze on save.

Any ideas?

Andy

like image 290
AndrewIanHalloway Avatar asked Dec 05 '16 00:12

AndrewIanHalloway


People also ask

Can a product have multiple categories in WooCommerce?

Yes, a WooCommerce product can have multiple categories. This is because WooCommerce products are actually WordPress posts, and WordPress supports post categories.

How do I show on sale items in WooCommerce?

To do this, go to WooCommerce > Settings > Products and scroll down to the Product Data section. Here, you will see an option for Enable Sale Badges. Check this box and save your changes. Now, when you go to add or edit a product, you will see a new Sale Status meta box.


1 Answers

Updated 2 (October 2018)

save_post is a WordPress hook that works with $post_id argument and target all kind of posts. You need to target product custom WooCommerce post_type first in a condition (and publish post_status).

Also as it's not a post object you can't use is_on_sale() method with it. But you can use get_post_meta() function to check if the sale price is set in the product.

Here is the fully functional and tested code (for simple products only):

add_action( 'save_post_product', 'update_product_set_sale_cat' );
function update_product_set_sale_cat( $post_id ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return $post_id;
    }

    if ( ! current_user_can( 'edit_product', $post_id ) ) {
        return $post_id;
    }

    if( get_post_status( $post_id ) == 'publish' && isset($_POST['_sale_price']) ) {
        $sale_price = $_POST['_sale_price'];

        if( $sale_price >= 0 && ! has_term( 'Sale', 'product_cat', $post_id ) ){
            wp_set_object_terms($post_id, 'sale', 'product_cat', true );
        }
    }
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

Related: Auto remove Sale product category from not on sale products in Woocommerce

like image 147
LoicTheAztec Avatar answered Sep 20 '22 23:09

LoicTheAztec