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.