How to integrate Custom Post Type in WooCommerce and update pricing

How to integrate Custom Post Type in WooCommerce and update pricing

WooCommerce is one of the best Online Shipping and open source systems in WordPress. WooCommerce is used for Online Store, Digital Store, Donation System, Services and Consulting Websites and much more. It is designed to be used for small and large scale online merchandising websites built with WordPress.

WooCommerce is a huge and flexible eCommerce system as well as offers ample extensions that are used to enhance the functionality of WooCommerce website.

Extensions developers of WooCommerce also have to give immense development hooks and flexibility so that they can develop any kind of extensions using WooCommerce. Agencies or developers can meet any of their client’s needs using WooCommerce.

Today, we’ll describe a little trick that is needs of many developers in which we’ll tell you how to register custom post type and then integrate it into WooCommerce.

Let’s Start with Registering a Post Type

In WordPress, if you doing some customization in Child Theme or a Plugin. You can write the below code at the top level either in plugin’s root file or in functions.php in your child theme.

You can read more about registering custom post type on WordPress developers resources. Here we are going to register a customer post type “Books”

/**
 * Register a custom post type called "book".
 *
 * @see get_post_type_labels() for label keys.
 */
function wpdocs_codex_book_init() {
    $labels = array(
        'name'                  => _x( 'Books', 'Post type general name', 'textdomain' ),
        'singular_name'         => _x( 'Book', 'Post type singular name', 'textdomain' ),
        'menu_name'             => _x( 'Books', 'Admin Menu text', 'textdomain' ),
        'name_admin_bar'        => _x( 'Book', 'Add New on Toolbar', 'textdomain' ),
        'add_new'               => __( 'Add New', 'textdomain' ),
        'add_new_item'          => __( 'Add New Book', 'textdomain' ),
        'new_item'              => __( 'New Book', 'textdomain' ),
        'edit_item'             => __( 'Edit Book', 'textdomain' ),
        'view_item'             => __( 'View Book', 'textdomain' ),
        'all_items'             => __( 'All Books', 'textdomain' ),
        'search_items'          => __( 'Search Books', 'textdomain' ),
        'parent_item_colon'     => __( 'Parent Books:', 'textdomain' ),
        'not_found'             => __( 'No books found.', 'textdomain' ),
        'not_found_in_trash'    => __( 'No books found in Trash.', 'textdomain' ),
        'featured_image'        => _x( 'Book Cover Image', 'Overrides the “Featured Image” phrase for this post type. Added in 4.3', 'textdomain' ),
        'set_featured_image'    => _x( 'Set cover image', 'Overrides the “Set featured image” phrase for this post type. Added in 4.3', 'textdomain' ),
        'remove_featured_image' => _x( 'Remove cover image', 'Overrides the “Remove featured image” phrase for this post type. Added in 4.3', 'textdomain' ),
        'use_featured_image'    => _x( 'Use as cover image', 'Overrides the “Use as featured image” phrase for this post type. Added in 4.3', 'textdomain' ),
        'archives'              => _x( 'Book archives', 'The post type archive label used in nav menus. Default “Post Archives”. Added in 4.4', 'textdomain' ),
        'insert_into_item'      => _x( 'Insert into book', 'Overrides the “Insert into post”/”Insert into page” phrase (used when inserting media into a post). Added in 4.4', 'textdomain' ),
        'uploaded_to_this_item' => _x( 'Uploaded to this book', 'Overrides the “Uploaded to this post”/”Uploaded to this page” phrase (used when viewing media attached to a post). Added in 4.4', 'textdomain' ),
        'filter_items_list'     => _x( 'Filter books list', 'Screen reader text for the filter links heading on the post type listing screen. Default “Filter posts list”/”Filter pages list”. Added in 4.4', 'textdomain' ),
        'items_list_navigation' => _x( 'Books list navigation', 'Screen reader text for the pagination heading on the post type listing screen. Default “Posts list navigation”/”Pages list navigation”. Added in 4.4', 'textdomain' ),
        'items_list'            => _x( 'Books list', 'Screen reader text for the items list heading on the post type listing screen. Default “Posts list”/”Pages list”. Added in 4.4', 'textdomain' ),
    );
 
    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'book' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
    );
 
    register_post_type( 'book', $args );
}
 
add_action( 'init', 'wpdocs_codex_book_init' );

Integration with WooCommerce

Now You’ll have to create a new PHP OOP Class and extend it to WC_Product_Data_Store_CPT. Then implement it to WC_Object_Data_Store_Interface, WC_Product_Data_Store_Interface as these are the WooCommerce core interfaces.

class My_Product_Data_Store_CPT extends WC_Product_Data_Store_CPT implements WC_Object_Data_Store_Interface, WC_Product_Data_Store_Interface {


    /**
     * 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() ) ) || 'product' !== $post_object->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 );
    }


}

Then call this class via filter hook as below

add_filter( 'woocommerce_data_stores', 'my_woocommerce_data_stores' );
function my_woocommerce_data_stores( $stores ) {

    require_once PLUGIN_PATH . '/includes/classes/class-data-store-cpt.php';
    $stores['product'] = 'MY_Product_Data_Store_CPT';

    return $stores;
}

Now we’ll have to set the price via filter so whenever user adds item to cart. WooCommerce should use our price. Also we can use this filter on card and checkout pages.

add_filter('woocommerce_product_get_price', 'my_woocommerce_product_get_price', 10, 2 );
function my_woocommerce_product_get_price( $price, $product ) {

    if ($product->get_id() == 815 ) {
        $price = 10;        
    }
    return $price;
}

We’ll create a URL so user clicks on it to add an item to cart like http://localhost/wordpress/?add-to-cart=244 will add the item to cart.

Here is an example of how to create add to cart button.

<form action="" method="post">
      <input name="add-to-cart" type="hidden" value="<?php the_ID(); ?>" />
      <input name="quantity" type="number" value="1" min="1"  />
      <input name="submit" type="submit" value="Add to cart" />
</form>

Conclusion

Here is what we have learnt. Registering a new custom Post type in WordPress. Integrating the custom post type in WooCommerce. Using our price whenever a user adds in item to cart. image source

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.