简体   繁体   中英

Overwrite cart item title and price from Toolset CRED form data in Woocommerce

I'm trying to overwrite the price for a product in the WooCommerce cart. The problem is that I'm using Divi which includes an ajax cart update. So when I reload the checkout page I can see my overwritten changes for 1-2 seconds (during the ajax loading) and after this the cart details get overwritten again by the default values. I've tried everythink, different hooks, delays, priority changes but nothing works.

This is my initial code:

add_filter( 'woocommerce_calculate_totals', 'custom_cart_items_prices', 1000, 1 )
function custom_cart_items_prices( $cart_object ) {

$title = $_GET['form-title'];
$money = $_GET['money'];

if ($title && $money) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

        // Get an instance of the WC_Product object
        $wc_product = $cart_item['data'];

        // Get the product name (WooCommerce versions 2.5.x to 3+)
        $original_name = method_exists( $wc_product, 'get_name' ) ? $wc_product->get_name() : $wc_product->post->post_title;

        // SET THE NEW NAME
        $new_name = $title;

        // Set the new name (WooCommerce versions 2.5.x to 3+)
        if( method_exists( $wc_product, 'set_name' ) )
            $wc_product->set_name( $new_name );
        else
            $wc_product->post->post_title = $new_name;
        }

    // Updated cart item price
    $cart_item['data']->set_price( $money ); 

}}

Picture during the loading (Everything looks great):

在此处输入图片说明

When the loading is completed:

在此处输入图片说明


Update - I've also tried a different approach as I am using a custom form made with CRED Toolset and Toolset Woocommerce plugins where customer create a product with a custom title and price, adding to cart a default existing product (and redirected to checkout page) . I am trying to replace the cart item title and price by the submitted form data.

Here is my code:

// Change the product ID
add_filter('cred_commerce_add_product_to_cart', function( $product_id, $form_id, $post_id ) {
    error_log($form_id);
    if( $form_id == 55 ) {
        if (!session_id()) {
            session_start();
        }
        $_SESSION['target_post_id'] = $post_id;
        if(isset($_POST['product-id'])){
            $product_id = $_POST['product-id'];
            $_SESSION['target_post_id'] = $post_id;
        }
    }
    return $product_id;
}, 20, 3);

// change the price in cart
add_action('woocommerce_before_calculate_totals', function(){
    session_start();
    if($form_id != 55 && !isset($_SESSION['target_post_id']))return;
    global $woocommerce;

    $post_id = $_SESSION['target_post_id']; 
    $price = 0;
    foreach ( $woocommerce->cart->get_cart() as $key => $cart_item ) {

        $product_id = $cart_item['data']->get_id();
        $adult_price = get_post_meta($product_id, 'wpcf-prezzo-1', true);
        $adult_num = get_post_meta($post_id, 'wpcf-adult-number', true);
        $child_price = get_post_meta($product_id, 'wpcf-prezzo-2', true);
        $child_num = get_post_meta($post_id, 'wpcf-children-number', true);

        $price = $adult_price * $adult_num + $child_price * $child_num; 
        $cart_item['data']->set_price($price); 
    }

}, 999);

But it doesn't work either.

How can I get the submitted form data (custom title and price) and to overwrite the cart item title and price in Woocommerce?

Try the following instead as you are using the toolset plugin with a custom form, where you will use WC_Sessions to store the product ID and change the price:

add_filter( 'cred_commerce_add_product_to_cart', 'cred_commerce_add_product_to_cart', 20, 3 );
function cred_commerce_add_product_to_cart( $product_id, $form_id, $post_id ) {
    if( $form_id == 55 && $post_id > 0 ) {
        WC()->session->set( 'cp_id', $post_id );
    }
    return $product_id;
}

add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data', 30, 4 );
function filter_add_cart_item_data( $cart_item_data, $product_id, $variation_id ){
    if ( WC()->session->get('cp_id') ) {
        $cp_id   = WC()->session->get('cp_id');
        $product = wc_get_product($cp_id);
        $cart_item_data['cp_price'] = $product->get_regular_price();
        $cart_item_data['cp_title'] = $product->get_title();
    }
    return $cart_item_data;
}

add_action( 'woocommerce_before_calculate_totals', 'custom_cart_items_price', 30, 1 );
function custom_cart_items_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    // Iterating through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset($cat_item['cp_price']) && isset($cat_item['cp_title']) ){
            $cart_item['data']->set_price( $cat_item['cp_price'] ); 
            $cart_item['data']->set_name( $cat_item['cp_title'] );
        }
    }
}

Code goes in function.php file of your active child theme (or active theme). It should works.


Some related answers :

Deactivate all of your plugins and voila! You will suprisingly understand that its a cause of one.

Enabling them one by one back, will let you know which one is conflicting. And.. Please consider using WordPress stack exchange for WordPress-specific questions.

1 woocommerce_add_cart_item_data

add_filter( 'woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id ){
    if ( empty( $_GET['form-title'] ) ||  empty( $_GET['money'] ) ) {
        return;
    }
    $title = $_GET['form-title'];
    $money = $_GET['money'];
    $cart_item_data['form-title']   = $title  ;
    $cart_item_data['money']        = $money  ;
    return $cart_item_data;
} ,100,4);

2 woocommerce_before_calculate_totals

add_action( 'woocommerce_before_calculate_totals', 'update_custom_price', 10, 1 );
function update_custom_price( $cart_object ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }
    foreach ( $cart_object->cart_contents as $cart_item_key => $cart_item ) {
        if(isset($cart_item["money"]) ){
            $money = $cart_item["money"] ;
            $cart_item['data']->set_price( $money);
        }
        if(isset($cart_item["form-title"]) ){
            $title = $cart_item["form-title"] ;
        }
        $wc_product = $cart_item['data'];

        // Get the product name (WooCommerce versions 2.5.x to 3+)
        $original_name = method_exists( $wc_product, 'get_name' ) ? $wc_product->get_name() : $wc_product->post->post_title;

        // SET THE NEW NAME
        $new_name = $title;

        // Set the new name (WooCommerce versions 2.5.x to 3+)
        if( method_exists( $wc_product, 'set_name' ) )
            $wc_product->set_name( $new_name );
        else
            $wc_product->post->post_title = $new_name;
        }
    }
    return $cart_object ;
}

Hope this will help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM