Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

php - Set cart item price from a hidden input field custom price in Woocommerce 3

In Woocommerce, I used jQuery to calculate a custom price on a single product pages, and now need to pass this value to the cart.

The desired behavior is to pass the new price retrieved from the hidden field to the cart item price.

Here is my actual code:

// Hidden input field in single product page
add_action( 'woocommerce_before_add_to_cart_button', 'custom_hidden_product_field', 11, 0 );
function custom_hidden_product_field() {
    echo '<input type="hidden" id="hidden_field" name="custom_price" class="custom_price" value="">';
}


// The code to pass this data to the cart:
add_action( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 10, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {

    if( ! empty( $_REQUEST['custom_price'] ) ) {
        // Set the custom data in the cart item
        $cart_item_data['custom_data']['custom_price'] = $_REQUEST['custom_price'];
        $data = array( 'custom_price' => $_REQUEST['custom_price'] );
        
        // below statement make sure every add to cart action as unique line item
        $cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
        WC()->session->set( 'custom_data', $data );
    }
    return $cart_item_data;
}

And check both $data and $cart_item_data to see that they both return the custom_price data that is calculated on the page.

However, I go to view cart, and the value of the line item is still 0.

I set a var equal to the WC()->session->set( 'custom_data', $data ); and then var_dump to check it, but this returns NULL which might just be what it returns, I'm not entirely sure because I've never used it.

I should also add that I have the regular_price in the product backend set to 0. When I erase this (and leave it blank) I get back the error:

Warning: A non-numeric value encountered in C:xampphtdocsmy-transfer-sourcewp-contentpluginswoocommerceincludesclass-wc-discounts.php on line 85

I'm wondering if I've missed something here, and if someone could lend some light onto this? Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update 2021 - Handling custom price item in mini cart

First for testing purpose we add a price in the hidden input field as you don't give the code that calculate the price:

// Add a hidden input field (With a value of 20 for testing purpose)
add_action( 'woocommerce_before_add_to_cart_button', 'custom_hidden_product_field', 11 );
function custom_hidden_product_field() {
    echo '<input type="hidden" id="hidden_field" name="custom_price" class="custom_price" value="20">'; // Price is 20 for testing
}

Then you will use the following to change the cart item price (WC_Session is not needed):

// Save custom calculated price as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 10, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {

    if( isset( $_POST['custom_price'] ) && ! empty( $_POST['custom_price'] )  ) {
        // Set the custom data in the cart item
        $cart_item_data['custom_price'] = (float) sanitize_text_field( $_POST['custom_price'] );

        // Make each item as a unique separated cart item
        $cart_item_data['unique_key'] = md5( microtime().rand() );
    }
    return $cart_item_data;
}

// For mini cart
add_action( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 2 );
function filter_cart_item_price( $price, $cart_item ) {
    if ( isset($cart_item['custom_price']) ) {
        $args = array( 'price' => floatval( $cart_item['custom_price'] ) );

        if ( WC()->cart->display_prices_including_tax() ) {
            $product_price = wc_get_price_including_tax( $cart_item['data'], $args );
        } else {
            $product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
        }
        return wc_price( $product_price );
    }
    return $price;
}

// Updating cart item price
add_action( 'woocommerce_before_calculate_totals', 'change_cart_item_price', 30, 1 );
function change_cart_item_price( $cart ) {
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) )
        return;

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

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Set the new price
        if( isset($cart_item['custom_price']) ){
            $cart_item['data']->set_price($cart_item['custom_price']);
        }
    }
}

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...