Woocommerce product notes add to order meta - php

I created textarea field to save woocommerce products notes, i want to save these notes into admin order if any product available in cart and have product notes.
// WooCommerce Products Custom Field
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Textarea Field
woocommerce_wp_textarea_input(
array(
'id' => 'product_notes',
'label' => __( 'Product Notes', 'woocommerce' ),
'placeholder' => 'Enter product notes here.',
'desc_tip' => 'true',
'description' => __( 'Enter product notes here.', 'woocommerce' )
)
);
echo '</div>';
}
// Save Product notes
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
// Textarea
$woocommerce_textarea = $_POST['product_notes'];
if( !empty( $woocommerce_textarea ) )
update_post_meta( $post_id, 'product_notes', esc_html( $woocommerce_textarea ) );
}

Ok, i find solution.
add_action( 'woocommerce_checkout_update_order_meta', 'custom_product_notes_order_meta', 10, 2 );
function custom_product_notes_order_meta( $order_id ) {
global $woocommerce;
$i=1; //product counter
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
$product_note = 'product_notes_'.$i++;
if( !empty(get_post_meta( $product_id, 'product_notes', true )) ){
$product_notes = get_post_meta( $product_id, 'product_notes', true );
add_post_meta( $order_id, $product_note, $product_notes );
}
}
}

Related

Save custom metadata from subscription product variation to order

I need to be able to add admin data to subscription product variations (Woo Subscriptions extension) in order to pass this data on to fulfilment centres when an order is placed.
The issue I have is getting these values out from the product and passing them into the order and email notifications such that they can be properly exported, added to shipping labels and emailed via the various woo notifications.
I have custom meta fields added to variations on a subscription product. I can add data into these and they save data properly into the database on the correct variation ID. No problem there.
I can show custom test data on the cart and checkout page and also save this data into the order as you'll see in the code.
For brevity, the code is reduced below but there are in fact 6 text fields:
// Add custom field inputs to each product variation
add_action( 'woocommerce_variation_options_pricing', 'add_custom_field_to_variations', 10, 3 );
function add_custom_field_to_variations( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input(
array(
'id' => '_dose_customer_field[' . $loop . ']',
'label' => __( 'Dose (Customer)', 'woocommerce' ),
'placeholder' => __('Enter the treatment dosage','woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter dosage info for this variation', 'woocommerce' ),
'class' => '',
'value' => get_post_meta( $variation->ID, '_dose_customer_field', true )
)
);
}
// Save custom field on product variation save
add_action( 'woocommerce_save_product_variation', 'save_custom_field_variations', 10, 2 );
function save_custom_field_variations( $variation_id, $i ) {
$_dose_customer_field = $_POST['_dose_customer_field'][$i];
if ( isset( $_dose_customer_field ) ) update_post_meta( $variation_id, '_dose_customer_field', esc_attr( $_dose_customer_field ) );
}
// Add metadata to cart item post.
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_fields_cart_item_data', 10, 2 );
function add_custom_fields_cart_item_data( $cart_item_data, $product_id ){
$cart_item_data['custom_data']['_dose_customer_field'] = 'TEST DATA' /* HOW TO GET DATA FROM CUSTOM FIELD HERE */
$cart_item_data['custom_data']['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'custom_data', $cart_item_data['custom_data'] );
return $cart_item_data;
}
// Display custom meta data on cart and checkout page.
add_filter( 'woocommerce_get_item_data', 'display_custom_fields_cart_item_data', 10, 2 );
function display_custom_fields_cart_item_data($item_data, $cart_item){
if( ! array_key_exists( 'custom_data', $cart_item ) )
return $item_data;
if( array_key_exists( '_dose_customer_field', $cart_item['custom_data'] ) )
$item_data[] = array(
'key' => __('Dose (Customer)', 'woocommerce'),
'value' => $cart_item['custom_data']['_dose_customer_field']
);
return $item_data;
}
// Add metadata to the order.
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_fields_as_order_item_meta', 20, 4);
function save_custom_fields_as_order_item_meta($item, $cart_item_key, $values, $order) {
if( ! isset($values['custom_data']) )
return;
$text_domain ='woocommerce';
if( array_key_exists('_dose_customer_field', $values['custom_data']) ){
$item->update_meta_data( __('Dose (Customer)', $text_domain), $values['custom_data']['_dose_customer_field'] );
}
}
// Frontend & emails: Display data on notifications
add_action( 'woocommerce_order_item_meta_start', 'vp_order_item_display_commodity_code', 10, 4 );
function vp_order_item_display_commodity_code( $item_id, $item, $order, $plain_text ) {
// Not on admin
//if( is_admin() ) return;
if( $value = $item->get_meta('_dose_customer_field') ) {
$value = '<strong>' . __("Dose (Customer)", "woocommerce") . ':</strong> ' . esc_attr( $value );
// On orders
if( is_wc_endpoint_url() )
echo '<div class="vp-ccode"><small>' . $value . '</small></div>';
// On Emails
else
echo '<div>' . $value . '</div>';
}
}
So everything is working except getting the data from the custom fields. It seems odd that I have to create a new array (here called 'custom_data') and add it to the cart_item_data, when the data is already available on the product variation, albeit private.
My question is how do get the metadata within add_custom_fields_cart_item_data()? Is this even the correct approach?
Many thanks
As this custom data exist for the product, you can get it easily and save it as order item custom data (so it will be displayed everywhere):
The complete code (changed the 2 last functions):
// Add custom field inputs to each product variation
add_action( 'woocommerce_variation_options_pricing', 'add_custom_field_to_variations', 10, 3 );
function add_custom_field_to_variations( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input(
array(
'id' => '_dose_customer_field[' . $loop . ']',
'label' => __( 'Dose (Customer)', 'woocommerce' ),
'placeholder' => __('Enter the treatment dosage','woocommerce' ),
'desc_tip' => 'true',
'description' => __( 'Enter dosage info for this variation', 'woocommerce' ),
'class' => '',
'value' => get_post_meta( $variation->ID, '_dose_customer_field', true )
)
);
}
// Save custom field on product variation save
add_action( 'woocommerce_save_product_variation', 'save_custom_field_variations', 10, 2 );
function save_custom_field_variations( $variation_id, $i ) {
$_dose_customer_field = $_POST['_dose_customer_field'][$i];
if ( isset( $_dose_customer_field ) ) update_post_meta( $variation_id, '_dose_customer_field', esc_attr( $_dose_customer_field ) );
}
// Display custom meta data on cart and checkout page.
add_filter( 'woocommerce_get_item_data', 'display_custom_fields_cart_item_data', 10, 2 );
function display_custom_fields_cart_item_data( $item_data, $cart_item ) {
if( $value = $cart_item['data']->get_meta( '_dose_customer_field' ) )
$item_data[] = array(
'key' => __('Dose (Customer)', 'woocommerce'),
'value' => $value
);
return $item_data;
}
// Add metadata to the order item (and display it everywhere).
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_fields_as_order_item_meta', 10, 4);
function save_custom_fields_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
if( $meta_value = $values['data']->get_meta( '_dose_customer_field' ) )
$item->update_meta_data( __('Dose (Customer)', 'woocommerce'), $meta_value );
}
Code goes in functions.php file of your active child theme (or active theme). It should work.

Displaying custom field of product variations within Woocommerce orders and emails

I successfully added a custom field for product variations within the backend of WooCommerce and was able to display its value. I'd like to contain this value within order and emails as well.
//Display Fields in admin on product edit screen
add_action( 'woocommerce_product_after_variable_attributes', 'woo_variable_fields', 10, 3 );
//Save variation fields values
add_action( 'woocommerce_save_product_variation', 'save_variation_fields', 10, 2 );
// Create new fields for variations
function woo_variable_fields( $loop, $variation_data, $variation ) {
echo '<div class="variation-custom-fields">';
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field['. $loop .']',
'label' => __( 'additional fees (e.g. monthly fee)', 'woocommerce' ),
'placeholder' => '',
//'desc_tip' => true,
'wrapper_class' => 'form-row form-row-first',
//'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta($variation->ID, '_text_field', true)
)
);
echo "</div>";
}
/** Save new fields for variations */
function save_variation_fields( $variation_id, $i) {
// Text Field
$text_field = stripslashes( $_POST['_text_field'][$i] );
update_post_meta( $variation_id, '_text_field', esc_attr( $text_field ) );
}
// Custom Product Variation
add_filter( 'woocommerce_available_variation', 'custom_load_variation_settings_products_fields' );
function custom_load_variation_settings_products_fields( $variations ) {
$variations['variation_custom_field'] = get_post_meta( $variations[ 'variation_id' ], '_text_field', true );
return $variations;
}
I'm using the following to display the custom field's value within the cart.
add_filter( 'woocommerce_get_item_data', 'display_custom_field_as_item_data', 20, 2 );
function display_custom_field_as_item_data( $cart_data, $cart_item ) {
if( $value = get_post_meta( $cart_item['data']->get_id(), '_text_field', true ) ){
$cart_data[] = array(
'name' => __( 'Additional Monthly Fee', 'woocommerce' ),
'value' => sanitize_text_field( $value )
);
}
return $cart_data;
}
Further as for now I'm displaying its value below the product price / total of each item within cart/checkout template with the following
echo get_post_meta( $_product->get_id(), '_text_field', true );
How about displaying the value of this field within orders and emails?
Updated: To display that in order pages and email notifications try the following additional functions (I have made some changes in the woocommerce_get_item_data hooked function, so you need to replace it with the following one):
// Save custom field value in cart item
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_field_in_cart_object', 30, 3 );
function save_custom_field_in_cart_object( $cart_item_data, $product_id, $variation_id ) {
// Get the correct Id to be used
$the_id = $variation_id > 0 ? $variation_id : $product_id;
if( $value = get_post_meta( $the_id, '_text_field', true ) )
$cart_item_data['custom_data'] = sanitize_text_field( $value );
return $cart_item_data;
}
// Display on cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'display_custom_field_as_item_data', 20, 2 );
function display_custom_field_as_item_data( $cart_data, $cart_item ) {
if( isset( $cart_item['custom_data'] ) ){
$cart_data[] = array(
'name' => __( 'Additional Monthly Fee', 'woocommerce' ),
'value' => $cart_item['custom_data']
);
}
return $cart_data;
}
// Save custom field value in order items meta data
add_action( 'woocommerce_add_order_item_meta', 'add_custom_field_to_order_item_meta', 20, 3 );
function add_custom_field_to_order_item_meta( $item_id, $values, $cart_item_key ) {
if( isset( $values['custom_data'] ) )
wc_add_order_item_meta( $item_id, __( 'Additional Monthly Fee', 'woocommerce' ), $values['custom_data'] );
}
Code goes in function.php file of your active child theme (or theme). Tested and works.
It will display the custom field label and value in all Order pages and in email notifications too.

Add a drop down to product edit pages in product data "General" settings tab

I am trying to figure out how to modify the singe product options so the product admin can pick from the drop down list the condition of product, i.e. new/ used.
Below is a code that allows product admin to enter the condition of product manually.
// Enabling and Displaying Fields in backend
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_wp_text_input( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'placeholder' => 'i.e: nowa; uzywana...',
'desc_tip' => 'true',
'description' => __( 'Podaj stan plyty.', 'woocommerce' )
) );
echo '</div>'; // Closing </div> tag HERE
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields' );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$Stan_field = $_POST['_Stan'];
if( !empty( $Stan_field ) )
update_post_meta( $post_id, '_Stan', esc_attr( $Stan_field ) );
}
add_action('woocommerce_single_product_summary', 'woo_display_custom_general_fields_values', 45);
function woo_display_custom_general_fields_values() {
global $product;
echo '<p class="custom-Stan">Stan: ' . get_post_meta( $product->id, '_Stan', true ) . '</p>';
}
There is some errors and mistakes so I have revisited a little bit your code. Now you will have to replace woocommerce_wp_text_input() by woocommerce_wp_select() to get a select field instead, this way:
// Enabling and Displaying Fields in backend
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
echo '<div class="options_group">';
woocommerce_wp_select( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'description' => __( 'Podaj stan plyty.', 'woocommerce' ),
'desc_tip' => true,
'options' => array(
'' => __( 'Select product condition', 'woocommerce' ),
'Nowa' => __('Nowa', 'woocommerce' ),
'Uzywana' => __('Uzywana', 'woocommerce' ),
)
) );
echo '</div>';
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields', 30, 1 );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$posted_field_value = $_POST['_Stan'];
if( ! empty( $posted_field_value ) )
update_post_meta( $post_id, '_Stan', esc_attr( $posted_field_value ) );
}
// Display In front end
add_action( 'woocommerce_product_meta_start', 'woo_display_custom_general_fields_values', 50 );
function woo_display_custom_general_fields_values() {
global $product;
// compatibility with WC +3
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo '<span class="stan">Stan: ' . get_post_meta( $product_id, '_Stan', true ) . '</span>';
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
Is better to avoid capitals in meta keys and they should start with an underscore.

WooComerce Custom Field show only in default site language?

I have one issue that dont know how to resolve myself, so need your help. I have inserted Custom Field into my WooCommerce site product page. I have used this code to show my custom field bellow "Add to Cart" page, and also bellow product into cart page.
// Display Product settings Fields
add_action( 'woocommerce_product_options_general_product_data',
'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
woocommerce_wp_text_input( array(
'id' => '_pd_number',
'label' => __( 'Delivery Time', 'woocommerce' ),
'placeholder' => 'Some text here',
'desc_tip' => 'true',
'description' => __( 'Enter some text', 'woocommerce' )
));
}
// Save Product settings Fields
add_action( 'woocommerce_process_product_meta',
'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$pd_number = $_POST['_pd_number'];
if( !empty( $pd_number ) )
update_post_meta( $post_id, '_pd_number', esc_attr( $pd_number ) );
}
// Show text in Product Page
add_action( 'woocommerce_after_add_to_cart_button',
'add_cf_before_addtocart_in_single_products', 1, 0 );
function add_cf_before_addtocart_in_single_products()
{
global $product;
$pd_number = get_post_meta( $product->get_id(), '_pd_number', true );
if( !empty( $pd_number ) )
echo '<div class="pd-number">'. $pd_number .'</div><br>';
}
// Displaying the product custom field in the Cart items
add_filter( 'woocommerce_cart_item_name', 'add_cf_after_cart_item_name', 10,
3 );
function add_cf_after_cart_item_name( $name_html, $cart_item, $cart_item_key
)
{
$product_id = $cart_item['product_id'];
if( $cart_item['variation_id'] > 0 )
$product_id = $cart_item['variation_id'];
$pd_number = get_post_meta( $product_id, '_pd_number', true );;
if( !empty( $pd_number ) )
$name_html .= '<br><span class="pd-number">'.$pd_number .'</span>';
return $name_html;
}
but show only on my default site language Dansk. If choise English from top bar, custom field is not shown. I use WPML as language plugin. Any help ?
In this image, if you put the blank custom field in other languages then it does not appear in front end

Woocommerce custom product field in checkout [duplicate]

This question already has an answer here:
Admin product pages custom field displayed in Cart and checkout
(1 answer)
Closed 5 years ago.
I have a seemingly simple task, that I can't, for the life of me, seem to figure out.
I have a custom field on the admin page of my Woocommerce products. I just need the value I set here to display in the Woocommerce Checkout page and email.
I have managed to get the field to display on the product page using the following code:
add_action( 'woocommerce_product_options_general_product_data', 'create_shipdate_custom_field' );
function create_shipdate_custom_field() {
woocommerce_wp_text_input( array(
'id' => '_shipdate',
'type' => 'text',
'label' => __('Shipping Date', 'woocommerce' ),
'description' => '',
'desc_tip' => 'true',
'placeholder' => __('i.e. 16 December 2017', 'woocommerce' ),
) );
}
// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_shipdate_custom_field' );
function save_shipdate_custom_field( $post_id ) {
$wc_text_field = $_POST['_shipdate'];
if ( !empty($wc_text_field) ) {
update_post_meta( $post_id, '_shipdate', esc_attr( $wc_text_field ) );
}
}
function product_date() {
echo get_post_meta( get_the_ID(), '_shipdate', true );
}
add_action('woocommerce_single_product_summary', 'product_date', 30);
I am able to get static text to display on the checkout page, using the following code, but it just won't work with my custom field:
function emaildate() { echo "This will display fine"; }
add_action('woocommerce_order_item_meta_start', 'emaildate', 10, 1);
Thanks in advance for the help!
You are missing a couple of steps to have your custom value display on the cart/checkout pages, namely, storing the custom field in the cart and in the order as meta data. Here is the full code which should work as expected:
// create the custom field on product admin tab
add_action( 'woocommerce_product_options_general_product_data', 'create_shipping_custom_field' );
function create_shipping_custom_field() {
// Create a custom text field
woocommerce_wp_text_input( array(
'id' => '_shipdate',
'type' => 'text',
'label' => __('Shipping Date', 'woocommerce' ),
'description' => '',
'desc_tip' => 'true',
'placeholder' => __('i.e. 16 December 2017', 'woocommerce' ),
) );
}
// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_shipping_custom_field' );
function save_shipping_custom_field( $post_id ) {
$wc_text_field = $_POST['_shipdate'];
if ( !empty($wc_text_field) ) {
update_post_meta( $post_id, '_shipdate', esc_attr( $wc_text_field ) );
}
}
// Store custom field in Cart
add_action( 'woocommerce_add_cart_item_data', 'store_shipping_custom_field', 10, 2 );
function store_shipping_custom_field( $cart_item_data, $product_id ) {
$ship_date = get_post_meta( $product_id , '_shipdate', true );
if( !empty($ship_date) ) {
$cart_item_data[ '_shipdate' ] = $ship_date;
$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'date_shipping', $ship_date );
}
return $cart_item_data;
}
// Render meta on cart and checkout
add_filter( 'woocommerce_get_item_data', 'rendering_meta_field_on_cart_and_checkout', 10, 2 );
function rendering_meta_field_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['_shipdate'] ) ) {
$custom_items[] = array( "name" => __( "Shipping Date", "woocommerce" ), "value" => $cart_item['_shipdate'] );
}
return $custom_items;
}
// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_shipping_to_order_item_meta', 1, 3 );
function add_shipping_to_order_item_meta( $item_id, $values, $cart_item_key ) {
$prod_id = wc_get_order_item_meta( $item_id, '_product_id', true );
$shipdate = get_post_meta( $prod_id, '_shipdate', true );
wc_add_order_item_meta( $item_id, 'Shipping Date', $shipdate, true );
}

Categories