Adding custom post type / post to Woocommerce

We can try a easy thing .. you want a custom post type to store your products and when WooCommerce is integrated the added products in your custom post type can work as woocommerce products ..

  1. Check if woocommerce is installed ot not.

  2. If not, then Create a custom post type as 'product' (similar to woocommerce).

  3. Add the custom fields similar to Woocommerce and add the products under that. (Image added for the custom fields with Woocommerce)
  4. Now, add the products under custom post type , and when woocommerce will be added it will face a issue the custom post type already exist .
  5. So if in future you want to add woocommerce to your site disable you register_post_Type function and install the WooCommerce.
  6. All the products created in Custom post type will be visible in Woocommerce products options also

To check whether woocommerce is active or not use this code

<?php
    if ( class_exists( 'WooCommerce' ) ) {
      // code that requires WooCommerce
    } else {
      // you don't appear to have WooCommerce activated
    }
    ?>

enter image description here


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 to make it compatible with WooCommerce 3.0

But here 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.

WooCommerce Custom Post Type

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.

WooCommerce Custom Post Type


I have created a simple tutorial as to adding it here would be too long.

To achieved your goal, your post type must have a price. That said, the custom field for price should have a meta key _price.

if you already have a meta key which is not _price, you can add a filter to woocommerce_get_price shown below.

add_filter('woocommerce_get_price','reigel_woocommerce_get_price',20,2);
function reigel_woocommerce_get_price($price,$post){
    if ($post->post->post_type === 'post') // change this to your post type
        $price = get_post_meta($post->id, "price", true); // assuming your price meta key is price
    return $price;
}

With this, you can now add any post in your post type to the cart. Do so like http://localhost/wordpress/cart/?add-to-cart=1 where 1 is the ID of your post in your post type.

sample result image after visiting that link:

reigelgallarde.me

Now, you have to setup a form like below..

<form action="" method="post">
    <input name="add-to-cart" type="hidden" value="<?php echo $post->ID ?>" />
    <input name="quantity" type="number" value="1" min="1"  />
    <input name="submit" type="submit" value="Add to cart" />
</form>

you need to have this to get "Add to Cart" button. The name of the inputs are required to be as is.