Custom hidden field on WooCommerce checkout not saving to user meta issue - php

I cannot figure out what i am missing here.
I am creating a hidden field on the checkout page, that contains a value after a customer's choice.
This part is working, as i can see in the inspector on the checkout page.
The hidden field should be saved to the logged-in user, as i need it on another place in the website.
I have the following:
//This part is working!!
add_action( 'woocommerce_after_checkout_billing_form', function() {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
if( isset($values['programmakeuze']) ){
echo '<input type="hidden" name="programchoice" id="programchoice" class="input-hidden" value="'.$values['programmakeuze'].'">';
}
}
});
//Save hidden field to user
function elearning_checkout_update_user_meta( $customer_id, $posted ) {
if (!empty($_POST['programchoice'])) {
$program = intval($_POST['programchoice'] );
update_user_meta( $customer_id, 'programchoice', $program);
}
}
add_action( 'woocommerce_checkout_update_user_meta', 'elearning_checkout_update_user_meta', 10, 2 );
function testing(){
$id = get_current_user_id();
$value = get_user_meta($id,'programchoice',true);
if ( !empty($value)) {
var_dump ($value);
}
}
add_action('wp_head','testing');
The $value returns nothing. What am i missing here?

I've partly rewritten your code. Including the use of woocommerce_checkout_update_customer action hook.
Also note the use of break in the for loop, as this is about a specific ID, and therefore about 1 unique field
However, I wouldn't use the wp_head action hook for debugging. See How to debug in WooCommerce instead.
But this should suffice, to answer your question:
// Display a custom hidden field after checkout billing form
function action_woocommerce_after_checkout_billing_form( $checkout ) {
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['programmakeuze'] ) ) {
echo '<input type="hidden" name="programchoice" id="programchoice" class="input-hidden" value="' . $cart_item['programmakeuze'] . '">';
break;
}
}
}
add_action( 'woocommerce_after_checkout_billing_form', 'action_woocommerce_after_checkout_billing_form', 10, 1 );
// Save/update user data from custom field value
function action_woocommerce_checkout_update_customer( $customer, $data ) {
// Isset
if ( isset( $_POST['programchoice'] ) ) {
$customer->update_meta_data( '_programchoice', sanitize_text_field( $_POST['programchoice'] ) );
}
}
add_action( 'woocommerce_checkout_update_customer', 'action_woocommerce_checkout_update_customer', 10, 2 );
// Debugging purposes
function action_wp_head(){
// Get user id
$user_id = get_current_user_id();
// Get user meta
$value = get_user_meta( $user_id, '_programchoice', true );
// NOT empty
if ( ! empty( $value ) ) {
var_dump ( $value );
}
}
add_action( 'wp_head', 'action_wp_head' );

Related

Checkbox in WooCommerce product loop that add an option on Ajax add to cart

In WooCommerce, I have added a checkbox in single product pages and also on the products loops, where the user can check that they want to request a certificate.
My code below works fine on single product pages. However, in the products loops, the value of the check box is always taken, even if the checkbox is unchecked. It should only be taken if the checkbox is checked.
Here is my code:
function add_name_on_certificate_field() {
echo '<table class="certificate" cellspacing="0">
<tbody>
<tr>
<td class="value">
Certificate: <input type="checkbox" name="name_on_certificate" value="certificate" "/>
</td>
</tr>
</tbody>
</table>';}
add_action( 'woocommerce_before_add_to_cart_button', 'add_name_on_certificate_field');
function save_name_on_certificate_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['name_on_certificate'] ) ) {
$cart_item_data[ 'name_on_certificate' ] = $_REQUEST['name_on_certificate'];
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_name_on_certificate_field', 10, 2 ); code here
function render_meta_on_cart_and_checkout2( $cart_data, $cart_item = null ) {
$custom_items = array();
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['name_on_certificate'] ) ) {
$custom_items[] = array( "name" => 'Certificate', "value" =>
$cart_item['name_on_certificate']);
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout2', 10, 2 );
function certificate_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values['name_on_certificate'] ) ) {
wc_add_order_item_meta( $item_id, "name_on_certificate", $values['name_on_certificate']);
}
}
add_action( 'woocommerce_add_order_item_meta', 'certificate_order_meta_handler', 1, 3 );
function add_custom_fields_on_product_listing2() {
global $product;
echo '</a><div class="sark-custom-fields-wrapper">
<input type="checkbox" id="name_on_certificate-'. $product->id .'" value="certificate-required" /> </div>';
}
add_action( "woocommerce_after_shop_loop_item", 'add_custom_fields_on_product_listing2', 1 );
function inject_custom_field_script2() { ?>
<script type="text/javascript">
jQuery(document).on("adding_to_cart", function( e, btn, data ){
data["name_on_certificate"] = jQuery("#name_on_certificate-" + btn.attr( "data-product_id" )).val();
return true;
});
</script>
<?php }
add_action( "woocommerce_after_main_content", 'inject_custom_field_script2', 1 );
For info, there is already a text field, where you can set the size of the product that works fine.
Any help will be appreciated.
I have revisited your code, renaming functions, changing an obsolete hook, adding some missing things and making multiple changes.
Now only when the checkbox is checked and when the related product is added to cart (on single product pages or in product loops via Ajax add to cart), an option is added as custom cart item data, displayed on cart, checkout, orders and emails.
The code:
// Products Loop: Display the checkbox field on products that have Ajax add to cart enabled
add_action( "woocommerce_after_shop_loop_item", 'product_loop_display_certificate_field' );
function product_loop_display_certificate_field() {
global $product;
if ( $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ) {
echo '</a><div class="sark-custom-fields-wrapper"><input type="checkbox" id="name_on_certificate-' .
$product->get_id() . '" value="required" /></div>';
}
}
// Products Loop: Handle Ajax add to cart for the checkbox
add_action( "init", 'certificate_field_loop_jquery_script', 1 );
function certificate_field_loop_jquery_script() {
wc_enqueue_js("jQuery( function($){
$(document.body).on('adding_to_cart', function( e, btn, data ){
var checkbox = $('#name_on_certificate-'+data.product_id);
if( checkbox.is(':checked') ) {
data['name_on_certificate'] = checkbox.val();
return data['name_on_certificate'];
}
});
});");
}
// Single products: Display the checkbox field
add_action( 'woocommerce_before_add_to_cart_button', 'single_product_display_certificate_field');
function single_product_display_certificate_field() {
echo '<table class="certificate" cellspacing="0"><tbody><tr>
<td class="value">' . __("Certificate:", "woocommerce") .
' <input type="checkbox" name="name_on_certificate" value="required" "/>
</td>
</tr></tbody></table>';
}
// Add checked checkbox value as custom cart item data
add_action( 'woocommerce_add_cart_item_data', 'add_cart_item_certificate_field_value', 10, 2 );
function add_cart_item_certificate_field_value( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['name_on_certificate'] ) ) {
$cart_item_data[ 'name_on_certificate' ] = $_REQUEST['name_on_certificate'];
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Display required certificate in minicart, cart and checkou
add_filter( 'woocommerce_get_item_data', 'display_cart_item_certificate_field_value', 10, 2 );
function display_cart_item_certificate_field_value( $cart_data, $cart_item ) {
if( isset( $cart_item['name_on_certificate'] ) ) {
$cart_data[] = array( "name" => 'Certificate', "value" => $cart_item['name_on_certificate']);
}
return $cart_data;
}
// Save required certificate as custon order item data and display it on orders and emails
add_action( 'woocommerce_checkout_create_order_line_item', 'add_order_item_certificate_field_value', 10, 4 );
function add_order_item_certificate_field_value( $item, $cart_item_key, $values, $order ) {
if( isset( $values['name_on_certificate'] ) ) {
$item->update_meta_data( 'name_on_certificate', esc_attr($values['name_on_certificate']) );
}
}
// Change required certificate displayed meta key label to something readable
add_filter('woocommerce_order_item_display_meta_key', 'filter_order_item_displayed_meta_key', 20, 3 );
function filter_order_item_displayed_meta_key( $displayed_key, $meta, $item ) {
// Change displayed meta key label for specific order item meta key
if( $item->get_type() === 'line_item' && $meta->key === 'name_on_certificate' ) {
$displayed_key = __("Certificate", "woocommerce");
}
return $displayed_key;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Pass custom posted variable from a page to Woocommerce order data

I can add a custom variable to a WooCommerce order, using code like this - but only if the code is on the product page:
<form action="<?php echo esc_url( wc_get_checkout_url() ); ?>" method="post">
<?php
$value = isset( $_POST['dogname'] ) ? sanitize_text_field( $_POST['dogname'] ) : '';
echo '<div><label>Name of Dog</label><p><input name="dogname" value="' . $value . '"></p></div>';
?> <button type="submit">Checkout</button>
</form>
But how do I add the data to the order it if I am not on the product page? I redirect the page after add to cart to a custom page. On this custom page the cart is already populated with the product . But submitting this form on the custom page - goes to checkout but does not update or add the variable to the order. How would I update the order with my custom variable from my custom page?
Maybe I need some extra code for the button to update the order on click?
What code would I use for a button - that on click would post the form values to my order, and direct to another page?
Here below is a way to get posted data available in checkout page and anywhere else without loosing this posted data. For that we set the posted data to a WC session variable, so this posted data is available at any moment when needed.
The form on your page (example with multiple fields):
?><form action="<?php echo esc_url( wc_get_checkout_url() ); ?>" method="post">
<?php
$dogname = isset( $_POST['dogname'] ) ? sanitize_text_field( $_POST['dogname'] ) : '';
$dogcolor = isset( $_POST['dogcolor'] ) ? sanitize_text_field( $_POST['dogcolor'] ) : '';
?>
<div><label><?php _e("Name of Dog"); ?></label><p><input name="dogname" value="<?php echo $dogname; ?>"></p></div>
<div><label><?php _e("Color of Dog"); ?></label><p><input name="dogcolor" value="<?php echo $dogcolor; ?>"></p></div>
<button class="button" type="submit" name="dog_form" value="submited"><?php _e("Checkout"); ?></button>
</form><?php
The code that set the posted data to a WC_Session variable:
// Early enable customer WC_Session
add_action( 'init', 'wc_session_enabler' );
function wc_session_enabler() {
if ( is_user_logged_in() || is_admin() )
return;
if ( isset(WC()->session) && ! WC()->session->has_session() ) {
WC()->session->set_customer_session_cookie( true );
}
}
// Set posted data in a WC session variable
add_action( 'template_redirect', 'set_custom_posted_data_to_wc_session' );
function set_custom_posted_data_to_wc_session() {
if ( is_checkout() && ! is_wc_endpoint_url() ) {
if ( isset($_POST['dog_form']) ) {
$values = array(); // Initializing
if ( isset($_POST['dogname']) && ! empty($_POST['dogname']) ) {
$values['dogname'] = sanitize_text_field($_POST['dogname']);
}
if ( isset($_POST['dogcolor']) && ! empty($_POST['dogcolor']) ) {
$values['dogcolor'] = sanitize_text_field($_POST['dogcolor']);
}
// Set data to a WC_Session variable
if ( ! empty($values) ) {
WC()->session->set('custom_data', $values);
}
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Then you can get that data on any function or template with:
$values = WC()->session->get('custom_data');
$dogname = isset($values['dogname']) ? $values['dogname'] : '';
$dogcolor = isset($values['dogcolor']) ? $values['dogcolor'] : '';
Save that data to order details:
// Save WC session data as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'action_checkout_add_custom_order_meta', 10, 2 );
function action_checkout_add_custom_order_meta( $order, $data ) {
$values = WC()->session->get('custom_data'); // Get data from WC Session variable
if( ! empty($values) ) {
if ( isset($values['dogname']) ) {
$order->update_meta_data( '_dogname', $values['dogname'] ); // Set dog name to order details
}
if ( isset($values['dogcolor']) ) {
$order->update_meta_data( '_dogcolor', $values['dogcolor'] ); // Set dog color to order details
}
// Remove the WC_Session variable (as we don't need it anymore)
WC()->session->__unset('custom_data');
}
}
Code goes in functions.php file of the active child theme (or active theme).
Then you can get that data from The WC_Order object order using:
$order = wc_get_order( $order_id ); // If needed, get the WC_Order object from order Id
$dogname = $order->get_meta('_dogname');
$dogcolor = $order->get_meta('_dogcolor');
Like in this hooked function that will display data on "Order received" page:
add_action( 'woocommerce_thankyou', 'thankyou_display_dog_data' );
function thankyou_display_dog_data( $order_id ) {
$order = wc_get_order( $order_id ); // Get an instance of the WC_Order object
$dog_name = $order->get_meta('_dogname');
$dog_color = $order->get_meta('_dogcolor');
echo ! empty($dog_name) ? '<p>' . $dog_name .'<p>' : '';
echo ! empty($dog_color) ? '<p>' . $dog_color .'<p>' : '';
}
Tested and works on last WooCommerce version.
To add some more functionality to LoicTheAztec answer using his thankyou_display_dog_data function. His included action shows the function on thank you after checkout form
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'thankyou_display_dog_data' ); //add to admin order data under shipping
add_action( 'woocommerce_admin_order_data_after_billing_address', 'thankyou_display_dog_data' ); //add to admin under billing - pick one or duplicate of shipping
add_action( 'woocommerce_order_details_after_order_table', 'thankyou_display_dog_data' ); //add to frontend customers my account
add_action( 'woocommerce_email_after_order_table', 'thankyou_display_dog_data', 15, 2 ); // add to emails

How to disable fields that are pre-filled in WooCommerce checkout?

I would like to prevent (make these fields readonly, for example) users from changing their billing information on the WooCommerce checkout form.
I'm currently using this code snippet:
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );
function mycustom_woocommerce_billing_fields($fields)
{
$fields['billing_first_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_last_name']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_email']['custom_attributes'] = array('readonly'=>'readonly');
$fields['billing_phone']['custom_attributes'] = array('readonly'=>'readonly');
return $fields;
}
But the problem is: If the user has not filled in any of these fields in the registration, he is unable to insert his data in the checkout form because these fields are not editable.
My question is:
If the fields are not empty, how to make them readonly (or disabled)
Someone who can help me with this?
The answer of 7uc1f3r certainly works getting the user data… But since WooCommerce 3, you can use WC_Checkout get_value() dedicated method as follow:
add_filter( 'woocommerce_billing_fields', 'filter_wc_billing_fields', 10, 1 );
function filter_wc_billing_fields( $fields ) {
// On checkout and if user is logged in
if ( is_checkout() && is_user_logged_in() ) {
// Define your key fields below
$keys_fields = ['billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone'];
// Loop through your specific defined fields
foreach ( $keys_fields as $key ) {
// Check that a value exist for the current field
if( ( $value = WC()->checkout->get_value($key) ) && ! empty( $value ) ) {
// Make it readonly if a value exist
$fields[$key]['custom_attributes'] = ['readonly'=>'readonly'];
}
}
}
return $fields;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
If you want this code to be also active in My account > Addresses > edit…, you will just have to remove is_checkout() && from the first IF statement.
I believe this is what you are looking for, comment with explanation added in code
function mycustom_woocommerce_billing_fields( $fields ) {
// Get current user
$user = wp_get_current_user();
// User id
$user_id = $user->ID;
// User id is found
if ( $user_id > 0 ) {
// Fields
$read_only_fields = array ( 'billing_first_name', 'billing_last_name', 'billing_email', 'billing_phone' );
// Loop
foreach ( $fields as $key => $field ) {
if( in_array( $key, $read_only_fields ) ) {
// Get key value
$key_value = get_user_meta($user_id, $key, true);
if( strlen( $key_value ) > 0 ) {
$fields[$key]['custom_attributes'] = array(
'readonly'=>'readonly'
);
}
}
}
}
return $fields;
}
add_filter('woocommerce_billing_fields', 'mycustom_woocommerce_billing_fields', 10, 1 );

Can't get custom fields of a woocommerce product

i am trying to get the custom fields with this function and multiply by the product price. I am getting the product price but when printing the custom fields, i am only getting zeros.. i dont understand why, i had tryed get_metadata() and get_post_custom() too.. but nothing works
function filter_woocommerce_cart_product_subtotal( $product_subtotal, $product, $quantity, $instance ) {
$fields = get_post_meta(get_the_id(), false);
$add_on = $product->get_price()*$fields[0] + $product->get_price()*$fields[1] + $product-
>get_price()*0.75*$fields[2];
return $product_subtotal + $add_on;
};
add_filter( 'woocommerce_cart_product_subtotal', 'filter_woocommerce_cart_product_subtotal', 10, 4 );
I have tryed to get single fields too but always getting zeros.
I can get the custom fields in function below and save it in a global variable but when i try to access the global variable in the function above, i get zero again.
function tour_product_add_on_cart_item_data( $cart_item, $product_id, $cart ){
/*
if( isset( $_POST['time_add_on'] ) ) {
$cart_item['time_add_on'] = sanitize_text_field( $_POST['time_add_on'] );
}
*/
if( isset( $_POST['date_add_on'] ) ) {
$cart_item['date_add_on'] = sanitize_text_field( $_POST['date_add_on'] );
}
if( isset( $_POST['place_add_on'] ) ) {
$cart_item['place_add_on'] = sanitize_text_field( $_POST['place_add_on'] );
}
if( isset( $_POST['adult_add_on'] ) ) {
$cart_item['adult_add_on'] = sanitize_text_field( $_POST['adult_add_on'] );
}
if( isset( $_POST['child_add_on'] ) ) {
$cart_item['child_add_on'] = sanitize_text_field( $_POST['child_add_on'] );
}
if( isset( $_POST['infant_add_on'] ) ) {
$cart_item['infant_add_on'] = sanitize_text_field( $_POST['infant_add_on'] );
}
$product = wc_get_product($product_id);
$GLOBALS["fee"] = $_POST['adult_add_on']*$product->get_price() +
$_POST['child_add_on']*$product->get_price() + $_POST['infant_add_on']*0.75*$product->get_price();
return $cart_item;
}
get_post_meta() second parameter is the meta key value. So you should use for example
$date_add_on = get_post_meta(get_the_id(), 'date_add_on')
So, i have resolved this issue. When you add a custom field to a woocommerce product or a wordpress post, you have to update it's meta data. Here is a good tutorial of every step you have to follow to add a custom field.
HOW TO ADD WOOCOMMERCE CUSTOM FIELDS TO A PRODUCT

Save and display a custom field as order item meta data in WooCommerce

In woocommerce, I have maisd wome customizations and I can add a custom text field in my products, Display the values in cart and checkout (see the screenshots below).
Text field in product page:
Value in the cart:
Value in the checkout:
But I can not get it to appear in the purchase details or in the administration section (see the screenshots below).
Checkout details without the value:
Administration orders without the value:
In my code below, could someone tell what I am doing wrong?
The code that I use in my functions.php file:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$id = $product->get_id();
// Get the field name of InputText1
$InputText1Name = get_post_meta($id, 'InputText1', true);
if ((!empty(get_post_meta($id, $InputText1, true)))){
echo '<div id="InputText1">';
echo '<label>'.__($InputText1Name).'</label> <input type="text" name="$InputText1V">';
echo '</div>';
}
}
// Store custom field
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['$InputText1V'] ) ) {
$cart_item_data[ '$InputText1V' ] = $_REQUEST['$InputText1V'];
/* below statement make sure every add to cart action as unique line item */
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
// Render meta on cart and checkout
function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ){
// Get the product id inside the cart
foreach( WC()->cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
}
// Get the field name of InputText1
$InputText1Name = get_post_meta($product_id, 'InputText1', true);
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['$InputText1V'] ) ) {
$custom_items[] = array( "name" => $InputText1Name, "value" => $cart_item['$InputText1V'] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
// Display as order meta
function my_field_order_meta_handler( $item_id, $values, $cart_item_key ) {
if( isset( $values['$InputText1V'] ) ) {
wc_add_order_item_meta( $product_id, "$InputText1V", $values['$InputText1V'] );
}
}
// Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['$InputText1V']) update_post_meta( $order_id, '$InputText1Name', esc_attr($_POST['$InputText1V']));
}
// Update the user meta with field value
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['$InputText1V']) update_user_meta( $user_id, '$InputText1V', esc_attr($_POST['$InputText1V']) );
}
add_filter( 'woocommerce_hidden_order_itemmeta', 'hide_order_item_meta_fields' );
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ){
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
echo '<p><strong>'.__($InputText1V).':</strong> ' . get_post_meta( $order_id, $InputText1V, true ) . '</p>';
}
function hide_order_item_meta_fields( $fields ) {
$fields[] = 'current_view';
$fields[] = 'custom_image';//Add all meta keys to this array,so that it will not be displayed in order meta box
return $fields;
}
add_action( 'woocommerce_after_order_itemmeta', 'order_meta_customized_display',10, 3 );
function order_meta_customized_display( $item_id, $item, $product ){
$order_product_id = $item['product_id'];
$field1name = get_post_meta($order_product_id, 'InputText1', true);
echo'<br>';
print_r($InputText1V);
echo'<br>';
echo $field1name;
echo ': ';
}
There are errors and missing things in your code. You don't need all that functions too and you should really avoid to use $ (and if you can capitals) in your custom field slugs (or in key slugs and even in function names) in your code.
I have tested and revisited your code. Here is what you need and can remove everything else:
// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
global $product;
$product_id = $product->get_id();
// Get the field name of InputText1
$label = get_post_meta($product_id, 'InputText1', true);
if( ! empty( $label ) ){
echo '<div id="InputText1">
<label>'.$label.':</label> <input type="text" name="custom_slug" value="">
</div>';
}
}
// Store custom field label and value in cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 );
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_slug'] ) ) {
$cart_item_data['custom_data']['label'] = get_post_meta($product_id, 'InputText1', true);
$cart_item_data['custom_data']['value'] = sanitize_text_field( $_REQUEST['custom_slug'] );
$cart_item_data['custom_data']['ukey'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Display items custom fields label and value in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item ){
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['custom_data'] ) ) {
$custom_items[] = array(
'name' => $cart_item['custom_data']['label'],
'value' => $cart_item['custom_data']['value'],
);
}
return $custom_items;
}
// Save item custom fields label and value as order item meta data
add_action('woocommerce_add_order_item_meta','save_in_order_item_meta', 10, 3 );
function save_in_order_item_meta( $item_id, $values, $cart_item_key ) {
if( isset( $values['custom_data'] ) ) {
wc_add_order_item_meta( $item_id, $values['custom_data']['label'], $values['custom_data']['value'] );
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
This way you will get the display in Order received, Order view, Edit order (admin) and email notifications…

Categories