Create user on order status completed action hook in WooCommerce 3+ - php

I am trying to create a new user within the woocommerce_order_status_completed hook.
add_action( 'woocommerce_order_status_completed', 'custom_woocommerce_order_status_completed', 10, 1 );
function custom_woocommerce_order_status_completed( $order_id )
{
$password = wp_generate_password( 16, true );
$user_id = wp_create_user( 'usertest#gmail.com', $password, 'usertest#gmail.com' );
}
$user_id returns an actual ID. It appears to create the user but when i look at the backend the user is not there. I even check the database for the user id and it's not there.
If i call the same function on the action woocommerce_after_register_post_type it creates the user.
Any idea what could be causing this issue?

The following code uses Woocommerce wc_create_new_customer() dedicated function instead:
add_action( 'woocommerce_order_status_completed', 'action_on_order_status_completed', 20, 2 );
function action_on_order_status_completed( $order_id, $order ){
$password = wp_generate_password( 16, true );
$user_name = $user_email = 'usertest#gmail.com';
// $user_name = $user_email = $order->get_billing_email();
$customer_id = wc_create_new_customer( $user_email, $user_name, $password );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

It looks like your function name does not match the one call within your hook:
custom_woocommerce_order_status_completed

Related

Add user meta data as order meta on WooCommerce order status change

I am trying to add a custom user meta field to the order meta data.
And I want to add this when I am changing my order status to "wordt-verwerkt" which is a custom order status I added with the WooCommerce plugin for custom order statuses.
I tried to use the code from this post, but I am getting an error when I change my order status.
(I also tried it with the status "processing", and didn't have any success neither)
What I have now is the following code:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order, $data ) {
$user_id = $order->get_user_id(); // Get the user id
if( $WefactEmail = get_user_meta( $user_id, 'KVK_nummer_2', true ) ) {
$order->update_meta_data( 'WeFact_email', $WefactEmail );
}
if( isset($WefactEmail) ) {
$order->save();
}
}
There are some mistakes in your code (the hooked function arguments are wrong).
See the related source code for this composite hook located in WC_Order status_transition() method (on line 363):
do_action( 'woocommerce_order_status_' . $status_transition['to'], $this->get_id(), $this );
where $this is $order (the WC_Order Object) and $this->get_id() is $order_id (the order Id).
Use instead the following:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );
if( ! empty($wf_email) ) {
$order->update_meta_data( 'WeFact_email', $wf_email );
$order->save();
}
}
or also this works too:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );
if( ! empty($wf_email) ) {
update_post_meta( $order_id, 'WeFact_email', $wf_email );
}
}
Code goes in functions.php file of the active child theme (or active theme). both should work.
For processing status, replace:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
with:
add_action( 'woocommerce_order_status_processing', 'add_order_meta_from_custom_user_meta', 10, 2 );

Update user meta data after Woocommerce new user registration

Im trying to add a custom field to WP_USERMETA table after Woocommerce registration
add_filter('woocommerce_new_customer_data', 'wc_assign_custom_role', 10, 1);
function wc_assign_custom_role($args) {
update_user_meta($user_id, 'user_pass2', password_hash($_POST['password'], PASSWORD_DEFAULT));
return $args;
}
as you see Im trying to capture password before hashing and save it in a different hash format in that table
but It doesnt add anything to the table
I tested the same line inside wordpress registration hook user_register and it worked but only for wordpress registration not woocommerce
UPDATE
add_filter('woocommerce_new_customer_data', 'wc_assign_custom_role', 10, 1);
function wc_assign_custom_role($args) {
global $current_user;
update_user_meta($current_user->$user_id, 'user_pass2', password_hash($_POST['password'], PASSWORD_DEFAULT));
return $args;
}
still doesnt work
UPDATE II
function action_woocommerce_created_customer( $customer_id, $new_customer_data, $password_generated ) {
update_user_meta($customer_id, 'user_pass2', password_hash($_POST['password'], PASSWORD_DEFAULT));
};
add_action( 'woocommerce_created_customer', 'action_woocommerce_created_customer', 10, 3 );
this one create meta data but it seems it uses different $_POST['password'] rather than the password I entered, so hash something else rather than password
Any thoughts??
When looking at the source code where woocommerce_created_customer action hook is located, the password can be found as $new_customer_data['user_pass'] (see at the end of the answer).
So your code should be:
add_action( 'woocommerce_created_customer', 'action_woocommerce_created_customer', 10, 3 );
function action_woocommerce_created_customer( $customer_id, $new_customer_data, $password_generated ) {
update_user_meta($customer_id, 'user_pass2', password_hash($new_customer_data['user_pass'], PASSWORD_DEFAULT));
}
Code goes in function.php file of your active child theme (or active theme). It should work.
Here is the related source code involved from wc_create_new_customer() function:
$new_customer_data = apply_filters( 'woocommerce_new_customer_data', array(
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'role' => 'customer',
) );
and $_POST['account_password'] is not required as it's already stored in $password variable.
Found the solution, We should use $_POST['account_password'] instead of $_POST['password']
function action_woocommerce_created_customer( $customer_id, $new_customer_data, $password_generated ) {
update_user_meta($customer_id, 'user_pass2', password_hash($_POST['account_password'], PASSWORD_DEFAULT));
};
add_action( 'woocommerce_created_customer', 'action_woocommerce_created_customer', 10, 3 );

I want to update WooCommerce status for a order with the user name

I am able to update status using this code
In this image highlighted text is username of currently logged in user, when I changed status from dashboard it shows me name, but when I change status using code it won't show any name.
I want username should be display like in this screenshot:
add_filter('woocommerce_new_order_note_data', 'modify_added_by');
function modify_added_by($args) {
$user = get_user_by('id', get_current_user_id());
$comment_author = $user->display_name;
$comment_author_email = $user->user_email;
$args['comment_author'] = $comment_author;
$args['comment_author_email'] = $comment_author_email;
}
Try this code
You can use the following hooked function to get the shop manager user name in the order note:
add_filter( 'woocommerce_new_order_note_data', 'filter_woocommerce_new_order_note_data', 10, 2 );
function filter_woocommerce_new_order_note_data( $args, $args2 ) {
if( ! $args2['is_customer_note'] && is_user_logged_in() && current_user_can( 'edit_shop_order', $args2['order_id'] ) ){
$user = get_user_by( 'id', get_current_user_id() );
$args['comment_author'] = $user->display_name;
$args['comment_author_email'] = $user->user_email;
}
return $args;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Related thread: Add the Shop Manager username to Woocommerce Admin Order notes

Change Wordpress user role on gravityforms submission

I am using Gravityforms along with User registration add-on and have a form which when submitted should change the role of the current user to a new role without any underlying conditions.
Using the gravity\forms docs https://docs.gravityforms.com/gform_user_updated/#1-update-user-role and trying this:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
global $current_user;
get_currentuserinfo();
$user_id = $current_user->ID;
echo $user_id;
if( ! $user_id ) {
return;
}
$user = new WP_User( $user_id );
$user->set_role( 'role' ); // update 'role' to the name of the desired role
}
But its not working! Does anyone have any idea why this is incorrect or any other modifications to the code?
There's a couple things I see with your code when comparing it to the Gravity Forms doc.
Here's your code with some added comments:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
global $current_user; // you probably don't need this
get_currentuserinfo(); // you probably don't need this
$user_id = $current_user->ID; // $user_id should already be a numeric value passed in to the function containing the logged in user's ID so you shouldn't need to do this. You're resetting the $user_id variable here to whatever is being pulled out of the get_currentuserinfo() function, and I'm guessing that's the problem
//I would get rid of this echo and if statement
echo $user_id;
if( ! $user_id ) {
return;
}
$user = new WP_User( $user_id );
$user->set_role( 'role' ); // the word "role" here needs to be the role name
}
I think you can simplify it some. Try this instead:
add_action( 'gform_user_updated_3', 'change_role', 10, 3 );
function change_role( $user_id, $feed, $entry, $user_pass ) {
$user = new WP_User( $user_id );
$user->set_role( 'new_role_name_here' ); // Add an existing role here to update the user too
}

Avoid sending completed order status email notification for a specific user role

I have a user role for wholesale customers (wholesale_customer). When I mark an order as completed a notification is send to customers. This is ok for my regular customers but I would like to disable/remove the notification for wholesale customers.
What I've got so far:
function do_not_send_some_email_notifications(WC_Emails $wc_emails) {
$order = new WC_Order( $order_id );
if ( $order->user_id > 0 ) {
$user_id = $order->user_id;
$get_user_data = get_userdata($user_id);
$user_roles = $get_user_data->roles;
if (in_array('wholesale_customer', $user_roles)) {
remove_action('woocommerce_order_status_completed_notification', array($wc_emails->emails['WC_Email_Customer_Completed_Order'], 'trigger'));
}
}
}
add_action('woocommerce_email', 'do_not_send_some_email_notifications');
I have tested this but it's not working.
It would be very nice if someone can point me in the right direction.
Thanks.
Updated 2: I finally find the right hook to make it work. I have revisited your code a little bit using a very similar custom function hooked in the woocommerce_order_status_completed action hook.
Here is the code:
function custom_conditional_email_notifications( $order_id ) {
// Set HERE the targetted user role
$targeted_user_role = 'wholesale_customer';
// Get the order object, the user ID, and the user role.
$order = wc_get_order($order_id);
$user_id = $order->get_user_id();
$user_info = get_userdata($user_id);
if ( in_array( $targeted_user_role, $user_info->roles ) && $user_id > 0 )
remove_action( 'woocommerce_order_status_completed_notification', array(
$wc_emails->emails['WC_Email_Customer_Completed_Order'],
'trigger'
) );
}
add_action( 'woocommerce_order_status_completed', 'custom_conditional_email_notifications' );
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.

Categories