提问者:小点点

为什么Woocommerce在Woocommerce\u add\u cart\u item\u data hook中以编程方式更新价格不起作用


我有两种产品:1-有固定价格的产品2-有计算价格的产品

我在产品页面表单中添加了一些隐藏字段,代码如下:

function agop_plugin_add_text_field() { 
    global $product;
    // print_r($product);
    if ( agop_use_calculated_price($product->get_ID()) ) {
        echo '<input type="text" name="agop-new-price" id="agop-new-price" value="'. agop_calculate_product_price($product->get_ID()) .'">';    
    }
?>

    <input type="hidden" name='agop-date-shamsi' id='agop-date-shamsi' value=''>
    <input type="hidden" name='agop-date-miladi' id='agop-date-miladi' value=''>
    <input type="hidden" name='agop-shipping-method' id='agop-shipping-method' value=''>
    <input type="hidden" name='agop-shipping-method-price' id='agop-shipping-method-price' value=''>
    <input type="hidden" name='agop-shipping-method-price-number' id='agop-shipping-method-price-number' value=''>
    <input type="hidden" name='agop-shipping-time'   id='agop-shipping-time' value=''>
    
    <div id="selectedDateTimeMethod">
        <div id="dtmDatesWrapper">
            <span id="dtmDateShamsi"></span>
            <span id="dtmEqual">&nbsp; = &nbsp;</span>
            <span id="dtmDateMiladi"></span>
        </div>
        <div id="dtmMethodWrapper">
            <span id="dtmMethodName"></span>
            <span id="dtmMethodPrice"></span>
        </div>
        <div id="dtmTimeWrapper">
            <span id="dtmMethodTime"></span>
        </div>
        <div id="dtmTotalPriceWrapper">
            <span id="dtmMethodTime"></span>
        </div>
    </div>
<?php }
add_action( 'woocommerce_before_add_to_cart_button', 'agop_plugin_add_text_field' );

并通过以下方式将这些字段数据发送到购物车项:

function agop_plugin_add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
    
    if( isset( $_POST['agop-date-shamsi'] ) ) {
        $cart_item_data['agop_date_shamsi'] = sanitize_text_field( $_POST['agop-date-shamsi'] );
    }

    if( isset( $_POST['agop-date-miladi'] ) ) {
        $cart_item_data['agop_date_miladi'] = sanitize_text_field( $_POST['agop-date-miladi'] );
    }

    if( isset( $_POST['agop-shipping-method'] ) ) {
        $cart_item_data['agop_shipping_method'] = sanitize_text_field( $_POST['agop-shipping-method'] );
    }

    if( isset( $_POST['agop-shipping-method-price'] ) ) {
        $cart_item_data['agop_shipping_method_price'] = sanitize_text_field( $_POST['agop-shipping-method-price'] );
    }

    $product = wc_get_product( $product_id );
    $final_price = $product->get_price();
    
    if( isset( $_POST['agop-new-price'] ) && filter_var( $_POST['agop-new-price'], FILTER_VALIDATE_INT)) {
        // $cart_item_data['agop_new_price'] = sanitize_text_field( $_POST['agop-new-price'] );
        $final_price =  floatval(sanitize_text_field( $_POST['agop-new-price'] ));

        error_log('isset( $_POST[agop-new-price] FIRED---- '.$final_price);
    }

    if( isset( $_POST['agop-shipping-method-price-number'] ) && filter_var( $_POST['agop-shipping-method-price-number'], FILTER_VALIDATE_INT) ) {
        // $cart_item_data['product_price_with_shipping'] = sanitize_text_field( $_POST['agop-shipping-method-price-number'] );
        $final_price = floatval($final_price) + floatval(sanitize_text_field( $_POST['agop-shipping-method-price-number'] ));
        error_log('isset( $_POST[agop-shipping-method-price-number] FIRED---- '.$final_price);
    }


    if( isset( $_POST['agop-shipping-time'] ) ) {
        $cart_item_data['agop_shipping_time'] = sanitize_text_field( $_POST['agop-shipping-time'] );
    }
    
    $cart_item_data['agop_final_price'] = $final_price;
    // $data = array();
    // WC()->session->set( 'agop_final_price', $data );

    return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'agop_plugin_add_cart_item_data', 10, 3 );

最后使用woocommerce\u before\u calculate\u totals钩子通过以下代码更改产品价格:

function agop_before_calculate_totals( $cart ) {
    
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

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

    // Iterating though cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        

        // The WC_Product object
        $product = $cart_item['data'];
        // Get the price (WooCommerce versions 2.5.x to 3+)
        $product_price = method_exists( $product, 'get_price' ) ? floatval($product->get_price()) : floatval($product->price);

        // Continue if we get the custom data for the current cart item
        if( ! empty( $cart_item['agop_final_price'] ) ){
            // Get the custom field "added price" value
            $new_price =  floatval($cart_item['agop_final_price'] );
        
            // Set the calculeted price (WooCommerce versions 2.5.x to 3+)
            method_exists( $product, 'set_price' ) ? $product->set_price( $new_price ) : $product->price = $new_price;
        } else {
            // Set the calculeted price (WooCommerce versions 2.5.x to 3+)
            method_exists( $product, 'set_price' ) ? $product->set_price( $product_price ) : $product->price = $product_price;
        }
    }

}
add_action( 'woocommerce_before_calculate_totals', 'agop_before_calculate_totals' );

现在的问题是$final\u price变量在$\u POST['agop-new-price']和$\u POST['agop-shipping-method-price-number']同时存在时不起作用我的代码的哪一部分是错误的?


共1个答案

匿名用户

我发现了问题:我使用了woocommerce\u product\u get\u price和woocommerce\u product\u get\u常规价格过滤器,这影响了结帐和购物车页面。因此,我将这些过滤器的命令置于类似以下代码的条件下,问题就解决了:)

function agop_change_product_price_by_custom_fields( $price, $product ) {
    // if ( (! is_cart()) and (! is_checkout()) ) {
    if ( is_singular('product') || is_product_category() || is_product_tag() || is_shop()) {
        if ( agop_use_calculated_price($product->get_id()) ) {
            $price = agop_calculate_product_price($product->get_id());
        }
        return $price;
    }
    
    return $price;
}

add_filter( 'woocommerce_product_get_price', 'agop_change_product_price_by_custom_fields', 20, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'agop_change_product_price_by_custom_fields', 20, 2 );