'profile_update' hook alternative for WooCommerce user meta data

I am trying to get all user details (including WooCommerce meta data) in a function that is called with user_register and profile_update hooks. This is the simplified code:

function get_all_user_data($user_id) {

    $user_data = get_userdata($user_id);

    $login = $user_data->user_login;

    $b_firstname = get_user_meta($user_id, 'billing_first_name', true);

}
add_action('user_register','get_all_user_data');
add_action('profile_update','get_all_user_data');

The behavior:

  1. User is registered, I can access it’s userdata (e.g. login) immediately
  2. WooCommerce billing address is updated and saved, however I still only can access the $login variable, ‘billing_first_name’ meta is apparently still empty at this time
  3. WooCommerce shipping address is updated and saved, after this I can access the billing information that were saved in previous step, but not the shipping data that was saved in current step

The same goes for a scenario in which the user is registered during WooCommerce checkout, no WC data is accessible at that time yet.

PS: I have also tried the woocommerce_after_save_address_validation hook, but that seems to have the same behavior as the profile_update in my case.

Edit: edit_user_profile_update doesn’t work as well. Setting the action priority to a high number (executed later) doesn’t help either. insert_user_meta filter works, but only returns native WP’s user meta, not WooCommerce customer’s meta.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

My solution would be this:

function get_all_user_data($user_id) {

    $user_data = get_userdata($user_id);

    $login = $user_data->user_login;

    $customer_array = new WC_Customer( $user_id );
    $customer = $customer_array->get_data();
    $billing_first_name = $customer[billing][first_name];
    $shipping_first_name = $customer[shipping][first_name];
}
add_action('user_register','get_all_user_data');
add_action('profile_update','get_all_user_data');

The array setup for the Customer arrays [billing] and [shipping] is as so (you can just change my values and get different data or add more variables if you’d like):

    [billing] => Array
        (
            [first_name] => John
            [last_name] => Doe
            [company] => 
            [address_1] => 1338 Easy St
            [address_2] => 
            [city] => Oakland
            [postcode] => 48094
            [country] => US
            [state] => CA
            [email] => [email protected]
            [phone] => 6167783456
        )

    [shipping] => Array
        (
            [first_name] => John
            [last_name] => Doe
            [company] => 
            [address_1] => 1338 Easy St
            [address_2] => 
            [city] => Oakland
            [postcode] => 48094
            [country] => US
            [state] => CA
        )

Solution 2

I got it working. The key was the woocommerce_update_customer action. In the end my function was triggered only by these two actions:

add_action('user_register','get_all_user_data', 99);
add_action('woocommerce_update_customer','get_all_user_data', 99);

I don’t need the profile_update because I don’t need to track changes in default WP’s user data. However it can be used along with woocommerce_update _customer, but keep in mind your function will be triggered twice.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply