Leave a Reply

3 comments

  1. The code he posted in that tutorial (very nice BTW) post’s the form to the build-in “reset password” module which redirects to the login.php on error, but you can change that and build your own based on the original and add it to the template page, change:

    <form method="post" action="<?php echo site_url('wp-login.php?action=lostpassword', 'login_post') ?>" class="wp-user-form">
        <div class="username">
            <label for="user_login" class="hide"><?php _e('Username or Email'); ?>: </label>
            <input type="text" name="user_login" value="" size="20" id="user_login" tabindex="1001" />
        </div>
        <div class="login_fields">
            <?php do_action('login_form', 'resetpass'); ?>
            <input type="submit" name="user-submit" value="<?php _e('Reset my password'); ?>" class="user-submit" tabindex="1002" />
            <?php $reset = $_GET['reset']; if($reset == true) { echo '<p>A message will be sent to your email address.</p>'; } ?>
            <input type="hidden" name="redirect_to" value="<?php echo $_SERVER['REQUEST_URI']; ?>?reset=true" />
            <input type="hidden" name="user-cookie" value="1" />
        </div>
    </form>
    

    to:

    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>" class="wp-user-form">
    <div class="username">
        <label for="user_login" class="hide"><?php _e('Username or Email'); ?>: </label>
        <input type="text" name="user_login" value="" size="20" id="user_login" tabindex="1001" />
    </div>
    <div class="login_fields">
        <?php do_action('login_form', 'resetpass'); ?>
        <input type="submit" name="user-submit" value="<?php _e('Reset my password'); ?>" class="user-submit" tabindex="1002" />
    
        <?php
        if (isset($_POST['reset_pass']))
        {
            global $wpdb;
            $username = trim($_POST['user_login']);
            $user_exists = false;
            if (username_exists($username))
            {
                $user_exists = true;
                $user_data = get_userdatabylogin($username);
            } elseif (email_exists($username))
            {
    
                $user_exists = true;
                $user = get_user_by_email($username);
            } else
            {
                $error[] = '<p>' . __('Username or Email was not found, try again!') . '</p>';
            }
            if ($user_exists)
            {
                $user_login = $user->user_login;
                $user_email = $user->user_email;
                // Generate something random for a password... md5'ing current time with a rand salt
                $key = substr(md5(uniqid(microtime())), 0, 8);
                // Now insert the new pass md5'd into the db
                $wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
                //create email message
                $message = __('Someone has asked to reset the password for the following site and username.') . "rnrn";
                $message .= get_option('siteurl') . "rnrn";
                $message .= sprintf(__('Username: %s'), $user_login) . "rnrn";
                $message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "rnrn";
                $message .= get_option('siteurl') . "/wp-login.php?action=rp&key=$keyrn";
                //send email meassage
                if (FALSE == wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_option('blogname')), $message))
                $error[] = '<p>' . __('The e-mail could not be sent.') . "<br />n" . __('Possible reason: your host may have disabled the mail() function...') . '</p>';
            }
            if (count($error) > 0)
            {
                foreach ($error as $e)
                {
                    echo $e . '<br/>';
                }
            } else
            {
                echo '<p>' . __('A message will be sent to your email address.') . '</p>';
            }
        }
        ?> 
        <input type="hidden" name="reset_pass" value="1" />
        <input type="hidden" name="user-cookie" value="1" />
    </div>
    </form>
    
  2. Here is an updated version of the code from @bainternet with the syntax errors corrected, the suggestion by @Val and the key generator from wp-login.php 3.4.2:

    global $wpdb;
    $username = trim($_POST['user_login']);
    $user_exists = false;
    // First check by username
    if ( username_exists( $username ) ){
        $user_exists = true;
        $user = get_user_by('login', $username);
    }
    // Then, by e-mail address
    elseif( email_exists($username) ){
            $user_exists = true;
            $user = get_user_by_email($username);
    }else{
        $error[] = '<p>'.__('Username or Email was not found, try again!').'</p>';
    }
    if ($user_exists){
        $user_login = $user->user_login;
        $user_email = $user->user_email;
    
        $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
        if ( empty($key) ) {
            // Generate something random for a key...
            $key = wp_generate_password(20, false);
            do_action('retrieve_password_key', $user_login, $key);
            // Now insert the new md5 key into the db
            $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
        }
    
        //create email message
        $message = __('Someone has asked to reset the password for the following site and username.') . "rnrn";
        $message .= get_option('siteurl') . "rnrn";
        $message .= sprintf(__('Username: %s'), $user_login) . "rnrn";
        $message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "rnrn";
        $message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "&redirect_to=".urlencode(get_option('siteurl'))."rn";
        //send email meassage
        if (FALSE == wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_option('blogname')), $message))
        $error[] = '<p>' . __('The e-mail could not be sent.') . "<br />n" . __('Possible reason: your host may have disabled the mail() function...') . '</p>';
    }
    if (count($error) > 0 ){
        foreach($error as $e){
                    echo $e . "<br/>";
                }
    }else{
        echo '<p>'.__('A message will be sent to your email address.').'</p>'; 
    }
    
  3. I was still encountering issues with the reset key not working properly, the link in the email would redirect me to the standard password reset page with the URL parameter indicating a problem with the key, so I more closely followed the wp-login.php file and included the $wp_hasher object, this fixed the problem and the password reset in the email now works

    if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass']))) {
    
    // Acccess global properties
    global $wpdb, $wp_hasher;
    
    
    // Variables
    $error_pass_reset = array();
    $username         = (string) trim($_POST['user_login']);
    $user_exists      = (bool)   false;
    
    
    
    // ---- USERNAME OR EMAIL EXISTS ---- //
    if (username_exists($username)) {
        $user_exists = (bool)   true;
        $user        = (object) get_user_by('login', $username);
    } // end if
    
    else if (email_exists($username)) {
        $user_exists = (bool)   true;
        $user        = (object) get_user_by('email', $username);
    } // end else if
    
    else {
        $error_pass_reset[] = '<p>Username or Email was not found, please try again.</p>';
    } // end else
    
    
    
    // ---- USER EXISTS ---- //
    if ($user_exists === (bool) true) {
        // Variables
        $user_login = (string) $user -> user_login;
        $user_email = (string) $user -> user_email;
    
    
        // Generate password reset key
    if (empty($key)) {
        $key = (string) wp_generate_password(20, false);
    
        do_action('retrieve_password_key', $user_login, $key);
    
    
        // Create the $wp_hasher object
        if (empty($wp_hasher)) {
            require_once(ABSPATH . WPINC . '/class-phpass.php');
    
            $wp_hasher = new PasswordHash(8, true);
        }
    
        // Reset key with hasher applied (MD5 has string output)
        $hashed = (string) time() . ':' . $wp_hasher -> HashPassword($key);
    
    
        // Insert the new key into the database
        $wpdb -> update(
            $wpdb -> users,
            array(
                'user_activation_key' => $hashed
            ),
            array(
                'user_login' => $user_login
            )
        );
    } // end if
    
    
        // Email message
        $message = (string)
        'Someone requested that the password be reset for the following account:' . "rnrn" .
    
        get_option('siteurl') . "rnrn" .
    
        'Username: ' . $user_login . "rnrn" .
        'If this was a mistake, just ignore this email and nothing will happen.' . "rnrn" .
        'To reset your password, visit the following address:' . "rnrn" .
    
        get_option('siteurl') . '/wp-login.php?action=rp&key=' . $key . '&login=' . $user_login . "rn";
    
    
        // Send email
        if ((bool) false === wp_mail($user_email, get_option('blogname') . ' Password Reset', $message)) {
            $error_pass_reset[] = '<p>The e-mail could not be sent at this time.</p>' . "n";
        } // end if
    } // end if
    
    
    // Send the rest password email
    do_action('login_form', 'resetpass');
    
    } // end if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass'])))