I'm trying to retrieve (via Ajax) a custom name I've set on my product but so far I'm unable to retrieve it.
Here's my code to set the custom name;
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 10, 1);
function add_custom_price( $cart_obj ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart_obj->get_cart() as $cart_item ) {
$cart_item['data']->set_name( 'My Test Name' );
$cart_item['data']->set_price( 40 );
}
}
In my Javascript, I make my Ajax call when the checkout is updated:
$( document.body ).on( 'updated_checkout', function() {...
And from there I call this PHP function;
add_action( 'wp_ajax_retrieve_custom_product_name', 'retrieve_custom_product_name' );
function retrieve_custom_product_name() {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$items = WC()->cart->get_cart();
foreach($items as $item => $cart_item) {
$item_name = $cart_item['data']->get_name();
}
echo $item_name;
wp_die();
}
I was expected $cart_item['data']->get_name(); to give me the custom name I have set, but it just returns the original product name.
Does anyone have any ideas as to what I'm doing wrong here?
You can't get the new cart item name via Ajax this way from the cart item, and you will need to use some tricks using WC_Sessions
to make it work.
Note that you can have many cart items and that you will be able to return only one new cart item name with your actual logic.
The code:
// Change cart item name and price
add_action( 'woocommerce_before_calculate_totals', 'change_cart_item_name_and_price', 10, 1 );
function change_cart_item_name_and_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Get new items names from WC_Session
$session_data = (array) WC()->session->get( 'new_item_names' );
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$new_item_name = 'My Test Name';
$cart_item['data']->set_name( 'My Test Name' );
$cart_item['data']->set_price( 40 );
// If item name doesn't exist in WC_Session for this cart item, we do it
if( ! isset($session_data[$cart_item_key]) ) {
$session_data[$cart_item_key] = $new_item_name;
WC()->session->set( 'new_item_names', $session_data );
}
}
}
// PHP WP Ajax
add_action( 'wp_ajax_get_cart_item_name', 'retrieve_custom_product_name' );
add_action( 'wp_ajax_nopriv_get_cart_item_name', 'retrieve_custom_product_name' );
function retrieve_custom_product_name() {
$session_data = (array) WC()->session->get( 'new_item_names' );
// Loop through cart items
foreach( WC()->session->get('cart') as $cart_item_key => $cart_item ) {
// Get the new item name from WC_Session
if( isset($session_data[$cart_item_key]) ) {
$item_name = $session_data[$cart_item_key];
break; // We stop the loop to get one item name only (the first one)
}
}
if( isset($item_name) ) {
echo $item_name;
}
die();
}
// Jquery Ajax
add_action('wp_footer', 'custom_ajax_checkout_script');
function custom_ajax_checkout_script( $checkout ) {
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
// update cart on delivery location checkbox option
$(document.body).on( 'updated_checkout', function() {
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'get_cart_item_name',
},
success: function (result) {
console.log('response: '+result); // just for testing
},
error: function(error){
console.log(error); // just for testing
}
});
});
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.