我正在使用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' );
没有工作
答案 0 :(得分:1)
在最新版本3.0中。* Woocommcerce用于硬检查return handleActions({
[FOOBAR]: (state) => {
console.log('I LOG ALL THE THINGS');
return {...state, value: 'the user clicked something 2'};
}
}, {});
你可以覆盖它
$post_type === 'product'
然后通过hook包含此文件;
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;
}
添加到购物车,例如http://localhost/wordpress/cart/?add-to-cart=244,则会将该项目添加到购物车。
您也可以使用按钮添加到购物车。
add-to-cart=[POST_ID]
答案 1 :(得分:1)
解决了这个问题,由于以上代码无法正常工作,因此我继续制作了一个可行的版本。请注意,此代码(至少)可用于 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 );
答案 2 :(得分:0)
如果您已有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;
}