I am building a site using WooCommerce and Advanced Custom Fields (ACF) plugin. I've created two ACF custom fields with names "plant" and "amount".
I am trying to display them both on front end but currently only the custom field "plant" is displaying everywhere. I've been looking around the net with no luck.
add_action( 'woocommerce_before_add_to_cart_button', 'add_custom_field', 0 );
function add_custom_field() {
global $product; // Changed this
// Added this too (compatibility with WC +3)
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo "<div class='produto-informacoes-complementares'>";
echo get_field( 'plant', $product_id );
echo "</div>";
echo "<div class='produto-informacoes-complementares'>";
echo get_field( 'amount', $product_id );
echo "</div>";
return true;
}
add_filter( 'woocommerce_add_cart_item_data', 'save_my_custom_product_field', 10, 2 );
function save_my_custom_product_field( $cart_item_data, $product_id ) {
$custom_field_value = get_field( 'plant', $product_id, true );
$custom_field_value = get_field( 'amount', $product_id, true );
if( !empty( $custom_field_value ) )
{
$cart_item_data['plant'] = $custom_field_value;
$cart_item_data['amount'] = $custom_field_value;
// 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_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['plant'] )) {
$custom_items[] = array( "name" => "גודל עציץ", "value" => $cart_item['plant'] );
$custom_items[] = array( "name" => "כמות במגש", "value" => $cart_item['amount'] );
}
return $custom_items;
}
function add_order_item_meta_acf( $item_id, $values ) {
wc_add_order_item_meta( $item_id, 'גודל עציץ', $values [ 'plant' ] );
wc_add_order_item_meta( $item_id, 'גודל עציץ', $values [ 'amount' ] );
}
add_action( 'woocommerce_add_order_item_meta', 'add_order_item_meta_acf' , 10, 2);
Your code is a bit outdated and with some mistakes. Use the following to display product ACF custom fields everywhere (product page, cart, checkout, orders and email notifications):
// Display on product page
add_action( 'woocommerce_before_add_to_cart_button', 'display_acf_single_product_pages', 1 );
function display_acf_single_product_pages() {
global $product;
$plant = get_field( 'plant', $product->get_id() );
$amount = get_field( 'amount', $product->get_id() );
if ( ! empty($plant) && ! empty($amount) ) {
echo '<div class="produto-informacoes-complementares">';
if ( ! empty($plant) ) {
echo '<div class="plant"><strong>' . __("Size", "woocommerce") . '</strong>: ' . $plant . '</div>';
}
if ( ! empty($amount) ) {
echo '<div class="amount"><strong>' . __("Amount", "woocommerce") . '</strong>: ' . $amount . '</div>';
}
echo '</div>';
}
}
// Display on cart and checkout
add_filter( 'woocommerce_get_item_data', 'display_acf_on_cart_and_checkout', 10, 2 );
function display_acf_on_cart_and_checkout( $cart_data, $cart_item ) {
$plant = get_field( 'plant', $cart_item['product_id'] );
$amount = get_field( 'amount', $cart_item['product_id'] );
if ( ! empty($plant) ) {
$custom_items[] = array( "name" => __("Size", "woocommerce"), "value" => $plant );
}
if ( ! empty($amount) ) {
$custom_items[] = array( "name" => __("Amount", "woocommerce"), "value" => $amount );
}
return $custom_items;
}
// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$plant = get_field( 'plant', $values['product_id'] );
$amount = get_field( 'amount', $values['product_id'] );
if ( ! empty($plant) ) {
$item->add_meta_data( __("Size", "woocommerce"), $plant );
}
if ( ! empty($amount) ) {
$item->add_meta_data( __("Amount", "woocommerce"), $amount );
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Related
With WooCommerce, I'm using the Advanced Custom Fields plugin to Add product design URL
I tide this code to display "design_url"
// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$plant = get_field( 'plant', $values['product_id'] );
$amount = get_field( 'amount', $values['product_id'] );
if ( ! empty($plant) ) {
$item->add_meta_data( __("Size", "woocommerce"), $plant );
}
if ( ! empty($amount) ) {
$item->add_meta_data( __("Amount", "woocommerce"), $amount );
}
}
But I want display it only on order Admin page
add_action( 'woocommerce_order_item_meta_start', 'display_acf_on_order_admin_page', 10, 3 );
function display_acf_on_order_admin_page( $item_id, $item, $order ) {
$product_id = $item->get_product_id();
$plant = get_field( 'plant', $product_id );
$amount = get_field( 'amount', $product_id );
if ( ! empty( $plant ) ) {
echo '<p><strong>' . __( 'Size', 'woocommerce' ) . ':</strong> ' . $plant . '</p>';
}
if ( ! empty( $amount ) ) {
echo '<p><strong>' . __( 'Amount', 'woocommerce' ) . ':</strong> ' . $amount . '</p>';
}
}
This function will be called for each order item in the order, and it will display the "plant" and "amount" custom field values if they are present.
Ive set up an ACF with 2 checkboxes, which are shown up in the product admin:
on the product frontend only the selected values form the backend are chooseable:
Ive the following code im my funtions:
// Display on product page
add_action( 'woocommerce_before_add_to_cart_button', 'display_acf_single_product_pages', 1 );
function display_acf_single_product_pages() {
global $product;
$colors = get_field( 'colors', $product->get_id() );
$sizes = get_field( 'sizes', $product->get_id() );
if( $colors ): ?>
<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="cars">Farbe wählen:</label>
<select name="farbe" id="farbe">
<?php foreach( $colors as $color ): ?>
<option><span class="color"><?php echo $color['label']; ?></span></option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<br>
<?php
if( $sizes ): ?>
<div class="vorcartbuttonlable">
<label for="cars">Größe wählen:</label>
<select name="groesse" id="groesse">
<?php foreach( $sizes as $sizes ): ?>
<option><span class="groesse"><?php echo $sizes['label']; ?></span></option>
<?php endforeach; ?>
</select>
</div>
</div>
<?php endif; ?>
<br>
<?php
}
// Display on cart and checkout
add_filter( 'woocommerce_get_item_data', 'display_acf_on_cart_and_checkout', 10, 2 );
function display_acf_on_cart_and_checkout( $cart_data, $cart_item ) {
$colors = get_field( 'colors', $cart_item['product_id'] );
$sizes = get_field( 'sizes', $cart_item['product_id'] );
if ( ! empty($colors) ) {
$custom_items[] = array( "name" => __("Farbe", "woocommerce"), "value" => $colors );
}
if ( ! empty($sizes) ) {
$custom_items[] = array( "name" => __("Größe", "woocommerce"), "value" => $sizes );
}
return $custom_items;
}
// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$colors = get_field( 'colors', $values['product_id'] );
$sizes = get_field( 'sizes', $values['product_id'] );
if ( ! empty($colors) ) {
$item->add_meta_data( __("size", "woocommerce"), $colors );
}
if ( ! empty($sizes) ) {
$item->add_meta_data( __("color", "woocommerce"), $sizes );
}
}
In the cart the values just show array:
Can someone push me in the right direction, to get the correct values in the cart, checkout, mails and orders?
Originally taken from here Display ACF product custom fields everywhere in WooCommerce 3+
There are mistakes and some missing things in your code. Instead use the following revisited code:
// Display on product page
add_action( 'woocommerce_before_add_to_cart_button', 'display_acf_single_product_pages', 1 );
function display_acf_single_product_pages() {
global $product;
$colors = get_field( 'colors', $product->get_id() );
if ( ! empty($colors) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="farbe">'. __("Farbe wählen") .':</label>
<select name="farbe" id="farbe">';
foreach ( $colors as $color ) {
echo '<option value="'. $color['label'] .'"><span class="color">'. $color['label'] .'</span></option>';
}
echo '</select>
</div><br>';
}
$sizes = get_field( 'sizes', $product->get_id() );
if ( ! empty($sizes) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="groesse">'. __("Größe wählen") .':</label>
<select name="groesse" id="groesse">';
foreach ( $sizes as $size ) {
echo '<option value="'. $size['label'] .'"><span class="color">'. $size['label'] .'</span></option>';
}
echo '</select>
</div><br>
</div>';
}
}
// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_acf_as_cart_item_data', 10, 2 );
function save_acf_as_cart_item_data( $cart_item_data, $cart_item ) {
if ( isset($_POST['farbe']) || isset($_POST['groesse']) ) {
if ( isset($_POST['farbe']) ) {
$cart_item_data['farbe'] = esc_attr($_POST['farbe']);
}
if ( isset($_POST['groesse']) ) {
$cart_item_data['groesse'] = esc_attr($_POST['groesse']);
}
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}
// Display on cart and checkout
add_filter( 'woocommerce_get_item_data', 'display_acf_on_cart_and_checkout', 10, 2 );
function display_acf_on_cart_and_checkout( $cart_data, $cart_item ) {
if ( isset($cart_item['farbe']) ) {
$custom_items[] = array( 'name' => __("Farbe", "woocommerce"), 'value' => $cart_item['farbe'] );
}
if ( isset($cart_item['groesse']) ) {
$custom_items[] = array( 'name' => __("Größe", "woocommerce"), 'value' => $cart_item['groesse'] );
}
return $custom_items;
}
// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$colors = get_field( 'colors', $values['product_id'] );
$sizes = get_field( 'sizes', $values['product_id'] );
if ( isset($values['farbe']) ) {
$item->add_meta_data( 'farbe', $values['farbe'] );
}
if ( isset($values['groesse']) ) {
$item->add_meta_data( 'groesse', $values['groesse'] );
}
}
// Change displayed label for specific custom order item meta keys
add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 10, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {
// Change displayed label for specific order item meta key
if( is_admin() && $item->get_type() === 'line_item' ) {
if( $meta->key === 'farbe' ) {
$display_key = __("Farbe", "woocommerce");
}
if( $meta->key === 'groesse' ) {
$display_key = __("Größe", "woocommerce");
}
}
return $display_key;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
The goal here is to have a text field on the product page.
The customer fills it in and adds to cart. The text is added to the product and included in the cart and on the checkout and on the order.
The field works and the validation works fine, but the text is not included / transferred to the cart, checkout and order.
Here's the code:
add_action( 'woocommerce_before_add_to_cart_button', 'product_add_on', 9 );
function product_add_on() {
$value = isset( $_POST['_custom_text_add_on'] ) ? sanitize_text_field( $_POST['_custom_text_add_on'] ) : '';
echo '<div><label>Custom Text Add-On <abbr class="required" title="required">*</abbr></label><p><input name="_custom_text_add_on" value="' . $value . '"></p></div>';
}
add_filter( 'woocommerce_add_to_cart_validation', 'product_add_on_validation', 10, 3 );
function product_add_on_validation( $passed, $product_id, $qty ){
if( isset( $_POST['_custom_text_add_on'] ) && sanitize_text_field( $_POST['_custom_text_add_on'] ) == '' ) {
wc_add_notice( 'Custom Text Add-On is a required field', 'error' );
$passed = false;
}
return $passed;
}
add_filter( 'woocommerce_add_cart_item_data', 'product_add_on_cart_item_data', 10, 2 );
function product_add_on_cart_item_data( $cart_item, $product_id ){
if( isset( $_POST['_custom_text_add_on'] ) ) {
$cart_item['custom_text_add_on'] = sanitize_text_field( $_POST['custom_text_add_on'] );
}
return $cart_item;
}
add_filter( 'woocommerce_get_item_data', 'product_add_on_display_cart', 10, 2 );
function product_add_on_display_cart( $_data, $cart_item ) {
if ( isset( $cart_item['custom_text_add_on'] ) ){
$data[] = array(
'name' => 'Custom Text Add-On',
'value' => sanitize_text_field( $cart_item['custom_text_add_on'] )
);
}
return $data;
}
add_action( 'woocommerce_add_order_item_meta', 'product_add_on_order_item_meta', 10, 2 );
function product_add_on_order_item_meta( $item_id, $values ) {
if ( ! empty( $values['custom_text_add_on'] ) ) {
wc_add_order_item_meta( $item_id, 'Custom Text Add-On', $values['custom_text_add_on'], true );
}
}
add_filter( 'woocommerce_order_item_product', 'product_add_on_display_order', 10, 2 );
function product_add_on_display_order( $cart_item, $order_item ){
if( isset( $order_item['custom_text_add_on'] ) ){
$cart_item_meta['custom_text_add_on'] = $order_item['custom_text_add_on'];
}
return $cart_item;
}
add_filter( 'woocommerce_email_order_meta_fields', 'product_add_on_display_emails' );
function product_add_on_display_emails( $fields ) {
$fields['custom_text_add_on'] = 'Custom Text Add-On';
return $fields;
}
I have copied the code and done a quick test and could found that you are missing underscore _ for the field name in two functions. You were using $_POST['custom_text_add_on'] instead of $_POST['_custom_text_add_on'] in the product_add_on_cart_item_data function. That was just a mistake.
add_filter( 'woocommerce_add_cart_item_data', 'product_add_on_cart_item_data', 10, 2 );
function product_add_on_cart_item_data( $cart_item, $product_id ){
if( isset( $_POST['_custom_text_add_on'] ) ) {
$cart_item['custom_text_add_on'] = sanitize_text_field( $_POST['_custom_text_add_on'] );
}
return $cart_item;
}
Hope you got the issue resolved
I've added two customer date inputs to the single product page. I need them to be required and validated before adding to the cart, and would also like the dates to be shown on the cart/checkout page and in the order emails.
I found the snippets needed here, however it was only for one custom field so I adjusted to make it for two: https://www.kathyisawesome.com/add-a-custom-field-to-woocommerce-product/
The input fields show up fine, but once you hit the Add to Cart button it doesn't carry throughout the order.
Here is the code used in my functions.php file:
/*
* Display inputs on single product page
*/
function amp_custom_option_1(){
$value = isset( $_POST['_est_delivery'] ) ? sanitize_text_field( $_POST['_est_delivery'] ) : '';
printf( '<div id="dates"><div class="delivery"><label>%s</label><input name="_est_delivery" value="%s" type="date" required /></div>', __( 'Estimated Delivery Date:', 'amp-plugin-textdomain-1' ), esc_attr( $value ) );
}
add_action( 'woocommerce_before_add_to_cart_form', 'amp_custom_option_1', 9 );
function amp_custom_option_2(){
$value = isset( $_POST['_est_pickup'] ) ? sanitize_text_field( $_POST['_est_pickup'] ) : '';
printf( '<div class="pickup"><label>%s</label><input name="_est_pickup" value="%s" type="date" required /></div></div>', __( 'Estimated Pickup Date:', 'amp-plugin-textdomain-2' ), esc_attr( $value ) );
}
add_action( 'woocommerce_before_add_to_cart_form', 'amp_custom_option_2', 9 );
/*
* Validate when adding to cart
*/
function amp_add_to_cart_validation_1($passed, $product_id, $qty){
if( isset( $_POST['_est_delivery'] ) && sanitize_text_field( $_POST['_est_delivery'] ) == '' ){
$product = wc_get_product( $product_id );
wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter a delivery date.', 'amp-plugin-textdomain-1' ), $product->get_title() ), 'error' );
return false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'amp_add_to_cart_validation_1', 10, 3 );
function amp_add_to_cart_validation_2($passed, $product_id, $qty){
if( isset( $_POST['_est_pickup'] ) && sanitize_text_field( $_POST['_est_pickup'] ) == '' ){
$product = wc_get_product( $product_id );
wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter a pickup date.', 'amp-plugin-textdomain-2' ), $product->get_title() ), 'error' );
return false;
}
return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'amp_add_to_cart_validation_2', 10, 3 );
/*
* Add custom data to the cart item
*/
function amp_add_cart_item_data_1( $cart_item, $product_id ){
if( isset( $_POST['_est_delivery'] ) ) {
$cart_item['est_delivery'] = sanitize_text_field( $_POST['_est_delivery'] );
}
return $cart_item;
}
add_filter( 'woocommerce_add_cart_item_data', 'amp_add_cart_item_data_1', 10, 2 );
function amp_add_cart_item_data_2( $cart_item, $product_id ){
if( isset( $_POST['_est_pickup'] ) ) {
$cart_item['est_pickup'] = sanitize_text_field( $_POST['_est_pickup'] );
}
return $cart_item;
}
add_filter( 'woocommerce_add_cart_item_data', 'amp_add_cart_item_data_2', 10, 2 );
/*
* Load cart data from session
*/
function amp_get_cart_item_from_session_1( $cart_item, $values ) {
if ( isset( $values['est_delivery'] ) ){
$cart_item['est_delivery'] = $values['est_delivery'];
}
return $cart_item;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'amp_get_cart_item_from_session_1', 20, 2 );
function amp_get_cart_item_from_session_2( $cart_item, $values ) {
if ( isset( $values['est_pickup'] ) ){
$cart_item['est_pickup'] = $values['est_pickup'];
}
return $cart_item;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'amp_get_cart_item_from_session_2', 20, 2 );
/*
* Add meta to order item
*/
function amp_add_order_item_meta_1( $item_id, $values ) {
if ( ! empty( $values['est_delivery'] ) ) {
woocommerce_add_order_item_meta( $item_id, 'est_delivery', $values['est_delivery'] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'amp_add_order_item_meta_1', 10, 2 );
function amp_add_order_item_meta_2( $item_id, $values ) {
if ( ! empty( $values['est_pickup'] ) ) {
woocommerce_add_order_item_meta( $item_id, 'est_pickup', $values['est_pickup'] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'amp_add_order_item_meta_2', 10, 2 );
/*
* Get item data to display in cart
*/
function amp_get_item_data_1( $other_data, $cart_item ) {
if ( isset( $cart_item['est_delivery'] ) ){
$other_data[] = array(
'name' => __( 'Estimated Delivery Date:', 'amp-plugin-textdomain-1' ),
'value' => sanitize_text_field( $cart_item['est_delivery'] )
);
}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'amp_get_item_data_1', 10, 2 );
function amp_get_item_data_2( $other_data, $cart_item ) {
if ( isset( $cart_item['est_pickup'] ) ){
$other_data[] = array(
'name' => __( 'Estimated Pickup Date', 'amp-plugin-textdomain-2' ),
'value' => sanitize_text_field( $cart_item['est_pickup'] )
);
}
return $other_data;
}
add_filter( 'woocommerce_get_item_data', 'amp_get_item_data_2', 10, 2 );
/*
* Show custom field in order overview
*/
function amp_order_item_product_1( $cart_item, $order_item ){
if( isset( $order_item['est_delivery'] ) ){
$cart_item_meta['est_delivery'] = $order_item['est_delivery'];
}
return $cart_item;
}
add_filter( 'woocommerce_order_item_product', 'amp_order_item_product_1', 10, 2 );
function amp_order_item_product_2( $cart_item, $order_item ){
if( isset( $order_item['est_pickup'] ) ){
$cart_item_meta['est_pickup'] = $order_item['est_pickup'];
}
return $cart_item;
}
add_filter( 'woocommerce_order_item_product', 'amp_order_item_product_2', 10, 2 );
/*
* Add the field to order emails
*/
function amp_email_order_meta_fields_1( $fields ) {
$fields['est_delivery'] = __( 'Estimated Delivery Date:', 'amp-plugin-textdomain-1' );
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'amp_email_order_meta_fields_1');
function amp_email_order_meta_fields_2( $fields ) {
$fields['est_delivery'] = __( 'Estimate Pickup Date:', 'amp-plugin-textdomain-2' );
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'amp_email_order_meta_fields_2');
I'm not sure what is wrong with my code? Any help is appreciated.
There was some errors and mistakes. I have changed and removed some hooks, remove unnecessary code, merged functions, revisited all your code. As Your 2 dates fields are on single product pages, they will be related to cart items and order items (so order items meta data).
I have set your 2 date fields slugs and labels in the first function, inside an array. Then I call that function everywhere else and I use a foreach loop to process each field. This avoid repetitions, optimize and compact the code.
The code (commented):
// Utility function that contain the 2 field keys and labels pairs used on all other functions
function get_date_label_keys(){
$text_domain = 'woocommerce';
return array( 'est_delivery' => __( 'Estimated Delivery Date', $text_domain ),
'est_pickup' => __( 'Estimated Pickup Date', $text_domain ) );
}
// Display custom fields on single product page (hook replaced)
add_action( 'woocommerce_before_add_to_cart_button', 'amp_display_custom_fields', 20 );
function amp_display_custom_fields(){
echo '<div id="dates">';
// Loop through each custom field
foreach( get_date_label_keys() as $key => $label ){
$class = str_replace('est_', '', $key); // The class
$value = isset($_POST[$key]) ? sanitize_text_field($_POST[$key]) : ''; // Display the value
printf( '<div class="%s"><label>%s:</label> <input type="date" name="%s" value="%s" required /></div>', $class, $label, $key, $value );
}
echo '</div><br clear="all">';
}
// Add to cart fields validation (in case of need)
add_filter( 'woocommerce_add_to_cart_validation', 'amp_add_to_cart_validation', 20, 3 );
function amp_add_to_cart_validation( $passed, $product_id, $qty ){
// Loop through each custom field
foreach( get_date_label_keys() as $key => $label ){
if( isset( $_POST[$key] ) && empty( $_POST[$key] ) ){
wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter a delivery date.', $domain ), get_the_title() ), 'error' );
$passed = false;
}
}
return $passed;
}
// Add to cart items the custom data
add_filter( 'woocommerce_add_cart_item_data', 'amp_add_cart_item_data', 20, 2 );
function amp_add_cart_item_data( $cart_item, $product_id ){
// Loop through each custom field
foreach( get_date_label_keys() as $key => $label ){
if( isset( $_POST[$key] ) )
$cart_item['dates'][$key] = sanitize_text_field( $_POST[$key] );
}
return $cart_item;
}
// Display the dates in cart items on cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'amp_get_item_data', 20, 2 );
function amp_get_item_data( $item_data, $cart_item = null ) {
// Loop through each custom field
foreach( get_date_label_keys() as $key => $label ){
if ( isset( $cart_item['dates'][$key] ) )
$item_data[] = array(
'name' => $label,
'value' => sanitize_text_field( $cart_item['dates'][$key] )
);
}
return $item_data;
}
// Add order item meta data and Display the data in order items (hook replaced)
add_action( 'woocommerce_checkout_create_order_line_item', 'amp_add_order_item_meta', 20, 4 );
function amp_add_order_item_meta( $item, $cart_item_key, $values, $order ) {
foreach( get_date_label_keys() as $key => $label ){
// Loop through each custom field
if ( ! empty( $values['dates'][$key] ) )
$item->update_meta_data( $label, $values['dates'][$key] );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
On cart page (and checkout too):
Order received and order view pages (in admin order edit pages and email notifications too):
I have a a custom field value for each product. This custom field is inserted with the code below :
<?php
// Insert a Custom Admin Field
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_text_input( array(
'id' => 'days_manufacture',
'label' => __( 'Days for Manufacture', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Insert here', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '1'
),
) );
echo '</div>';
}
// Save the field
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_number_field = $_POST['days_manufacture'];
if( !empty( $woocommerce_number_field ) )
update_post_meta( $post_id, 'days_manufacture', esc_attr( $woocommerce_number_field ) );
}
// Store custom field
add_action( 'woocommerce_add_cart_item_data', 'save_days_field', 10, 2 );
function save_days_field( $cart_item_data, $product_id ) {
$special_item = get_post_meta( $product_id , 'days_manufacture',true );
if(!empty($special_item)) {
$cart_item_data[ 'days_manufacture' ] = $special_item;
// below statement make sure every add to cart action as unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'days_manufacture', $special_item );
}
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['days_manufacture'] ) ) {
$custom_items[] = array( "name" => __( "Days", "woocommerce" ), "value" => $cart_item['days_manufacture'] );
}
return $custom_items;
} ?>
This code works perfectly.
Now I would like on Cart and checkout (before coupon notice) pages to display the highest value of this custom field (days_manufacture) on a custom message, when multiple items are in Cart, like in this screenshot.
How can I achieve this?
Thanks.
Here is a custom function that will display a message on cart and checkout (before coupon notice) pages with the highest number of days of manufacture…
Here is the code:
add_action('woocommerce_before_cart', 'days_of_manufacture');
add_action('woocommerce_before_checkout_form', 'days_of_manufacture', 5);
function days_of_manufacture() {
$day_txt = ' ' . __('day', 'your_theme_domain_slug' );
$days_txt = ' ' . __('days', 'your_theme_domain_slug' );
$text = __('Your Order will be produced in: ', 'your_theme_domain_slug' );
$max_days = 0;
foreach( WC()->cart->get_cart() as $cart_item )
if($cart_item['days_manufacture'] > $max_days)
$max_days = $cart_item['days_manufacture'];
if($max_days != 0) {
if ($max_days == 1)
$days_txt = $day_txt;
$output = $text . $max_days . $days_txt;
echo "<div class='woocommerce-info'>$output</div>";
}
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Store the variable in the $_SESSION, then loop thru them and pick the highest, so you can use it later anywhere in your code