使用WPML在WooCommerce上结帐和订购时更改产品名称

时间:2019-05-31 08:22:59

标签: wordpress woocommerce checkout wpml

我正在将WooCommerce与WPML插件一起使用。当客户在特定条件下可以升级其产品但保持旧产品价格时,我想在结帐时实现一项功能。

产品是可变的,具有许多可变属性。 因此,更具体地说,我想要的是,如果客户在结帐时(在一定条件下)选择了价格为x价格的特定产品变体,那么我可以使用其他产品的变体来更改其购物车商品,但保持x价格。

我首先尝试使用woocommerce_order_item_name钩子仅更改产品名称,但是更改不随订单而进行。这很重要,因为随后会将一些订单数据发送到API。

然后,我使用Changing WooCommerce cart item names应答代码,该代码可以很好地满足我的目的,直到我安装WPML。由于某些原因,WC_Cart方法set_name()不适用于WPML。我打开了a support thread,但他们仍然找不到解决方案。

有人可以建议其他解决方案吗?

2 个答案:

答案 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()未应用于辅助语言。但是,如果我重新加载结帐页面并再次发送数据,则将应用新价格。