【问题标题】:Set a calculated price for variable products in the WooCommerce在 WooCommerce 中为可变产品设置计算价格
【发布时间】:2018-08-24 18:02:17
【问题描述】:

在 Woocommerce 中,我使用自定义字段来计算产品的价格,基于此代码 - Add custom fields to custom product calculated price in Woocommerce。感谢 LoicTheAztec 的帮助。

// Add a custom field before single add to cart
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_price_field', 5 );
function custom_product_price_field(){
echo '<div class="custom-text text">
<h3>Rental</h3>
<label>Start Date:</label>
<input type="date" name="rental_date" value="" class="rental_date" />
<label>Period Rental:</label>
<select name="custom_price" class="custom_price">
    <option value="30" selected="selected">2 days</option>
    <option value="35">4 days</option> 
</select>
</div>';
}

// Get custom field value, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 2 );
function add_custom_field_data( $cart_item_data, $product_id ){
if ( isset($_POST['rental_date']) && ! empty($_POST['rental_date']) ){
    $cart_item_data['custom_data']['date'] = $_POST['rental_date'];
}
if ( isset($_POST['custom_price']) && ! empty($_POST['custom_price']) ){
    $product      = wc_get_product($product_id); // The WC_Product Object
    $base_price   = (float) $product->get_regular_price(); // Product reg price
    $custom_price = (float) sanitize_text_field( $_POST['custom_price'] );

    $cart_item_data['custom_data']['base_price'] = $base_price;
    $cart_item_data['custom_data']['new_price'] = $base_price * $custom_price/100;
    $cart_item_data['custom_data']['rental'] = $custom_price;
}
if ( isset($cart_item_data['custom_data']['new_price']) || isset($cart_item_data['custom_data']['date']) ){
    $cart_item_data['custom_data']['unique_key'] = md5( microtime() . rand() ); // Make each item unique
}
return $cart_item_data;
}

// Set the new calculated cart item price
add_action( 'woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1 );
function extra_price_add_custom_price( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
    return;

foreach ( $cart->get_cart() as $cart_item ) {
    if( isset($cart_item['custom_data']['new_price']) )
        $cart_item['data']->set_price( (float) $cart_item['custom_data']['new_price'] );
}
}

// Display cart item custom price details
add_filter('woocommerce_cart_item_price', 'display_cart_items_custom_price_details', 20, 3 );
function display_cart_items_custom_price_details( $product_price, $cart_item, $cart_item_key ){
if( isset($cart_item['custom_data']['new_price']) ) {
    $product        = $cart_item['data'];
    $new_price     = $cart_item['custom_data']['new_price'];
    $product_price  = wc_price( wc_get_price_to_display( $product, array( 'price' => $new_price ) ) ) . '<br>';
    if( isset($cart_item['custom_data']['rental']) ) {
        $product_price .= $cart_item['custom_data']['rental'] == '30' ? __("2 days") : __("4 days");
    }
}
return $product_price;
}

// Display in cart item the selected date
add_filter( 'woocommerce_get_item_data', 'display_custom_item_data', 10, 2 );
function display_custom_item_data( $cart_item_data, $cart_item ) {
if ( isset( $cart_item['custom_data']['date'] ) ){

    $cart_item_data[] = array(
        'name' => __("Chosen date", "woocommerce" ),
        'value' =>   date('d.m.Y', strtotime($cart_item['custom_data']['date'])),
    );
}
if ( isset( $cart_item['custom_data']['rental'] ) ){
    $cart_item_data[] = array(
        'name' => __("Period Rental", "woocommerce" ),
        'value' =>   $cart_item['custom_data']['rental'] == '30' ? __("2 days") : __("4 days"),         
    );
}
return $cart_item_data;
}

我决定创建一个新问题,因为我认为在这种情况下是合适的。

所有代码都可以正常工作,但是有一个问题。这段代码适用于简单的产品,我有很多变体产品。

此代码不显示变体产品的价格。它只显示日期和期间。

如何解决这个问题?有什么想法吗?

【问题讨论】:

    标签: php wordpress woocommerce cart custom-fields


    【解决方案1】:

    更新

    在您的代码中,您需要更改 woocommerce_add_cart_item_data() 函数,以处理产品变化。

    在这个钩子中还有其他一些参数可以用作$variation_id

    代码:

    // Add a custom field before single add to cart
    add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_price_field', 5 );
    function custom_product_price_field(){
        echo '<div class="custom-text text">
        <h3>Rental</h3>
        <label>Start Date:</label>
        <input type="date" name="rental_date" value="" class="rental_date" />
        <label>Period Rental:</label>
        <select name="custom_price" class="custom_price">
            <option value="30" selected="selected">2 days</option>
            <option value="35">4 days</option>
        </select>
        </div>';
    }
    
    // Get custom field value, calculate new item price, save it as custom cart item data
    add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 3 );
    function add_custom_field_data( $cart_item_data, $product_id, $variation_id ){
        if ( isset($_POST['rental_date']) && ! empty($_POST['rental_date']) ){
            $cart_item_data['custom_data']['date'] = $_POST['rental_date'];
        }
        if ( isset($_POST['custom_price']) && ! empty($_POST['custom_price']) ){
            $_product_id = $variation_id > 0 ? $variation_id : $product_id;
            $product      = wc_get_product($_product_id); // The WC_Product Object
            $base_price   = (float) $product->get_regular_price(); // Product reg price
            $custom_price = (float) sanitize_text_field( $_POST['custom_price'] );
    
            $cart_item_data['custom_data']['base_price'] = $base_price;
            $cart_item_data['custom_data']['new_price'] = $base_price/100 * $custom_price;
            $cart_item_data['custom_data']['rental'] = $custom_price;
        }
        if ( isset($cart_item_data['custom_data']['new_price']) || isset($cart_item_data['custom_data']['date']) ){
            $cart_item_data['custom_data']['unique_key'] = md5( microtime() . rand() ); // Make each item unique
        }
        return $cart_item_data;
    }
    
    // Set the new calculated cart item price
    add_action( 'woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1 );
    function extra_price_add_custom_price( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        foreach ( $cart->get_cart() as $cart_item ) {
            if( isset($cart_item['custom_data']['new_price']) )
                $cart_item['data']->set_price( (float) $cart_item['custom_data']['new_price'] );
        }
    }
    
    // Display cart item custom price details
    add_filter('woocommerce_cart_item_price', 'display_cart_items_custom_price_details', 20, 3 );
    function display_cart_items_custom_price_details( $product_price, $cart_item, $cart_item_key ){
        if( isset($cart_item['custom_data']['base_price']) ) {
            $product        = $cart_item['data'];
            $base_price     = $cart_item['custom_data']['base_price'];
            $product_price  = wc_price( wc_get_price_to_display( $product, array( 'price' => $base_price ) ) ) . '<br>';
            if( isset($cart_item['custom_data']['rental']) ) {
                $product_price .= $cart_item['custom_data']['rental'] == '30' ? __("2 days") : __("4 days");
            }
        }
        return $product_price;
    }
    
    // Display in cart item the selected date
    add_filter( 'woocommerce_get_item_data', 'display_custom_item_data', 10, 2 );
    function display_custom_item_data( $cart_item_data, $cart_item ) {
        if ( isset( $cart_item['custom_data']['date'] ) ){
    
            $cart_item_data[] = array(
                'name' => __("Chosen date", "woocommerce" ),
                'value' =>   date('d.m.Y', strtotime($cart_item['custom_data']['date'])),
            );
        }
        if ( isset( $cart_item['custom_data']['rental'] ) ){
            $cart_item_data[] = array(
                'name' => __("Period Rental", "woocommerce" ),
                'value' =>   $cart_item['custom_data']['rental'] == '30' ? __("2 days") : __("4 days"),
            );
        }
        return $cart_item_data;
    }
    

    代码进入您的活动子主题(或活动主题)的 function.php 文件中。经过测试并且可以工作。

    【讨论】:

      猜你喜欢
      • 2018-07-25
      • 1970-01-01
      • 2019-02-12
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      相关资源
      最近更新 更多