skip to Main Content

I added a custom field to the checkout (select field) and I would like to save that field along with all the other fields, but it is not showing me the custom field at all on any plugin I am using.

This is the code I added to my functions.php file:


//* Add select field to the checkout page
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');

function wps_add_select_checkout_field( $checkout ) {

    woocommerce_form_field( 'studio', array(
        'type'          => 'select',
        'class'         => array( 'wps-drop' ),
        'label'         => __( 'Select your studio' ),
        'required'    => true,
        'priority'    => 5, // Priority sorting option
        'options'       => array(
            'blank'     => __( 'Select Your Studio', 'wps' ),
           'Ukraine & Poland' => __('Ukraine & Poland', 'wps' ),
            'Israel' => __('Israel',  'wps' ),
           'Kyiv' => __('Kyiv',  'wps' ),
            'Finland ' => __('Finland',  'wps' )
        )
 ),
    $checkout->get_value( 'studio' ));
}



//* Process the checkout
 add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
 function wps_select_checkout_field_process() {
    global $woocommerce;

    // Check if set, if its not set add an error.
    if ($_POST['studio'] == "blank")
     wc_add_notice( '<strong>Please select your studio</strong>', 'error' );
 }

Any idea what I need to do in order to save this field?

2

Answers


  1. Your code is ok but you dont save the field!

    Add this to save the field in order meta data:

    /**
     * Saves the value of the "studio" custom checkout field to the order meta data.
     *
     * @param int $order_id The ID of the order being processed.
     */
    function wps_save_select_checkout_field( $order_id ) {
        // Check if the "studio" field was submitted and is not empty.
        if ( ! empty( $_POST['studio'] ) ) {
            // Sanitize the input before saving it to the database.
            $studio_value = sanitize_text_field( $_POST['studio'] );
    
            // Update the order meta data.
            update_post_meta( $order_id, 'studio', $studio_value );
        }
    }
    
    add_action( 'woocommerce_checkout_update_order_meta', 'wps_save_select_checkout_field' );
    

    Then you can retrieve it as any other meta field. Here is a function that will output the selection made in field ‘studio’:

    /**
     * Gets the value of the "studio" custom checkout field from a WooCommerce order.
     *
     * @param int $order_id The ID of the WooCommerce order.
     * @return string|null The value of the "studio" field, or null if not found.
     */
    function wps_get_order_studio_field( $order_id ) {
        $order = wc_get_order( $order_id );
    
        if ( $order ) {
            return $order->get_meta( 'studio' );
        }
        
        return null;
        
    }
    

    Usage:

    // save the choice in a variable for order with id 1235
    $studio_selection = wps_get_order_studio_field( '1235 );
    
    // display the choice
    echo esc_html( $studio_selection );
    

    Note: I strongly recommend to not use "studio" for the field name, add a preffix to avoid conflicts i.e. "wps_studio"

    Login or Signup to reply.
  2. You need to save your custom checkout field selected value as order metadata like:

    add_action( 'woocommerce_checkout_create_order', 'save_custom_fields_as_order_metadata' );
    function save_custom_fields_as_order_metadata( $order ) {
        if ( isset($_POST['studio']) ) 
            $order->add_meta_data('studio', esc_attr($_POST['studio']), true );
        }
    }
    

    Since version 3, WooCommerce is migrating to custom database tables, (specially for orders), and with recent High Performance Order Storage (HPOS), the only way is to use setter methods to save the custom metadata, instead of using WordPress post meta functions.

    For example you can display it in admin orders with:

    add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_custom_field_after_admin_order_shipping_address' );
    function display_custom_field_after_admin_order_shipping_address( $order ) {
        if ( $studio_value = $order->get_meta('studio') ) {
            printf( '<div><strong>%s:</strong> <span>%s</span></div>', 
                __('Studio', 'wps'), $studio_value
            );
        }
    }
    

    So as you see, you can access ‘studio’ metadata from the WC_Order object like:

    $studio_value = $order->get_meta('studio');
    

    This is compatible with legacy Post data and High Performance Order Storage (HPOS).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search