Cum să schimbi programatic numele de utilizator (user_login)?
Ca în titlu, cum pot schimba programatic numele de login al utilizatorului?
Am vrut să folosesc funcția wp_insert_user, dar se pare că atunci când actualizez utilizatorul curent, aceasta nu schimbă numele de utilizator. Ar trebui să folosesc $wpdb->update pentru asta? Dacă da, cum ar arăta codul pentru schimbarea numelui de utilizator? Ce consecințe ar avea schimbarea numelui de utilizator, având în vedere că API-ul WordPress nu permite schimbarea numelor de utilizator?
Eram sigur că funcția wp_update_user() ar trebui să facă asta.
Chiar primește user_login ca parametru, dar se pare că îl ignoră când îl setezi.
Deci acest cod arată OK, dar nu funcționează așa cum ai vrea tu :( :
wp_update_user(
['ID' => $user_id, 'user_login' => $new_login]
);
Trebuie să apelezi o interogare SQL personalizată pentru a actualiza user_login:
global $wpdb;
$wpdb->update(
$wpdb->users,
['user_login' => $new_user_login],
['ID' => $user_id]
);
Funcționează corect și nu cred că are consecințe grave, deoarece WordPress folosește ID-ul utilizatorilor pentru a atribui postări/comentarii (și altele) utilizatorilor.
Singura problemă la care mă pot gândi este că atunci când acest utilizator este conectat în prezent, va fi deconectat după schimbarea user_login.
Nu chiar, verifică notele pentru această funcție (precum și codul): Te rog să reții că nu putem schimba numelele de utilizator prin această funcție, de fapt numele de utilizator nu pot fi modificate nici din panoul de administrare, deoarece WordPress nu permite actualizarea numelor de utilizator.
Mateusz Hajdziony
Mulțumesc, funcționează perfect! Nu-ți face griji cu privire la utilizatorii autentificați, deoarece permit schimbarea numelui de utilizator doar pentru cei neautentificați (activarea contului prin e-mail).
Mateusz Hajdziony
@pogoking Un lucru pe care ai putea să-l iei în considerare este că legăturile permanente (permalinks) ale utilizatorilor sau autorilor ar putea fi întrerupte după activarea opțiunii de schimbare a numelui de utilizator dacă legăturile permanente personalizate sunt activate, așa că poate fi nevoie să iei măsuri pentru a compensa acest lucru.
Ahmad M
@AhmadM Mulțumesc, Ahmad, dar cum am spus înainte - utilizatorii înainte de activarea contului nu vor fi listați nicăieri, astfel încât permalinkurile nu sunt o problemă. Totuși, mulțumesc pentru avertizare!
Mateusz Hajdziony
@Mauro Ei bine, dacă rulezi acest cod în interiorul unei funcții, atunci da - desigur. Trebuie să declari și $user_id și $new_login, dar este evident și nu este legat de WordPress, nu-i așa?
Krzysiek Dróżdż
Postare veche, dar și eu mă gândesc să fac asta. Ar fi bine să verifici dacă nu există deja un alt utilizator cu același user_login înregistrat pe site-ul tău, deoarece formularul de autentificare folosește evident această valoare pentru a găsi conturi și a potrivi hash-urile de parole.
haxxxton
@haxxxton M-am gândit la același lucru, ! username_exists( sanitize_user( $new_user_login ) ); va face exact asta.
amarinediary
Aș sugera să adaugi fie update_user_caches(get_user_by('id', $user_id)) fie clean_user_cache($user_id) după acea actualizare dacă folosești wp_object_cache. Am aflat pe pielea mea că modificarea directă a înregistrărilor de utilizator în WP poate duce la un comportament foarte neașteptat altfel.
Dan B
În schimb, ai putea lua în considerare utilizarea unui slug de profil bazat pe ID în loc de unul bazat pe nice_name. Acest lucru va asigura că profilul va avea o adresă URL universală și nu vei avea pagini 404 aleatoare care apar (presupun că e mai bine pentru SEO).
amarinediary
În plus față de răspunsul lui Krzysiek Dróżdż.
Dacă nu doriți să deconectați utilizatorii după modificarea user_login, trebuie să faceți următoarele pentru a menține utilizatorul autentificat cu noile date:
clean_user_cache($user->ID);
wp_clear_auth_cookie();
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID, true);
update_user_caches($user);
Trebuie să folosești filtru pentru a modifica $data atunci când utilizatorul este actualizat, nu poți acționa cu acțiunea pe care ai fi tentat să o folosești pentru un hook de actualizare a utilizatorului.
De asemenea, trebuie să implementezi mai multe dintre măsurile de securitate și verificări pe care WordPress le aplică în codul său în noua ta funcție.
Ce poți face:
- Folosește hook-ul
wp_pre_insert_user_data. Asigură-te că faci acest lucru doar cu permisiunile corecte:add_filter( 'wp_pre_insert_user_data', 'prefix_change_user_login', 10, 4 ); - Acum creează o funcție
prefix_change_user_loginunde preiei$data,user_logindin$_POSTși o treci prin mai multe validări și sanitizări (vezi https://github.com/WordPress/wordpress-develop/blob/bb27ffce6c3b10738008f9a054782945a0744960/src/wp-includes/user.php#L2076-L2498 pentru mai multe detalii) - De asemenea, va trebui să permiți editarea efectivă a câmpului de login al utilizatorului în ecranul WP Admin Edit User, sau să transmiți acea valoare într-un alt mod către codul tău.
Un exemplu de astfel de funcție:
/**
* Actualizează numele de login al utilizatorului
*
* @since x.x.x
* @param array $data {
* Valori și chei pentru utilizator.
*
* @type string $user_login Login-ul utilizatorului. Este inclus doar dacă $update == false
* @type string $user_pass Parola utilizatorului.
* @type string $user_email Email-ul utilizatorului.
* @type string $user_url URL-ul utilizatorului.
* @type string $user_nicename Numele frumos al utilizatorului. Implicit este o versiune URL-safe a login-ului utilizatorului
* @type string $display_name Numele afișat al utilizatorului.
* @type string $user_registered Timestamp MySQL care descrie momentul în care utilizatorul s-a înregistrat. Implicit este
* timestamp-ul UTC curent.
* }
* @param bool $update Dacă utilizatorul este actualizat și nu creat.
* @param int|null $user_id ID-ul utilizatorului care va fi actualizat, sau NULL dacă utilizatorul este creat.
* @param array $userdata Matricea brută de date transmisă către wp_insert_user().
*/
function prefix_change_user_login( $data, $update, $user_id, $userdata ){
// NU UITAȚI SĂ ADĂUGAȚI VALIDARE ADECVATĂ A NONCE ȘI A REFERER AICI!!!!
$sanitized_user_login = sanitize_user( wp_unslash( $_POST['user_login'] ), true );// În cazul nostru, obținem noul login din valoarea POST a formularului din WP Admin. Dacă în cazul tău este diferit, adaptează!!
/**
* Filtrează un nume de utilizator după ce a fost sanitizat.
*
* Acest filtru este apelat înainte ca utilizatorul să fie creat sau actualizat.
*
* @since 2.0.3
*
* @param string $sanitized_user_login Numele de utilizator după ce a fost sanitizat.
*/
$pre_user_login = apply_filters( 'pre_user_login', $sanitized_user_login );
$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
// Elimină orice caracter neafișabil din șirul de login pentru a verifica dacă am rămas cu un nume de utilizator gol.
$user_login = trim( $pre_user_login );
if ( empty( $user_login )
|| mb_strlen( $user_login ) > 60
|| username_exists( $user_login )
|| in_array( strtolower( $user_login ), array_map( 'strtolower', $illegal_logins ), true )
) {
return $data;
}
$data['user_login'] = $user_login;
$user_nicename = sanitize_title( mb_substr( $user_login, 0, 50 ) );// Cine știe ce au fumat dezvoltatorii WordPress când au decis să facă nicename-ul cu 10 caractere mai scurt decât numele de login?
global $wpdb;
$user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $user_nicename, $user_login ) );
if ( $user_nicename_check ) {
$suffix = 2;
while ( $user_nicename_check ) {
// user_nicename permite 50 de caractere. Scade unul pentru o liniuță, plus lungimea sufixului.
$base_length = 49 - mb_strlen( $suffix );
$alt_user_nicename = mb_substr( $user_nicename, 0, $base_length ) . "-$suffix";
$user_nicename_check = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1", $alt_user_nicename, $user_login ) );
$suffix++;
}
$user_nicename = $alt_user_nicename;
}
$data['user_nicename'] = $user_nicename;
return $data;
}
Acest lucru îți va permite să actualizezi numele de login al utilizatorului, și va actualiza și nicename-ul utilizatorului (folosit, de exemplu, în arhive) Desigur, acest lucru necesită totuși să "activezi" editarea în zona WP Admin, dar acest lucru nu ar trebui să fie prea dificil.
Reține că dacă apare vreo eroare în codul de mai sus (numele de utilizator există deja, etc.) NU se afișează nicio eroare, în schimb, utilizatorul este actualizat și revine la valoarea anterioară.
Reține că, deși acest cod a fost testat, tu ești responsabil pentru ceea ce faci cu el și există MOTIVE pentru care WordPress nu permite actualizarea numelui de login.