douan4347 2019-03-06 13:14
浏览 63
已采纳

显示Woocommerce订阅中每月的变化价格

I have three subscription products, yearly, half-yearly and monthly. By default, prices are shown per year, per every 6 months and per month on my Shop page.

Based on "Change product prices via a hook in WooCommerce 3" answer code, I am trying to display all the prices per month, so to change the price display based on the subscription term:

// Utility function to change the prices with a multiplier (number)
function get_price_multiplier($var_product) {
    switch($var_product) {
        case 111:
            // Annual
            return 12;
            break;
        case 222:
            // Semiannual
            return 6;
            break;
        case 333:
            // Month
            return 1;
            break;          
        default:
            return 1;
            break;
    }
}

add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
    $var_product = $product->get_id();
    return $price / get_price_multiplier($var_product);
}

This worked but when a product is added to the cart, the price is not the regular price but the modified price from the function above.

Based on "Set programmatically product sale price and cart item prices in Woocommerce 3" answer code, I have been able to fix that:

add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
function set_cart_item_sale_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Iterate through each cart item
    foreach( $cart->get_cart() as $cart_item ) {
        $regular_price = $cart_item['data']->get_regular_price();
        $variation_id = $cart_item['variation_id'];
        $cart_item['data']->set_price( $regular_price * get_price_multiplier($variation_id) );
    }
}

This reset the cart price and it seems to work although one of the prices is off by a penny.

Is this all convoluted and prone to problems or is it a solid way to achieve what I am after: to show the price per subscription term on the shop page?

  • 写回答

1条回答 默认 最新

  • dongzuozhu66776 2019-03-06 14:39
    关注

    You are doing it in the right way… There is 2 ways (the last is the best one):

    Note: The calculation and the price change is not needed when the multiplier is equal to 1.

    1) First alternative: Improved code version that is very similar to yours.

    Here is my commented code:

    // Utility function that increase conditionally the variation price with a multiplier (int)
    function get_variation_calculated_price( $variation_id, $price, $multiplier = true ) {
        switch( $variation_id ) {
            case 111: // Annual
                $rate = 12;
                break;
    
            case 222: // Semi-annual
                $rate = 6;
                break;
    
            default: // Month (and others)
                $rate = 1;
                break;
        }
        // Return calculated price (or false when multiplier is 1, as calculation is not needed)
        return $rate !== 1 ? ( $multiplier ? $price * $rate : $price / $rate ) : false;
    }
    
    
    // Change variations calculated prices
    add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
    function custom_price( $price, $variation ) {
        if( $new_price = get_variation_calculated_price( $variation->get_id(), $price, false ) )
            return $new_price;
    
        return $price;
    }
    
    // Customizing cart item prices
    add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
    function set_cart_item_sale_price( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Required since Woocommerce version 3.2 for cart items properties changes
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        // Loop  through cart items
        foreach( $cart->get_cart() as $cart_item ) {
            // Only for variations
            if( $cart_item['variation_id'] > 0 ) {
                if( $new_price = get_variation_calculated_price( $cart_item['variation_id'], $cart_item['data']->get_price() ) ) {
                    $cart_item['data']->set_price( $new_price );
                }
            }
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.


    2) Second Alternative: much more accurate and lighter, restricting the product price avoiding price change on cart, checkout and backend.

    Note: You will need to avoid displaying Cross-sells products in cart page (as the prices will not be changed like in shop page).

    So the code will be more light, compact and efficient:

    // Utility function that increase conditionally the variation price with a multiplier (int)
    function get_variation_calculated_price( $variation_id, $price ) {
        switch( $variation_id ) {
            case 111: // Annual
                $rate = 12;
                break;
    
            case 939: // Semi-annual
                $rate = 6;
                break;
    
            default: // Month (and others)
                $rate = 1;
                break;
        }
        // Return calculated price (or false when multiplier is 1, as calculation is not needed)
        return $rate !== 1 ? $price / $rate : false;
    }
    
    
    // Change variations calculated prices
    add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
    function custom_price( $price, $variation ) {
        // Not in cart, checkout and admin
        if( is_cart() || is_checkout() || is_admin() ) 
            return $price;
    
        if( $new_price = get_variation_calculated_price( $variation->get_id(), $price ) )
            return $new_price;
    
        return $price;
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 高价求中通快递查询接口
  • ¥15 解决一个加好友限制问题 或者有好的方案
  • ¥15 关于#java#的问题,请各位专家解答!
  • ¥15 急matlab编程仿真二阶震荡系统
  • ¥20 TEC-9的数据通路实验
  • ¥15 ue5 .3之前好好的现在只要是激活关卡就会崩溃
  • ¥50 MATLAB实现圆柱体容器内球形颗粒堆积
  • ¥15 python如何将动态的多个子列表,拼接后进行集合的交集
  • ¥20 vitis-ai量化基于pytorch框架下的yolov5模型
  • ¥15 如何实现H5在QQ平台上的二次分享卡片效果?