I have a personal theme "A" and I want that it can also work without Woocommerce.
When Woocommerce "WC" plugin is added I would integrate A products with WC. I have a custom post type called "objects", how can I make "object" buyable throught WC?
I've alredy seen this answer on StackOverflow Adding Custom Post Types to Woocommerce
Where the solution in the end gives a free (not anymore) plugin to resolve.
I'd prefer to do this thing on my own, without helps of plugin. I'm curious and a pre-package solution isn't what i'm looking for.
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 ..
Check if woocommerce is installed ot not.
If not, then Create a custom post type as 'product' (similar to woocommerce).
- Add the custom fields similar to Woocommerce and add the products under that. (Image added for the custom fields with Woocommerce)
- 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 .
- So if in future you want to add woocommerce to your site disable you register_post_Type function and install the WooCommerce.
- 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
}
?>
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:
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.
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.
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.
I was facing the same issue. After spending days I figured out how it should work and its solution.
Here what I did
- Keep price meta as
_price
for my custom post
Changed the if
condition in class woocommerce/includes/class-wc-product-factory.php
's function get_product_class
like this:
before
if ( 'product' === $post_type){
after
if ( 'product' === $post_type || 'packages' === $post_type ){
It worked perfectly.
Now I want to change this product type using some filter method. Can anybody let me know about it:
if ( 'product' === $post_type || 'packages' === $post_type ){