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 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了