Carnet Wiki

Plugin _VISITEUR : du php dans le squelette à la place de #SESSION ou #CACHE{0}

SPIP-Contrib :: Carnet Wiki :: Recherche :

Plugin _VISITEUR : du php dans le squelette à la place de #SESSION ou #CACHE{0}

Ce plugin est issu d’une interrogation et vise à répondre au besoin associé :

Quels sont les outils pour la couche de PHP nécessaire pour faire des squelettes très personnalisés selon l’auteur connecté (article « Du php dans le squelette à la place de #SESSION ou #CACHE0 ») ?

Outils existants et insuffisants

Pour le diagnostic
-  la mesure du nombre de fichiers cache et la taille du répertoire cache : reflet de l’éclatement du cache et la perte de son efficacité par multiplication des calculs
-  mesure de la fréquence des calculs de squelettes précompilés (on en trouve juste la trace dans spip.log)

Pour le code php
-  l’accés direct à $_SESSION
-  la fonction session_get

Nouvelles balises #_VISITEUR et compagnie

Ces balises sont des macros php, c’est à dire qu’elles insèrent un appel à php dans le code compilé, au lieu d’insérer le résultat html comme le font la plupart des balises.

Ainsi on peut cour-circuiter le mécanisme de cache SPIP lorsqu’il est inadapté et notamment, #VISITEUR donne accés aux données de la session, dont la valeur dépend de la session, MAIS ne multiplie pas les caches.

Attention : le fait que ce sont des macros a des conséquences importantes (voir plus loin), et c’est pour bien le rappeler que le nom de cette balise commence par un _ (sel syntaxique).

Pour ceux qui lisent le php SPIP (et c’est recommandé pour utiliser ce plugin) voici une idée du code de la balise :

  1. function balise__VISITEUR_dist($p) {
  2. $_nom = interprete_argument_balise(1, $p);
  3. if (!$_nom)
  4. $_nom = "'id_auteur'";
  5. $p->code="'<'.'" . '?php echo session_get("\' . ' . $_nom . ' . \'"); ?' . "'.'>'";
  6. $p->interdire_scripts = false;
  7. return $p;
  8. }

Télécharger

L’ensemble du source est sur la zone : https://zone.spip.org/trac/spip-zone/browser/_plugins_/visiteur/trunk

La compagnie

D’autres macros remplacent les codes php les plus fréquemment utilisés :
-  #_VISITEUR_SI{nom} pour le bloc php très fréquent qui ouvre un test :

<?php
if (isset($GLOBALS['visiteur_session']['nom'])
   AND $GLOBALS['visiteur_session']['nom'] )
{ ?>


-  #_VISITEUR_FINSI pour le bloc php qui ferme un test : <?php }; ?>
-  #_VISITEUR_SINON pour le else php<?php } else { ?>
-  #_VISITEUR_SI_EGAL pour comparer un champ de la session du visiteur avec une valeur passée en 2e argument

Le code php qui définit toutes ces balises est dans le plugin _visiteur.

Emboîtements
On peut emboiter ces structures de test :

  1. <h4>Emboitements</h4>
  2. #_VISITEUR_SI{nom}
  3. le nom existe
  4. #_VISITEUR_SI_EGAL{nom,Secretaire}
  5. et vaut bien Secrétaire
  6. #_VISITEUR_SINON
  7. et ne vaut pas Secrétaire. Il vaut #VISITEUR{nom}.
  8. #_VISITEUR_FINSI
  9. #_VISITEUR_SINON
  10. le nom n'existe pas !
  11. #_VISITEUR_FINSI

Télécharger

Accès à des données de session étendues

Selon le site ou l’application, il est possible d’accéder avec #_VISITEUR à des données relatives à l’internaute connecté, même si ces données ne sont pas dans sa session. Les données de cette session étendue peuvent être stockées dans une table spécifique de la BDD, dans une autre BDD ou sous toute autre forme, quelque part sur le net.

Pour cela il faut définir une fonction php _visiteur_session_get qui recevant le nom du champ désiré, récupère et renvoie la valeur de ce champ pour l’internaute connecté. L’accès est ensuite transparent dans les squelettes, puisque #_VISITEUR accède et renvoie de manière indifférenciées les données de la session SPIP ou celles issues de la session étendue.

Par exemple, on pourrait définir une fonction _visiteur_session_get qui va interroger le réseau social fictif http://per.sonn.es et renvoyer les différents champs disponibles.
#_VISITEUR{listedamis} renverra ainsi la liste d’amis de l’internaute connecté.

Attention

Appel de filtre

On ne peut pas appliquer de filtres ni de partie conditionnelle avant après sur une telle balise, car ces derniers s’appliquent au source du code php inclu en tant que chaine, et non au résultat.

Par exemple [(#VISITEUR{nom}|strlen)] renvoie toujours 33, quel que soit le nom de la personne connectée, car ça s’applique sur le source php et non sur le résultat php : il ne faut PAS appeler de filtre sur # _VISITEUR)

À la place d’un appel de filtre sur le résultat de la balise, il est possible de passer un filtre en 2e argument de la balise, et un ou plusieurs arguments supplémentaires qui seront passés au filtre.

#VISITEUR{nom,strlen)

Parties conditionnelles avant après appel de balise

Les parties conditionnelles avant après sur balise s’affichent toujours, même si le résultat php est vide (par exemple car il n’y a pas de visiteur), car le source php n’est jamais vide, lui : [avant si non vide (#_VISITEUR{nom}) apres si non vide]

Effets de bords

Les morceaux de squelettes SPIP présents dans des zones conditionnelles non affichées à cause d’un #_VISITEUR_SI sont quand mêmes calculées.

Il y a donc

  1. un coût CPU à prendre en compte si ça nécessite de gros calculs
  2. un risque d’effets de bords non voulus, si les balises appelées dans ce code ont des effets de bord : #SET par exemple, car le #SET se fera même si la partie ne s’affiche pas, contrairement à ce qui se passe avec les parties avant après conditionnelles des balises ou des boucles.
  1. <h4>Ce qu'il ne faut pas faire</h4>
  2. #SET{var,var} var vaut var<br>
  3. _VISITEUR_SI{nom} :
  4. #_VISITEUR_SI{nom}
  5. / #SET{var,oui_visiteur} IL Y A UN_VISITEUR var vaut oui_visiteur : #GET{var}<br>
  6. #_VISITEUR_SINON{nom}
  7. / #SET{var,pas_de_visiteur} IL Y A UN_VISITEUR var vaut pas_de_visiteur : #GET{var}<br>
  8. #_VISITEUR_FINSI
  9. / après_VISITEUR_finsi var vaut : #GET{var}<br>

Télécharger

Squelette de test et debuging

  1. <html><head></head>
  2. <body>
  3. Squelette : [(#DATE|affdate{'Y-m-d H:i:s'})]<br>
  4. php session_get <?= session_get('nom') ?> --> php date <?= date('Y-m-d H:i:s') ?> :: SPIP eval session_get : #EVAL{session_get('nom')} :: SPIP eval globals : #EVAL{$GLOBALS['visiteur_session']['nom']}
  5. <br>
  6. <b>_VISITEUR{nom} : #_VISITEUR{nom}</b><br>
  7. <br><hr><br>
  8.  
  9. _VISITEUR_SI{nom} :
  10. #_VISITEUR_SI{nom}
  11. / IL Y A UN_VISITEUR
  12. #_VISITEUR_FINSI
  13. / après_VISITEUR_finsi
  14.  
  15. <br><br>
  16.  
  17. _VISITEUR_SI{nom} puis SINON :
  18. #_VISITEUR_SI{nom}
  19. / apres_VISITEUR_si
  20. #_VISITEUR_SINON
  21. / PAS DE_VISITEUR
  22. #_VISITEUR_FINSI
  23. / après_VISITEUR_finsi
  24.  
  25. <br><br>
  26.  
  27. _VISITEUR_SI_EGAL{nom,Secretaire} :
  28. #_VISITEUR_SI_EGAL{nom,Secretaire}
  29. / c'est egal
  30. #_VISITEUR_FINSI
  31. / après_VISITEUR_finsi
  32.  
  33. <br><br>
  34.  
  35. _VISITEUR_SI_EGAL{nom,Secretaire} puis SINON :
  36. #_VISITEUR_SI_EGAL{nom,Secretaire}
  37. / c'est encore egal
  38. #_VISITEUR_SINON
  39. / pas egal
  40. #_VISITEUR_FINSI
  41. / après_VISITEUR_finsi
  42.  
  43. </body>
  44. </html>

Télécharger

Souhaitable de développer encore

Autres pistes

microcache

Le microcache est un fichier cache totalement statique, de longue durée et dont le nom est facilement accessible. Du fait que le nom est accessible, on peut en effacer un sélectivement.

-  Annonce sur seenthis
-  Sources sur la zone

Le filtre |microcache s’applique sur un id_auteur, et reçoit le nom de fichier d’un squelette en argument. Le squelette caché par microcache reçoit l’id_auteur dans #ENVid. On peut aussi appliquer |microcache sur une chaine (un identifiant alphanumérique).

microcache stocke sous forme de fichiers et n’est donc souvent pas plus efficace que memoization.
Mais microcache a une interface pratique pour le stockage de data visiteur étendues ou squelettes de visu = un filtre portant sur un id_auteur, que n’a pas memoization en l’état. Le code de microcache est simple et peut facilement être dupliqué et adapté pour d’autres formes de stockage que sur le disque. On pourrait donc faire un plugin dupliquant l’interface filtre de microcache et stockant avec memoization.

Une autre différence, c’est que microcache enregistre de manière plus « définitive » sur le disque dur, avec l’avantage que ça tient entre les redémarrages et l’inconvénients que ça se remplit sans jamais se vider si on ne fait rien.

Selon fil, ce serait mieux de faire évoluer memoization et d’abandonner microcache, donc ajouter à memoization une couche « filtre sur id_auteur ou identifiant string ».