Sometimes you need to create users in WordPress with PHP code, be it because you’re importing users, or because you want to let one user add other users. When you do this you want the new users to be able to reset their password.

At first I thougth to use a password reset link, to the password reset page in WordPress, but this is not very user friendly:

  1. The user has to enter his username or email address
  2. The user will receive a resetmail with a link.
  3. After clicking it, the user can reset the password.

It would be much better if we could directly send the resetlink that leads to the third step. To do this we need to create a password reset key, which is only temporarily valid.

The code below generates such an email.

function dtc_send_password_reset_mail($user_id){

    $user = get_user_by('id', $user_id);
    $firstname = $user->first_name;
    $email = $user->user_email;
    $adt_rp_key = get_password_reset_key( $user );
    $user_login = $user->user_login;
    $rp_link = '<a href="' . wp_login_url()."/resetpass/?key=$adt_rp_key&login=" . rawurlencode($user_login) . '">' . wp_login_url()."/resetpass/?key=$adt_rp_key&login=" . rawurlencode($user_login) . '</a>';

    if ($firstname == "") $firstname = "gebruiker";
    $message = "Hi ".$firstname.",<br>";
    $message .= "An account has been created on ".get_bloginfo( 'name' )." for email address ".$email."<br>";
    $message .= "Click here to set the password for your account: <br>";
    $message .= $rp_link.'<br>';

    //deze functie moet je zelf nog toevoegen. 
   $subject = __("Your account on ".get_bloginfo( 'name'));
   $headers = array();

   add_filter( 'wp_mail_content_type', function( $content_type ) {return 'text/html';});
   $headers[] = 'From: Your company name <[email protected]>'."\r\n";
   wp_mail( $email, $subject, $message, $headers);

   // Reset content-type to avoid conflicts -- http://core.trac.wordpress.org/ticket/23578
   remove_filter( 'wp_mail_content_type', 'set_html_content_type' );
}

Usage: this function should be called in the function which creates the user

For example, if you want a user to create other users, clicking a link could call this function, which creates a user based on email address, and optionally, firstname and lastname. The last step in this function calls the reset password function:

function dtc_create_user($email, $firstname='', $lastname=''){
    $user_name = $email;
    
    //check if the email is not in use yet
    if (!email_exists($email)) {
        $random_password = wp_generate_password(16);
        //create the user 
        $user_id = wp_create_user($user_name, $random_password, $email);
        if (!is_wp_error($user_id)) {
            
            //Not required: update user with details, role, firstname, lastname. 
            $userdata = array(
                "ID" => $user_id,
                "first_name" => $firstname,
                "last_name" => $lastname,
                "role" => "subscriber",
            );
            $user_id = wp_update_user($userdata);
            
            //send password reset to user. 
            dtc_send_password_reset_mail($user_id);
            
        }

    }
}

20 Responses

  1. Excellent article. Can you tell me how/when we need to fire the function dtc_send_password_reset_mail() for password reset.

    1. Sure. I have updated the article with a function which creates a user, then calls the password reset link function

    1. What is the use case? Do you have a user generation system which you want to hook a password reset email to?

  2. This is what I am looking for, but I am not a developer! I’d love to find something like this in a plugin. Here is the use case: My shopping cart for a membership site creates a new user when they purchase a membership. This triggers WordPress to send the email with username (which is their email) and a link so they can set the password. Then the user can set that password and complete registration. However, I have to use the ugly WordPress screen to do this, and it is unbranded and clunky! If I could find a way to send an email that generates this key, I could alter the URL (with the key) to redirect it to a custom page for the user to set their password. That’s what I need anyhow. Any thoughts on the best way to do this? (Like I said, I’m not a developer, but with decent instructions, I can handle a bit of coding. I just need to know what to do and how to do it.) Thanks!

  3. Hey Rogier,

    Something has happened to your code sample. The function has been broken out into two code panels and the line:

    wp_mail( $email, $subject, $message, $headers) === false);

    is invalid.

    1. Hi Joe,

      You’re right. I’ve simplified that line, but it ended up with a bug. I’ve updated it, and fixed the layout issue as well.

      Thanks for mentioning it!

    1. Hi Omer,

      the e-mail will already be sent as HTML. To add additional styling to it, you can add HTML to the $message variable. If you want Heading 2, just wrap the $message line in < h2>/< h2> tags.

      1. Thanks for the reply,
        what I did was:

        add_filter( ‘wp_mail_content_type’,’set_mail_content_type’ );
        function set_mail_content_type(){
        return “text/html”;
        }

  4. hello, great article.
    Would you by any chance have any idea to avoid sending mail? I need the user to directly access the reset page. This is possible because it is an intranet site. Thanks

    1. Hi Paolo,

      you can comment out the wp_mail( $email, $subject, $message, $headers); line by putting // in front of it, that will prevent the mail from sending. The password reset link is contained in the $rp_link variable, so you could just redirect to that page instead.

    1. Hi Scott,

      the line you have posted contains the wrong qoutes, ‘‘ instead of “, This can happen when copying and pasting code and can result in an error. I’d suggest to check the entire function you have copied for ‘‘ and ` and replace them with the correct ‘ and ” qoutes.

      1. Hi Thanks for getting back, commented out the variable rp_link and it seems to send the email. I’ve also tried fixing the back ticks but nothing seems to be getting it to like the constructed link. I managed to get it to throw an error which looks to point to the variable $adt_rp_key = get_password_reset_key( $user ); : – error looks to be:
        “Password reset is not allowed for this user”

        Also if I reset the password on the site the manual way it looks to provide a link like: https://www.mydomain.com/my-account/lost-password/?key=yO85dZsSu1ozdTBm39pa&id=1001 so maybe i need to make the link up different?

        Any ideas?

        1. OK so think I have it now, turns out i think woo commerce was over-riding the standard link and with that there was a captcha plugin causing it to fail, thanks for your help and the tutorial!

Leave a Reply

Your email address will not be published. Required fields are marked *