【问题标题】:woocommerce add custom post type to cartwoocommerce 将自定义帖子类型添加到购物车
【发布时间】:2017-04-05 14:04:51
【问题描述】:

我正在使用 woocommerce,我创建了一个自定义帖子类型,必须将其视为产品,用户可以添加到购物车。我跟着这个教程 http://reigelgallarde.me/programming/how-to-add-custom-post-type-to-woocommerce/ 并确保我的价格字段元键是“_price” 但它没有用。

当我尝试将此代码添加到functions.php时

function reigel_woocommerce_get_price($price = null,$post = null){
if ($post->post->post_type === 'aytam'){
    $price = get_post_meta($post->id, "_price", true);
    }

return $price;
}
add_filter('woocommerce_get_price','reigel_woocommerce_get_price',20,1);
add_action( 'init', 'reigel_woocommerce_get_price' );

也没有用

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    如果您已经有一个元键 not _price,您可以向woocommerce_get_price 添加一个过滤器,如下所示。

      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); // your price meta key is price
            return $price;
        }
    

    【讨论】:

    • 对我不起作用,我使用了自定义产品类型。但感谢您的帮助:)
    • 对我不起作用,因为在最新版本 3.0 中。* 有很多东西发生了变化。仍在寻找解决方案。
    【解决方案2】:

    在最新版本 3.0 中。* Woocommcerce 用于硬检查 $post_type === 'product' 您可以覆盖它

    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 );
        }
    
    
    }
    

    然后通过钩子包含这个文件;

    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;
    }
    

    使用此过滤器从自定义元数据中提供价格;

    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;
    }
    

    现在,如果您尝试使用 url 参数 add-to-cart=[POST_ID] 添加到购物车,例如 http://localhost/wordpress/cart/?add-to-cart=244 会将商品添加到购物车。

    您也可以使用按钮添加到购物车。

            <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>
    

    【讨论】:

      【解决方案3】:

      一直在解决这个问题,由于上面的代码不起作用,我继续制作了一个工作版本。请注意,此代码适用于 Woocommerce 3.6.2(至少)并且旨在使其适用于自定义帖子类型 industry-ad ,但您可以更改为您的渴望

      class IA_Woo_Product extends WC_Product  {
      
          protected $post_type = 'industry-ad';
      
          public function get_type() {
              return 'industry-ad';
          }
      
          public function __construct( $product = 0 ) {
              $this->supports[]   = 'ajax_add_to_cart';
      
              parent::__construct( $product );
      
      
          }
          // maybe overwrite other functions from WC_Product
      
      }
      
      class IA_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 || 'industry-ad' !== $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 IA_WC_Order_Item_Product extends WC_Order_Item_Product {
          public function set_product_id( $value ) {
              if ( $value > 0 && 'industry-ad' !== 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 IA_woocommerce_data_stores( $stores ) {
          // the search is made for product-$post_type so note the required 'product-' in key name
          $stores['product-industry-ad'] = 'IA_Data_Store_CPT';
          return $stores;
      }
      add_filter( 'woocommerce_data_stores', 'IA_woocommerce_data_stores' , 11, 1 );
      
      
      function IA_woo_product_class( $class_name ,  $product_type ,  $product_id ) {
          if ($product_type == 'industry-ad')
              $class_name = 'IA_Woo_Product';
          return $class_name; 
      }
      add_filter('woocommerce_product_class','IA_woo_product_class',25,3 );
      
      
      
      function my_woocommerce_product_get_price( $price, $product ) {
      
          if ($product->get_type() == 'industry-ad' ) {
              $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 IA_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 == 'industry-ad' && $post->ID == $product_id) 
                      return 'industry-ad';
                  else {
                      $product = get_post( $product_id );
                      if (is_object($product) && !is_wp_error($product)) { // post not set but it's a industry-ad
                          if ($product->post_type == 'industry-ad') 
                              return 'industry-ad';
                      } // 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 == 'industry-ad') 
                      return 'industry-ad';
              } else { 
                  $product = get_post( $product_id );
                  if (is_object($product) && !is_wp_error($product)) { // post not set but it's a industry-ad
                      if ($product->post_type == 'industry-ad') 
                          return 'industry-ad';
                  } // end if 
      
              } // end if  // end if 
      
      
      
          } // end if 
          return false;
      }
      add_filter('woocommerce_product_type_query','IA_woo_product_type',12,2 );
      
      function IA_woocommerce_checkout_create_order_line_item_object($item, $cart_item_key, $values, $order) {
      
          $product                    = $values['data'];
          if ($product->get_type() == 'industry-ad') {
              return new IA_WC_Order_Item_Product();
          } // end if 
          return $item ;
      }   
      add_filter( 'woocommerce_checkout_create_order_line_item_object', 'IA_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() == 'industry-ad') {
              $item->update_meta_data( '_industry-ad', '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 IA_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 = '_industry-ad'");
      
      
          if ('yes' === $is_IA) { // load the new class if the item is our custom post
              $classname = 'IA_WC_Order_Item_Product';
          } // end if 
          return $classname;
      }
      add_filter( 'woocommerce_get_order_item_classname', 'IA_woocommerce_get_order_item_classname', 20, 3 );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-14
        • 2018-05-18
        • 2015-12-04
        • 2015-11-28
        • 2015-05-27
        • 1970-01-01
        相关资源
        最近更新 更多