【发布时间】:2019-05-31 08:22:58
【问题描述】:
我正在使用带有 WPML 插件的 WooCommerce。当客户在某些条件下可以升级其产品但保持旧产品价格时,我想在结帐时实施一项功能。
产品是可变的,具有许多可变属性。 因此,更具体地说,我想要的是,如果客户在结帐时选择了 x 价格的特定产品变体(在特定条件下),我可以用其他产品的变体更改他的购物车商品,但保留 x 价格。
我首先尝试的是使用woocommerce_order_item_name 钩子仅更改产品名称,但更改并未遵循订单。这很重要,因为一些订单数据随后会发送到 API。
之后我使用了 "Changing WooCommerce cart item names" 答案代码,在我安装 WPML 之前,它非常适合我的目的。出于某种原因,WC_Cart 方法 set_name() 不适用于 WPML。我打开了a support thread,但他们仍然找不到解决方案。
任何人都可以提出任何其他解决方案吗?
更新
我尝试了一种方法,即删除购物车上的产品项目,然后添加我需要的产品。在我使用 set_price() 更改新添加项目的价格之后。删除/添加似乎正在工作,但一种语言的价格没有改变,并且在下订单后也不适用于两种语言。 这是我使用的代码:
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) {
$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( $cart_item['s-fare'] );
}
}
} else {
if (isset($cart_item['s-member-level']) && $cart_item['s-member-level'] == 3 && $product_id == 282) {
$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( $cart_item['s-fare']);
}
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'berrytaxiplon_change_product_name', 10, 1 );
知道为什么不应用 set_price() 方法吗?
更新 2
WPMl 使用 'woocommerce_before_calculate_totals' 并覆盖在 functions.php 上添加的操作
WPML 支持提供了一个使用 3 个过滤器的解决方案:
【问题讨论】:
-
您能否详细说明“某些条件”部分。这是用户在页面加载时执行或确定的某些操作还是类似的操作?
-
用户在结账前做出选择(跳过购物车页面,只能购买一种产品),作为项目元传递。如果此元存在并且选择了特定产品,我必须进行升级。
-
在这种情况下,做出选择后,您可以清空购物车并添加具有自定义价格的新产品,然后再重定向到结帐。我将在几分钟后将示例代码粘贴到答案中。
-
@thepi 请注意,“寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误 以及最短的代码有必要在问题本身中重现它。没有明确的问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Reproducible Example"。
-
@LoicTheAztec 如果我使用了错误的问题类别,我很抱歉。在 WPML 上打开支持线程之前,我几天前已经创建(但未发布)这个问题。这个问题更多的是关于如何处理这个问题的建议。
标签: wordpress woocommerce checkout wpml