I can still add custom post type to cart in WooCommerce 2.6 just by adding a filter to 'woocommerce_product_class'
function wc_product_class( $class, $product_type, $post_type ) {
if( 'my_custom_post_type_slug' == $post_type )
$class = 'WC_Product_Simple';
return $class;
}
add_filter( 'woocommerce_product_class', 'wc_product_class', 10, 3);
//This will echo the carti item id
echo WC()->cart->add_to_cart($custom_post_type_id, $quantity, null, null, array());
Unfortunately this doesn't already work on the latest version of WooCommerce. Would somebody please help me what is the solution for this issue? Any suggestions, comments, solutions are much appreciated.
I'm selling a plugin that would enable to use Custom Post Type as "product" of WooCommerce. I did a lot of work on that.
But this is the most important part.
You have to create your own data store, like this:
first create a class that extends to WC_Product_Data_Store_CPT
. The idea is to overwrite the existing function of this class that check the post type. I found read
and get_product_type
that does the checking.
class WCCPT_Product_Data_Store_CPT extends WC_Product_Data_Store_CPT {
/**
* Method to read a product from the database.
* @param WC_Product
*/
public function read( &$product ) {
$product->set_defaults();
if ( ! $product->get_id() || ! ( $post_object = get_post( $product->get_id() ) ) || ! in_array( $post_object->post_type, array( 'birds', 'product' ) ) ) { // change birds with your post type
throw new Exception( __( 'Invalid product.', 'woocommerce' ) );
}
$id = $product->get_id();
$product->set_props( array(
'name' => $post_object->post_title,
'slug' => $post_object->post_name,
'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null,
'date_modified' => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null,
'status' => $post_object->post_status,
'description' => $post_object->post_content,
'short_description' => $post_object->post_excerpt,
'parent_id' => $post_object->post_parent,
'menu_order' => $post_object->menu_order,
'reviews_allowed' => 'open' === $post_object->comment_status,
) );
$this->read_attributes( $product );
$this->read_downloads( $product );
$this->read_visibility( $product );
$this->read_product_data( $product );
$this->read_extra_data( $product );
$product->set_object_read( true );
}
/**
* Get the product type based on product ID.
*
* @since 3.0.0
* @param int $product_id
* @return bool|string
*/
public function get_product_type( $product_id ) {
$post_type = get_post_type( $product_id );
if ( 'product_variation' === $post_type ) {
return 'variation';
} elseif ( in_array( $post_type, array( 'birds', 'product' ) ) ) { // change birds with your post type
$terms = get_the_terms( $product_id, 'product_type' );
return ! empty( $terms ) ? sanitize_title( current( $terms )->name ) : 'simple';
} else {
return false;
}
}
}
after that, add a filter to woocommerce_data_stores
and use your class.
add_filter( 'woocommerce_data_stores', 'woocommerce_data_stores' );
function woocommerce_data_stores ( $stores ) {
$stores['product'] = 'WCCPT_Product_Data_Store_CPT';
return $stores;
}
with that, you'll be able to add a post type of birds
to cart. But will not actually be a success add to cart. Because there's no price, cart will reject it.
To solve that, you need another filter. Below is a simple way of adding the price.
add_filter('woocommerce_product_get_price', 'woocommerce_product_get_price', 10, 2 );
function woocommerce_product_get_price( $price, $product ) {
if ($product->get_id() == 815 ) {
$price = 10;
}
return $price;
}
Once that's done, you'll have success adding to cart.