Verificare nume de utilizator corect în formularul personalizat de autentificare
Am folosit tutorialul lui Jeff Star pentru crearea propriului formular personalizat de autentificare http://digwp.com/2010/12/login-register-password-code/. Funcționează foarte bine, dar am o problemă. În formularul de resetare a parolei, dacă cineva introduce numele de utilizator incorect (astfel încât să nu se verifice), este redirecționat către pagina implicită wp-login.php?action=lostpassword cu mesajul de eroare.
Există vreo modalitate de a redirecționa către propria mea pagină de eroare?
Mulțumesc!

Codul pe care l-a postat în acel tutorial (foarte frumos, apropo) trimite formularul către modulul integrat de "resetare parolă", care redirecționează către login.php în caz de eroare, dar poți schimba asta și să-ți construiești propriul bazat pe original și să-l adaugi în pagina de template, schimbă:
<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>
cu:
<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;
// Generează ceva aleatoriu pentru parolă... folosind md5 pe timpul curent cu un salt aleator
$key = substr(md5(uniqid(microtime())), 0, 8);
// Inserează noua parolă md5 în baza de date
$wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
//crează mesajul de email
$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 .= get_option('siteurl') . "/wp-login.php?action=rp&key=$key\r\n";
//trimite mesajul de email
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>

Ok, am reușit să fac asta să funcționeze excelent, cu doar câteva modificări. Erau câteva erori de sintaxă și generatorul de cheie md5 nu funcționa, așa că am luat cel din wp-login.php. Am o singură problemă acum. Când cineva dă click pe linkul din email pentru a crea o parolă nouă, este redirecționat către formularul implicit, așa că acum trebuie să creez un formular și pentru asta.

@pippin: codul generatorului de cheie md5 de aici este cel pentru wp-login.php, iar pentru redirecționare încearcă să adaugi &redirect_to=$_SERVER['REQUEST_URI']
la linkul din emailul pe care îl trimiți.

Linkul meu arată acum așa $message .= get_option('siteurl') . "/wp-login.php?action=rp&key=$key&login=$user_login&redirect_to=$_SERVER['REQUEST_URI']\r\n";
, dar ciudat este că atunci când adaug &redirect, mesajul nu este trimis... De asemenea, nu va trebui să creez un nou formular pentru ca utilizatorul să își introducă noua parolă și altele?

Da, am uitat de asta, ar trebui să-ți creezi propriul formular pentru resetarea parolei și probabil să înlocuiești linkul trimis utilizatorului cu URL-ul curent, iar pe baza cheii să verifici dacă este utilizatorul și să-i afișezi formularul.

linia 17 get_user_by('login', $user_login);
deoarece get_userdatabylogin
este învechit...

Îmi dau seama că acest răspuns este destul de vechi și sunt puțin nesigur de fiabilitatea lui. Presupun că ar trebui să funcționeze, dar aș prefera să nu mă joc cu SQL deoarece s-ar putea să se schimbe în viitor. Pe de altă parte, nu găsesc detalii despre alternative.

Iată o versiune actualizată a codului de la @bainternet cu erorile de sintaxă corectate, sugestia lui @Val și generatorul de chei din wp-login.php 3.4.2:
global $wpdb;
$username = trim($_POST['user_login']);
$user_exists = false;
// Mai întâi verificăm după numele de utilizator
if ( username_exists( $username ) ){
$user_exists = true;
$user = get_user_by('login', $username);
}
// Apoi, după adresa de e-mail
elseif( email_exists($username) ){
$user_exists = true;
$user = get_user_by_email($username);
}else{
$error[] = '<p>'.__('Numele de utilizator sau adresa de e-mail nu au fost găsite, încercați din nou!').'</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) ) {
// Generăm ceva aleatoriu pentru cheie...
$key = wp_generate_password(20, false);
do_action('retrieve_password_key', $user_login, $key);
// Inserăm noua cheie md5 în baza de date
$wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
}
//creăm mesajul de e-mail
$message = __('Cineva a solicitat resetarea parolei pentru următorul site și nume de utilizator.') . "\r\n\r\n";
$message .= get_option('siteurl') . "\r\n\r\n";
$message .= sprintf(__('Nume de utilizator: %s'), $user_login) . "\r\n\r\n";
$message .= __('Pentru a vă reseta parola, accesați următoarea adresă, altfel ignorați acest e-mail și nu se va întâmpla nimic.') . "\r\n\r\n";
$message .= network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "&redirect_to=".urlencode(get_option('siteurl'))."\r\n";
//trimitem mesajul de e-mail
if (FALSE == wp_mail($user_email, sprintf(__('[%s] Resetare parolă'), get_option('blogname')), $message))
$error[] = '<p>' . __('E-mailul nu a putut fi trimis.') . "<br />\n" . __('Posibil motiv: gazda dvs. poate fi dezactivată funcția mail()...') . '</p>';
}
if (count($error) > 0 ){
foreach($error as $e){
echo $e . "<br/>";
}
}else{
echo '<p>'.__('Un mesaj va fi trimis la adresa dvs. de e-mail.').'</p>';
}

Încă întâmpinam probleme cu cheia de resetare care nu funcționa corect, link-ul din e-mail mă redirecționa către pagina standard de resetare a parolei cu parametrul URL care indica o problemă cu cheia, așa că am urmărit mai atent fișierul wp-login.php și am inclus obiectul $wp_hasher, această soluție a rezolvat problema și acum resetarea parolei prin e-mail funcționează corect.
if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass']))) {
// Acces la proprietăți globale
global $wpdb, $wp_hasher;
// Variabile
$error_pass_reset = array();
$username = (string) trim($_POST['user_login']);
$user_exists = (bool) false;
// ---- NUMELE DE UTILIZATOR SAU EMAIL-UL EXISTĂ ---- //
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>Numele de utilizator sau Email-ul nu a fost găsit, vă rugăm încercați din nou.</p>';
} // end else
// ---- UTILIZATORUL EXISTĂ ---- //
if ($user_exists === (bool) true) {
// Variabile
$user_login = (string) $user -> user_login;
$user_email = (string) $user -> user_email;
// Generare cheie de resetare parolă
if (empty($key)) {
$key = (string) wp_generate_password(20, false);
do_action('retrieve_password_key', $user_login, $key);
// Creare obiect $wp_hasher
if (empty($wp_hasher)) {
require_once(ABSPATH . WPINC . '/class-phpass.php');
$wp_hasher = new PasswordHash(8, true);
}
// Cheie de resetare cu hasher aplicat (MD5 are ieșire string)
$hashed = (string) time() . ':' . $wp_hasher -> HashPassword($key);
// Inserare cheie nouă în baza de date
$wpdb -> update(
$wpdb -> users,
array(
'user_activation_key' => $hashed
),
array(
'user_login' => $user_login
)
);
} // end if
// Mesaj email
$message = (string)
'Cineva a solicitat resetarea parolei pentru următorul cont:' . "\r\n\r\n" .
get_option('siteurl') . "\r\n\r\n" .
'Nume utilizator: ' . $user_login . "\r\n\r\n" .
'Dacă aceasta a fost o greșeală, ignorați acest email și nu se va întâmpla nimic.' . "\r\n\r\n" .
'Pentru a vă reseta parola, vizitați următoarea adresă:' . "\r\n\r\n" .
get_option('siteurl') . '/wp-login.php?action=rp&key=' . $key . '&login=' . $user_login . "\r\n";
// Trimitere email
if ((bool) false === wp_mail($user_email, get_option('blogname') . ' Resetare Parolă', $message)) {
$error_pass_reset[] = '<p>E-mailul nu a putut fi trimis în acest moment.</p>' . "\n";
} // end if
} // end if
// Trimite emailul de resetare parolă
do_action('login_form', 'resetpass');
} // end if (($_SERVER['REQUEST_METHOD'] === (string) 'POST') && (isset($_POST['reset_pass'])))
