我正在将WooCommerce与WPML插件一起使用。当客户在特定条件下可以升级其产品但保持旧产品价格时,我想在结帐时实现一项功能。
产品是可变的,具有许多可变属性。 因此,更具体地说,我想要的是,如果客户在结帐时(在一定条件下)选择了价格为x价格的特定产品变体,那么我可以使用其他产品的变体来更改其购物车商品,但保持x价格。
我首先尝试使用woocommerce_order_item_name
钩子仅更改产品名称,但是更改不随订单而进行。这很重要,因为随后会将一些订单数据发送到API。
然后,我使用“ Changing WooCommerce cart item names” 应答代码,该代码可以很好地满足我的目的,直到我安装WPML。由于某些原因,WC_Cart
方法set_name()
不适用于WPML。我打开了a support thread,但他们仍然找不到解决方案。
有人可以建议其他解决方案吗?
答案 0 :(得分:0)
所以这是我在一个项目中使用的代码,用于基于一些过滤器和所选产品向购物车添加产品变体:
$product = new WC_Product($product_id); //The main product whose variation has to be added
$product_name = $product->get_name(); //Name of the main product
$quantity = sanitize_text_field($cData['quantity']); //You can set this to 1
$variation_id = sanitize_text_field($cData['variation_id']); //I had the variation ID from filters
$variation = array(
'pa_duration' => sanitize_text_field($cData['duration']) //The variation slug was also available for me.
);
$cart_item_data = array('custom_price' => sanitize_text_field($custom_price));
$cart = WC()->cart->add_to_cart( (int)$product_id, (int)$quantity, (int)$variation_id, $variation, $cart_item_data ); //This will add products to cart but with the actual price of the variation being added and meta data holding the custom price.
WC()->cart->calculate_totals();
WC()->cart->set_session();
WC()->cart->maybe_set_cart_cookies();
然后,您需要在计算购物车总额之前进行检查,并将价格设置为自定义价格,如下所示:
function woocommerce_custom_price_to_cart_item( $cart_object ) {
if( !WC()->session->__isset( "reload_checkout" )) {
foreach ( $cart_object->cart_contents as $key => $value ) {
if( isset( $value["custom_price"] ) ) {
$value['data']->set_price($value["custom_price"]);
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'woocommerce_custom_price_to_cart_item', 99 );
答案 1 :(得分:0)
Faham提供的代码非常有用,但是导致结帐的页面模板已经过于复杂,因此我一直在尝试使用“ woocommerce_before_calculate_totals”挂钩上的逻辑。 因此,我没有尝试更改名称,而是删除了该项并添加了新项。然后调用一个新的循环,我将价格设置为已删除商品的价格。
function berrytaxiplon_change_product_name( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Get an instance of the WC_Product object
$product = $cart_item['data'];
// Get the product name (Added Woocommerce 3+ compatibility)
$product_id = method_exists( $product, 'get_parent_id' ) ? $product->get_parent_id() : $product->post->post_parent;
if ( ICL_LANGUAGE_CODE == 'en') {
if (isset($cart_item['s-member-level']) && $cart_item['s-member-level'] == 3 && $product_id == 12) {
// SET THE NEW NAME
$new_product = wc_get_product( 82 );
$atrributes = $product->get_attributes('view');
foreach ($atrributes as $atrribute_key => $atrribute_value) {
$new_attributes['attribute_' . $atrribute_key] = strtolower($atrribute_value);
}
$new_variation_id = find_matching_product_variation_id(82, $new_attributes);
$cart->remove_cart_item( $cart_item_key );
$cart->add_to_cart( 82, 1, $new_variation_id, $new_attributes, $cart_item );
foreach ( WC()->cart->get_cart() as $new_item ) {
$new_item['data']->set_price( get_post_meta( $cart_item['variation_id'], '_price', true ) );
}
}
} else {
if (isset($cart_item['s-member-level']) && $cart_item['s-member-level'] == 3 && $product_id == 282) {
// SET THE NEW NAME
$new_product = wc_get_product( 303 );
$atrributes = $product->get_attributes('view');
foreach ($atrributes as $atrribute_key => $atrribute_value) {
$new_attributes['attribute_' . $atrribute_key] = strtolower($atrribute_value);
}
$new_variation_id = find_matching_product_variation_id(303, $new_attributes);
$cart->remove_cart_item( $cart_item_key );
$cart->add_to_cart( 303, 1, $new_variation_id, $new_attributes, $cart_item );
foreach ( WC()->cart->get_cart() as $new_item ) {
$new_item['data']->set_price( get_post_meta( $cart_item['variation_id'], '_price', true ) );
}
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'berrytaxiplon_change_product_name', 10, 1 );
我使用下面的函数来匹配问题WooCommerce: Get Product Variation ID from Matching Attributes的属性
function find_matching_product_variation_id($product_id, $attributes)
{
return (new \WC_Product_Data_Store_CPT())->find_matching_product_variation(
new \WC_Product($product_id),
$attributes
);
}
我对$ cart_item中使用add_to_cart()和第二个foreach()表示怀疑。但是我进行了测试,它似乎可以正常运行。
更新
实际上,此代码(或再次与WPML)存在问题。似乎set_price()未应用于辅助语言。但是,如果我重新加载结帐页面并再次发送数据,则将应用新价格。