Search code examples
phpwordpresswoocommerceproductvirtual

Disallow purchases from virtual products in WooCommerce


I'm trying to remove the add to cart button from the categories page for products that are not purchasable.

This is my current code, which I have placed in the functions.php file of my child theme;

function buy_filter()
{
    if ( ! is_product() ) return;
    $product_id=get_the_ID();
    $product = wc_get_product($product_id);
    if ($product->is_virtual('yes'))

    if ($product->is_virtual('yes'))
    {
        add_filter( 'woocommerce_is_purchasable', '__return_false');
    }
}

add_action ('wp', 'buy_filter');

I've managed to remove the button from the individual product pages, however I still can't get it to be removed from the categories page. Now when I inspect the button shows the following code:

<a href="?add-to-cart=16972" data-quantity="1" class="button product_type_simple add_to_cart_button
ajax_add_to_cart" data-product_id="16972" data-product_sku="604544617405" aria-label=
"Add “Federal -  9MM Syntech, 115gr” to your cart" rel="nofollow">Add to cart</a>

Does this button need to be disabled in another way?

I really need this button to be removed as its a product that we only want to sell in our store, but we want people to know that we do stock that product as well.

Below is an image of what it currently looks like, and what I want to go. Ideally, I would like the button gone completely, but I will definitely settle for a replacement to the read more button if that is easier.

Remove Add to Cart Button


Solution

  • To remove it from everywhere (on single pages and category pages) use directly the filter instead, replacing your code with:

    add_filter( 'woocommerce_variation_is_purchasable', 'filter_virtual_products', 10, 2 );
    add_filter( 'woocommerce_is_purchasable', 'filter_virtual_products', 10, 2 );
    function filter_virtual_products( $is_purchasable, $product )
    {
        if ( $product->is_virtual('yes') ) {
            $is_purchasable = false;
        }
        return $is_purchasable;
    }
    

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