Come modificare programmaticamente il nome utente (user_login)?
Come indicato nel titolo, come si può modificare programmaticamente il login di un utente?
Volevo utilizzare la funzione wp_insert_user, ma sembra che quando si aggiorna l'utente corrente, questa non modifichi il loro nome utente. Dovrei utilizzare $wpdb->update per questo? Se sì, come dovrebbe essere il codice per modificare il nome utente? Quali conseguenze avrebbe la modifica del login utente, considerando che l'API di WordPress non permette di modificare i nomi utente?
Ero sicuro che wp_update_user() dovesse fare questo.
Accetta anche user_login come parametro, ma sembra che lo ignori quando lo imposti.
Quindi questo codice sembra OK, ma non funziona come vorresti :( :
wp_update_user(
['ID' => $user_id, 'user_login' => $new_login]
);
Devi chiamare una query SQL personalizzata per aggiornare user_login:
global $wpdb;
$wpdb->update(
$wpdb->users,
['user_login' => $new_user_login],
['ID' => $user_id]
);
Funziona correttamente e non penso che abbia conseguenze serie, perché WP utilizza l'ID degli utenti per assegnare post/commenti (e così via) all'utente.
L'unico problema che mi viene in mente è che quando questo utente è attualmente loggato, verrà disconnesso dopo la modifica di user_login.
Non proprio, controlla le note per questa funzione (così come il codice): Tieni presente che non possiamo modificare i nomi utente tramite questa funzione, infatti i nomi utente non possono essere cambiati nemmeno dalla dashboard di amministrazione poiché WordPress non consente l'aggiornamento dei nomi utente.
Mateusz Hajdziony
Grazie, funziona perfettamente! Non preoccuparti per gli utenti loggati però, visto che permetto il cambio nome utente solo per gli utenti non loggati (attivazione dell'account via e-mail).
Mateusz Hajdziony
@pogoking Una cosa che potresti voler considerare è che i permalink degli utenti o degli autori potrebbero rompersi dopo aver abilitato la modifica dei nomi utente se i pretty permalink sono attivi, quindi potresti dover prendere provvedimenti per compensare questo aspetto.
Ahmad M
@AhmadM Grazie Ahmad, ma come ho detto prima - gli utenti prima dell'attivazione dell'account non saranno elencati da nessuna parte, quindi i permalink non sono un problema. Grazie comunque per l'avvertimento!
Mateusz Hajdziony
@Mauro Beh, se esegui questo codice all'interno di una funzione, allora sì - ovviamente. Devi dichiarare anche $user_id e $new_login, ma è ovvio e non connesso a WP, giusto?
Krzysiek Dróżdż
Vecchio post, ma sto valutando di farlo da solo, varrebbe la pena verificare che non ci sia un altro utente con lo stesso user_login registrato sul tuo sito, dato che il modulo di login ovviamente utilizza questo valore per trovare gli account e confrontare gli hash delle password.
haxxxton
@haxxxton Ho pensato la stessa cosa, ! username_exists( sanitize_user( $new_user_login ) ); farà proprio questo.
amarinediary
Suggerirei di aggiungere update_user_caches(get_user_by('id', $user_id)) o clean_user_cache($user_id) dopo quell'aggiornamento se stai usando wp_object_cache. Ho scoperto a mie spese che modificare direttamente i record utente in WP può portare a comportamenti molto inaspettati altrimenti.
Dan B
Oltre alla risposta di Krzysiek Dróżdż.
Se non vuoi disconnettere gli utenti dopo aver modificato user_login, devi fare quanto segue per mantenere l'utente connesso con i nuovi dati:
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);
Devi utilizzare il filtro per modificare il $data quando l'utente viene aggiornato, non puoi agire con l'azione a cui ti collegheresti normalmente per un aggiornamento utente.
Inoltre, devi integrare diverse misure di sicurezza e controlli che WordPress applica nel suo codice nella tua nuova funzione.
Cosa puoi fare:
- Collegati al filtro
wp_pre_insert_user_data. Assicurati di farlo solo con i permessi corretti:add_filter( 'wp_pre_insert_user_data', 'prefix_change_user_login', 10, 4 ); - Ora crea una funzione
prefix_change_user_logindove prendi il$data, iluser_logindal$_POSTe lo sottoponi a una serie di validazioni e sanificazioni (vedi https://github.com/WordPress/wordpress-develop/blob/bb27ffce6c3b10738008f9a054782945a0744960/src/wp-includes/user.php#L2076-L2498 per maggiori dettagli) - Inoltre, ovviamente, dovrai consentire la modifica effettiva del campo di login utente nella schermata di modifica utente di WP Admin, oppure passare quel valore in qualche altro modo al tuo codice.
Un esempio di tale funzione:
/**
* Aggiorna il nome di login dell'utente
*
* @since x.x.x
* @param array $data {
* Valori e chiavi per l'utente.
*
* @type string $user_login Il login dell'utente. Incluso solo se $update == false
* @type string $user_pass La password dell'utente.
* @type string $user_email L'email dell'utente.
* @type string $user_url L'URL dell'utente.
* @type string $user_nicename Il nome "nice" dell'utente. Di default una versione URL-safe del login
* @type string $display_name Il nome visualizzato dell'utente.
* @type string $user_registered Timestamp MySQL che descrive il momento della registrazione. Default
* al timestamp UTC corrente.
* }
* @param bool $update Indica se l'utente viene aggiornato anziché creato.
* @param int|null $user_id ID dell'utente da aggiornare, o NULL se l'utente viene creato.
* @param array $userdata L'array grezzo di dati passato a wp_insert_user().
*/
function prefix_change_user_login( $data, $update, $user_id, $userdata ){
// NON DIMENTICARE DI AGGIUNGERE QUI LA VALIDAZIONE DEL NONCE E DEL REFERRER!!!!
$sanitized_user_login = sanitize_user( wp_unslash( $_POST['user_login'] ), true );// Nel nostro caso otteniamo il nuovo user login dal valore POST del form in WP Admin. Se il tuo caso d'uso è diverso, adattalo!!
/**
* Filtra un username dopo che è stato sanificato.
*
* Questo filtro viene chiamato prima che l'utente venga creato o aggiornato.
*
* @since 2.0.3
*
* @param string $sanitized_user_login Username dopo la sanificazione.
*/
$pre_user_login = apply_filters( 'pre_user_login', $sanitized_user_login );
$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
// Rimuovi qualsiasi carattere non stampabile dalla stringa di login per verificare se abbiamo ottenuto un username vuoto.
$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 ) );// Chi sa cosa avessero fumato gli sviluppatori di WP quando hanno deciso di rendere il nicename 10 caratteri più corto del nome di 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 permette 50 caratteri. Sottrai uno per il trattino, più la lunghezza del suffisso.
$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;
}
Questo ti permetterà di aggiornare il nome di login dell'utente, e aggiornerà anche il user nicename (usato negli archivi per esempio) Ovviamente questo richiede ancora di "abilitare" la modifica nell'area di amministrazione di WP, ma non dovrebbe essere troppo difficile
Nota che se si verifica qualsiasi errore nel codice sopra (username già esistente, ecc.) NON viene mostrato alcun errore, invece l'utente viene semplicemente aggiornato e torna al valore precedente.
Nota che, sebbene questo codice sia testato, sta a te decidere cosa farne, e ci sono MOTIVI per cui wp non permette di aggiornare il login utente