Search code examples
phpwordpresswoocommerceform-fieldsusermetadata

Adding some billing fields to WooCommerce My Account Edit account form


By design all three forms - checkout, register and edit_account are the same. So I have to add all needed fields to edit account form, because edit address form from myaccount isn't needed by design at all. I already added all of the fields, but have some issues with the country field. It has to be with select2, all is fine with that, but it doesn't update. When new user is created, it saves the country in user metas. But inside the edit account page I can't change the country. After updating it's still the one, which was saved on registration. To compare - I copy the city field too as an example.

add_action( 'woocommerce_edit_account_form', 'add_billing_phone_to_edit_account_form' );
function add_billing_phone_to_edit_account_form() {
    $user = wp_get_current_user();
    ?>
<div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">  
            <label for="reg_billing_city"><?php _e( 'Town/City', 'woocommerce' ); ?></label>
            <input type="text" name="billing_city" id="reg_billing_city" placeholder="<?php _e( 'Town/City', 'woocommerce' ); ?>" value="<?php echo get_user_meta( get_current_user_id(), 'billing_city', true );?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" />
        </div>

<?php
    wp_enqueue_script('wc-country-select');
    woocommerce_form_field('billing_country',array(
        'type'        => 'country',
        'class'       => array('dop'),
        'label'       => __('Country'),
        'placeholder' => __('Choose your country.'),
        'required'    => true,
        'clear'       => true,
        'default'     => 'FR'
    ));
}
add_action( 'woocommerce_save_account_details', 'save_billing_city_account_details', 16, 1 );
function save_billing_city_account_details( $customer_id ) {    
     if( isset( $_POST['billing_city'] ) )
        update_user_meta(  $customer_id, 'billing_city', sanitize_text_field( $_POST['billing_city'] ) );           
    }



add_action( 'woocommerce_save_account_details', 'save_billing_country_account_details', 17, 1 );
function save_billing_country_account_details( $customer_id  ) {    
     if( isset( $_POST['billing_country'] ) )
        update_user_meta(  $customer_id, 'billing_country', sanitize_text_field( $_POST['billing_country'] ) );         
}

I experimented with $user_id instead of $customer_id - it didn't help. With city I use the same methods of updating, and the city updates fine. So as the postcode, phone etc What's special with the country?


Solution

  • There was a missing argument in woocommerce_form_field() function for "billing_country". The country was saved in the database, but was not displayed in the field on reload.

    I have revisited your code a little bit more merging the 2 last functions and changed the country value sanitization.

    add_action( 'woocommerce_edit_account_form', 'add_custom_billing_fields_to_edit_account_form' );
    function add_custom_billing_fields_to_edit_account_form() {
        $user = wp_get_current_user();
        ?>
        <div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">  
            <label for="reg_billing_city"><?php _e( 'Town/City', 'woocommerce' ); ?></label>
            <input type="text" name="billing_city" id="reg_billing_city" placeholder="<?php _e( 'Town/City', 'woocommerce' ); ?>" value="<?php echo isset($user->billing_city) ? $user->billing_city : '';?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" />
        </div>
        <?php
        wp_enqueue_script('wc-country-select');
    
        woocommerce_form_field('billing_country', array(
            'type'        => 'country',
            'class'       => array('dop'),
            'label'       => __('Country'),
            'placeholder' => __('Choose your country.'),
            'required'    => true,
            'clear'       => true,
            'default'     => 'FR'
        ), isset($user->billing_country) ? $user->billing_country : 'FR' ); // <== HERE this was missing
    }
    
    add_action( 'woocommerce_save_account_details', 'save_account_details_custom_billing_fields', 20 );
    function save_account_details_custom_billing_fields( $customer_id ) {    
         if( isset( $_POST['billing_city'] ) ) {
            update_user_meta(  $customer_id, 'billing_city', sanitize_text_field( $_POST['billing_city'] ) ); 
         } 
        
         if( isset( $_POST['billing_country'] ) ) {
             update_user_meta(  $customer_id, 'billing_country', esc_attr( $_POST['billing_country'] ) ); // Changed sanitization
         } 
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.