Support

Account

Home Forums Front-end Issues Price field as WooCommerce price

Solved

Price field as WooCommerce price

  • I’ve seen online that you can add all Custom Post Types to a WooCommerce cart as long as the CPT has a price field. The only issue is that you have to tell WooCommerce what CPT field contains the price.

    Afterwords you can create an add-to-cart url like this:
    https://yourdomain.com/?add-to-cart=XXX (XXX being the Custom Post Type post ID)

    Why is this handy?
    I have an online menu (just to inform guest what we order) but because of Corona we have to close our doors so I want these dishes to be ordered online.

    The code should be something like this but the CPT is not added to cart:

    
    add_filter('woocommerce_get_price', 'yl_get_dish_price', 20,2);
    function yl_get_dish_price($price,$post) {
    	if ($post->post->post_type === 'dish') {
    		$price = get_field('price', $post->ID);
    	}
    	return $price;
    }
    
  • The following code adds the CPT (dish in my case) to the WooCommerce cart but the price is incorrect. It always displays € 10,00

    
    class YL_Dish_Product extends WC_Product  {
    
        protected $post_type = 'dish';
    
        public function get_type() {
            return 'dish';
        }
    
        public function __construct( $product = 0 ) {
            $this->supports[]   = 'ajax_add_to_cart';
    
            parent::__construct( $product );
    
        }
        // maybe overwrite other functions from WC_Product
    
    }
    
    class YL_Data_Store_CPT extends WC_Product_Data_Store_CPT {
    
        public function read( &$product ) { // this is required
            $product->set_defaults();
            $post_object = get_post( $product->get_id() );
    
            if ( ! $product->get_id() || ! $post_object || 'dish' !== $post_object->post_type ) {
    
                throw new Exception( __( 'Invalid product.', 'woocommerce' ) );
            }
    
            $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 );
        }
    
        // maybe overwrite other functions from WC_Product_Data_Store_CPT
    
    }
    
    class YL_WC_Order_Item_Product extends WC_Order_Item_Product {
        public function set_product_id( $value ) {
            if ( $value > 0 && 'dish' !== get_post_type( absint( $value ) ) ) {
                $this->error( 'order_item_product_invalid_product_id', __( 'Invalid product ID', 'woocommerce' ) );
            }
            $this->set_prop( 'product_id', absint( $value ) );
        }
    
    }
    
    function YL_woocommerce_data_stores( $stores ) {
        // the search is made for product-$post_type so note the required 'product-' in key name
        $stores['product-dish'] = 'YL_Data_Store_CPT';
        return $stores;
    }
    add_filter( 'woocommerce_data_stores', 'YL_woocommerce_data_stores' , 11, 1 );
    
    function YL_woo_product_class( $class_name ,  $product_type ,  $product_id ) {
        if ($product_type == 'dish')
            $class_name = 'YL_Dish_Product';
        return $class_name; 
    }
    add_filter('woocommerce_product_class','YL_woo_product_class',25,3 );
    
    function my_woocommerce_product_get_price( $price, $product ) {
    
        if ($product->get_type() == 'dish' ) {
            $price = 10;  // or get price how ever you see fit     
        }
        return $price;
    }
    add_filter('woocommerce_get_price','my_woocommerce_product_get_price',20,2);
    add_filter('woocommerce_product_get_price', 'my_woocommerce_product_get_price', 10, 2 );
    
    // required function for allowing posty_type to be added; maybe not the best but it works
    function YL_woo_product_type($false,$product_id) { 
        if ($false === false) { // don't know why, but this is how woo does it
            global $post;
            // maybe redo it someday?!
            if (is_object($post) && !empty($post)) { // post is set
                if ($post->post_type == 'dish' && $post->ID == $product_id) 
                    return 'dish';
                else {
                    $product = get_post( $product_id );
                    if (is_object($product) && !is_wp_error($product)) { // post not set but it's a dish
                        if ($product->post_type == 'dish') 
                            return 'dish';
                    } // end if 
                }    
    
            } else if(wp_doing_ajax()) { // has post set (usefull when adding using ajax)
                $product_post = get_post( $product_id );
                if ($product_post->post_type == 'dish') 
                    return 'dish';
            } else { 
                $product = get_post( $product_id );
                if (is_object($product) && !is_wp_error($product)) { // post not set but it's a dish
                    if ($product->post_type == 'dish') 
                        return 'dish';
                } // end if 
    
            } // end if  // end if 
    
        } // end if 
        return false;
    }
    add_filter('woocommerce_product_type_query','YL_woo_product_type',12,2 );
    
    function YL_woocommerce_checkout_create_order_line_item_object($item, $cart_item_key, $values, $order) {
    
        $product                    = $values['data'];
        if ($product->get_type() == 'dish') {
            return new YL_WC_Order_Item_Product();
        } // end if 
        return $item ;
    }   
    add_filter( 'woocommerce_checkout_create_order_line_item_object', 'YL_woocommerce_checkout_create_order_line_item_object', 20, 4 );
    
    function cod_woocommerce_checkout_create_order_line_item($item,$cart_item_key,$values,$order) {
        if ($values['data']->get_type() == 'dish') {
            $item->update_meta_data( '_dish', 'yes' ); // add a way to recognize custom post type in ordered items
            return;
        } // end if 
    
    }
    add_action( 'woocommerce_checkout_create_order_line_item', 'cod_woocommerce_checkout_create_order_line_item', 20, 4 );
    
    function YL_woocommerce_get_order_item_classname($classname, $item_type, $id) {
        global $wpdb;
        $is_IA = $wpdb->get_var("SELECT meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = {$id} AND meta_key = '_dish'");
    
        if ('yes' === $is_IA) { // load the new class if the item is our custom post
            $classname = 'YL_WC_Order_Item_Product';
        } // end if 
        return $classname;
    }
    add_filter( 'woocommerce_get_order_item_classname', 'YL_woocommerce_get_order_item_classname', 20, 3 );
    

    Any idea how to get the price field right? This doesn’t work:

    
    add_filter('woocommerce_get_price', 'yl_get_dish_price', 20,2);
    function yl_get_dish_price($price,$post) {
    	if ($post->post_type === 'dish') {
    		$price = get_field('price', $post->ID);
    	}
    	return $price;
    }
    
  • 
    add_filter( 'woocommerce_product_get_price', 'yl_get_dish_price', 20, 2 );
    add_filter( 'woocommerce_product_get_regular_price', 'yl_get_dish_price', 20, 2 );
    function yl_get_dish_price( $price, $product ) {
        if ( $product->is_type('dish') ) {
            $price = get_field( 'price', $product->get_id() );
        }
        return $price;
    }
    
Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.