Come verificare se un utente (non l'utente corrente) è connesso?
Devo mostrare lo stato di connessione (online/offline) per ogni pagina autore (template personalizzato della pagina autore).
is_user_logged_in() si applica solo all'utente corrente e non riesco a trovare un approccio rilevante per l'autore attuale, ad esempio is_author_logged_in()
Qualche idea?
Risposta
One Trick Pony è stato così gentile da preparare il codice per due o tre funzioni utilizzando i transients, qualcosa che non avevo mai usato prima.
http://codex.wordpress.org/Transients_API
Aggiungi questo a functions.php:
add_action('wp', 'update_online_users_status');
function update_online_users_status(){
if(is_user_logged_in()){
// ottieni la lista degli utenti online
if(($logged_in_users = get_transient('users_online')) === false) $logged_in_users = array();
$current_user = wp_get_current_user();
$current_user = $current_user->ID;
$current_time = current_time('timestamp');
if(!isset($logged_in_users[$current_user]) || ($logged_in_users[$current_user] < ($current_time - (15 * 60)))){
$logged_in_users[$current_user] = $current_time;
set_transient('users_online', $logged_in_users, 30 * 60);
}
}
}
Aggiungi questo a author.php (o un altro template di pagina):
function is_user_online($user_id) {
// ottieni la lista degli utenti online
$logged_in_users = get_transient('users_online');
// online, se è nella lista e l'ultima attività è stata meno di 15 minuti fa
return isset($logged_in_users[$user_id]) && ($logged_in_users[$user_id] > (current_time('timestamp') - (15 * 60)));
}
$passthis_id = $curauth->ID;
if(is_user_online($passthis_id)){
echo 'Utente è online.';}
else {
echo 'Utente non è online.';}
Seconda Risposta (da non usare)
Questa risposta è inclusa come riferimento. Come sottolineato da One Trick Pony, questo approccio è sconsigliato perché il database viene aggiornato ad ogni caricamento di pagina. Dopo un'ulteriore analisi, il codice sembrava rilevare solo lo stato di connessione dell'utente corrente piuttosto che abbinarlo anche all'autore attuale.
1) Installa questo plugin: http://wordpress.org/extend/plugins/who-is-online/
2) Aggiungi il seguente al tuo template di pagina:
//Imposta la variabile $curauth
if(isset($_GET['author_name'])) :
$curauth = get_userdatabylogin($author_name);
else :
$curauth = get_userdata(intval($author));
endif;
// Definisci l'ID della pagina autore visualizzata
$authortemplate_id = $curauth->ID;
// Connettiti al database
global $wpdb;
// Definisci la tabella come variabile
$who_is_online_table = $wpdb->prefix . 'who_is_online';
// Query: Conta il numero di user_id (plugin) che corrispondono all'id autore (pagina template autore)
$onlinestatus_check = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM ".$who_is_online_table." WHERE user_id = '".$authortemplate_id."';" ) );
// Se viene trovata una corrispondenza...
if ($onlinestatus_check == "1"){
echo "<p>L'utente è <strong>online</strong> ora!</p>";
}
else{
echo "<p>L'utente è attualmente <strong>offline</strong>.</p>";
}

Userei i transient per fare questo:
crea una funzione di aggiornamento utente-online che colleghi all'hook
init
; potrebbe essere qualcosa del genere:// ottieni la lista delle attività degli utenti $logged_in_users = get_transient('online_status'); // ottieni l'ID dell'utente corrente $user = wp_get_current_user(); // verifica se l'utente corrente deve aggiornare il suo stato online; // deve farlo se non esiste nella lista $no_need_to_update = isset($logged_in_users[$user->ID]) // e se la sua "ultima attività" è stata meno di, diciamo... 15 minuti fa && $logged_in_users[$user->ID] > (time() - (15 * 60)); // aggiorna la lista se necessario if(!$no_need_to_update){ $logged_in_users[$user->ID] = time(); set_transient('online_status', $logged_in_users, $expire_in = (30*60)); // 30 min }
Quindi questo dovrebbe essere eseguito a ogni caricamento di pagina, ma il transient verrà aggiornato solo se necessario. Se hai un gran numero di utenti online, potresti voler aumentare il tempo dell'"ultima attività" per ridurre le scritture nel database, ma 15 minuti sono più che sufficienti per la maggior parte dei siti...
ora per verificare se un utente è online, basta controllare all'interno di quel transient per vedere se un determinato utente è online, proprio come hai fatto sopra:
// ottieni la lista delle attività degli utenti $logged_in_users = get_transient('online_status'); // ad esempio nella pagina dell'autore $user_to_check = get_query_var('author'); $online = isset($logged_in_users[$user_to_check]) && ($logged_in_users[$user_to_check] > (time() - (15 * 60)));
Il transient scade dopo 30 minuti se non c'è alcuna attività. Ma nel caso in cui tu abbia utenti online tutto il tempo, non scadrà, quindi potresti voler ripulire periodicamente quel transient collegando un'altra funzione a un evento bisettimanale o qualcosa del genere. Questa funzione rimuoverebbe le voci vecchie di $logged_in_users
...

I transient sono una novità per me. Grazie per il codice. Non riesco a implementare il primo passo. Ho copiato il tuo primo blocco di codice e l'ho incollato in function user_online_update() {
[YOUR CODE] }add_action('init', 'user_online_update');
nel mio file functions.php - Ricevo un errore del server che suggerisce che qualcosa non viene analizzato correttamente o che ho interpretato male le tue istruzioni.

+1 per aver suggerito di usare i transient. Non molti li conoscono.

@Dominor: il codice completo.

@OneTrickPony: Ho aggiunto l'azione a functions.php. Dove devo aggiungere la seconda funzione (vedi riga 27 del tuo codice completo)? Ho provato authors.php e poi functions.php ma senza successo. Ho provato a usare la condizione alla riga 25 del tuo codice completo. Ogni volta, la pagina restituisce un errore del server oppure non analizza nulla nella mia pagina oltre al tuo codice. Ho rimosso il mio codice originale e disattivato il plugin "Who is online?". Cosa sto trascurando?

sostituisci $time_limit
con 15
e assicurati di aver aperto/chiuso correttamente i tag php...

Grazie, finalmente ho capito. Ho sostituito la variabile $time_limit. Il codice in PASTEBIN, alla riga 27, sembrava mancare di una parentesi tonda e quadra per funzionare. L'ho testato accedendo con tre o quattro account utilizzando browser separati per ciascuno. Sembra funzionare alla grande. Grazie! Ho aggiunto il codice finale alla domanda (sopra).

Per quanto ne so, non esiste un modo per fare questo utilizzando le funzioni integrate di WordPress, ma non lasciarti scoraggiare; scrivi un plugin!
Un modo per farlo sarebbe creare una nuova tabella nel database che tenga semplicemente traccia dell'ultima volta in cui l'utente è stato attivo sul sito. Potresti anche avere una pagina delle impostazioni per il tuo plugin che determini per quanto tempo considerare un utente registrato come "Connesso".
Implementeresti questo utilizzando un hook di WordPress. Comincerei agganciandomi al login, in modo che quando un utente accede, il tuo plugin registri l'orario nel database. Potresti poi esplorare altre opzioni come impostare il loro stato su 'assente' se fanno clic su logout, o 'inattivo' se il loro tempo di accesso risale a più di due ore fa.
Incontreresti un problema se sono connessi e attivi sul sito, ma oltre questa finestra di due ore. In questo caso, dovresti agganciarti alla sezione wp-admin in modo che ogni volta che fanno qualcosa in wp-admin, il tuo database venga aggiornato con l'ora corrente.
Poi, sugli articoli, dovresti fare due cose: ottenere l'autore dell'articolo corrente:
<?php $user_login = the_author_meta( $user_login ); ?>
quindi interrogare il tuo database per determinare se sono connessi:
<?php if your_plugin_function($user_login)... ?>
...visualizza qualcosa...

Basandomi sulla tua soluzione ho trovato un plugin che crea la tabella e permette di definire il tempo di scadenza tramite impostazioni. Dopo aver esaminato i file del plugin, non sono sicuro di come manipolare il codice per visualizzare online/offline nella mia pagina template dell'autore. Se potessi dare un'occhiata ai file del plugin e indicarmi la direzione giusta, te ne sarei grato: http://wordpress.org/extend/plugins/who-is-online/ (Nel frattempo, seguendo le tue istruzioni, procederò il più possibile usando un hook nel mio file functions.php)

Ho deciso di rivedere la risposta data e adattarla ai commenti.
Una cosa di cui si è parlato nei commenti è stato un tipo di pulitore giornaliero dei transient. Come sottolineato da @onetrickpony possiamo usare wp_schedule_event()
per impostare un reset giornaliero.
Ho deciso di implementare un modo semplice per recuperare tutti gli utenti attualmente online e quelli recentemente offline.
Il tutto è basato su programmazione orientata agli oggetti, racchiuso in una classe.
Indice dei contenuti |
---|
Ottieni lo stato di attività di un utente specifico dal suo ID. |
Ottieni un array di tutti gli utenti attualmente online. |
Ottieni un array di tutti gli utenti recentemente offline. |
Programma un evento ricorrente giornaliero per eliminare il transient dell'attività utente. |
Impacchetta il tutto in un bel plugin. |
if ( ! class_exists( 'WPC_User_Activity_Monitoring' ) ) {
class WPC_User_Activity_Monitoring {
/**
* @var Integer Margine di inattività dell'utente in minuti.
*/
private const USER_INACTIVITY_MARGIN = 10 * MINUTE_IN_SECONDS;
/**
* @var Integer Margine di auto-pulizia del transient in minuti.
*/
private const TRANSIENT_SELF_CLEAR = 30 * MINUTE_IN_SECONDS;
/**
* Aggancia i metodi a un insieme di azioni.
*
* @since 1.0.0
*/
public function __construct() {
add_action( 'init', array( $this, 'wpc_user_activity_monitoring_transient' ) );
}
/**
* Imposta e aggiorna il transient di monitoraggio dell'attività utente WPC durante le interazioni con il server.
*
* @since 1.0.0
*
* @param Integer $user_id L'ID dell'utente.
*
* @return Bool True se online.
*/
public function wpc_user_activity_monitoring_transient() {
if ( is_user_logged_in() ) {
$wpc_user_activity_monitoring_transient = get_transient( 'wpc_user_activity_monitoring_transient' );
if ( empty( $wpc_user_activity_monitoring_transient ) ) {
$wpc_user_activity_monitoring_transient = array();
};
$user_id = get_current_user_id();
$timestamp = current_time( 'timestamp' );
if ( empty( $wpc_user_activity_monitoring_transient[$user_id] ) || ( $wpc_user_activity_monitoring_transient[$user_id] < ( $timestamp - self::USER_INACTIVITY_MARGIN ) ) ) {
$wpc_user_activity_monitoring_transient[$user_id] = $timestamp;
set_transient( 'wpc_user_activity_monitoring_transient', $wpc_user_activity_monitoring_transient, self::TRANSIENT_SELF_CLEAR );
};
};
}
/**
* Ottieni lo stato di attività di un utente specifico dal suo ID.
*
* @since 1.0.0
*
* @param Integer $user_id L'ID dell'utente.
*
* @return Bool True se online.
*/
public function is_user_currently_online( $user_id ) {
$wpc_user_activity_monitoring_transient = get_transient( 'wpc_user_activity_monitoring_transient' );
if ( ! isset( $wpc_user_activity_monitoring_transient[$user_id] ) ) {
return;
};
if ( $wpc_user_activity_monitoring_transient[$user_id] > ( current_time( 'timestamp' ) - self::USER_INACTIVITY_MARGIN ) ) {
return isset( $wpc_user_activity_monitoring_transient[$user_id] );
};
}
/**
* Ottieni un array di tutti gli utenti attualmente online.
*
* @since 1.0.0
*
* @param Integer $nusers Numero di utenti online da recuperare.
*
* @return Array Un array di ID degli utenti attualmente online.
*/
public function get_currently_online_nusers() {
$wpc_user_activity_monitoring_transient = array_reverse( get_transient( 'wpc_user_activity_monitoring_transient' ), true );
$currently_online_nusers = array();
foreach ( $wpc_user_activity_monitoring_transient as $user_id => $timestamp ) {
if ( $timestamp > ( current_time( 'timestamp' ) - self::USER_INACTIVITY_MARGIN ) ) {
array_push( $currently_online_nusers, $user_id );
};
};
return $currently_online_nusers;
}
/**
* Ottieni un array di tutti gli utenti recentemente offline.
*
* @since 1.0.0
*
* @param Integer $nusers Numero di utenti offline da recuperare.
*
* @return Array Un array di ID degli utenti recentemente offline.
*/
public function get_recently_offline_nusers() {
$wpc_user_activity_monitoring_transient = array_reverse( get_transient( 'wpc_user_activity_monitoring_transient' ), true );
$recently_offline_nusers = array();
foreach ( $wpc_user_activity_monitoring_transient as $user_id => $timestamp ) {
if ( $timestamp < ( current_time( 'timestamp' ) - self::USER_INACTIVITY_MARGIN ) ) {
array_push( $recently_offline_nusers, $user_id );
};
};
return $recently_offline_nusers;
}
};
$wpc_user_activity_monitoring = new WPC_User_Activity_Monitoring();
};
/**
* Programma un evento ricorrente giornaliero, che si attiva alle 23:59:00 per eliminare il transient di monitoraggio dell'attività utente WPC.
*
* @since 1.0.0
*/
if ( ! wp_next_scheduled ( 'schedule_event_delete_wpc_user_activity_monitoring_transient' ) ) {
wp_schedule_event( strtotime( '23:59:00' ), 'daily', 'schedule_event_delete_wpc_user_activity_monitoring_transient' );
};
/**
* Elimina il transient di monitoraggio dell'attività utente WPC.
*
* @since 1.0.0
*/
add_action( 'schedule_event_delete_wpc_user_activity_monitoring_transient', 'delete_wpc_user_activity_monitoring_transient' );
if ( ! function_exists( 'delete_wpc_user_activity_monitoring_transient' ) ) {
function delete_wpc_user_activity_monitoring_transient() {
delete_transient( 'wpc_user_activity_monitoring_transient' );
};
};
Impacchetta il tutto in un bel plugin.
Ho anche creato un plugin per una facile implementazione. È open source su GitHub @ https://github.com/amarinediary/WPC-User-Activity-Monitoring. Ci sono documentazioni e funzionalità aggiuntive.
