0

I'm building a members style site using WordPress. When a user registers their default role is "subscriber" once we manually approve their account we change the user role to "private_event_member", we need to send the user an email to tell them we have changed their role. I found the following code snippet and added it to the functions.php file

function user_role_update( $user_id, $new_role ) {
        $site_url = get_bloginfo('wpurl');
        $user_info = get_userdata( $user_id );
        $to = $user_info->user_email;
        $subject = "Role changed: ".$site_url."";
        $message = "Hello " .$user_info->display_name . " your role has changed on ".$site_url.", congratulations you are now an " . $new_role;
        wp_mail($to, $subject, $message);
}
add_action( 'set_user_role', 'user_role_update', 10, 2);

This failed to send the email as expected. So to be sure I decided to install a plugin called WP Mail Log and then also WP Mail SMTP, I configured the Sendblue SMTP option. I've tested this and all other emails like for example user registration notifications and new orders are being sent and recorded successfully in the logs, these are being received. The above mentioned code however seems to do nothing.

This seems to be a widely used piece of code that should work so can anyone explain to me why this snippet behaves differently from other mail on the server? It doesn't even appear in the sending logs so as far as I can see it's not doing anything at all. Has the set_user_role action I'm hooking into changed? What could be the cause?

Any help much appreciate!

Æthelstan
  • 883
  • 1
  • 5
  • 12

2 Answers2

2

You should use profile_update hook for this. Read more here - https://developer.wordpress.org/reference/hooks/profile_update/

function notify_user_on_role_change($user_id,$old_user_data,$userdata) {
    // Getting role before update
    foreach($old_user_data->roles as $role):
        $old_role = $role;
    endforeach;

    // error_log(print_r($userdata,true)); // debug 

    //If we change role send email
    if($old_role != $userdata['role']):
        $user_info = get_userdata( $user_id );
        $to = $user_info->user_email; 
        $subject = "Profile Updated";
        $message = "Hello, your user role is changed to ".$userdata['role']."";
        wp_mail( $to, $subject, $message);
    endif;
}
add_action('profile_update','notify_user_on_role_change',10,3);

Send notification only if you change to specific user role

function notify_user_on_role_change($user_id,$old_user_data,$userdata) {
    // Getting role before update
    foreach($old_user_data->roles as $role):
        $old_role = $role;
    endforeach;

    // error_log(print_r($old_role,true)); // debug 

    //If we change role send email
    if($old_role != 'private_event_member' && $userdata['role'] == 'private_event_member'):
        $user_info = get_userdata( $user_id );
        $to = $user_info->user_email; 
        $subject = "Profile Updated";
        $message = "Hello, your user role is changed to ".$userdata['role']."";
        wp_mail( $to, $subject, $message);
    endif;
}
add_action('profile_update','notify_user_on_role_change',10,3);
Snuffy
  • 1,723
  • 1
  • 5
  • 9
  • I've discovered a slight problem with this answer now @MartinMirchev. The profile_update hook also fires when a user goes through the "forgot password" process, I think it sends on all changes to a user's profile, not just a role change. Is there anyway to modify this code so it only sends the email when the role is changed? In fact I only need this to send when a users account is updated to a specific user role, in my case it is a custom 1 called private_event_member. – Æthelstan Sep 23 '21 at 06:34
  • The function executes only if this condition is met - if($old_role != $userdata['role']): Debug and share what you get. Its normal profile update to run when you change something in your profile. – Snuffy Sep 23 '21 at 06:47
  • I have updated the condition to your request. – Snuffy Sep 23 '21 at 06:57
  • Thank you so much for your help with this @MartinMirchev ! I've tried out the new version looking for if the old role is not private_event_member and userdata role updated to private_event_member. I understand this and I see it should really work, but it fails to send according to my mail logs and nothing is received. So, I've logged the PHP errors, I'm getting "Undefined index: role" when moving from "subscriber" to "private_event_member". – Æthelstan Sep 24 '21 at 11:40
  • Make sure this is your correct role ? Use error_log(print_r($old_role,true)); to check what is your old role and error_log(print_r($userdata['role'],true)); to check new role. – Snuffy Sep 24 '21 at 11:52
0

I know this is late, but I figured I'll add if anyone else is getting the following issue. I don't have enough rep to comment on MartinMirchev's Answer, so I'll have to post a separate one.

Adding onto their answer, it wasn't placing the name of the role in the email, however, I got it to work now by changing:

$message = "Hello, your user role is changed to ".$userdata['role']."";

to:

$message = "Hello, your user role is changed to ".$role."";