SPIP-Contrib

SPIP-Contrib

عربي | Deutsch | English | Español | français | italiano | Nederlands

290 Plugins, 198 contribs sur SPIP-Zone, 93 visiteurs en ce moment

Accueil > Optimisation et performances > Macrosession > Plugin ’macrosession’ : usage optimisé et extension des données de (...)

Plugin ’macrosession’ : usage optimisé et extension des données de session

4 décembre 2017 – par JLuc – commentaire

12 votes

Ce plugin est issu d’une interrogation et vise à répondre au besoin associé : quels sont les outils pour écrire des squelettes très personnalisés selon l’internaute connecté, en évitant de créer un cache différent pour chacun de ces utilisateurs ?

Pour bien s’en servir il faut avoir compris les mécanismes de cache de SPIP et les articles suivants :
-  SPIP, PHP et Javascript sont dans un bateau
-  Utilisation de la balise #SESSION et optimisation
-  Du php dans le squelette à la place de #SESSION ou #CACHE 0
-  Optimiser les performances de SPIP

L’état actuel de ce plugin est « test ». Actuellement il n’y a pas de bug connu mais vos retours sont bienvenus.

Nouvelles balises #_SESSION et compagnie

Attention macros !

Notez le ’_’ au début de #_SESSION !!

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. C’est ainsi qu’elles permettent de court-circuiter le mécanisme de cache SPIP lorsqu’il est inadapté.

Le fait que ces balises sont en fait des macros a des conséquences importantes, présentées plus loin, et c’est pour bien le rappeler que leur nom commence par un _.

Balise #_SESSION

#_SESSION donne accès aux données de la session, c’est-à-dire dont la valeur dépend de la session, mais à la différence de #SESSION, la balise #_SESSION ne crée pas un cache SPIP pour chaque visiteur : elle insère un code php dont le résultat n’est pas mis en cache, et qui cherche le résultat à chaque affichage de la page. De plus, la balise #_SESSION permet d’accéder à des données de session étendue, qui ne sont pas présente dans la session SPIP de base. Cette seconde fonctionnalité est présentée plus loin.

Dans un squelette, #_SESSION{nom} insère le nom de l’internaute connecté s’il y en a un.

Parce que c’est une macro, on ne peut pas appeler un filtre sur cette balise. Pour compenser cela, la balise propose un mécanisme interne pour appeler un filtre : il suffit de le passer en deuxième argument.

Par exemple : #_SESSION{nom,strlen} renverra la longueur du nom de l’internaute connecté.

Il est possible de passer 1 ou 2 arguments supplémentaires au filtre.
Par exemple #_SESSION{anciennete,plus,3} renverra l’ancienneté + 3.

Balises de test #_SESSION_SI, #_SESSION_SINON, #_SESSION_FIN

Il est très fréquent de devoir tester une valeur de session du visiteur connecté et produire un affichage différent selon sa valeur.

-  #_SESSION_SI{nom} produit le bloc php qui ouvre un test.

-  #_SESSION_SINON produit le bloc php <?php } else { ?>

-  #_SESSION_FIN produit le bloc php qui ferme un test : <?php }; ?>

Exemple

À la place de

  1. <?php
  2. if (isset($GLOBALS['visiteur_session']['nom'])
  3.     AND $GLOBALS['visiteur_session']['nom'] )
  4. { ?>
  5. <h3>Bonjour <?php echo $GLOBALS['visiteur_session']['nom']; ?></h3>
  6. <?php } else { ?>
  7. <h3>Voulez vous vous connecter ?</h3>
  8. <?php }; ?>

Télécharger

on écrira :

  1. #_SESSION_SI{nom}
  2.   <h3>Bonjour #_SESSION{nom}</h3>
  3. #_SESSION_SINON
  4.    <h3>Voulez vous vous connecter ?</h3>
  5. #_SESSION_FIN

Télécharger

Si vous trouvez ça plus lisible et plus facile à écrire, ce plugin est fait pour vous !

#_SESSION_SI avec comparaisons de valeur

Il est également possible de faire des comparaisons avec ==, != , >, <, >= et <= :

-  #_SESSION_SI{nom,==,Linda} sera vérifié si le nom de l’internaute connecté est « Linda ».

-  #_SESSION_SI{nom,>,K} sera vérifié pour tous les noms qui viennent après la lettre K

#_SESSION_SI avec filtres

Comme avec #_SESSION il est possible d’appliquer un filtre avant de tester la valeur :
#_SESSION_SI{email,mail_est_valide}mail_est_valide est un filtre maison qui teste si un email est valide.

On peut également passer 1 ou 2 arguments supplémentaires au filtre

Les filtres suivants peuvent également être utilisés :
-  ! ou non : négation de la valeur du champ trouvé.
-  ? ou choixselon : renvoie le 1er argument suivant, ou le 2e, selon que la valeur est nulle ou non.

Si les variations syntaxiques permises par ce plugin sont insuffisantes pour les besoins de vos squelettes, il vous sera possible de créer un filtre maison pour tester ce qu’il faut comme il faut.

Emboîtements
On peut emboiter les structures de test à volonté.
Par exemple ici un emboitement de 3 niveaux de test :

  1. <h4>Emboitements</h4>
  2. #_SESSION_SI
  3.    Vous êtes connecté
  4.    #_SESSION_SI{nom}
  5.         et vous avez un nom.
  6.         #_SESSION_SI{nom,==,Linda}
  7.                 Je vous reconnais, c'est vous : Linda !
  8.         #_SESSION_SINON
  9.                 Vous n'êtes pas Linda. Votre nom est #_SESSION{nom}.
  10.         #_SESSION_FIN
  11.   #_SESSION_SINON
  12.         Vous n'avez pas de nom ?!
  13.   #_SESSION_FIN
  14. #_SESSION_SINON
  15.    Vous n'êtes pas connecté...
  16. #_SESSION_FIN

Télécharger

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

Selon le site ou l’application, il est possible d’accéder avec #_SESSION à 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 calculées à partir des données de session déjà présentes, ou stockées dans une table spécifique de la BDD, dans une table externe, ou issus d’un autre serveur quelque part sur le net et accédées à travers une API REST.

Pour cela un pipeline SPIP session_get a été défini.
Il reçoit un tableau avec 2 entrées :
-  champ contient le champ recherché,
-  visiteur_session contient la session en cours d’élaboration, que le pipeline peut, ou non, utiliser pour le calcul ou la recherche de la valeur demandée.

Pour donner accès à des données de session étendues, un plugin doit implémenter ce pipeline par une fonction prefixe_session_get qui reçoit le tableau de session SPIP et renvoie le tableau reçu en enrichissant l’entrée ’visiteur_session’ avec la valeur calculée pour le champ demandé.

L’accès est ensuite transparent dans les squelettes, puisque #_SESSION accède et renvoie de manière indifférenciées les données de la session SPIP ou celles issues de la session étendue.

Exemple 1
Un plugin ’majuscule’ pourrait donner accès à un champ nom_majuscule, qui vaudrait le nom du visiteur en majuscule. Pour cela, il définirait la fonction suivante :

  1. function majuscule_session_get($session) {
  2.   if ($session['champ'] == 'nom_majuscule')
  3.      $session['visiteur_session']['nom_majuscule'] = mb_strtoupper($visiteur_session['nom']);
  4.   return $session;
  5. };

Télécharger

En pratique, il serait plus simple d’accéder à ce nom en majuscule par l’application d’un filtre au champ : #_SESSION{nom,mb_strtouuper}

Exemple 2
Le pipeline d’extension des sessions a été conçu, à l’origine, pour interroger des bases de données externes, qui fournissent des compléments d’informations ou d’interaction avec le visiteur courant.

Un plugin pourrait par exemple interroger l’API du réseau social ludique http://per.sonn.es et permettre à #_SESSION{listedamis} de renvoyer la liste des amis de l’internaute connecté.

Remarque
Ce pipeline est utilisé uniquement pour les accès aux données de session requises par les balises #_SESSION et #_SESSION_SI, et pas par la fonction php session_get du noyau spip ou par la balise #SESSION d’origine.

Attention : Les macros ne sont pas des balises comme les autres !

Ces balises étant des macros, il faut être particulièrement vigilant en les utilisant car elles ont un comportement spécial dans certains cas et certains usages ne sont pas possibles.

Appels de filtre

Les classiques appels de filtres sur ces balises ne fonctionneront pas correctement, de même que les parties conditionnelles avant ou après. En effet, les filtres appliqués avec la syntaxe classique de SPIP s’appliquent au source du code php généré par la macro, en tant que fragment de code source en langage PHP, et non au résultat de l’exécution de ce code.

Par exemple [(#_SESSION{nom}|strlen)] renvoie toujours 33, quel que soit le nom de la personne connectée, car ça s’applique sur le source php (qui s’écrit en 33 caractères à l’heure où cette documentation est rédigée) et non sur le résultat php : il ne faut PAS appeler de filtre sur # _SESSION.

C’est pour pallier à cette contrainte qu’a été développée l’alternative présentée plus haut : passer un filtre en 2ème argument de la balise.

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 (#_SESSION{nom}) apres si non vide]

Il est tout de même possible d’utiliser cette syntaxe de base de spip dans un cas : pour forcer l’insertion d’un espace après ou avant l’appel de la balise :
[(#_SESSION{nom}) ][(#_SESSION{prenom}) ]
Car sans cela, SPIP accole les 2 résultats des appels de balises en supprimant les espaces, comme il fait partout.

Macros et SPIP sont dans un bateau

En employant des macros, tout se passe comme si du php figurait dans le squelette, et tout ce qui s’applique au php dans l’article « SPIP, PHP et javascript sont dans un bateau » s’applique aussi aux macros.

Et donc, les valeurs #_SESSION et les tests #_SESSION_SI se calculent aprés l’évaluation par SPIP des balises et des boucles.

Effets de bords

Ce point est une des conséquences du point précédent.

La partie de HTML masquée par un #_SESSION_SI n’est pas affichée mais elle est quand même compilée par SPIP, et donc les #SET et #GET et autres morceaux de squelettes SPIP présents dans des zones conditionnelles non affichées à cause d’un #_SESSION_SI sont quand même calculés.

Il y a donc un risque d’effets indésirérables si vous vous servez de balises qui ont des effets de bords : #SET par exemple, car le #SET se fera même si la partie ne s’affiche pas. C’est la règle du « SPIP d’abord ! » expliquée dans l’article SPIP, PHP et Javascript sont dans un bateau.

L’exemple suivant illustre la difficulté.

  1. <h4>Ce qu'il ne faut pas faire</h4>
  2. #SET{var,debut} var vaut debut<br>
  3. Le nom : _SESSION_SI{nom} :
  4. #_SESSION_SI{nom}
  5.   Ya un nom. #SET{var,oui_visiteur} var vaut maintenant : #GET{var}<br>
  6. #_SESSION_SINON{nom}
  7.   Il n'y a pas de nom. #SET{var,pas_de_visiteur} var vaut maintenant : pas_de_visiteur : #GET{var}<br>
  8. #_SESSION_FIN
  9. À la fin, var vaut : #GET{var}<br>

Télécharger

Dans le cas où il y a une session avec le nom ’jluc’, il s’affichera :

Le nom : jluc
Ya un nom. var vaut maintenant : oui_visiteur
À la fin, var vaut : non_visiteur

Ce n’est pas un bug ! C’est déconcertant de prime abord, mais c’est normal. Pour comprendre ce qui se passe là, il faut 2 flux indépendants de lecture, l’un pour php et l’autre pour SPIP. C’est pénible. Comme c’est trop difficile de maintenir un tel code, il ne faut pas utiliser de #SET (ou d’autres balises ou filtres ayant des effets de bord) dans les parties conditionnées par ces macros.

Arguments calculés

Une autre conséquence, est qu’on ne peut passer que des constantes en argument de comparaison de #_SESSION. Ainsi, #_SESSION_SI{id_auteur,==,#ID_AUTEUR} n’est pas possible. macrosession signale cette impossibilité par une erreur de compilation.

Cache du pipeline session_get

Le mécanisme d’extension doit bien gérer son système de cache afin de ne pas refaire inutilement des calculs à chaque appel de page, et ne pas servir non plus des informations périmées.

Boucles

Les résultats des balises #_SESSION ou #_AUTORISER ne sont pas utilisables en critères de boucle.

Balises #_AUTORISER_SI et compagnie

Les balises #SESSION ne sont pas les seules à générer des caches sessionnés. Il y a aussi les balises #AUTORISER, et leur emploi expose à voir se multiplier les caches.

Le plugin macrosession propose donc 3 autres balises pour tester les autorisations en php : #_AUTORISER_SI, #_AUTORISER_SINON et #_AUTORISER_FIN.

Exemple

  1. #_AUTORISER_SI{ecrire, article, 2}
  2.   - Modifier l'article
  3.   #_AUTORISER_SI{webmestre}
  4.      - Accèder à l'administration
  5.   #_AUTORISER_FIN
  6. #_AUTORISER_SINON
  7.   - Vous ne pouvez pas modifier cet article
  8. #_AUTORISER_FIN

Télécharger

Autres restrictions

Contrairement aux balises #_SESSION, il n’y a pas de filtre ou comparaison prévue dans la syntaxe de ces balises, donc si jamais vous en avez besoin, vous devrez définir une nouvelle autorisation.

Par contre, de nouvelles possibilités sont offertes, tels que le recours aux id_objets issus de l’environnement, de la boucle englobante, de l’url ou d’un #GET ou d’une #BALISE. La partie suivante présente ces possibilités.

Pour le reste, il y a les mêmes restrictions énoncées plus haut et les mêmes possibilités d’emboîtements.

Arguments calculés pour #_AUTORISER

Dans mon expérience, le fait de ne pas pouvoir accéder à un champ dont le nom est calculé n’est pas une restriction gênante pour l’accès aux valeurs de session, mais il y a souvent besoin d’accéder à un argument calculé pour évaluer une autorisation. Le plus souvent, la valeur requise est l’objet principal de la page, présent dans l’url, ou directement dans l’environnement.

Avec la balise #_AUTORISER, le webmestre dispose donc de 4 possibilités pour passer une valeur calculée pour l’identifiant : env , url, boucle, #BALISE et #GET{variable}

Dans les 3 premiers cas, l’identifiant utilisé est directement déduit du type (2e argument). Pour ’article’, c’est ’id_article’, pour ’document’, c’est ’id_document’, etc

-  Avec env, c’est la valeur de l’identifiant dans l’environnement qui est testée. Attention, cela ne s’applique PAS aux valeurs des champs directement issus de la boucle englobante.

Exemple : #_AUTORISER{modifier,article,env}

-  Avec boucle, c’est la valeur d’un champ issu de la boucle immédiatement englobante qui est utilisé.

Exemple #_AUTORISER{modifier,article,boucle} : testera la valeur de #ID_ARTICLE issue de la boucle immédiatement englobante.

-  Avec url, c’est la valeur de l’identifiant en url qui est testée.

Exemple #_AUTORISER{modifier,article,url} : testera la valeur de #ID_ARTICLE issue de l’url.

Les 2 autres cas introduisent des libertés supplémentaires :

-  Avec #BALISE et #GET{variable}, c’est la valeur de la balise, ou de la variable SPIP, dans l’environnement qui est testée (mais pas les valeurs issues de la boucle immédiatement englobante).

Exemples :
-  #_AUTORISER{modifier,article,#GET{alaune}}
-  #_AUTORISER{modifier,article,#ID_ARTICLE} est équivalent à #_AUTORISER{modifier,article,env}.

Remarque :
-  Les autres calculs ne sont pas admis mais il est possible de faire un calcul en amont, le mettre dans un #SET puis y accéder dans un #GET.
-  Lorsqu’on peut utiliser ’env’, ’boucle’, ou ’url’, ces syntaxes doivent être favorisées plutôt que #UNEBALISE et #GET, car l’accès aux valeurs #UNEBALISE et #GET nécessite de décompiler le code généré par le compilateur de SPIP, ce qui est assez délicat et plus difficile à maintenir.

Mise au point et debuging

Découverte et tests
Le plugin embarque plusieurs squelettes de tests qui permettent de voir comment l’utiliser :
-  test_visiteur
-  test_visiteur_si
-  test_visiteur_comparaison
-  test_visiteur_filtre
-  test_visiteur_etendu
-  test_visiteur_si_etendu
...

Plugin XRay

Si votre hébergement est boosté par APCCache, le plugin XRay est très pratique pour la mise au point avec macrosession. Il permet en effet de voir quels sont les squelettes sessionnés et non sessionnés, leur taille et fréquences d’usages. Il calcule aussi le rendement des caches sur le site, qui est un indice d’efficacité globale, et le détaille pour les js et css (pour lesquels il faut viser 100%) et pour les autres squelettes (html).

XRay permet ainsi de voir comment se comporte le cache et de déterminer sur quels squelettes porter prioritairement vos efforts de réécriture avec macrosession.

Stratégie d’emploi

Lorsque vous avez décidé qu’un squelette ne devrait pas être sessionné, il vous faut :

  • dans le squelette choisi, remplacer tous les appels à #SESSION et #AUTORISER par des appels aux balises macrosession
  • faire de même pour tous les squelettes inclus statiquement (avec une balise #INCLURE) dans le squelette choisi. Ou sinon : remplacer ces inclusions statiques par des <INCLURE> dynamiques.
  • dans les squelettes incluant le squelette choisi, remplacer les éventuelles inclusions statiques #INCLURE du squelette choisi par des inclusions dynamiques <INCLURE> (mais si les squelettes incluant le squelette choisi ne sont pas sessionnés, vous pouvez laisser #INCLURE).
  • s’il reste une balise #SESSION ou #AUTORISER que vous n’avez pu convertir en macro, alors il ne vous reste plus qu’à déporter cette partie du squelette dans une noisette à part, inclue dynamiquement (cf Utilisation de la balise #SESSION et optimisation). Tous les squelettes ne se prêtent donc pas aussi bien à cette stratégie.
  • vérifier ensuite que le squelette n’est plus sessionné.

P.-S.

-  Source
-  Compléments d’infos et notes sur les développements en cours
-  La balise #URL_ACTION_AUTEUR et le critère  {id_auteur=#SESSION{id_auteur}} sessionnent aussi les caches. Le plugin macrosession ne propose pas d’alternative à ces syntaxes.

Dernière modification de cette page le 3 octobre 2018

Retour en haut de la page

Vos commentaires

Répondre à cet article

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici Les choses à faire avant de poser une question (Prolégomènes aux rapports de bugs. )
Ajouter un document

Retour en haut de la page

Ça discute par ici

  • ScolaSPIP 4

    19 janvier 2016 – 383 commentaires

    ScolaSPIP est plugin-squelette responsive personnalisable pour sites Web d’établissements scolaires basé sur SPIPr Présentation de ScolaSPIP Ce plugin pour SPIP 3 est développé par la Dane de l’académie de Versailles pour les webmestres de cette (...)

  • Jeux pour SPIP 3

    27 juillet 2012 – 53 commentaires

    Un portage pour SPIP 3 du plugin Jeux a été fait. Explications et nouveautés. Cet article concerne une mise à jour du plugin Jeux dont la description complète est disponible ici : Des jeux dans vos articles !. Le code du plugin Jeux est un code (...)

  • Plugin Vidéo(s)

    23 novembre 2010 – 704 commentaires

    Interface de gestion et modèle d’insertion des vidéos : Dailymotion Vimeo Youtube Modèle de la balise HTML5 video avec alternative flash html5media : Lecture HTML5/Flash pour tout navigateur des fichiers MP4/H264/Ogg/WebM/Mkv Support mobile, iPad, (...)

  • Vidéo Accessible

    6 avril 2011 – 168 commentaires

    Un plugin pour faciliter la diffusion de vidéos accessibles. Accessibilité des vidéos Accessibilité de la vidéo Afin d’être pleinement accessible, une vidéo (composée d’images et de sons) doit répondre à plusieurs critères. Le critère de base est (...)

  • Groupes de mots clés arborescents

    26 juillet 2012 – 37 commentaires

    Ce plugin permet de gérer une arborescence de groupes de mots clés. Les sous groupes de mots héritent des propriétés du groupe racine (sur quoi peut on le lier ? peut il y avoir un ou plusieurs mots). Les formulaires de liens qui permettent de lier (...)