Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a custom WooCommerce product type that extends WC_Product_Variable to the cart

I've created a custom WooCommerce product type that's based on the built-in variable product type. I want to have both product variations and custom characteristics and fields specific to my product type. This is all working and displaying fine in the admin and my custom front-end product page template.

Here's my custom product, for reference:

add_action( 'init', 'register_book_type' );
function register_book_type () {
    class WC_Product_Book extends WC_Product_Variable {
        public function __construct( $product ) {
            parent::__construct( $product );
        }

        public function get_type() {
            return 'book';
        }
    }
}

However, when I post the product with its variation to the cart, the behavior messes up because the code $adding_to_cart->get_type() in add_to_cart_action() (in the WC_Form_Handler class) is identifying the product as my custom "book" type and not treating it as a "variable" product and falling back to treating it as a "simple" product type by default.

Here's that built-in WooCommerce area that's causing me trouble:

$add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );
if ( 'variable' === $add_to_cart_handler || 'variation' === $add_to_cart_handler ) {
    $was_added_to_cart = self::add_to_cart_handler_variable( $product_id );
} elseif ( 'grouped' === $add_to_cart_handler ) {
    $was_added_to_cart = self::add_to_cart_handler_grouped( $product_id );
} elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ) {
    do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url ); // Custom handler.
} else {
    $was_added_to_cart = self::add_to_cart_handler_simple( $product_id );
}

The problem seems to be that my own get_type() method returns "book" when this code is expecting "variable." I need it to return "book" so the product edit page will recognize the type properly.

I know I can remove and replace the add_to_cart_action() function in my own code to override this behavior and add my custom type, but then I'm unable to call all the other private methods in the WC_Form_Handler class. Or is it okay to just override that entire class..?

Any other way to bypass all this to get my variable-based custom product into the shopping cart?

like image 374
Raelshark Avatar asked Dec 03 '25 23:12

Raelshark


1 Answers

I believe you could change the handler to tell WooCommerce to use the variable product handler by filtering woocommerce_add_to_cart_handler like so:

function kia_custom_add_to_cart_handler( $handler, $adding_to_cart ){
    if( $handler == 'book' ){
        $handler = 'variable';
    }
    return $handler;
}
add_filter( 'woocommerce_add_to_cart_handler', 'kia_custom_add_to_cart_handler', 10, 2 );

OR

you could add the default variable product handler to the custom woocommerce_add_to_cart_handler_$type hook like so:

add_action( 'woocommerce_book_add_to_cart', 'woocommerce_variable_add_to_cart' );
like image 104
helgatheviking Avatar answered Dec 06 '25 14:12

helgatheviking