Have a script in my functions.php to show certain custom fields I created to appear at checkout, but some products do not need these fields to appear. So I assigned these as virtual and used this code to make these only appear on standard products:
add_action( 'woocommerce_before_order_notes', 'my_checkout_fields' );
function my_checkout_fields( $checkout ) {
$only_virtual = false;
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! $cart_item['data']->is_virtual() ) $only_virtual = true;
}
if( $only_virtual ) {
woocommerce_form_field( 'so_childs_name', array(
'type' => 'text',
'required' => 'true',
'class' => array('cname-class form-row-wide'),
'label' => __('Child's Name'),
), $checkout->get_value( 'so_childs_name' ));
}
It works.... occasionally.
Of course, I need it to work all the time, so why isn't it working or is there is a way instead of using only_virtual, can I just use an array of product ID's?
There are some mistake and a missing closing bracket in your code (if I have well understood). Try:
add_action( 'woocommerce_before_order_notes', 'my_checkout_fields' );
function my_checkout_fields( $checkout ) {
$has_virtual = false; // Initializing
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->is_virtual() ) {
$has_virtual = true; // Stop the loop
break;
}
}
if( ! $has_virtual ) {
woocommerce_form_field( 'so_childs_name', array(
'type' => 'text',
'required' => 'true',
'class' => array('cname-class form-row-wide'),
'label' => __('Child's Name'),
), $checkout->get_value( 'so_childs_name' ) );
}
}
Code goes in functions.php file of the active child theme (or active theme). It should work.