Modify WooCommerce Is_Purchasable

I was working on implementing my own pre-order system, where I set a is_preorder custom field for each product.

I was trying to modify the WooCommerce’s Is_Purchasable option so that, if the product has pre-order status and it’s already passed the pre-order deadline, it shouldn’t be able to be purchased. I’ve tried a bunch of ways, but nothing seems working.

Read More

Here’s something that I did (rough idea)

add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable');

function preorder_is_purchasable() {

    // this is a field added using 'Advance Custom Fields' plugin 
    $is_preorder = get_field('is_preorder'); 

    if($is_preorder && "not yet passed deadline")
        return true;
    else
        return false;
}

I don’t just wanna disable the add_to_cart button, I also want to disable the functionality (should prompt error if user tried to add product by hardcoding in url).
How should I go on with this?

===========================================================================

Here’s my final code:

add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable', 10, 2);

function preorder_is_purchasable( $is_purchasable, $object ) {

// this is a field added using 'Advance Custom Fields' plugin 
$is_preorder = get_field('is_preorder', $object->id); 

// if product is Pre-Order
if($is_preorder)
{
    $today = date('Ymd');

    // another field added using 'Advance Custom Fields' plugin 
    $preorder_deadline = get_field('preorder_deadline', $object->id); 

    if($today <= $preorder_deadline) // if not yet pass deadline
        return true;
    else
        return false;
}
else
    return $is_purchasable; // normal

Related posts

Leave a Reply

2 comments

  1. Update 2019: please see dev_masta answer for correct solution nowadays.


    Not sure if it solves the issue as this has to be tested on your own custom set up. But you’re using get_field wrong: if it is not used inside a Loop, you should provide the post ID.

    Analyzing the filter woocommerce_is_purchasable, we see that it takes two parameters, a boolean (is_purchasable) and an object (WC_Product).

    Try this:

    add_filter('woocommerce_is_purchasable', 'preorder_is_purchasable', 10, 2);
    
    function preorder_is_purchasable( $is_purchasable, $object ) {
    
        // this is a field added using 'Advance Custom Fields' plugin 
        $is_preorder = get_field('is_preorder', $object->id); 
    
        if($is_preorder && $is_purchasable)
            return true;
        else
            return false;
    }
    
  2. The accepted answer is a bit outdated today.

    Instead of using $object->id you should use $object->get_id(), otherwise you’ll get a PHP notice about incorrect use.

    function disable_purchased_products( $is_purchasable, $object ){
    
        // custom function to get the array of purchased products ID's
        $already_purchased = get_purchased_products();
    
        if( in_array( $object->get_id(), $already_purchased ) ){
            return false;
        } else {
            return $is_purchasable;
        }
    }
    add_filter( 'woocommerce_is_purchasable', 'disable_purchased_products', 10, 2 );
    

    I hope this will help someone, I’ve seen this (outdated) code all around the net..