Ce que j’essaie d’obtenir est le suivant: pour chaque utilisateur de notre site Web, je souhaite envoyer une demande d’API à un service (une API locale REST interagissant avec une autre base de données), puis mettre en cache le résultat dans la mémoire. WP_User (sous) classe jusqu'à ce que l'utilisateur se déconnecte et se reconnecte (car cette valeur est utilisée une fois sur chaque page de l'application, sinon elle devrait être extraite une fois pour chaque chargement de page, ce qui est très peu performant au niveau des performances).
La manière la plus élégante en termes de séparation des problèmes que j'ai trouvée jusqu'à présent consiste à étendre (sous-classer) la classe WP_User selon l'exemple présenté dans le livre O'Reilly Création d'applications Web avec WordPress Par Brian Messenlehner & Jason Coleman .
L'exemple de code peut être vu ici: voir ce fichier sur le GitHub de l'auteur .
Cependant, le problème est que nous n'avons toujours pas cet étudiant (étend WP_User, donc la sous-classe) disponible dans notre code. Nous devons encore l'instancier de la manière suivante pour obtenir une instance d'étudiant pour l'utilisateur actuel:
$student = new Student($current_user->ID);
Si nous faisons cela sur une page, l'instance sera toujours créée à nouveau (d'où mon renvoi au cycle de vie dans le titre) et l'appel à $student->assignments
semble ne jamais être mis en cache dans la sous-classe WP_User
elle-même après avoir navigué vers une nouvelle page et/ou recharger la page, donc pour chaque chargement de page, nous atteignons l'API et la base de données qui ne fonctionneront probablement jamais dans notre environnement de production à fort trafic.
Cependant, la variable globale $current_user
au sein de WordPress lui-même (qui est une instance de WP_User
) semble être créée directement après la connexion et est ensuite disponible dans toute l'application, pour autant que je sache. Ce que je veux vraiment, c’est la même disponibilité dans l’application, mais pour ma sous-classe (Étudiant) au lieu de la classe WP_User
, mais plus important encore, je veux être sûr que pour chaque utilisateur connecté, la frappe d’API n’est effectuée qu’une seule fois ( comme pour $current_user->user_login
qui est dans WP_User
par exemple).
J'ai également envisagé d'ajouter user_meta
à WP_User
et de vérifier cette question qui semblait en partie utile: WordPress met-il en cache les résultats get_user_meta ()?
Cependant, ceci est récupéré via wp_cache_get
qui est un cache d'objets WordPress qui indique clairement:
Nous n'utilisons pas les valeurs de la sous-classe Student plus d'une fois dans la création de la page. Cependant, la valeur est utilisée une fois sur chaque page de l'application. Elle doit donc être récupérée une fois pour chaque chargement de page.
Suis-je simplement en train de penser dans la mauvaise direction, ou comment cela serait-il possible dans WordPress? J'ai vraiment besoin d'une bonne solution à long terme ici, qui devrait fonctionner dans un environnement de production à fort trafic. Merci pour tous vos commentaires et votre aide!
Si j'ai bien compris, nous devons mettre en cache une valeur extraite d'un autre service REST, de la connexion à la déconnexion de l'utilisateur sur l'installation de wordpress. Nous allons donc nous connecter à ce wp_login
pour obtenir la valeur et le cache. en utilisant API transitoire , Options API ou un cache persistant plugin.
add_action('wp_login', 'my_get_and_cache_rest_value');
function my_get_and_cache_rest_value ($user_login, $user) {
// do your rest call
// cache it using Transient API, Options API or a persistent caching plugin
}
Nous pouvons ensuite étendre l'objet WP_User
et définir nos appels magiques pour extraire les données souhaitées du cache.
class MY_User extends WP_User {
// no constructor so WP_User's constructor is used
// method to get cached data
function getMyCachedData() {
// get data via my cache solution
if ( ! isset( $this->data->myData ) )
$this->data->myData = my_get_cached_data( $this->ID );
return $this->data->myData;
}
// magic method to detect $user->my_data
function __get( $key ) {
if ( $key == 'my_data' )
{
return $this->getMyCachedData();
}
else
{
// fallback to default WP_User magic method
return parent::__get( $key );
}
}
}
J'espère que cela aiderait quelqu'un et bravo à @Daniel.
Ce qui suit ne répond pas à toute la question, mais aborde cette partie:
@ Daniel: La variable globale
$current_user
... est alors disponible dans toute l'application pour autant que je sache. Ce que je veux vraiment, c'est la même disponibilité dans l'application ...
J'avais un besoin similaire, et c'est ce que j'ai proposé.
Il y a un hook set_current_user
(dans la fonction wp_set_current_user () _) et, comme la variable globale $current_user
est définie sur une instance de WP_User au moment où l'action est déclenchée, vous pouvez utiliser ce hook pour "effectuer des tâches "à cela.
Les appels à wp_get_current_user () _ retournent essentiellement la valeur du $current_user
global, mais peuvent éventuellement appeler wp_set_current_user()
dans certaines conditions, ce qui entraînera le déclenchement de votre action personnalisée.
Donc, dans un plugin personnalisé (je ne pense pas que cela fonctionnerait dans un fichier theme.php), vous pouvez définir une action:
add_action( 'set_current_user', 'extend_current_user', PHP_INT_MAX );
Et alors votre action peut écraser le $current_user
global:
public function extend_current_user()
{
global $current_user;
if( $current_user->ID == 0 )
return;
$current_user = new Student( $current_user->ID );
}
Votre classe d’étudiant peut ensuite implémenter la API transitoire pour mettre en cache les données RESTful et proposer des méthodes ou des propriétés qui exposeront ces données. Et comme le $current_user
global restera en tant qu'instance de Student, ces méthodes/propriétés seront toujours disponibles à partir de wp_get_current_user()
chaque fois que vous en aurez besoin.
Bien entendu, en faisant cela, un programmeur défensif voudra vérifier que tout appel à wp_get_current_user()
renvoie une instance de Student avant d'appeler des méthodes.
Votre question est un peu large, mais le problème principal semble être que pour chaque nouvel étudiant, vous souhaitez contacter une API externe, une seule fois .
Pour ce faire, vous devez vous connecter à wp_insert_user
, qui est la fonction principale qui enregistre un nouvel utilisateur. Par définition, cette fonction n'est appelée qu'une fois pour chaque nouvel utilisateur. À la fin de cette fonction, vous voyez un crochet user_register
, qui permet d’approcher l’API.
add_action ('user_register','wpse185731_approach_api');
function wpse185731_approach_api ($user_id) {
$userdata = get_userdata( $user_id );
if ( some condition based on $userdata) {
... approach API with $userdata, then store with:
add_user_meta( $user_id, $meta_key, $meta_value, $unique );
}
}
Vous voudrez probablement faire cela dans un plugin, pas dans votre thème.