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

Ce plugin permet d’écrire des squelettes très personnalisés selon l’internaute connecté, tout en évitant de créer un cache différent pour chacun de ces utilisateurs.

Préambules

  1. Ce plugin ne se substitue pas aux balise #SESSION et #AUTORISER fournies par le noyau de SPIP, qui font très bien ce pour quoi elles sont conçues : donner accés aux données de sessions et aux autorisations de l’internaute connecté, et servir comme balise SPIP pour des tests et calculs.
  2. Pour bien se servir du plugin macrosession, il faut avoir compris les mécanismes de cache de SPIP et en particulier le sessionnement des caches et ses effets.
    Voyez 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

Nouvelles balises #_SESSION et compagnie

Attention macros !

Notez le ’_’ au début de #_SESSION, #_SESSION_SI, #_SESSION_SINON et #_SESSION_FIN !!
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 du cache SPIP lorsqu’il est inadapté.

Le fait que ces balises sont 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 _.

Il en va de même pour les balises #_AUTORISER_SI et compagnie qu’on verra plus loin.

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.

Le plugin fournit quelques filtres particulièrement adaptés pour un usage avec #_SESSION ou #_SESSION_SI.

C’est ainsi que #_SESSION{id_auteur,?,oui,non} renverra ’oui’ si le visiteur est identifié, et ’non’ si le visiteur n’est pas connecté.

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 qui introduit l’alternative : <?php } else { ?>

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

Exemple

À la place de

<?php 
if (
    isset($GLOBALS['visiteur_session']['nom']) 
    AND $GLOBALS['visiteur_session']['nom'] 
) { ?>
<h3>Bonjour <?php echo $GLOBALS['visiteur_session']['nom']; ?></h3>
<?php 
} else { 
?>
<h3>Voulez vous vous connecter ?</h3>
<?php 
}; 
?>

on écrira :

#_SESSION_SI{nom}
  <h3>Bonjour #_SESSION{nom}</h3>
#_SESSION_SINON
   <h3>Voulez vous vous connecter ?</h3>
#_SESSION_FIN

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

#_SESSION_SI{id_auteur,aime,l'art} sera vérifié si l’internaute connecté aime l’art.

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.

Attention aux arguments calculés

Le fait que ces balises sont des macros restreint la syntaxe acceptable pour l’argument de comparaison ou de filtre de #_SESSION.

Cet argument ne peut être que

  • une constante ;
    Exemple : #_SESSSION_SI{nom,==,Linda}....#_SESSION_FIN
  • une balise simple, tirant sa valeur soit de la boucle immédiatement englobante, soit de l’environnement plus large.
    Exemple : #_SESSION_SI{id_auteur,==,#ID_AUTEUR}....#_SESSION_FIN
    Dans ce cas, un champ de boucle ne doit pas disposer d’un traitement SPIP pour être acceptable ou sinon il faut l’enlever avec l’étoile : #TITRE*.
  • un #GET :
    Exemple : #_SESSION_SI{statut,==,#GET{statutvoulu}}...#_SESSION_FIN

Pour des calculs plus complexes (usage de filtres, etc) il reste possible de faire un #SET préalable avec le résultat du calcul, et utiliser #GET.

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

<h4>Emboitements</h4>
#_SESSION_SI
   Vous êtes connecté
   #_SESSION_SI{nom}
	et vous avez un nom.
	#_SESSION_SI{nom,==,Linda}
		Je vous reconnais, c'est vous : Linda !
	#_SESSION_SINON
		Vous n'êtes pas Linda. Votre nom est #_SESSION{nom}.
	#_SESSION_FIN
  #_SESSION_SINON
	Vous n'avez pas de nom ?!
  #_SESSION_FIN
#_SESSION_SINON
   Vous n'êtes pas connecté... 
#_SESSION_FIN

Étendre les données de session

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.

Le pipeline session_get

Ce pipeline reçoit un tableau avec 2 entrées :
-  champ contient le nom du champ recherché,
-  visiteur_session contient la session en cours d’élaboration (array php), 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 PHP 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é.
Rq : Cette fonction peut en fait également ajouter d’autres champs ou modifier les valeurs reçues.

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 :

function majuscule_session_get($session) {
  if ($session['champ'] == 'nom_majuscule') {
     $session['visiteur_session']['nom_majuscule'] = mb_strtoupper($visiteur_session['nom']);
  }
  return $session;
};

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
Le fonctionnement du noyau de spip n’est pas modifié car ce pipeline n’est utilisé que pour les balises #_SESSION et #_SESSION_SI, et non par la fonction php session_get ou par la balise #SESSION du noyau spip.

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 de la manière habituelle, de même que les parties conditionnelles avant ou après. En effet, avec ces balises, les filtres appliqués avec la syntaxe classique de SPIP ne s’appliquent pas au résultat de l’exécution du filtre, mais au source du code php généré par la macro (et qui appelle le filtre), 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 reste intéressant d’encapsuler la balise macro dans un crochet-parenthèse lorsqu’on veut garantir des espaces après ou avant l’appel à #_SESSION. Car sans les crochets-parenthèses, l’espace après serait « mangé » par la balise, comme d’ordinaire.
Par exemple : Votre nom est [ (#_SESSIONnom) ] mais quel est votre prénom.

L’opportunité de ce type d’usage reste toutefois exceptionnel et très circonstancié, puisque une balise macro ne renvoie jamais une chaine vide, et que normalement, on ne veut pas appeler les filtres sur le source php mais sur le résultat de son exécution.

C’est pour pallier à cette contrainte qu’est proposé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.

Horribles effets de bords si mal utilisé !

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

La partie de HTML masquée par un #_SESSION_SI ou un #_AUTORISER_SIn’est pas affichée mais elle est tout de même compilée par SPIP, et donc les #SET et #GET et tous les morceaux de squelettes sont « calculés » (ou « exécutés ») par SPIP, même s’ils figurent dans des zones non affichées à cause d’un #_SESSION_SI ou d’un #_AUTORISER_SI.

Il y a donc un risque d’effets indésirables 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é.

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

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, 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. Ou plus simplement, n’utilisez PAS de #SET (ou d’autres balises ou filtres ayant des effets de bord) dans les parties conditionnées par ces macros.

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.

Limites conceptuelles

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

En conséquence, la boucle suivante ne peut PAS être dé-sessionnée en tant que boucle :

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

Néanmoins, on peut dé-sessionner le squelette avec :

<BOUCLE_auteur(AUTEURS){id_article}>
   #_SESSION_SI{id_auteur,==,#ID_AUTEUR}
       <INCLURE{fond=encart_auteur}> 
   #_SESSION_FIN
</BOUCLE_auteur>

Le critère, au lieu de s’appliquer via SQL et d’être mis en cache, s’applique alors en PHP... à tous les auteurs. L’intérêt à faire ainsi dépend donc du contexte.

Balises #URL_ACTION_AUTEUR et #BOUTON_ACTION_AUTEUR

Les balises #URL_ACTION_AUTEUR sessionnent le cache du squelette qui les inclue. Pour minimiser cet effet, le plugin macrosession met à disposition un mini-squelette inclure/url_action_auteur contenant uniquement un appel à cette balise, et qu’il sera possible d’appeler dynamiquement en lui passant les arguments désirés : action, arg et redirect. Cette balise est souvent employée avec #BOUTON_ACTION, aussi, une autre inclusion inclure/bouton_action_auteur est fournie pour faciliter les inclusions dynamiques. Cette inclusion requière les arguments libelle, action, arg, redirect, class, confirm

Par exemple, au lieu d’écrire :

[(#BOUTON_ACTION{
  <:medias:bouton_enlever_supprimer_document:>,
  #URL_ACTION_AUTEUR{dissocier_document,#ID_OBJET-#OBJET-#ID_DOCUMENT-suppr-safe,#SELF},
  ajax,
  <:medias:bouton_enlever_supprimer_document_confirmation:>
})]

on pourra écrire :

<INCLURE{fond=inclure/bouton_action_auteur,
  libelle=<:medias:bouton_enlever_supprimer_document:>,
  action=dissocier_document,
  arg=#ID_OBJET-#OBJET-#ID_DOCUMENT-suppr-safe,
  redirect=#SELF,
  class=ajax,
  confirm=<:medias:bouton_enlever_supprimer_document_confirmation:>
}>

Ainsi, les squelettes principaux ne sont plus sessionnés, seules les mini-squelettes spécifiquement dédiées au calcul des boutons le sont.

Balises #_AUTORISER_SI et compagnie

Outre les balises #SESSION et #URL_ACTION_AUTEUR , il y a aussi les balises #AUTORISER qui générent des caches sessionnés, 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

#_AUTORISER_SI{ecrire, article, 2}
  - Modifier l'article
  #_AUTORISER_SI{webmestre}
     - Accèder à l'administration
  #_AUTORISER_FIN
#_AUTORISER_SINON
  - Vous ne pouvez pas modifier cet article
#_AUTORISER_FIN

Particularités

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 aviez besoin pour un besoin spécifique, vous devriez 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 (en plus de ceux issus 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

Avec les autorisations, 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.

De même qu’avec les #_SESSION, la syntaxe acceptable pour le 3e argument de #_AUTORISER_SI est restreinte.

Le webmestre dispose de 5 possibilités pour passer une valeur calculée pour l’identifiant :

  • #BALISE et #GET{variable} comme pour #_SESSION. De même, un champ de boucle ne doit pas disposer d’un ’traitement’ SPIP pour être acceptable, ce qui est généralement le cas pour les identifiants utilisés par les autorisations puisque ce sont le plus souvent des identifiants numériques.

Exemples :
-  #_AUTORISER{modifier,article,#GET{alaune}}
-  #_AUTORISER{modifier,article,#ID_ARTICLE}

  • les motclés env , url et boucle .
    Dans ces cas, l’identifiant utilisé est directement déduit du type (passé en 2e argument). Pour un objet ’article’, c’est ’id_article’, pour ’document’, c’est ’id_document’, etc. Rq : Le plugin ne gère pas les exceptions telles que ’id_gis’ pour un objet ’gis’.

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 l’autorisation en utilisant la valeur de id_article issue de l’url.

Stratégie d’emploi

Dans un fichier squelette, il suffit qu’il y ait une seule balise #SESSION ou #AUTORISER pour que les caches issus de ce fichier squelette soient sessionnés. Il est alors inutile voire contre-productif d’utiliser une macro #_SESSION ou #_AUTORISER, sauf dans 2 cas :
-  pour faire appel aux fonctions d’extensions de la session, genre via une api...
-  OU, évidemment, pour remplacer cette balise et transformer le cache sessionné en un cache non sessionné.

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

  • 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).
  • vérifier ensuite que le squelette n’est plus sessionné (par exemple au moyen des fonctionnalités supplémentaires de la balise #CACHE fournie par cachelab, ou par la navigation dans les caches APCu avec xray).

Tous les squelettes ne se prêtent donc pas aussi bien à cette stratégie.

Mise au point et debuging

Découverte et tests
Le plugin embarque dans le dossier macrotests plusieurs squelettes de tests qui permettent de voir comment l’utiliser. On les appelle via page=macrotests. Une option permet d’activer le recalcul et l’affichage d’informations techniques pour la mise au point du code.
Note : Ces tests utilisent l’échappement des # : \# qui n’est disponible qu’à partir de SPIP3. Ils produiront de mauvais affichages avec SPIP2.

Plugin CacheLab

Le plugin CacheLab ajoute à SPIP des fonctionnalités fort utiles pour la mise au point de votre site avec Macrosession. Concernant l’aide à l’usage de macrosession, CacheLab propose notamment :
-  une balise #CACHE étendue qui vous donnera des informations sur les caches et leur sessionnement, et vous permettra de vérifier dans l’instant ou la durée si le cache se comporte bien de la manière voulue. Par exemple, dans un squelette dont on s’est assuré qu’il était non sessionné, on peut écrire : #CACHE{session assert non}
-  de disposer d’un argument d’url var_cache affichant des infos sur les caches de toutes les inclusions dynamiques de la page.

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.

Annexes


-  Compléments d’infos et notes sur les développements en cours
-  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. Et le premier jet de code d’une macro a bénéficié de l’aide de marcimat.

Discussion

9 discussions

  • 2

    Bonjour,
    Plugin très utile ma satisfaisant bien mais je butte sur quelque chose :
    J’utilise un champ extra permettent aux visiteurs identifiés de cocher une de trois propositions en boutons radios en utilisant

     #EDIT{monchampextra}

    Mais les réponses données par chacun des visiteurs ne sont pas conservées dans la session et c’est la dernière qui s’inscrit, celle du visiteur précédent.

    <BOUCLE_principale(SEANCES){id_seance}>
    ............................................
    [(#LISTER_VALEURS{monchampextra}|oui) <div class="#EDIT{monchampextra} ">#LISTER_VALEURS{monchampextra}</div>
           ]
    [(#LISTER_VALEURS{monchampextra}|non)   <div class="#EDIT{monchampextra}">texte</div> 
    ]
    #SESSION{truc,#LISTER_VALEURS{monchampextra}}
    #_SESSION{truc,monchampextra}
    ..................
    </BOUCLE_principale
    #_SESSION{truc,monchampextra}

    me donne le résultat, mais, il n’est pas conservé dans la session.
    Ai-je le bon outil ? Quelque chose manque-t-il dans mon développement ?

    Merci pour une piste de travail.

    • Bonjour,

      Tu ne précises pas « quand » la valeur n’est pas conservée, ce serait bien de savoir. Mais en tout cas #_SESSION ne modifie rien à la session et n’est pas chargé d’enregistrer quoi que ce soit, donc je ne pense pas que macrosession soit concerné. C’est plutôt ton formulaire le fautif ou ton usage des extras ou des crayons.

      Pour l’instant ma piste de travail sera donc : essaie de préciser et de simplifier ton squelette de dev et de mise au point. Enlève tout ce qui n’est pas nécessaire pour manifester le problème. As tu besoin de LISTER_VALEURS ? Essaie aussi, pour simplifier, de ne pas utiliser de plugins dans ce squelette. As tu besoin des crayons pour ton squelette ? En as tu besoin pour manifester le problème ?
      Souvent la simplification permet de découvrir des choses et parfois de régler le problème. Et en tout cas de mieux le communiquer. Reviens ensuite demander à l’endroit le plus adapté : discuter.spip.net ou le forum du plugin le plus concerné.

      À part ça, il suffit qu’il y ait une seule balise #SESSION ou #AUTORISER dans un fichier squelette pour que les caches issues de ce fichier squelette soient sessionnés, et il est alors inutile d’utiliser #_SESSION (sauf si tu fais appel aux fonctions d’extensions de la session, genre via une api) voire contreproductif puisque tu combines alors l’absence de cache (à cause du sessionnement) avec le recours à PHP (à cause des macros).

    • Merci à toi pour cette prompte réponse et pour les pistes.
      Je vais m’y prendre autrement.

    Répondre à ce message

  • 1

    Merci pour ce plugin très utile, et que j’utilise maintenant régulièrement.

    Répondre à ce message

  • Ajouté une précision :

    Il reste intéressant d’encapsuler la balise macro dans un crochet-parenthèse lorsqu’on veut garantir des espaces après ou avant l’appel à #_SESSION. Car sans les crochets-parenthèses, l’espace après serait « mangé » par la balise, comme d’ordinaire.
    Par exemple : Votre nom est [ (#_SESSIONnom) ] mais quel est votre prénom.

    L’opportunité de ce type d’usage reste toutefois exceptionnel et très circonstancié, puisque une balise macro ne renvoie jamais une chaine vide, et que normalement, on ne veut pas appeler les filtres sur le source php mais sur le résultat de son exécution.

    C’est pour pallier à cette contrainte qu’est proposé l’alternative...

    Répondre à ce message

  • Nouveau ! Dans la V0.13 une nouvelle inclusion inclure/bouton_action_auteur fait son apparition pour faciliter le dé-sessionnement des squelettes utilisant #BOUTON_ACTION avec #URL_ACTION_AUTEUR. La doc est actualisée.

    Répondre à ce message

  • 8

    Salut,

    merci pour ce plugin qui m’a grandement facilité la tache pour gérer l’ajout d’article depuis le public en gérant finement les droits.

    Mais j’ai un souci : dès que j’active le cache j’ai une fatal error à la 2de visite de la page.

    Fatal error: Uncaught Error: Call to undefined function autoriser() in D:\XXXXX\ecrire\public\evaluer_page.php(51) : eval()'d code:7 Stack trace: #0 D:\XXXXX\ecrire\public\evaluer_page.php(51): eval() #1 D:\XXXXX\ecrire\public\assembler.php(608): include('D:\\cousumain\\we...') #2 D:\XXXXX\ecrire\inc\utils.php(3224): evaluer_fond('content/ajouter...', Array, NULL) #3 D:\XXXXX\ecrire\public\evaluer_page.php(51) : eval()'d code(74): recuperer_fond('content/ajouter...', Array, Array, NULL) #4 D:\XXXXX\ecrire\public\evaluer_page.php(51): eval() #5 D:\XXXXX\ecrire\public\assembler.php(608): include('D:\\cousumain\\we...') #6 D:\XXXXX\ecrire\inc\utils.php(3224): evaluer_fond('body', Array, NULL) #7 D:\XXXXX\ecrire\public\evaluer_page.php(51) : eval()'d code(55): recuperer_fond('body', Array, Array, NULL) #8 D:\XXXXX\ecrir in D:\XXXXX\ecrire\public\evaluer_page.php(51) : eval()'d code on line 7

    Si je vide le cache ou que je recalcule la page, ça s’affiche bien à nouveau.

    Une piste d’où ça pourrait provenir ?

    • Il manque un include_spip (’inc/autoriser’) ; quelque part.
      Tu as raccourci le message d’erreur ? Le squelette qui pose pb semble être content/ajouter...
      Tu as quoi dans ce squelette ?

    • J’ai juste enlevé l’arborescence de D :\XXXXX\ecrire, c’est tout, et j’ai effectivement un squelette content/ajouter-evenement.html (avec Zpip V2) qui est la page appelée.

      Où faut-il ajouter include_spip (’inc/autoriser’) ; ?

    • J’ai ajouté inclure_spip(’inc/autoriser’) dans la nouvelle version du plugin (z113626) et ça devrait régler ce problème.

    • Salut,

      merci pour la rapidité et l’efficacité du SAD, l’erreur fatale a disparu...

      Par contre, je n’avais fait pas gaffe, mais est-ce que c’est normal que le fonctionnement de #SESSION soit modifié ?
      Sans identification, #SESSION renvoie systématiquement a:0 :{} au lieu de ne rien renvoyer...

    • macrosession ne touche pas à #SESSION. Pour en avoir le coeur net, ré-essaie aprés avoir désactivé macrosession pour voir si ça change qqchose.

    • Oui, c’est ce que j’ai fait et #SESSION ne renvoie rien sans macrosession.

    • Ya pas de raison. C’est dans quel contexte que tu t’en sers ?
      Si tu trouves pas, utilise [(#SESSION{id_auteur}|oui) ...] à la place, ou #_SESSION_SI

    • Oui, je teste le statut finalement, c’est mieux pour mon utilisation.

    Répondre à ce message

  • version 0.11 : la balise #_SESSION accepte maintenant un 3e argument calculé, qui peut être un #GET, une #BALISE dont la valeur est issue de l’environnement ou un #CHAMP sans ’traitement’ de la table de la boucle englobante.

    Répondre à ce message

  • Nouveau : sessionnement par la balise #URL_ACTION_AUTEUR

    Les balises #URL_ACTION_AUTEUR sessionnent le cache du squelette qui les inclue. Pour minimiser cet effet, le plugin macrossession met désormais à disposition un mini-squelette contenant uniquement un appel à cette balise. Il suffit d’inclure dynamiquement cette noisette en lui passant les arguments désirés : action, arg et url. Voir doc plus haut.

    Répondre à ce message

  • 7

    Salut,

    j’essaie

    #_SESSION_SI{id_auteur,!=,#ID_AUTEUR}
    [<h2><:ressourcotheque:contacter:></h2>
    (#FORMULAIRE_ECRIRE_AUTEUR)
    ]
    #_SESSION_FIN

    et j’obtiens

    ( ! ) ParseError: syntax error, unexpected '') { ?'' (T_CONSTANT_ENCAPSED_STRING) in /home/mrouquet/Sites/ressources.test/ecrire/public/composer.php(92) : eval()'d code on line 82

    une idée ?

    • my bad, tu explique.

      Cela autant, quel serait la solution optimale ?

    • En effet « on ne peut passer que des constantes en argument de comparaison de #_SESSION ». (J’en ai pour l’instant jamais eu besoin donc je n’ai pas étendu les possibilités comme je l’ai fait avec #_AUTORISER... mais visiblement ce serait bien de le faire !)

      La doc dit aussi « 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. ».

      Là tu dois pouvoir t’en sortir avec un filtre "cestpassapage"... que le plugin ou la doc pourrait fournir comme exemple.

    • ok
      un truc du style

      <?php
      
      function page_auteur_connecter($id_auteur){
        return $id_auteur == $session['id_auteur'];
      }

       ? ca marcherait en terme de cache ?

    • Oui je pense.

    • Ah non mais pas comme dans ton commit car comme ça, le résultat est figé dans le cache comme « normalement » avec SPIP !

      Je te suggérais bien d’utiliser un tel filtre, mais en argument de #_SESSION (voir doc plus haut : « #_SESSION_SI avec filtres », pour que ça soit appelé de manière dynamique à chaque besoin de la page :

      #_SESSION_SI{id_auteur,auteur_est_connecte}
         ...
      #_SESSION_FIN
    • C’est bien ce qu’il me semblait qu’il y avait un truc qui clochait...

      mais... mais comment je fais pour tester le #ID_AUTEUR courant, avec ce filtre ?

    • Non finalement c’est pas possible tant que #_SESSION n’accepte que des arguments constantes.
      Tu dois utiliser une boucle sessionnante

      (AUTEURS){id_auteur!=#SESSION{id_auteur}}

      J’aimerais étendre #_SESSION comme #_AUTORISER... un jour.

      [Edit] : Voilà c’est fait dans la version 0.11

    Répondre à ce message

  • Nouveau : J’ai complété la doc de #_AUTORISER, avec les nouvelles possibilités de tester l’autorisation au regard des valeurs d’environnement ou calculées.

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

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

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom