Home > Mobile >  How to loop though a number of custom fields in WooCommerce admin order edit pages
How to loop though a number of custom fields in WooCommerce admin order edit pages

Time:04-18

I have a WooCommerce custom field created dependent on product ID and the field name is incremented by 1 by quantity purchased.

add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta');
    /**
     * Save value of fields
     */
    function customise_checkout_field_update_order_meta($order_id) {
        // True
        if ( WC()->cart ) {
            // Specific product IDs
            $product_ids = array( 11,12,13 );
    
            // Initialize
            $count = 0;
    
            // Loop trough cart items quantities
        
            foreach ( WC()->cart->get_cart_item_quantities() as $product_id => $cart_item_quantity ) {
                // Checks if a value exists in an array
                if ( in_array( $product_id, $product_ids ) ) {
                    $count  = $cart_item_quantity;
                }
            }
            $i = 0;
            for($k=1; $k<= $count; $k  ) {
                $i  ;
            if (!empty($_POST['cstm_full_name'.$i])) {
                update_post_meta($order_id, 'Name of Attendee '.$i, sanitize_text_field($_POST['cstm_full_name'.$i]));
            }
     
        }
    }
}

That works fine, but I want to display the fields on the WooCommerce internal Order Admin screen, how can I loop through the custom field and display the incremented field names...

add_action( 'woocommerce_admin_order_data_after_billing_address', 'bt_attendees_field_display_admin_order_meta', 10, 1 );
/**
 * Display attendees value on the backend WooCommerce order
 */
function bt_attendees_field_display_admin_order_meta($order){

        $i = 1;
        echo '<p>Attendee Name ' . get_post_meta( $order->get_id(), 'Name of Attendee '.$i, true ) . '<p>'; 
   
}

So above the first field will be output above as the variable has been set to 1 - how can I loop though an indeterminate amount of the same field per order per order.

loop attendee name custom field

show incremented custom field

CodePudding user response:

There are different ways, you could use $order->get_meta_data() to get all meta data from the current $order object. Then you just display the values ​​that starts with a given substring.

Some notes about your current code

  • The woocommerce_checkout_create_order hook was used to save against the woocommerce_checkout_update_order_meta hook because the $order object is already passed to the callback function
  • It is recommended not to use spaces when creating meta_keys, this will reduce the error burden

So you get:

// Save meta data
function action_woocommerce_checkout_create_order( $order, $data ) {
    // Count
    $count = 6;

    // Some value
    $value = 'the_value_';

    // Loop
    for ( $i = 1; $i <= $count; $i   ) {
        // Update meta data
        $order->update_meta_data( 'name_of_attendee_' . $i, $value . $i );
    }
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );

function action_woocommerce_admin_order_data_after_billing_address( $order ) {
    // Get all meta data.
    $meta_data = $order->get_meta_data();

    // Loop through data
    foreach ( $meta_data as $meta_data_obj ) {
        $meta_data_array = $meta_data_obj->get_data();

        // Checks if a string starts with a given substring
        if ( str_starts_with( $meta_data_array['key'], 'name_of_attendee_' ) ) {
            // Output value
            echo '<p>Attendee name: ' . $meta_data_array['value'] . '<p>'; 
        }
    }
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'action_woocommerce_admin_order_data_after_billing_address', 10, 1 );

Another way is to add the $count value as a hidden field and save its value as order meta data (in addition to the other desired data)

Then you can use the $count value for the output

function action_woocommerce_before_order_notes( $checkout ) {
    // Count
    $count = 10;

    // Hidden field
    echo '<input type="hidden" name="_count" value="' . $count . '">';

    // Output of the other fields
    // etc...
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );

// Save
function action_woocommerce_checkout_create_order( $order, $data ) {
    // Isset    
    if ( isset( $_POST['_count'] ) ) {    
        // Update meta data
        $order->update_meta_data( '_count', sanitize_text_field( $_POST['_count'] ) );
    }

    // Save the other fields
    // etc..
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );

function action_woocommerce_admin_order_data_after_billing_address( $order ) {
    // Get count
    $count = $order->get_meta( '_count' );

    for ( $i = 1; $i <= $count; $i   ) {
        echo '<p>Attendee Name... etc.. </p>';

        // Get meta from the other fields
        // $output = $order->get_meta( 'name_of_attendee_' . $i );
    }
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'action_woocommerce_admin_order_data_after_billing_address', 10, 1 );
  • Related