Carnet Wiki

Version 18 — Octobre 2018 JLuc

En complément à Plugin ’macrosession’ : usage optimisé et extension des données de session.

Crédits et remerciements

Ce plugin s’appuie sur l’expertise de Cédric, collectée et mise en forme dans l’article Du php dans le squelette à la place de #SESSION ou #CACHE 0.

Le premier jet de code d’une macro a bénéficié de l’aide de marcimat.

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 bien plus souvent besoin d’accéder à un argument calculé pour #_AUTORISER . Le plus souvent, la valeur requise est l’objet principal de la page, présent dans l’url, ou directement dans l’environnement.

Un développement récent (intégré à la version 0.9) apporte donc une fonctionnalité fort appréciée : la possibilité d’utiliser une balise calculée, et non une constante, pour la valeur ’id’ de l’appel.

Avec la balise #_AUTORISER, le webmestre dispose désormais 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).

Exemple : #_AUTORISER{modifier,article,#GET{alaune}}

Rq : #_AUTORISER{modifier,article,#ID_ARTICLE} est équivalent à #_AUTORISER{modifier,article,env}.

Remarque :

  1. 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.
  2. 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 il n’est pas exclu qu’une mise à jour du plugin soit nécessaire si jamais le coeur du compilateur SPIP était modifié un jour (ça n’arrive que très rarement), alors qu’il y a moins de risque que ça soit nécessaire avec ’env’, ’boucle’ et ’url’.

Tester et explorer

-  Formulaires : les formulaires sont une autre cause de création de cache sessionnés. Explorer pour quelle raison et dans quels cas la présence d’un formulaire sessionne le cache d’un squelette, et trouver moyen de contourner.

-  #URL_ACTION_AUTEUR : sessionne aussi le cache

-  Modèles : Il semble que les modèles utilisés dans un article sont mis en cache en ce qui concerne l’usage des balises #_SESSION, et ce même lorsqu’il y a #CACHE{0} dans le squelette du modèle. C’est un peu étrange mais les modèles ont des mécaniques de cache spécifiques et d’ailleurs ce n’est que depuis SPIP3 que les modèles peuvent, normalement, avoir un cache à . Faudrait explorer plus en détail.

Comment faire pour les #SESSIONS en critères de boucle ?

Soit la boucle suivante :

<BOUCLE_auteur(AUTEURS){id_article}{id_auteur=#SESSION{id_auteur}}>
   <INCLURE{fond=encart_auteur}> 
</BOUCLE_auteur>

Comment faire pour la dessionnariser ?

Arguments calculés pour #_SESSION :

Actuellement les arguments doivent être des constantes, car le interprete_argument_balise se fait à la compilation et non dans le contexte de SPIP. Par exemple, après un #SET{arg, une valeur}, #GET{arg} renvoie table_valeur($Pile["vars"], (string)'arg', null) et non ’une valeur’.

Faire pareil que pour le 3e argument de #_AUTORISER

=====

Développements éventuels

-  calculer dès la compilation la fonction appelée pour un filtre, l’utiliser dans le code compilé, et du coup ne plus inclure inc/filtres dans mes_options.

-  interpréter dans le même bloc de code les 4 cas de calculs de l’argument id de #_AUTORISER_SI. Rassembler ’env’ et ’url’ au même endroit que #BALISE et #GETvariable

-  étendre la détection par le compilateur des erreurs et leur signalement :

<blockquote class="spip">
  • détection des mauvaises imbrications de SI SINON FIN et signalement proprement par une erreur.
  • si possible : appels de filtres et parties conditionnelles avant / après : détection et refus des affichages conditionnels [ ( |filtre) ]. </blockquote>

-  mettre à disposition un mécanisme simple pour cacher et raffraîchir les valeurs de session étendue (cf les notes sur microcache plus bas)

-  DONE : outil d’analyses et de suivi statistique du cache SPIP : xray

-  Dans SPIP, la syntaxe pour des éléments dynamiques (générant du PHP dans le cache) a souvent recours aux chevrons (<INCLURE> ou <BOUCLE_b()...>). Il y a aussi des exceptions (#FORMULAIRES).
Il serait logique d’avoir une syntaxe avec des chevrons pour ces macros. On pourrait alors se passer du préfixe underscore.

-  Pour #_AUTORISER, plutôt que ’boucle’, ’env’, ’url’, #GET et #BALISE en 3e argument, on pourrait proposer d’accéder par défaut à l’environnement le plus proche, et sinon à la valeur indiquée. Mais le pb est que je n’ai pas su accéder à une valeur générale calculée de manière générique, et que j’ai seulement pu décompiler certaines formes syntaxiques particulières (#GET, #BALISE et contantes) pour permettre à la macro d’accéder à leur valeur.

Pistes pour le cache des données étendues

Si l’accés ou le calcul des données étendues est coûteux, il faut le mettre en cache. C’est notamment le cas si l’accés se fait par une API sur un serveur externe.

recuperer_url_cache

Si les valeurs se font sur un serveur externe on peut simplement utiliser recuperer_url_cache qui met en cache SPIP le fichier récupéré.

Dans mes essais, la durée de l’accés est alors divisé par 100 ou 200 : on passe de environ 200 ms à 1ou 2 ms.

microcache

Le microcache (produit par le plugin éponyme) 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 #ENV{id}. On peut aussi appliquer |microcache sur une chaine qui sert d’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 ».