NickJWStone
NickJWStone

Reputation: 11

Disallow customer to change country in WooCommerce "My Account"

I'm looking for a solution in which customers are unable to edit the country when changing their address.

We sell subscriptions, which are tied to specific countries. So changing an address is no problem, although we don't want to enable changes to a different country.

During checkout the check is done, but currently clients are able to change it from 'my account' once the subscription is bought and active.

What I've tried so far is to disable the country dropdown fields with the following code:

add_filter('woocommerce_default_address_fields', 'readdonly_country_select_field');

function readdonly_country_select_field( $fields ) {

    //Only on account pages
    if( ! is_account_page() ) return $fields;

    // Make country field read only
    $fields['country']['custom_attributes'] = array( 'disabled' => 'disabled' );

    return $fields;
}

The problem is that the changed address is not saved. (No error messages are thrown, the pages just 'refreshes')

I assume this might be due to the fact that disabled fields don't get posted, but I cannot seem to find out how to do that. Does anyone now how to do that in this specific case?

Upvotes: 1

Views: 557

Answers (1)

7uc1f3r
7uc1f3r

Reputation: 29624

Besides using the woocommerce_billing_fields and the woocommerce_shipping_fields filter hooks you can use the woocommerce_after_edit_address_form_{$load_address} action hook so you can add the values ​​as hidden fields

So then you get:

function filter_woocommerce_billing_fields( $fields ) {
    // Only on My account > Edit address section
    if ( is_wc_endpoint_url('edit-address') ) { 
        $fields['billing_country']['custom_attributes']['disabled'] = 'disabled';
    }

    return $fields;
}
add_filter( 'woocommerce_billing_fields', 'filter_woocommerce_billing_fields', 10, 1 );

function filter_woocommerce_shipping_fields( $fields ) {
    // Only on My account > Edit address section
    if ( is_wc_endpoint_url('edit-address') ) { 
        $fields['shipping_country']['custom_attributes']['disabled'] = 'disabled';
    }

    return $fields;
}
add_filter( 'woocommerce_shipping_fields', 'filter_woocommerce_shipping_fields', 10, 1 );
    
function woocommerce_after_edit_address_form() {
    $billing_country = WC()->customer->get_billing_country();
    $shipping_country = WC()->customer->get_shipping_country();
    ?>
    <input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
    <input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
    <?php   
}
add_action( 'woocommerce_after_edit_address_form_billing', 'woocommerce_after_edit_address_form' );
add_action( 'woocommerce_after_edit_address_form_shipping', 'woocommerce_after_edit_address_form' );

Update: if you experience issues with the above answer you can also use the woocommerce_default_address_fields hook

function filter_woocommerce_default_address_fields( $fields ) {
    // Only on account pages
    if ( ! is_account_page() ) return $fields;
    
    // Make country field read only
    $fields['country']['custom_attributes'] = array( 'disabled' => 'disabled' );

    return $fields;
}
add_filter( 'woocommerce_default_address_fields' , 'filter_woocommerce_default_address_fields' );

function woocommerce_after_edit_address_form() {
    $billing_country = WC()->customer->get_billing_country();
    $shipping_country = WC()->customer->get_shipping_country();
    ?>
    <input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
    <input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
    <?php   
}
add_action( 'woocommerce_after_edit_address_form_billing', 'woocommerce_after_edit_address_form' );
add_action( 'woocommerce_after_edit_address_form_shipping', 'woocommerce_after_edit_address_form' );

Upvotes: 1

Related Questions