Search code examples
phpwordpresswoocommercefieldaccount

WooCommerce edit account additional required fields does not accept 0 value


I have created a plugin that extends the account details with additional fields in WooCommerce. I have made these fields required using woocommerce_save_account_details_required_fields, which works as expected.

However, these fields should also accept a zero (0) value, but currently, they do not. Is there a way to make this work? I prefer to avoid using custom JavaScript, as the current implementation uses actions and filter hooks.

add_action( 'woocommerce_edit_account_form', 'andom_add_id_field_to_edit_account_form' );
function andom_add_id_field_to_edit_account_form() {
    $user = wp_get_current_user();
    ?>
    <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
      <label for="id_card"><?php _e( 'Id Card ', 'woocommerce' ); ?><span class="required">*</span></label>
      <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="id_card" id="id_card" value="<?php echo esc_attr( $user->id_card ); ?>" required />
    </p>
    <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
      <label for="adults"><?php _e( 'Adults in your household ', 'woocommerce' ); ?><span class="required">*</span></label>
      <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="adults" id="adults" value="<?php echo esc_attr( $user->adults ); ?>" required/>
    </p>
    <p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
      <label for="children"><?php _e( 'Children >= 18 in your household ', 'woocommerce' ); ?><span class="required">*</span></label>
      <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="children" id="children" value="<?php echo esc_attr( $user->children ); ?>" required/>
    </p>
    <?php
}

add_filter( 'woocommerce_save_account_details_required_fields', 'andom_make_field_required' );
function andom_make_field_required( $required_fields ){

  $required_fields[ 'id_card' ] = 'Id Card';
  $required_fields[ 'adults' ] = 'Adults';
  $required_fields[ 'children' ] = 'Children';
  return $required_fields;

}

As I said, it works so far; the only thing that does not is that a value of 0 seems to be nothing.


Solution

  • For your required additional fields, use woocommerce_save_account_details_errors hook instead of woocommerce_save_account_details_required_fields that doesn't allow 0 values.

    Also, your code can be optimized and compacted.

    Try the following complete code (replacing all your existing related code):

    // Utility function: Your additional fields settings
    function edit_account_additional_fields() {
        return array (
            'id_card'   => __( 'Id Card', 'woocommerce' ),
            'adults'    => __( 'Adults in your household', 'woocommerce' ),
            'children'  => __( 'Children >= 18 in your household', 'woocommerce' ),
        );
    }
    
    // Display custom additional fields 
    add_action( 'woocommerce_edit_account_form', 'edit_account_form_additional_fields_display' );
    function edit_account_form_additional_fields_display() {
        foreach ( edit_account_additional_fields() as $key => $label ) {
            printf('<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
            <label for="%s">%s <span class="required">*</span></label>
            <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="%s" id="%s" value="%s" required />
            </p>', $key, $label, $key, $key, get_user_meta( get_current_user_id(), $key, true ) );
        }
    }
    
    // custom additional fields validation
    add_action( 'woocommerce_save_account_details_errors', 'edit_account_form_required_fields_validation', 10, 2 );
    function edit_account_form_required_fields_validation( $errors, $user ) {
        foreach ( edit_account_additional_fields() as $key => $label ) {
            if( isset($_POST[$key]) && $_POST[$key] == '' ) {
                $errors->add( 'error', sprintf( __('%s is a required field.', 'woocommerce'), '<strong>'.esc_html($label).'</strong>' ),'');
            }
        }
    }
    
    // Save the custom additional fields values
    add_action( 'woocommerce_save_account_details', 'edit_account_form_save_additional_fields' );
    function edit_account_form_save_additional_fields( $user_id ) {
        foreach ( edit_account_additional_fields() as $key => $label ) {
            if( isset($_POST[$key]) && $_POST[$key] != '' ) {
                update_user_meta( $user_id, $key , sanitize_text_field($_POST[$key]) );
            }
        }
    }
    

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