Created
October 30, 2012 16:42
-
-
Save jshakes/3981416 to your computer and use it in GitHub Desktop.
One-page WP password reset page (for themes with front-facing bespoke log-in)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Lets you display a forgot/reset password page within your theme. | |
Eg, create a page called 'Forgot Password'; save this file as page-forgot-password.php | |
Adapted from code posted here: http://wordpress.stackexchange.com/questions/14692/check-for-correct-username-on-custom-login-form/14696#14696 | |
*/ | |
//First pull a bunch of functions from the native WP password reset file | |
/** | |
* Retrieves a user row based on password reset key and login | |
* | |
* @uses $wpdb WordPress Database object | |
* | |
* @param string $key Hash to validate sending user's password | |
* @param string $login The user login | |
* @return object|WP_Error User's database row on success, error object for invalid keys | |
*/ | |
function check_password_reset_key($key, $login) { | |
global $wpdb; | |
$key = preg_replace('/[^a-z0-9]/i', '', $key); | |
if ( empty( $key ) || !is_string( $key ) ) | |
return new WP_Error('invalid_key', __('Invalid key')); | |
if ( empty($login) || !is_string($login) ) | |
return new WP_Error('invalid_key', __('Invalid key')); | |
$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $key, $login)); | |
if ( empty( $user ) ) | |
return new WP_Error('invalid_key', __('Invalid key')); | |
return $user; | |
} | |
/** | |
* Handles resetting the user's password. | |
* | |
* @param object $user The user | |
* @param string $new_pass New password for the user in plaintext | |
*/ | |
function reset_password($user, $new_pass) { | |
do_action('password_reset', $user, $new_pass); | |
wp_set_password($new_pass, $user->ID); | |
wp_password_change_notification($user); | |
} | |
/* | |
Forgot password page. This page allows users to enter their username/email address to reset the password. | |
The reset password email redirects here, allowing the user to specify a new password. | |
It will also process the reset password form. | |
*/ | |
$error = array(); | |
if (isset($_POST['reset_pass'])){ | |
global $wpdb; | |
$username = trim($_POST['user_login']); | |
$user_exists = false; | |
if ( username_exists( $username ) ){ | |
$user_exists = true; | |
$user = get_user_by('login', $username); | |
}elseif ( email_exists($username) ){ | |
$user_exists = true; | |
$user = get_user_by('email', $username); | |
}else{ | |
$error[] = "Username or Email was not found"; | |
} | |
if ($user_exists){ | |
$user_login = $user->user_login; | |
$user_email = $user->user_email; | |
// Generate something ran 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.') . "\r\n\r\n"; | |
$message .= get_option('siteurl') . "\r\n\r\n"; | |
$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; | |
$message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\r\n\r\n"; | |
$message .= $_SERVER['REQUEST_URI']."?action=rp&key=$key&login=$user_login\r\n"; | |
//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(isset($_GET['key'], $_GET['login'])){ | |
$user = check_password_reset_key($_GET['key'], $_GET['login']); | |
if(empty($user)){ | |
$error[] = "Sorry, that appears to be an invalid or expired key. Please <a href=\"/forgot-password/\">re-request the password reset email</a> and follow the link therein."; | |
} | |
else{ | |
if ( isset($_POST['pass1']) && $_POST['pass1'] != $_POST['pass2'] ) { | |
$error[] = "The passwords do not match"; | |
} elseif ( isset($_POST['pass1']) && !empty($_POST['pass1']) ) { | |
reset_password($user, $_POST['pass1']); | |
$success = 1; | |
} | |
} | |
} | |
/* ---------------------- PAGE OUTPUT ---------------------- */ | |
get_header(); | |
/* The password was reset successfully */ | |
if($success): | |
//Password reset message, eg. 'Thanks, your password has been reset. Click here to log in | |
/* The form was submitted successfully */ | |
elseif(isset($_POST['reset_pass']) && empty($error)): | |
//Email sent message, eg. 'Thanks, a message will be sent to your email address with instructions to reset your password.' | |
/* User has returned from the email bearing a user key */ | |
elseif(isset($_GET['key'], $_GET['login'])): | |
$key = $_GET['key']; | |
$login = $_GET['login']; | |
if(!empty($error)): //output errors if there are any ?> | |
<div class="warning"> | |
<p>The following errors occurred:</p> | |
<ul> | |
<?php foreach($error as $e): ?> | |
<li><?php echo $e; ?></li> | |
<?php endforeach; ?> | |
</ul> | |
</div> | |
<?php endif; ?> | |
<!-- Password reset form --> | |
<form class="signup" name="loginform" id="loginform" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>?action=resetpass&key=<?php echo $key; ?>&login=<?php echo $login; ?>"> | |
<input type="hidden" id="user_login" value="<?php echo $login; ?>" autocomplete="off"> | |
<fieldset> | |
<label for="pass1"><?php _e('New Password'); ?></label> | |
<input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off"> | |
</fieldset> | |
<fieldset> | |
<label for="pass2"><?php _e('Confirm new Password'); ?></label> | |
<input type="password" name="pass2" id="pass2" class="input" size="20" value="" autocomplete="off"> | |
</fieldset> | |
<fieldset class="last"> | |
<input type="submit" name="user-submit" value="<?php _e('Reset my password'); ?>" class="user-submit" tabindex="1002" /> | |
</fieldset> | |
</form> | |
<?php | |
/* Default state/show errors */ | |
else: | |
if(!empty($error)): ?> | |
<div class="warning"> | |
<p>The following errors occurred:</p> | |
<ul> | |
<?php foreach($error as $e): ?> | |
<li><?php echo $e; ?></li> | |
<?php endforeach; ?> | |
</ul> | |
</div> | |
<?php endif; ?> | |
<!-- Password reset form --> | |
<form class="signup" name="loginform" id="loginform" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>"> | |
<fieldset> | |
<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" /> | |
</fieldset> | |
<fieldset class="last"> | |
<?php do_action('login_form', 'resetpass'); ?> | |
<input type="hidden" name="reset_pass" value="1" /> | |
<input type="submit" name="user-submit" value="<?php _e('Send password reset email'); ?>" class="user-submit" tabindex="1002" /> | |
</fieldset> | |
</form> | |
<?php endif; | |
get_footer(); ?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: check_password_reset_key returns an error if the key and/or username does not match. It will never be empty! You need to test with is_wp_error instead of empty to make sure the check was successful.