After updating WooCommerce and Wordpress to last versions, I had some working code that just stop working:
function rl_save_extra_register_fields($customer_id){
if(isset($_POST['billing_first_name'])){ update_user_meta($customer_id,'first_name',sanitize_text_field($_POST['billing_first_name']));
// Update user role
$user = new WP_User($customer_id);
$user->set_role('customer_pending');
}
add_action('woocommerce_created_customer','rl_save_extra_register_fields');
I extended normal user registration form with extra fields and want to change user role. Code used to work, now user data is not updated.
What I checked/tested:
- Made sure my function fires
- Made sure correct $customer_id is used
- Made sure there is nothing else uses same action and overrides my changes (dumped $wp_filter[‘woocommerce_created_customer’])
I then looked through the Woo code — nothing out of ordinary.(function wc_create_new_customer()) Standard WP function to create user and id of user inserted in database is passed to action. Should work, but it does not.
I tried to change user role via ‘woocommerce_created_customer’ filter and that works.
I also tried to create an WC_Customer object instead of WP_User:
$user = new WC_Customer($customer_id);
$user->set_role('customer_pending');
Any ideas why my code stopped working and user data can not be changed via ‘woocommerce_created_customer’ action?
Can someone shed some light here?
EDIT: Additional Info Thank you all comments I now got the functionality working, but I hate it and still do not understand what is going on.
Firstly, to answer some suggestions:
- User is created normally. No errors
- My additional 'customer_pending' role is also present and works.
Here is more info and how I "hacked" it for now. Findings:
- User is created, correct user ID is being used in hooks.
- 'first_name' meta appears TWICE in the database for this user (in wp_user_meta table). This is strange as 'update_user_meta()' function is supposed to only create meta in case it does not exist. One of those is populated with my data, one is not.
- Added
update_user_meta($customer_id,'test_meta',"TEST");
This meta data is being inserted into database for the right user.
- I tried to use 'user_register' hook instead of 'woocommerce_created_customer'. This is WP hook on new user creation. Result is same, so it makes me think problem may be in Wordpress itself, not Woo. But read on
Before Woo calls 'woocommerce_created_customer' action, it inserts WP user and passes some data to this creation. This data can be accessed pre-user creation via filter 'woocommerce_new_customer_data'. When I set new role in this filter, it got assigned correctly. Same for the first name. Code is:
function rl_new_customer_role($args)
{
$args['role'] = 'customer_pending';
error_log(var_export($_POST,true));
if(isset($_POST['billing_first_name'])){
$args['first_name'] = sanitize_text_field($_POST['billing_first_name']);
$args['billing_first_name'] = sanitize_text_field($_POST['billing_first_name']);
}
return $args;
}
add_filter('woocommerce_new_customer_data', 'rl_new_customer_role');
But... code above did not work for the 'billing_post_name' field. This field was not even present in the database. Original code was inserting this field correctly. In the end, I had to split what data is updated by hook and what is updated by filter to get the functionality required. This is a terrible solution as I do not understand why things are happening the way they do.
It all feels like some sort of race condition where user meta is not ready when it supposed to be.
woocommerce_created_customer
hook is the correct one. However this will not trigger if the previouswp_insert_user()
function returns an error. Make sure the user is created correctly by going to Wordpress > Users > All Users or checking the database directly (via a known field, for example email). Here you will find documentation on Wordpress wp_insert_user () function. – Vincenzo Di Gaetano