Skip to content
Advertisement

Why Woocommerce update price programmically not working in woocommerce_add_cart_item_data hook

i have 2 type of products : 1- products that have regulare price 2- products that have calculated price

i added some hidden field to product page form with below code :

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' );

and send these fields data to cart item by :

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 );

and at last using woocommerce_before_calculate_totals hook to change product price by this code :

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' );

now problem is that $final_price variable not working when $_POST[‘agop-new-price’] and $_POST[‘agop-shipping-method-price-number’] are exists together What part of my code is wrong?

Advertisement

Answer

i found the problem: i used woocommerce_product_get_price and woocommerce_product_get_regular_price filters, Which affected the checkout and cart pages. So I put the commands of these filters in a condition like the following code and the problem was solved 🙂

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 );
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement