X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=www%2Fecrire%2Fpublic%2Fbalises.php;h=61dec244f1e17aabae705e13a81d115470ad2733;hb=4f443dce95ff6f8221c189880a70c74ce1c1f238;hp=a7c63e63debbc3967070190fb374aa73c5d08044;hpb=4a628e9b277d3617535f99d663ca79fa2e891177;p=lhc%2Fweb%2Fwww.git diff --git a/www/ecrire/public/balises.php b/www/ecrire/public/balises.php index a7c63e63..61dec244 100644 --- a/www/ecrire/public/balises.php +++ b/www/ecrire/public/balises.php @@ -3,361 +3,857 @@ /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * - * Copyright (c) 2001-2016 * + * Copyright (c) 2001-2017 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * \***************************************************************************/ -// Ce fichier regroupe la quasi totalite des definitions de #BALISES de spip -// Pour chaque balise, il est possible de surcharger, dans mes_fonctions, -// la fonction balise_TOTO_dist par une fonction balise_TOTO() respectant la -// meme API : -// elle recoit en entree un objet de classe CHAMP, le modifie et le retourne. -// Cette classe est definie dans public/interfaces +/** + * Ce fichier regroupe la quasi totalité des définitions de `#BALISES` de SPIP. + * + * Pour chaque balise, il est possible de surcharger, dans son fichier + * mes_fonctions.php, la fonction `balise_TOTO_dist()` par une fonction + * `balise_TOTO()` respectant la même API : elle reçoit en entrée un objet + * de classe `Champ`, le modifie et le retourne. Cette classe est définie + * dans public/interfaces. + * + * Des balises dites «dynamiques» sont également déclarées dans le + * répertoire ecrire/balise/ + * + * @package SPIP\Core\Compilateur\Balises + **/ -if (!defined('_ECRIRE_INC_VERSION')) return; +if (!defined('_ECRIRE_INC_VERSION')) { + return; +} -// http://doc.spip.org/@interprete_argument_balise -function interprete_argument_balise($n,$p) { - if (($p->param) && (!$p->param[0][0]) && (count($p->param[0])>$n)) +/** + * Retourne le code PHP d'un argument de balise s'il est présent + * + * @uses calculer_liste() + * @example + * ``` + * // Retourne le premier argument de la balise + * // #BALISE{premier,deuxieme} + * $arg = interprete_argument_balise(1,$p); + * ``` + * + * @param int $n + * Numéro de l'argument + * @param Champ $p + * Pile au niveau de la balise + * @return string|null + * Code PHP si cet argument est présent, sinon null + **/ +function interprete_argument_balise($n, $p) { + if (($p->param) && (!$p->param[0][0]) && (count($p->param[0]) > $n)) { return calculer_liste($p->param[0][$n], $p->descr, $p->boucles, $p->id_boucle); - else - return NULL; + } else { + return null; + } } + + // -// Definition des balises +// Définition des balises // -// http://doc.spip.org/@balise_NOM_SITE_SPIP_dist + +/** + * Compile la balise `#NOM_SITE_SPIP` retournant le nom du site + * + * @balise + * @link http://www.spip.net/4622 + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_NOM_SITE_SPIP_dist($p) { $p->code = "\$GLOBALS['meta']['nom_site']"; + #$p->interdire_scripts = true; return $p; } -// http://doc.spip.org/@balise_EMAIL_WEBMASTER_dist +/** + * Compile la balise `#EMAIL_WEBMASTER` retournant l'adresse courriel + * du webmestre + * + * @balise + * @link http://www.spip.net/4586 + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_EMAIL_WEBMASTER_dist($p) { $p->code = "\$GLOBALS['meta']['email_webmaster']"; + #$p->interdire_scripts = true; return $p; } -// http://doc.spip.org/@balise_DESCRIPTIF_SITE_SPIP_dist +/** + * Compile la balise `#DESCRIPTIF_SITE_SPIP` qui retourne le descriptif + * du site ! + * + * @balise + * @link http://www.spip.net/4338 + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_DESCRIPTIF_SITE_SPIP_dist($p) { $p->code = "\$GLOBALS['meta']['descriptif_site']"; + #$p->interdire_scripts = true; return $p; } -// http://doc.spip.org/@balise_CHARSET_dist + +/** + * Compile la balise `#CHARSET` qui retourne le nom du jeu de caractères + * utilisé par le site tel que `utf-8` + * + * @balise + * @link http://www.spip.net/4331 + * @example + * ``` + * + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_CHARSET_dist($p) { $p->code = "\$GLOBALS['meta']['charset']"; + #$p->interdire_scripts = true; return $p; } -// http://doc.spip.org/@balise_LANG_LEFT_dist +/** + * Compile la balise `#LANG_LEFT` retournant 'left' si la langue s'écrit + * de gauche à droite, sinon 'right' + * + * @note + * Peut servir à l'écriture de code CSS dans un squelette, mais + * pour inclure un fichier css, il vaut mieux utiliser le filtre + * `direction_css` si on le souhaite sensible à la langue utilisé. + * + * @balise + * @link http://www.spip.net/4625 + * @see lang_dir() + * @see balise_LANG_RIGHT_dist() + * @see balise_LANG_DIR_dist() + * @see direction_css() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_LANG_LEFT_dist($p) { $_lang = champ_sql('lang', $p); $p->code = "lang_dir($_lang, 'left','right')"; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_LANG_RIGHT_dist +/** + * Compile la balise `#LANG_RIGHT` retournant 'right' si la langue s'écrit + * de gauche à droite, sinon 'left' + * + * @balise + * @link http://www.spip.net/4625 + * @see lang_dir() + * @see balise_LANG_LEFT_dist() + * @see balise_LANG_DIR_dist() + * @see direction_css() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_LANG_RIGHT_dist($p) { $_lang = champ_sql('lang', $p); $p->code = "lang_dir($_lang, 'right','left')"; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_LANG_DIR_dist +/** + * Compile la balise `#LANG_DIR` retournant 'ltr' si la langue s'écrit + * de gauche à droite, sinon 'rtl' + * + * @balise + * @link http://www.spip.net/4625 + * @see lang_dir() + * @see balise_LANG_LEFT_dist() + * @see balise_LANG_RIGHT_dist() + * @example + * ``` + * + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_LANG_DIR_dist($p) { $_lang = champ_sql('lang', $p); $p->code = "lang_dir($_lang, 'ltr','rtl')"; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_PUCE_dist + +/** + * Compile la balise `#PUCE` affichant une puce + * + * @balise + * @link http://www.spip.net/4628 + * @see definir_puce() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_PUCE_dist($p) { $p->code = "definir_puce()"; $p->interdire_scripts = false; + return $p; } -// #DATE -// Cette fonction sait aller chercher dans le contexte general -// quand #DATE est en dehors des boucles -// http://www.spip.net/fr_article1971.html -// http://doc.spip.org/@balise_DATE_dist -function balise_DATE_dist ($p) { + +/** + * Compile la balise `#DATE` qui retourne la date de mise en ligne + * + * Cette balise retourne soit le champ `date` d'une table si elle est + * utilisée dans une boucle, sinon la date de calcul du squelette. + * + * @balise + * @link http://www.spip.net/4336 Balise DATE + * @link http://www.spip.net/1971 La gestion des dates + * @example + * ``` + * [(#DATE|affdate_jourcourt)] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ +function balise_DATE_dist($p) { $d = champ_sql('date', $p); # if ($d === "@\$Pile[0]['date']") # $d = "isset(\$Pile[0]['date']) ? $d : time()"; $p->code = $d; + return $p; } -// #DATE_REDAC -// http://www.spip.net/fr_article1971.html -// http://doc.spip.org/@balise_DATE_REDAC_dist -function balise_DATE_REDAC_dist ($p) { + +/** + * Compile la balise `#DATE_REDAC` qui retourne la date de première publication + * + * Cette balise retourne le champ `date_redac` d'une table + * + * @balise + * @link http://www.spip.net/3858 Balises DATE_MODIF et DATE_REDAC + * @link http://www.spip.net/1971 La gestion des dates + * @see balise_DATE_MODIF_dist() + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ +function balise_DATE_REDAC_dist($p) { $d = champ_sql('date_redac', $p); # if ($d === "@\$Pile[0]['date_redac']") # $d = "isset(\$Pile[0]['date_redac']) ? $d : time()"; $p->code = $d; $p->interdire_scripts = false; + return $p; } -// #DATE_MODIF -// http://www.spip.net/fr_article1971.html -// http://doc.spip.org/@balise_DATE_MODIF_dist -function balise_DATE_MODIF_dist ($p) { +/** + * Compile la balise `#DATE_MODIF` qui retourne la date de dernière modification + * + * Cette balise retourne le champ `date_modif` d'une table + * + * @balise + * @link http://www.spip.net/3858 Balises DATE_MODIF et DATE_REDAC + * @link http://www.spip.net/1971 La gestion des dates + * @see balise_DATE_REDAC_dist() + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ +function balise_DATE_MODIF_dist($p) { $p->code = champ_sql('date_modif', $p); $p->interdire_scripts = false; + return $p; } -// #DATE_NOUVEAUTES -// http://www.spip.net/fr_article1971.html -// http://doc.spip.org/@balise_DATE_NOUVEAUTES_dist +/** + * Compile la balise `#DATE_NOUVEAUTES` indiquant la date de dernier envoi + * du mail de nouveautés + * + * @balise + * @link http://www.spip.net/4337 Balise DATE_NOUVEAUTES + * @link http://www.spip.net/1971 La gestion des dates + * @see balise_DATE_REDAC_dist() + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ function balise_DATE_NOUVEAUTES_dist($p) { $p->code = "((\$GLOBALS['meta']['quoi_de_neuf'] == 'oui' AND isset(\$GLOBALS['meta']['dernier_envoi_neuf'])) ? \$GLOBALS['meta']['dernier_envoi_neuf'] : \"'0000-00-00'\")"; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_DOSSIER_SQUELETTE_dist + +/** + * Compile la balise `#DOSSIER_SQUELETTE` retournant le chemin vers le + * répertoire de squelettes actuellement utilisé + * + * @balise + * @deprecated Utiliser `#CHEMIN` + * @link http://www.spip.net/4627 + * @see balise_CHEMIN_dist() + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ function balise_DOSSIER_SQUELETTE_dist($p) { $code = substr(addslashes(dirname($p->descr['sourcefile'])), strlen(_DIR_RACINE)); $p->code = "_DIR_RACINE . '$code'" . - $p->interdire_scripts = false; + $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_SQUELETTE_dist +/** + * Compile la balise `#SQUELETTE` retournant le chemin du squelette courant + * + * @balise + * @link http://www.spip.net/4027 + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ function balise_SQUELETTE_dist($p) { $code = addslashes($p->descr['sourcefile']); $p->code = "'$code'" . - $p->interdire_scripts = false; + $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_SPIP_VERSION_dist +/** + * Compile la balise `#SPIP_VERSION` qui affiche la version de SPIP + * + * @balise + * @see spip_version() + * @example + * ``` + * + * ``` + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ function balise_SPIP_VERSION_dist($p) { $p->code = "spip_version()"; $p->interdire_scripts = false; + return $p; } - /** - * Affiche le nom du site. + * Compile la balise `#NOM_SITE` qui affiche le nom du site. * * Affiche le nom du site ou sinon l'URL ou le titre de l'objet - * Utiliser #NOM_SITE* pour avoir le nom du site ou rien. + * Utiliser `#NOM_SITE*` pour avoir le nom du site ou rien. * - * Cette balise interroge les colonnes 'nom_site' ou 'url_site' + * Cette balise interroge les colonnes `nom_site` ou `url_site` * dans la boucle la plus proche. * + * @balise + * @see calculer_url() * @example - * - * #NOM_SITE - * + * ``` + * #NOM_SITE + * ``` * * @param Champ $p - * Pile au niveau de la balise + * Pile au niveau de la balise * @return Champ - * Pile complétée par le code à générer -**/ + * Pile complétée par le code à générer + **/ function balise_NOM_SITE_dist($p) { if (!$p->etoile) { $p->code = "supprimer_numero(calculer_url(" . - champ_sql('url_site',$p) ."," . - champ_sql('nom_site',$p) . - ", 'titre', \$connect, false))"; - } else - $p->code = champ_sql('nom_site',$p); + champ_sql('url_site', $p) . "," . + champ_sql('nom_site', $p) . + ", 'titre', \$connect, false))"; + } else { + $p->code = champ_sql('nom_site', $p); + } $p->interdire_scripts = true; + return $p; } -// http://doc.spip.org/@balise_NOTES_dist + +/** + * Compile la balise `#NOTE` qui affiche les notes de bas de page + * + * @balise + * @link http://www.spip.net/3964 + * @see calculer_notes() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_NOTES_dist($p) { // Recuperer les notes $p->code = 'calculer_notes()'; + #$p->interdire_scripts = true; return $p; } -// http://doc.spip.org/@balise_RECHERCHE_dist + +/** + * Compile la balise `#RECHERCHE` qui retourne le terme de recherche demandé + * + * Retourne un terme demandé en recherche, en le prenant dans _request() + * sous la clé `recherche`. + * + * @balise + * @example + * ``` + *

Recherche de : #RECHERCHE

+ * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_RECHERCHE_dist($p) { $p->code = 'entites_html(_request("recherche"))'; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_COMPTEUR_BOUCLE_dist + +/** + * Compile la balise `#COMPTEUR_BOUCLE` qui retourne le numéro de l’itération + * actuelle de la boucle + * + * @balise + * @link http://www.spip.net/4333 + * @see balise_TOTAL_BOUCLE_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_COMPTEUR_BOUCLE_dist($p) { $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere']; if ($b === '') { - $msg = array('zbug_champ_hors_boucle', - array('champ' => '#COMPTEUR_BOUCLE') - ); + $msg = array( + 'zbug_champ_hors_boucle', + array('champ' => '#COMPTEUR_BOUCLE') + ); erreur_squelette($msg, $p); } else { $p->code = "\$Numrows['$b']['compteur_boucle']"; $p->boucles[$b]->cptrows = true; $p->interdire_scripts = false; + return $p; } } -// http://doc.spip.org/@balise_TOTAL_BOUCLE_dist +/** + * Compile la balise `#TOTAL_BOUCLE` qui retourne le nombre de résultats + * affichés par la boucle + * + * @balise + * @link http://www.spip.net/4334 + * @see balise_COMPTEUR_BOUCLE_dist() + * @see balise_GRAND_TOTAL_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_TOTAL_BOUCLE_dist($p) { $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere']; if ($b === '' || !isset($p->boucles[$b])) { - $msg = array('zbug_champ_hors_boucle', - array('champ' => "#$b" . 'TOTAL_BOUCLE') - ); + $msg = array( + 'zbug_champ_hors_boucle', + array('champ' => "#$b" . 'TOTAL_BOUCLE') + ); erreur_squelette($msg, $p); } else { $p->code = "\$Numrows['$b']['total']"; $p->boucles[$b]->numrows = true; $p->interdire_scripts = false; } + return $p; } -// Si on est hors d'une boucle {recherche}, ne pas "prendre" cette balise -// http://doc.spip.org/@balise_POINTS_dist + +/** + * Compile la balise `#POINTS` qui affiche la pertinence des résultats + * + * Retourne le calcul `points` réalisé par le critère `recherche`. + * Cette balise nécessite donc la présence de ce critère. + * + * @balise + * @link http://www.spip.net/903 Boucles et balises de recherche + * @see critere_recherche_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_POINTS_dist($p) { return rindex_pile($p, 'points', 'recherche'); } -// http://doc.spip.org/@balise_POPULARITE_ABSOLUE_dist + +/** + * Compile la balise `#POPULARITE_ABSOLUE` qui affiche la popularité absolue + * + * Cela correspond à la popularité quotidienne de l'article + * + * @balise + * @link http://www.spip.net/1846 La popularité + * @see balise_POPULARITE_dist() + * @see balise_POPULARITE_MAX_dist() + * @see balise_POPULARITE_SITE_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_POPULARITE_ABSOLUE_dist($p) { $p->code = 'ceil(' . - champ_sql('popularite', $p) . - ')'; + champ_sql('popularite', $p) . + ')'; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_POPULARITE_SITE_dist +/** + * Compile la balise `#POPULARITE_SITE` qui affiche la popularité du site + * + * La popularité du site est la somme de toutes les popularités absolues. + * + * @balise + * @link http://www.spip.net/1846 La popularité + * @see balise_POPULARITE_ABSOLUE_dist() + * @see balise_POPULARITE_dist() + * @see balise_POPULARITE_MAX_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_POPULARITE_SITE_dist($p) { $p->code = 'ceil($GLOBALS["meta"][\'popularite_total\'])'; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_POPULARITE_MAX_dist +/** + * Compile la balise `#POPULARITE_MAX` qui affiche la popularité maximum + * parmis les popularités des articles + * + * Cela correspond à la popularité quotidienne de l'article + * + * @balise + * @link http://www.spip.net/1846 La popularité + * @see balise_POPULARITE_ABSOLUE_dist() + * @see balise_POPULARITE_dist() + * @see balise_POPULARITE_SITE_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_POPULARITE_MAX_dist($p) { $p->code = 'ceil($GLOBALS["meta"][\'popularite_max\'])'; $p->interdire_scripts = false; + return $p; } -// http://doc.spip.org/@balise_EXPOSE_dist -function balise_EXPOSE_dist($p) { - $on = "'on'"; - $off= "''"; - if (($v = interprete_argument_balise(1,$p))!==NULL){ - $on = $v; - if (($v = interprete_argument_balise(2,$p))!==NULL) - $off = $v; - - } - return calculer_balise_expose($p, $on, $off); -} -// #VALEUR renvoie le champ valeur -// #VALEUR{x} renvoie #VALEUR|table_valeur{x} -// #VALEUR{a/b} renvoie #VALEUR|table_valeur{a/b} -// http://doc.spip.org/@balise_VALEUR_dist +/** + * Compile la balise `#VALEUR` retournant le champ `valeur` + * + * Utile dans une boucle DATA pour retourner une valeur. + * + * @balise + * @link http://www.spip.net/5546 #CLE et #VALEUR + * @see table_valeur() + * @example + * ``` + * #VALEUR renvoie le champ valeur + * #VALEUR{x} renvoie #VALEUR|table_valeur{x}, + * équivalent à #X (si X n'est pas une balise spécifique à SPIP) + * #VALEUR{a/b} renvoie #VALEUR|table_valeur{a/b} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_VALEUR_dist($p) { $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle; $p->code = index_pile($p->id_boucle, 'valeur', $p->boucles, $b);; - if (($v = interprete_argument_balise(1,$p))!==NULL){ - $p->code = 'table_valeur('.$p->code.', '.$v.')'; + if (($v = interprete_argument_balise(1, $p)) !== null) { + $p->code = 'table_valeur(' . $p->code . ', ' . $v . ')'; } $p->interdire_scripts = true; + return $p; } -// http://doc.spip.org/@calculer_balise_expose -function calculer_balise_expose($p, $on, $off) -{ +/** + * Compile la balise `#EXPOSE` qui met en évidence l'élément sur lequel + * la page se trouve + * + * Expose dans une boucle l'élément de la page sur laquelle on se trouve, + * en retournant `on` si l'élément correspond à la page, une chaîne vide sinon. + * + * On peut passer les paramètres à faire retourner par la balise. + * + * @example + * ``` + * + * + * + * ``` + * + * @balise + * @link http://www.spip.net/2319 Exposer un article + * @uses calculer_balise_expose() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_EXPOSE_dist($p) { + $on = "'on'"; + $off = "''"; + if (($v = interprete_argument_balise(1, $p)) !== null) { + $on = $v; + if (($v = interprete_argument_balise(2, $p)) !== null) { + $off = $v; + } + + } + + return calculer_balise_expose($p, $on, $off); +} + +/** + * Calcul de la balise expose + * + * @see calcul_exposer() + * + * @param Champ $p + * Pile au niveau de la balise + * @param string $on + * Texte à afficher si l'élément est exposé (code à écrire tel que "'on'") + * @param string $off + * Texte à afficher si l'élément n'est pas exposé (code à écrire tel que "''") + * @return Champ + * Pile complétée par le code à générer + **/ +function calculer_balise_expose($p, $on, $off) { $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle; - $key = $p->boucles[$b]->primary; - $type = $p->boucles[$p->id_boucle]->primary; - $desc = $p->boucles[$b]->show; - $connect = sql_quote($p->boucles[$b]->sql_serveur); - - if (!$key) { + if (empty($p->boucles[$b]->primary)) { $msg = array('zbug_champ_hors_boucle', array('champ' => '#EXPOSER')); erreur_squelette($msg, $p); - } + } else { - // Ne pas utiliser champ_sql, on jongle avec le nom boucle explicite - $c = index_pile($p->id_boucle, $type, $p->boucles); + $key = $p->boucles[$b]->primary; + $type = $p->boucles[$p->id_boucle]->primary; + $desc = $p->boucles[$b]->show; + $connect = sql_quote($p->boucles[$b]->sql_serveur); - if (isset($desc['field']['id_parent'])) { - $parent = 0; // pour if (!$parent) dans calculer_expose - } elseif (isset($desc['field']['id_rubrique'])) { - $parent = index_pile($p->id_boucle, 'id_rubrique', $p->boucles, $b); - } elseif (isset($desc['field']['id_groupe'])) { - $parent = index_pile($p->id_boucle, 'id_groupe', $p->boucles, $b); - } else $parent = "''"; + // Ne pas utiliser champ_sql, on jongle avec le nom boucle explicite + $c = index_pile($p->id_boucle, $type, $p->boucles); - $p->code = "(calcul_exposer($c, '$type', \$Pile[0], $parent, '$key', $connect) ? $on : $off)"; + if (isset($desc['field']['id_parent'])) { + $parent = 0; // pour if (!$parent) dans calculer_expose + } elseif (isset($desc['field']['id_rubrique'])) { + $parent = index_pile($p->id_boucle, 'id_rubrique', $p->boucles, $b); + } elseif (isset($desc['field']['id_groupe'])) { + $parent = index_pile($p->id_boucle, 'id_groupe', $p->boucles, $b); + } else { + $parent = "''"; + } + + $p->code = "(calcul_exposer($c, '$type', \$Pile[0], $parent, '$key', $connect) ? $on : $off)"; + } $p->interdire_scripts = false; + return $p; } -// Debut et fin de surlignage auto des mots de la recherche -// on insere une balise Span avec une classe sans spec: -// c'est transparent s'il n'y a pas de recherche, -// sinon elles seront remplacees par les fontions de inc_surligne - -// http://doc.spip.org/@balise_DEBUT_SURLIGNE_dist +/** + * Compile la balise `#DEBUT_SURLIGNE` qui permettait le surlignage + * des mots d'une recherche + * + * @note + * Cette balise n'a plus d'effet depuis r9343 + * + * @balise + * @see balise_FIN_SURLIGNE_dist() + * @deprecated Utiliser les classes CSS `surlignable` ou `pas_surlignable` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_DEBUT_SURLIGNE_dist($p) { include_spip('inc/surligne'); $p->code = "''"; + return $p; } -// http://doc.spip.org/@balise_FIN_SURLIGNE_dist + + +/** + * Compile la balise `#FIN_SURLIGNE` qui arrêtait le surlignage + * des mots d'une recherche + * + * @note + * Cette balise n'a plus d'effet depuis r9343 + * + * @balise + * @see balise_DEBUT_SURLIGNE_dist() + * @deprecated Utiliser les classes CSS `surlignable` ou `pas_surlignable` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_FIN_SURLIGNE_dist($p) { include_spip('inc/surligne'); $p->code = "''"; + return $p; } -// #INTRODUCTION -// #INTRODUCTION{longueur} -// http://www.spip.net/@introduction -// http://doc.spip.org/@balise_INTRODUCTION_dist +/** + * Compile la balise `#INTRODUCTION` + * + * Retourne une introduction d'un objet éditorial, c'est à dire les 600 + * premiers caractères environ du champ 'texte' de l'objet ou le contenu + * indiqué entre `` et `` de ce même champ. + * + * Pour les articles, l'introduction utilisée est celle du champ `descriptif` + * s'il est renseigné, sinon il est pris dans les champs `chapo` et `texte` et + * est par défaut limité à 500 caractères. + * + * Pour les rubriques, l'introduction utilisée est celle du champ `descriptif` + * s'il est renseigné, sinon du champ texte. + * + * La balise accèpte 1 paramètre indiquant la longueur en nombre de caractères + * de l'introduction. + * + * @see filtre_introduction_dist() + * @example + * ``` + * #INTRODUCTION + * #INTRODUCTION{300} + * ``` + * + * @balise + * @link http://www.spip.net/@introduction + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_INTRODUCTION_dist($p) { $type = $p->type_requete; $_texte = champ_sql('texte', $p); - $_descriptif = ($type == 'articles' OR $type == 'rubriques') ? champ_sql('descriptif', $p) : "''"; + $_descriptif = ($type == 'articles' or $type == 'rubriques') ? champ_sql('descriptif', $p) : "''"; if ($type == 'articles') { $_chapo = champ_sql('chapo', $p); @@ -367,25 +863,23 @@ function balise_INTRODUCTION_dist($p) { } // longueur en parametre, ou valeur par defaut - if (($v = interprete_argument_balise(1,$p))!==NULL) { - $longueur = 'intval('.$v.')'; - } else { - switch ($type) { - case 'articles': - $longueur = '500'; - break; - case 'breves': - $longueur = '300'; - break; - case 'rubriques': - default: - $longueur = '600'; - break; - } + $longueur_defaut = objet_info($type, 'introduction_longueur'); + if (!$longueur_defaut) { + $longueur_defaut = 600; + } + + $_suite = 'null'; + $_longueur = $longueur_defaut; + if (($v = interprete_argument_balise(1, $p)) !== null) { + $_longueur = 'is_numeric(' . $v . ')?intval(' . $v . '):' . $longueur_defaut; + $_suite = '!is_numeric(' . $v . ')?' . $v . ':null'; + } + if (($v2 = interprete_argument_balise(2, $p)) !== null) { + $_suite = $v2; } $f = chercher_filtre('introduction'); - $p->code = "$f($_descriptif, $_texte, $longueur, \$connect)"; + $p->code = "$f($_descriptif, $_texte, $_longueur, \$connect, $_suite)"; #$p->interdire_scripts = true; $p->etoile = '*'; // propre est deja fait dans le calcul de l'intro @@ -393,27 +887,52 @@ function balise_INTRODUCTION_dist($p) { } -// #LANG -// affiche la langue de l'objet (ou superieure), et a defaut la langue courante -// (celle du site ou celle qui a ete passee dans l'URL par le visiteur) -// #LANG* n'affiche rien si aucune langue n'est trouvee dans le sql/le contexte -// http://doc.spip.org/@balise_LANG_dist -function balise_LANG_dist ($p) { +/** + * Compile la balise `#LANG` qui affiche la langue de l'objet (ou d'une boucle supérieure), + * et à defaut la langue courante + * + * La langue courante est celle du site ou celle qui a été passée dans l'URL par le visiteur. + * L'étoile `#LANG*` n'affiche rien si aucune langue n'est trouvée dans le SQL ou le contexte. + * + * @balise + * @link http://www.spip.net/3864 + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_LANG_dist($p) { $_lang = champ_sql('lang', $p); - if (!$p->etoile) + if (!$p->etoile) { $p->code = "spip_htmlentities($_lang ? $_lang : \$GLOBALS['spip_lang'])"; - else + } else { $p->code = "spip_htmlentities($_lang)"; + } $p->interdire_scripts = false; + return $p; } -// #LESAUTEURS -// les auteurs d'un objet -// http://www.spip.net/fr_article902.html -// http://www.spip.net/fr_article911.html -// http://doc.spip.org/@balise_LESAUTEURS_dist -function balise_LESAUTEURS_dist ($p) { +/** + * Compile la balise `#LESAUTEURS` chargée d'afficher la liste des auteurs d'un objet + * + * - Soit le champ `lesauteurs` existe dans la table et à ce moment là, + * la balise retourne son contenu, + * - soit la balise appelle le modele `lesauteurs.html` en lui passant + * le couple `objet` et `id_objet` dans son environnement. + * + * @balise + * @link http://www.spip.net/3966 Description de la balise + * @link http://www.spip.net/902 Description de la boucle ARTICLES + * @link http://www.spip.net/911 Description de la boucle SYNDIC_ARTICLES + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + */ +function balise_LESAUTEURS_dist($p) { // Cherche le champ 'lesauteurs' dans la pile $_lesauteurs = champ_sql('lesauteurs', $p, false); @@ -422,16 +941,16 @@ function balise_LESAUTEURS_dist ($p) { // dans le cas contraire on prend le champ 'lesauteurs' // (cf extension sites/) if ($_lesauteurs - AND $_lesauteurs != '@$Pile[0][\'lesauteurs\']') { + and $_lesauteurs != '@$Pile[0][\'lesauteurs\']' + ) { $p->code = "safehtml($_lesauteurs)"; // $p->interdire_scripts = true; } else { - if(!$p->id_boucle){ + if (!$p->id_boucle) { $connect = ''; $objet = 'article'; $id_table_objet = 'id_article'; - } - else{ + } else { $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle; $connect = $p->boucles[$b]->sql_serveur; $type_boucle = $p->boucles[$b]->type_requete; @@ -441,13 +960,13 @@ function balise_LESAUTEURS_dist ($p) { $c = memoriser_contexte_compil($p); $p->code = sprintf(CODE_RECUPERER_FOND, "'modeles/lesauteurs'", - "array('objet'=>'".$objet. - "','id_objet' => ".champ_sql($id_table_objet, $p) . - ",'$id_table_objet' => ".champ_sql($id_table_objet, $p) . - ($objet=='article'?"":",'id_article' => ".champ_sql('id_article', $p)). - ")", - "'trim'=>true, 'compil'=>array($c)", - _q($connect)); + "array('objet'=>'" . $objet . + "','id_objet' => " . champ_sql($id_table_objet, $p) . + ",'$id_table_objet' => " . champ_sql($id_table_objet, $p) . + ($objet == 'article' ? "" : ",'id_article' => " . champ_sql('id_article', $p)) . + ")", + "'trim'=>true, 'compil'=>array($c)", + _q($connect)); $p->interdire_scripts = false; // securite apposee par recuperer_fond() } @@ -456,20 +975,26 @@ function balise_LESAUTEURS_dist ($p) { /** - * #RANG - * affiche le "numero de l'objet" quand on l'a titre '1. Premier article'; - * ceci est transitoire afin de preparer une migration vers un vrai systeme de - * tri des articles dans une rubrique (et plus si affinites) - * la balise permet d'extraire le numero masque par |supprimer_numero - * la balise recupere le champ declare dans la globale table_titre - * ou a defaut le champ 'titre' + * Compile la balise `#RANG` chargée d'afficher le numéro de l'objet + * + * Affiche le « numero de l'objet ». Soit `1` quand on a un titre `1. Premier article`. + * + * Ceci est transitoire afin de préparer une migration vers un vrai système de + * tri des articles dans une rubrique (et plus si affinités). + * La balise permet d'extraire le numero masqué par le filtre `supprimer_numero`. * - * si un champ rang existe, il est pris en priorite + * La balise recupère le champ declaré dans la définition `table_titre` + * de l'objet, ou à defaut du champ `titre` * - * http://doc.spip.org/@balise_RANG_dist + * Si un champ `rang` existe, il est pris en priorité. * - * @param object $p - * @return object + * @balise + * @link http://www.spip.net/5495 + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ function balise_RANG_dist($p) { $b = index_boucle($p); @@ -486,7 +1011,7 @@ function balise_RANG_dist($p) { $_rang = champ_sql('rang', $p, '', false); // si pas trouve de champ sql rang : - if (!$_rang) { + if (!$_rang or $_rang == "''") { $boucle = &$p->boucles[$b]; $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table($boucle->id_table); @@ -531,39 +1056,86 @@ function balise_RANG_dist($p) { } -// #POPULARITE -// http://www.spip.net/fr_article1846.html -// http://doc.spip.org/@balise_POPULARITE_dist -function balise_POPULARITE_dist ($p) { +/** + * Compile la balise `#POPULARITE` qui affiche la popularité relative. + * + * C'est à dire le pourcentage de la fréquentation de l'article + * (la popularité absolue) par rapport à la popularité maximum. + * + * @balise + * @link http://www.spip.net/1846 La popularité + * @see balise_POPULARITE_ABSOLUE_dist() + * @see balise_POPULARITE_MAX_dist() + * @see balise_POPULARITE_SITE_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_POPULARITE_dist($p) { $_popularite = champ_sql('popularite', $p); $p->code = "(ceil(min(100, 100 * $_popularite / max(1 , 0 + \$GLOBALS['meta']['popularite_max']))))"; $p->interdire_scripts = false; + return $p; } -// #PAGINATION -// Le code produit est trompeur, car les modeles ne fournissent pas Pile[0]. -// On produit un appel a _request si on ne l'a pas, mais c'est inexact: -// l'absence peut etre due a une faute de frappe dans le contexte inclus. - +/** + * Code de compilation pour la balise `#PAGINATION` + * + * Le code produit est trompeur, car les modèles ne fournissent pas Pile[0]. + * On produit un appel à `_request` si on ne l'a pas, mais c'est inexact: + * l'absence peut-être due à une faute de frappe dans le contexte inclus. + */ define('CODE_PAGINATION', - '%s($Numrows["%s"]["grand_total"], +'%s($Numrows["%s"]["grand_total"], %s, isset($Pile[0][%4$s])?$Pile[0][%4$s]:intval(_request(%4$s)), %5$s, %6$s, %7$s, %8$s, array(%9$s))'); -// http://www.spip.net/fr_article3367.html -// http://doc.spip.org/@balise_PAGINATION_dist -function balise_PAGINATION_dist($p, $liste='true') { +/** + * Compile la balise `#PAGINATION` chargée d'afficher une pagination + * + * Elle charge le modèle `pagination.html` (par défaut), mais un paramètre + * permet d'indiquer d'autres modèles. `#PAGINATION{nom}` utilisera le + * modèle `pagination_nom.html`. + * + * Cette balise nécessite le critère `pagination` sur la boucle où elle + * est utilisée. + * + * @balise + * @link http://www.spip.net/3367 Le système de pagination + * @see filtre_pagination_dist() + * @see critere_pagination_dist() + * @see balise_ANCRE_PAGINATION_dist() + * @example + * ``` + * [

(#PAGINATION{prive})

] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @param string $liste + * Afficher ou non les liens de pagination (variable de type `string` + * car code à faire écrire au compilateur) : + * - `true` pour les afficher + * - `false` pour afficher uniquement l'ancre. + * @return Champ + * Pile complétée par le code à générer + */ +function balise_PAGINATION_dist($p, $liste = 'true') { $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere']; // s'il n'y a pas de nom de boucle, on ne peut pas paginer if ($b === '') { - $msg = array('zbug_champ_hors_boucle', + $msg = array( + 'zbug_champ_hors_boucle', array('champ' => $liste ? 'PAGINATION' : 'ANCRE_PAGINATION') - ); + ); erreur_squelette($msg, $p); + return $p; } @@ -571,11 +1143,13 @@ function balise_PAGINATION_dist($p, $liste='true') { // dans un boucle recursive ou qu'on a oublie le critere {pagination} if (!$p->boucles[$b]->mode_partie) { if (!$p->boucles[$b]->table_optionnelle) { - $msg = array('zbug_pagination_sans_critere', - array('champ' => '#PAGINATION') - ); + $msg = array( + 'zbug_pagination_sans_critere', + array('champ' => '#PAGINATION') + ); erreur_squelette($msg, $p); } + return $p; } @@ -583,53 +1157,91 @@ function balise_PAGINATION_dist($p, $liste='true') { // si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise // si true, les arguments simples (sans truc=chose) vont degager $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false, false); - if (count($_contexte)){ - list($key,$val) = each($_contexte); - if (is_numeric($key)){ + if (count($_contexte)) { + list($key, $val) = each($_contexte); + if (is_numeric($key)) { array_shift($_contexte); - $__modele = interprete_argument_balise(1,$p); + $__modele = interprete_argument_balise(1, $p); } } - if (count($_contexte)){ - $code_contexte = implode(',',$_contexte); - } - else + if (count($_contexte)) { + $code_contexte = implode(',', $_contexte); + } else { $code_contexte = ''; + } $connect = $p->boucles[$b]->sql_serveur; $pas = $p->boucles[$b]->total_parties; $f_pagination = chercher_filtre('pagination'); $type = $p->boucles[$b]->modificateur['debut_nom']; - $modif = ($type[0]!=="'") ? "'debut'.$type" - : ("'debut" .substr($type,1)); + $modif = ($type[0] !== "'") ? "'debut'.$type" + : ("'debut" . substr($type, 1)); - $p->code = sprintf(CODE_PAGINATION, $f_pagination, $b, $type, $modif, $pas, $liste, ((isset($__modele) and $__modele) ? $__modele : "''"), _q($connect), $code_contexte); + $p->code = sprintf(CODE_PAGINATION, $f_pagination, $b, $type, $modif, $pas, $liste, + ((isset($__modele) and $__modele) ? $__modele : "''"), _q($connect), $code_contexte); $p->boucles[$b]->numrows = true; $p->interdire_scripts = false; + return $p; } -// N'afficher que l'ancre de la pagination (au-dessus, par exemple, alors -// qu'on mettra les liens en-dessous de la liste paginee) -// http://doc.spip.org/@balise_ANCRE_PAGINATION_dist +/** + * Compile la balise `#ANCRE_PAGINATION` chargée d'afficher l'ancre + * de la pagination + * + * Cette ancre peut ainsi être placée au-dessus la liste des éléments + * de la boucle alors qu'on mettra les liens de pagination en-dessous de + * cette liste paginée. + * + * Cette balise nécessite le critère `pagination` sur la boucle où elle + * est utilisée. + * + * @balise + * @link http://www.spip.net/3367 Le système de pagination + * @link http://www.spip.net/4328 Balise ANCRE_PAGINATION + * @see critere_pagination_dist() + * @see balise_PAGINATION_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_ANCRE_PAGINATION_dist($p) { - if ($f = charger_fonction('PAGINATION', 'balise', true)) - return $f($p, $liste='false'); - else return NULL; // ou une erreur ? + if ($f = charger_fonction('PAGINATION', 'balise', true)) { + return $f($p, $liste = 'false'); + } else { + return null; + } // ou une erreur ? } -// equivalent a #TOTAL_BOUCLE sauf pour les boucles paginees, ou elle -// indique le nombre total d'articles repondant aux criteres hors pagination -// http://doc.spip.org/@balise_GRAND_TOTAL_dist + +/** + * Compile la balise `#GRAND_TOTAL` qui retourne le nombre total de résultats + * d'une boucle + * + * Cette balise set équivalente à `#TOTAL_BOUCLE` sauf pour les boucles paginées. + * Dans ce cas elle indique le nombre total d'éléments répondant aux critères + * hors pagination. + * + * @balise + * @see balise_GRAND_TOTAL_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_GRAND_TOTAL_dist($p) { $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere']; if ($b === '' || !isset($p->boucles[$b])) { - $msg = array('zbug_champ_hors_boucle', - array('champ' => "#$b" . 'TOTAL_BOUCLE') - ); + $msg = array( + 'zbug_champ_hors_boucle', + array('champ' => "#$b" . 'TOTAL_BOUCLE') + ); erreur_squelette($msg, $p); } else { $p->code = "(isset(\$Numrows['$b']['grand_total']) @@ -637,43 +1249,107 @@ function balise_GRAND_TOTAL_dist($p) { $p->boucles[$b]->numrows = true; $p->interdire_scripts = false; } + return $p; } -// Reference a l'URL de la page courante -// Attention dans un INCLURE() ou une balise dynamique on n'a pas le droit de -// mettre en cache #SELF car il peut correspondre a une autre page (attaque XSS) -// (Dans ce cas faire pour differencier les caches.) -// http://www.spip.net/@self -// http://doc.spip.org/@balise_SELF_dist + +/** + * Compile la balise `#SELF` qui retourne l’URL de la page appelée. + * + * Cette URL est nettoyée des variables propres à l’exécution de SPIP + * tel que `var_mode`. + * + * @note + * Attention dans un `INCLURE()` ou une balise dynamique, on n'a pas le droit de + * mettre en cache `#SELF` car il peut correspondre à une autre page (attaque XSS) + * (Dans ce cas faire pour différencier les caches.) + * + * @balise + * @link http://www.spip.net/4574 + * @example + * ``` + *
... + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_SELF_dist($p) { $p->code = 'self()'; $p->interdire_scripts = false; + return $p; } -// -// #CHEMIN{fichier} -> find_in_path(fichier) -// -// http://doc.spip.org/@balise_CHEMIN_dist + +/** + * Compile la balise `#CHEMIN` qui cherche un fichier dans les chemins + * connus de SPIP et retourne son chemin complet depuis la racine + * + * Signature : `#CHEMIN{chemin/vers/fichier.ext}` + * + * Retourne une chaîne vide si le fichier n'est pas trouvé. + * + * @balise + * @link http://www.spip.net/4332 + * @see find_in_path() Recherche de chemin + * @example + * ``` + * [] + * [] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_CHEMIN_dist($p) { - $arg = interprete_argument_balise(1,$p); + $arg = interprete_argument_balise(1, $p); if (!$arg) { - $msg = array('zbug_balise_sans_argument', array('balise' => ' CHEMIN')); + $msg = array('zbug_balise_sans_argument', array('balise' => ' CHEMIN')); erreur_squelette($msg, $p); - } else - $p->code = 'find_in_path(' . $arg .')'; + } else { + $p->code = 'find_in_path(' . $arg . ')'; + } + + $p->interdire_scripts = false; - #$p->interdire_scripts = true; return $p; } +/** + * Compile la balise `#CHEMIN_IMAGE` qui cherche une image dans le thème + * de l'espace privé utilisé par SPIP et retourne son chemin complet depuis + * la racine + * + * Signature : `#CHEMIN_IMAGE{image.png}` + * + * Retourne une chaîne vide si le fichier n'est pas trouvé. + * + * @balise + * @see chemin_image() + * @example + * ``` + * #CHEMIN_IMAGE{article-24.png} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_CHEMIN_IMAGE_dist($p) { - $arg = interprete_argument_balise(1,$p); + $arg = interprete_argument_balise(1, $p); if (!$arg) { $msg = array('zbug_balise_sans_argument', array('balise' => ' CHEMIN_IMAGE')); erreur_squelette($msg, $p); - } else $p->code = 'chemin_image(' . $arg .')'; + } else { + $p->code = 'chemin_image(' . $arg . ')'; + } #$p->interdire_scripts = true; return $p; @@ -681,56 +1357,52 @@ function balise_CHEMIN_IMAGE_dist($p) { /** - * La balise #ENV permet de recuperer - * le contexte d'environnement transmis au calcul d'un squelette, - * par exemple #ENV{id_rubrique} + * Compile la balise `#ENV` qui permet de récupérer le contexte d'environnement + * transmis à un squelette. * - * La syntaxe #ENV{toto, valeur par defaut} - * renverra 'valeur par defaut' si $toto est vide + * La syntaxe `#ENV{toto, valeur par defaut}` + * renverra `valeur par defaut` si `$toto` est vide. * - * La recherche de la cle s'appuyant sur la fonction table_valeur - * il est possible de demander un sous element d'un tableau - * #ENV{toto/sous/element, valeur par defaut} retournera l'equivalent de - * #ENV{toto}|table_valeur{sous/element} c'est a dire en quelque sorte - * $env['toto']['sous']['element'] s'il existe, sinon la valeur par defaut. + * La recherche de la clé s'appuyant sur la fonction `table_valeur` + * il est possible de demander un sous élément d'un tableau : + * `#ENV{toto/sous/element, valeur par defaut}` retournera l'équivalent de + * `#ENV{toto}|table_valeur{sous/element}` c'est-à-dire en quelque sorte + * `$env['toto']['sous']['element']` s'il existe, sinon la valeur par défaut. * - * Si le tableau est vide on renvoie '' (utile pour #SESSION) + * Si le tableau est vide on renvoie `''` (utile pour `#SESSION`) * - * Enfin, la balise utilisee seule #ENV retourne le tableau complet - * de l'environnement. A noter que ce tableau est retourne serialise. + * Enfin, la balise utilisée seule `#ENV` retourne le tableau complet + * de l'environnement. À noter que ce tableau est retourné sérialisé. * - * - * En standard est applique |entites_html, mais si l'etoile est - * utilisee pour desactiver les filtres par defaut, par exemple avec - * [(#ENV*{toto})] , il *faut* s'assurer de la securite - * anti-javascript, par exemple en filtrant avec |safehtml : [(#ENV*{toto}|safehtml)] - * + * En standard est appliqué le filtre `entites_html`, mais si l'étoile est + * utilisée pour désactiver les filtres par défaut, par exemple avec + * `[(#ENV*{toto})]` , il *faut* s'assurer de la sécurité + * anti-javascript, par exemple en filtrant avec `safehtml` : `[(#ENV*{toto}|safehtml)]` * - * @param Champ $p - * Pile ; arbre de syntaxe abstrait positionne au niveau de la balise. * + * @param Champ $p + * Pile ; arbre de syntaxe abstrait positionné au niveau de la balise. * @param array $src - * Tableau dans lequel chercher la cle demandee en parametre de la balise. - * Par defaut prend dans le contexte du squelette. - * - * @return Champ $p - * Pile completee du code PHP d'execution de la balise -**/ -function balise_ENV_dist($p, $src = NULL) { + * Tableau dans lequel chercher la clé demandée en paramètre de la balise. + * Par defaut prend dans le contexte du squelette. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + **/ +function balise_ENV_dist($p, $src = null) { // cle du tableau desiree - $_nom = interprete_argument_balise(1,$p); + $_nom = interprete_argument_balise(1, $p); // valeur par defaut - $_sinon = interprete_argument_balise(2,$p); - + $_sinon = interprete_argument_balise(2, $p); + // $src est un tableau de donnees sources eventuellement transmis // en absence, on utilise l'environnement du squelette $Pile[0] - + if (!$_nom) { // cas de #ENV sans argument : on retourne le serialize() du tableau // une belle fonction [(#ENV|affiche_env)] serait pratique if ($src) { - $p->code = '(is_array($a = ('.$src.')) ? serialize($a) : "")'; + $p->code = '(is_array($a = (' . $src . ')) ? serialize($a) : "")'; } else { $p->code = '@serialize($Pile[0])'; } @@ -744,33 +1416,44 @@ function balise_ENV_dist($p, $src = NULL) { $p->code = "table_valeur($src, (string)$_nom, null)"; } } + #$p->interdire_scripts = true; return $p; } /** - * #CONFIG retourne lire_config() - * les reglages du site + * Compile la balise `#CONFIG` qui retourne une valeur de configuration * - * Par exemple #CONFIG{gerer_trad} donne 'oui' ou 'non' selon le reglage - * Le 3eme argument permet de controler la serialisation du resultat - * (mais ne sert que pour le depot 'meta') qui doit parfois deserialiser + * Cette balise appelle la fonction `lire_config()` pour obtenir les + * configurations du site. * - * ex: |in_array{#CONFIG{toto,#ARRAY,1}}. + * Par exemple `#CONFIG{gerer_trad}` donne 'oui ou 'non' selon le réglage. * - * Ceci n'affecte pas d'autres depots et |in_array{#CONFIG{toto/,#ARRAY}} sera equivalent - * #CONFIG{/tablemeta/champ,defaut} lit la valeur de 'champ' dans la table des meta 'tablemeta' + * Le 3ème argument permet de contrôler la sérialisation du résultat + * (mais ne sert que pour le dépot `meta`) qui doit parfois désérialiser, + * par exemple avec `|in_array{#CONFIG{toto,#ARRAY,1}}`. Ceci n'affecte + * pas d'autres dépots et `|in_array{#CONFIG{toto/,#ARRAY}}` sera + * équivalent. * - * @param Object $p Arbre syntaxique du compilo - * @return Object + * Òn peut appeler d'autres tables que `spip_meta` avec un + * `#CONFIG{/infos/champ,defaut}` qui lit la valeur de `champ` + * dans une table des meta qui serait `spip_infos` + * + * @balise + * @link http://www.spip.net/4335 + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise */ function balise_CONFIG_dist($p) { - if (!$arg = interprete_argument_balise(1,$p)) { + if (!$arg = interprete_argument_balise(1, $p)) { $arg = "''"; } - $_sinon = interprete_argument_balise(2,$p); - $_unserialize = sinon(interprete_argument_balise(3,$p),"false"); + $_sinon = interprete_argument_balise(2, $p); + $_unserialize = sinon(interprete_argument_balise(3, $p), "false"); $p->code = '(include_spip(\'inc/config\')?lire_config(' . $arg . ',' . ($_sinon && $_sinon != "''" ? $_sinon : 'null') . ',' . $_unserialize . "):'')"; @@ -779,20 +1462,55 @@ function balise_CONFIG_dist($p) { } -// http://doc.spip.org/@balise_CONNECT_dist +/** + * Compile la balise `#CONNECT` qui retourne le nom du connecteur + * de base de données + * + * Retourne le nom du connecteur de base de données utilisé (le nom + * du fichier `config/xx.php` sans l'extension, utilisé pour calculer + * les données du squelette). + * + * Retourne `NULL` si le connecteur utilisé est celui par défaut de SPIP + * (connect.php), sinon retourne son nom. + * + * @balise + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + */ function balise_CONNECT_dist($p) { $p->code = '($connect ? $connect : NULL)'; $p->interdire_scripts = false; + return $p; } -// -// #SESSION -// Cette balise est un tableau des donnees du visiteur (nom, email etc) -// Si elle est invoquee, elle leve un drapeau dans le fichier cache, qui -// permet a public/cacher d'invalider le cache si le visiteur suivant n'a -// pas la meme session -// http://doc.spip.org/@balise_SESSION_dist + +/** + * Compile la balise `#SESSION` qui permet d’accéder aux informations + * liées au visiteur authentifié et de différencier automatiquement + * le cache en fonction du visiteur. + * + * Cette balise est un tableau des données du visiteur (nom, email etc). + * Si elle est invoquée, elle lève un drapeau dans le fichier cache, qui + * permet à public/cacher de créer un cache différent par visiteur + * + * @balise + * @link http://www.spip.net/3979 + * @see balise_AUTORISER_dist() + * @see balise_SESSION_SET_dist() + * @example + * ``` + * #SESSION{nom} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + **/ function balise_SESSION_dist($p) { $p->descr['session'] = true; @@ -801,20 +1519,38 @@ function balise_SESSION_dist($p) { : 'balise_ENV_dist'; $p = $f($p, '$GLOBALS["visiteur_session"]'); + return $p; } -// -// #SESSION_SET{x,y} -// Ajoute x=y dans la session du visiteur -// http://doc.spip.org/@balise_SESSION_SET_dist + +/** + * Compile la balise `#SESSION_SET` qui d’insérer dans la session + * des données supplémentaires + * + * @balise + * @link http://www.spip.net/3984 + * @see balise_AUTORISER_dist() + * @see balise_SESSION_SET_dist() + * @example + * ``` + * #SESSION_SET{x,y} ajoute x=y dans la session du visiteur + * ``` + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + **/ function balise_SESSION_SET_dist($p) { - $_nom = interprete_argument_balise(1,$p); - $_val = interprete_argument_balise(2,$p); - if (!$_nom OR !$_val) { + $_nom = interprete_argument_balise(1, $p); + $_val = interprete_argument_balise(2, $p); + if (!$_nom or !$_val) { $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'SESSION_SET')); erreur_squelette($err_b_s_a, $p); - } else $p->code = '(include_spip("inc/session") AND session_set('.$_nom.','.$_val.'))'; + } else { + $p->code = '(include_spip("inc/session") AND session_set(' . $_nom . ',' . $_val . '))'; + } $p->interdire_scripts = false; @@ -822,29 +1558,44 @@ function balise_SESSION_SET_dist($p) { } - - -// -// #EVAL{...} -// evalue un code php ; a utiliser avec precaution :-) -// -// rq: #EVAL{code} produit eval('return code;') -// mais si le code est une expression sans balise, on se dispense -// de passer par une construction si compliquee, et le code est -// passe tel quel (entre parentheses, et protege par interdire_scripts) -// Exemples : #EVAL**{6+9} #EVAL**{_DIR_IMG_PACK} #EVAL{'date("Y-m-d")'} -// #EVAL{'str_replace("r","z", "roger")'} (attention les "'" sont interdits) -// http://doc.spip.org/@balise_EVAL_dist +/** + * Compile la balise `#EVAL` qui évalue un code PHP + * + * À utiliser avec précautions ! + * + * @balise + * @link http://www.spip.net/4587 + * @example + * ``` + * #EVAL{6+9} + * #EVAL{'date("Y-m-d")'} + * #EVAL{$_SERVER['REQUEST_URI']} + * #EVAL{'str_replace("r","z", "roger")'} (attention les "'" sont interdits) + * ``` + * + * @note + * `#EVAL{code}` produit `eval('return code;')` + * mais si le code est une expression sans balise, on se dispense + * de passer par une construction si compliquée, et le code est + * passé tel quel (entre parenthèses, et protégé par interdire_scripts) + * + * @param Champ $p + * Pile au niveau de la balise. + * @return Champ + * Pile completée du code PHP d'exécution de la balise + **/ function balise_EVAL_dist($p) { - $php = interprete_argument_balise(1,$p); + $php = interprete_argument_balise(1, $p); if ($php) { # optimisation sur les #EVAL{une expression sans #BALISE} # attention au commentaire "// x signes" qui precede if (preg_match(",^([[:space:]]*//[^\n]*\n)'([^']+)'$,ms", - $php,$r)) - $p->code = /* $r[1]. */'('.$r[2].')'; - else + $php, $r)) { + $p->code = /* $r[1]. */ + '(' . $r[2] . ')'; + } else { $p->code = "eval('return '.$php.';')"; + } } else { $msg = array('zbug_balise_sans_argument', array('balise' => ' EVAL')); erreur_squelette($msg, $p); @@ -855,52 +1606,129 @@ function balise_EVAL_dist($p) { return $p; } -// #CHAMP_SQL{x} renvoie la valeur du champ sql 'x' -// permet de recuperer par exemple un champ notes dans une table sql externe -// (impossible via #NOTES qui est une balise calculee) -// ne permet pas de passer une expression pour x qui ne peut etre qu'un texte statique ! -// http://doc.spip.org/@balise_CHAMP_SQL_dist -function balise_CHAMP_SQL_dist($p){ + +/** + * Compile la balise `#CHAMP_SQL` qui renvoie la valeur d'un champ SQL + * + * Signature : `#CHAMP_SQL{champ}` + * + * Cette balise permet de récupérer par exemple un champ `notes` dans une table + * SQL externe (impossible avec la balise `#NOTES` qui est une balise calculée). + * + * Ne permet pas de passer une expression comme argument, qui ne peut + * être qu'un texte statique ! + * + * @balise + * @link http://www.spip.net/4041 + * @see champ_sql() + * @example + * ``` + * #CHAMP_SQL{notes} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_CHAMP_SQL_dist($p) { if ($p->param - AND isset($p->param[0][1][0]) - AND $champ = ($p->param[0][1][0]->texte)) + and isset($p->param[0][1][0]) + and $champ = ($p->param[0][1][0]->texte) + ) { $p->code = champ_sql($champ, $p); - else { + } else { $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => ' CHAMP_SQL')); erreur_squelette($err_b_s_a, $p); } + #$p->interdire_scripts = true; return $p; } -// #VAL{x} renvoie 'x' (permet d'appliquer un filtre a une chaine) -// Attention #VAL{1,2} renvoie '1', indiquer #VAL{'1,2'} -// http://doc.spip.org/@balise_VAL_dist -function balise_VAL_dist($p){ - $p->code = interprete_argument_balise(1,$p); - if (!strlen($p->code)) +/** + * Compile la balise `#VAL` qui retourne simplement le premier argument + * qui lui est transmis + * + * Cela permet d'appliquer un filtre à une chaîne de caractère + * + * @balise + * @link http://www.spip.net/4026 + * @example + * ``` + * #VAL retourne '' + * #VAL{x} retourne 'x' + * #VAL{1,2} renvoie '1' (2 est considéré comme un autre paramètre) + * #VAL{'1,2'} renvoie '1,2' + * [(#VAL{a_suivre}|bouton_spip_rss)] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_VAL_dist($p) { + $p->code = interprete_argument_balise(1, $p); + if (!strlen($p->code)) { $p->code = "''"; + } $p->interdire_scripts = false; + return $p; } -// #NOOP est un alias pour regler #948, ne pas documenter -// http://doc.spip.org/@balise_NOOP_dist + +/** + * Compile la balise `#NOOP`, alias (déprécié) de `#VAL` + * + * Alias pour regler #948. Ne plus utiliser. + * + * @balise + * @see balise_VAL_dist() + * @deprecated Utiliser #VAL + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_NOOP_dist($p) { return balise_VAL_dist($p); } -// -// #REM -// pour les remarques : renvoie toujours '' -// -// http://doc.spip.org/@balise_REM_dist + +/** + * Compile la balise `#REM` servant à commenter du texte + * + * Retourne toujours une chaîne vide. + * + * @balise + * @link http://www.spip.net/4578 + * @example + * ``` + * [(#REM) + * Ceci est une remarque ou un commentaire, + * non affiché dans le code généré + * ] + * ``` + * + * @note + * La balise `#REM` n'empêche pas l'exécution des balises SPIP contenues + * dedans (elle ne sert pas à commenter du code pour empêcher son + * exécution). + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_REM_dist($p) { - $p->code="''"; + $p->code = "''"; $p->interdire_scripts = false; + return $p; } - /** * Compile la balise `#HTTP_HEADER` envoyant des entêtes de retour HTTP * @@ -936,36 +1764,74 @@ function balise_HTTP_HEADER_dist($p) { } - -// Filtre a appliquer a l'ensemble de la page une fois calculee -// (filtrage fait au niveau du squelette, et sans s'appliquer aux ) -// http://doc.spip.org/@balise_FILTRE_dist +/** + * Compile la balise `#FILTRE` qui exécute un filtre à l'ensemble du squelette + * une fois calculé. + * + * Le filtrage se fait au niveau du squelette, sans s'appliquer aux ``. + * Plusieurs filtres peuvent être indiqués, séparés par des barres verticales `|` + * + * @balise + * @link http://www.spip.net/4894 + * @example + * ``` + * #FILTRE{compacte_head} + * #FILTRE{supprimer_tags|filtrer_entites|trim} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_FILTRE_dist($p) { if ($p->param) { $args = array(); - foreach ($p->param as $i => $ignore) - $args[] = interprete_argument_balise($i+1,$p); + foreach ($p->param as $i => $ignore) { + $args[] = interprete_argument_balise($i + 1, $p); + } $p->code = "'<' . '" - .'?php header("X-Spip-Filtre: \'.' - .join('.\'|\'.', $args) + . '?php header("X-Spip-Filtre: \'.' + . join('.\'|\'.', $args) . " . '\"); ?'.'>'"; $p->interdire_scripts = false; + return $p; } } -// -// #CACHE -// definit la duree de vie ($delais) du squelette -// #CACHE{24*3600} -// parametre(s) supplementaire(s) : -// #CACHE{24*3600, cache-client} autorise gestion du IF_MODIFIED_SINCE -// #CACHE{24*3600, statique} ne respecte pas l'invalidation par modif de la base -// (mais s'invalide tout de meme a l'expiration du delai) -// par defaut cache-client => statique -// cf. ecrire/public/cacher.php -// http://doc.spip.org/@balise_CACHE_dist + +/** + * Compile la balise `#CACHE` definissant la durée de validité du cache du squelette + * + * Signature : `#CACHE{duree[,type]}` + * + * Le premier argument est la durée en seconde du cache. Le second + * (par défaut `statique`) indique le type de cache : + * + * - `cache-client` autorise gestion du IF_MODIFIED_SINCE + * - `statique` ne respecte pas l'invalidation par modif de la base + * (mais s'invalide tout de même à l'expiration du delai) + * + * @balise + * @see ecrire/public/cacher.php + * @link http://www.spip.net/4330 + * @example + * ``` + * #CACHE{24*3600} + * #CACHE{24*3600, cache-client} + * #CACHE{0} pas de cache + * ``` + * @note + * En absence de cette balise la durée est du cache est donné + * par la constante `_DUREE_CACHE_DEFAUT` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_CACHE_dist($p) { if ($p->param) { @@ -973,18 +1839,19 @@ function balise_CACHE_dist($p) { // noter la duree du cache dans un entete proprietaire - $code = '\'<'.'?php header("X-Spip-Cache: ' - . $duree - . '"); ?'.'>\''; + $code = "'<'.'" . '?php header("X-Spip-Cache: ' + . $duree + . '"); ?' . "'.'>'"; // Remplir le header Cache-Control // cas #CACHE{0} - if ($duree == 0) - $code .= '.\'<' - .'?php header("Cache-Control: no-cache, must-revalidate"); ?' - .'><' - .'?php header("Pragma: no-cache"); ?' - .'>\''; + if ($duree == 0) { + $code .= ".'<'.'" + . '?php header("Cache-Control: no-cache, must-revalidate"); ?' + . "'.'><'.'" + . '?php header("Pragma: no-cache"); ?' + . "'.'>'"; + } // recuperer les parametres suivants $i = 1; @@ -992,81 +1859,138 @@ function balise_CACHE_dist($p) { $pa = ($p->param[0][$i][0]->texte); if ($pa == 'cache-client' - AND $duree > 0) { - $code .= '.\'<'.'?php header("Cache-Control: max-age=' - . $duree - . '"); ?'.'>\''; - // il semble logique, si on cache-client, de ne pas invalider + and $duree > 0 + ) { + $code .= ".'<'.'" . '?php header("Cache-Control: max-age=' + . $duree + . '"); ?' . "'.'>'"; + // il semble logique, si on cache-client, de ne pas invalider $pa = 'statique'; } if ($pa == 'statique' - AND $duree > 0) - $code .= '.\'<'.'?php header("X-Spip-Statique: oui"); ?'.'>\''; + and $duree > 0 + ) { + $code .= ".'<'.'" . '?php header("X-Spip-Statique: oui"); ?' . "'.'>'"; + } } - } else $code = "''"; + } else { + $code = "''"; + } $p->code = $code; $p->interdire_scripts = false; + return $p; } /** - * #INSERT_HEAD - * pour permettre aux plugins d'inserer des styles, js ou autre - * dans l'entete sans modification du squelette - * les css doivent etre inserees de preference par #INSERT_HEAD_CSS - * pour en faciliter la surcharge + * Compile la balise `#INSERT_HEAD` permettant d'insérer du contenu dans + * le `` d'une page HTML * - * on insere ici aussi un morceau de PHP qui verifiera a l'execution que le pipeline insert_head_css a bien ete vu - * et dans le cas contraire l'appelera. Permet de ne pas oublier les css de #INSERT_HEAD_CSS meme si cette balise - * n'est pas presente. - * Il faut mettre ce php avant le insert_head car le compresseur y mets ensuite un php du meme type pour collecter - * CSS et JS, et on ne veut pas qu'il rate les css inserees en fallback par insert_head_css_conditionnel + * La balise permet aux plugins d'insérer des styles, js ou autre + * dans l'entête sans modification du squelette. + * Les css doivent être inserées de préférence par `#INSERT_HEAD_CSS` + * pour en faciliter la surcharge. * - * http://doc.spip.org/@balise_INSERT_HEAD_dist + * On insère ici aussi un morceau de PHP qui verifiera à l'exécution + * que le pipeline `insert_head_css` a bien été vu + * et dans le cas contraire l'appelera. Ceal permet de ne pas oublier + * les css de `#INSERT_HEAD_CSS` même si cette balise n'est pas presente. * - * @param object $p - * @return object + * Il faut mettre ce php avant le `insert_head` car le compresseur y mets + * ensuite un php du meme type pour collecter + * CSS et JS, et on ne veut pas qu'il rate les css insérées en fallback + * par `insert_head_css_conditionnel`. + * + * @link http://www.spip.net/4629 + * @see balise_INSERT_HEAD_CSS_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ function balise_INSERT_HEAD_dist($p) { - $p->code = '\'<' - .'?php header("X-Spip-Filtre: \'.' - .'\'insert_head_css_conditionnel\'' - . " . '\"); ?'.'>'"; + $p->code = "'<'.'" + . '?php header("X-Spip-Filtre: insert_head_css_conditionnel"); ?' + . "'.'>'"; $p->code .= ". pipeline('insert_head','')"; $p->interdire_scripts = false; + return $p; } /** - * homologue de #INSERT_HEAD pour les CSS - * (et par extension pour le js inline qui doit preferentiellement etre insere avant les CSS car bloquant sinon) + * Compile la balise `#INSERT_HEAD_CSS` homologue de `#INSERT_HEAD` pour les CSS + * + * Et par extension pour le JS inline qui doit préférentiellement + * être inséré avant les CSS car bloquant sinon. * - * http://doc.spip.org/@balise_INSERT_HEAD_CSS_dist + * @link http://www.spip.net/4605 + * @see balise_INSERT_HEAD_dist() * - * @param object $p - * @return object + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ function balise_INSERT_HEAD_CSS_dist($p) { $p->code = "pipeline('insert_head_css','')"; $p->interdire_scripts = false; + return $p; } -// -// #INCLURE statique -// l'inclusion est realisee au calcul du squelette, pas au service -// ainsi le produit du squelette peut etre utilise en entree de filtres a suivre -// on peut faire un #INCLURE{fichier} sans squelette -// (Incompatible avec les balises dynamiques) -// http://doc.spip.org/@balise_INCLUDE_dist + +/** + * Compile la balise `#INCLUDE` alias de `#INCLURE` + * + * @balise + * @see balise_INCLURE_dist() + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_INCLUDE_dist($p) { - if(function_exists('balise_INCLURE')) + if (function_exists('balise_INCLURE')) { return balise_INCLURE($p); - else + } else { return balise_INCLURE_dist($p); + } } -// http://doc.spip.org/@balise_INCLURE_dist + +/** + * Compile la balise `#INCLURE` qui inclut un résultat de squelette + * + * Signature : `[(#INCLURE{fond=nom_du_squelette, argument, argument=xx})]` + * + * L'argument `env` permet de transmettre tout l'environnement du squelette + * en cours au squelette inclus. + * + * On parle d’inclusion « statique » car le résultat de compilation est + * ajouté au squelette en cours, dans le même fichier de cache. + * Cette balise est donc différente d’une inclusion « dynamique » avec + * `` qui, elle, crée un fichier de cache séparé + * (avec une durée de cache qui lui est propre). + * + * L'inclusion est realisée au calcul du squelette, pas au service + * ainsi le produit du squelette peut être utilisé en entrée de filtres + * à suivre. On peut faire un `#INCLURE{fichier}` sans squelette + * (Incompatible avec les balises dynamiques). + * + * @balise + * @example + * ``` + * [(#INCLURE{fond=inclure/documents,id_article, env})] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_INCLURE_dist($p) { $id_boucle = $p->id_boucle; // la lang n'est pas passe de facon automatique par argumenter @@ -1077,7 +2001,9 @@ function balise_INCLURE_dist($p) { // erreur de syntaxe = fond absent // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP - if (!$_contexte) $contexte = array(); + if (!$_contexte) { + $contexte = array(); + } if (isset($_contexte['fond'])) { @@ -1086,7 +2012,9 @@ function balise_INCLURE_dist($p) { if (preg_match('/^.fond.\s*=>(.*)$/s', $f, $r)) { $f = $r[1]; unset($_contexte['fond']); - } else spip_log("compilation de #INCLURE a revoir"); + } else { + spip_log("compilation de #INCLURE a revoir"); + } // #INCLURE{doublons} if (isset($_contexte['doublons'])) { @@ -1094,44 +2022,72 @@ function balise_INCLURE_dist($p) { } // Critere d'inclusion {env} (et {self} pour compatibilite ascendante) - if (isset($_contexte['env']) - || isset($_contexte['self']) - ) { + $flag_env = false; + if (isset($_contexte['env']) or isset($_contexte['self'])) { $flag_env = true; unset($_contexte['env']); - } else $flag_env = false; + } $_options = array(); if (isset($_contexte['ajax'])) { - $_options[] = preg_replace(",=>(.*)$,ims",'=> ($v=(\\1))?$v:true',$_contexte['ajax']); + $_options[] = preg_replace(",=>(.*)$,ims", '=> ($v=(\\1))?$v:true', $_contexte['ajax']); unset($_contexte['ajax']); } - if ($p->etoile) $_options[] = "'etoile'=>true"; - $_options[] = "'compil'=>array(" . memoriser_contexte_compil($p) .")"; + if ($p->etoile) { + $_options[] = "'etoile'=>true"; + } + $_options[] = "'compil'=>array(" . memoriser_contexte_compil($p) . ")"; - $_l = 'array(' . join(",\n\t", $_contexte) .')'; - if ($flag_env) $_l = "array_merge(\$Pile[0],$_l)"; + $_l = 'array(' . join(",\n\t", $_contexte) . ')'; + if ($flag_env) { + $_l = "array_merge(\$Pile[0],$_l)"; + } - $p->code = sprintf(CODE_RECUPERER_FOND, $f, $_l, join(',',$_options),"''"); + $p->code = sprintf(CODE_RECUPERER_FOND, $f, $_l, join(',', $_options), "_request('connect')"); } elseif (!isset($_contexte[1])) { - $msg = array('zbug_balise_sans_argument', array('balise' => ' INCLURE')); - erreur_squelette($msg, $p); - } else $p->code = 'charge_scripts(' . $_contexte[1] . ',false)'; + $msg = array('zbug_balise_sans_argument', array('balise' => ' INCLURE')); + erreur_squelette($msg, $p); + } else { + $p->code = 'charge_scripts(' . $_contexte[1] . ',false)'; + } $p->interdire_scripts = false; // la securite est assuree par recuperer_fond return $p; } -// Inclure un modele : #MODELE{modele, params} -// http://doc.spip.org/@balise_MODELE_dist + +/** + * Compile la balise `#MODELE` qui inclut un résultat de squelette de modèle + * + * `#MODELE{nom}` insère le résultat d’un squelette contenu dans le + * répertoire `modeles/`. L’identifiant de la boucle parente est transmis + * par défaut avec le paramètre `id` à cette inclusion. + * + * Des arguments supplémentaires peuvent être transmis : + * `[(#MODELE{nom, argument=xx, argument})]` + * + * @balise + * @see balise_INCLURE_dist() + * @example + * ``` + * #MODELE{article_traductions} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_MODELE_dist($p) { $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false); // erreur de syntaxe = fond absent // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP - if (!$_contexte) $contexte = array(); + if (!$_contexte) { + $contexte = array(); + } if (!isset($_contexte[1])) { $msg = array('zbug_balise_sans_argument', array('balise' => ' MODELE')); @@ -1140,33 +2096,47 @@ function balise_MODELE_dist($p) { $nom = $_contexte[1]; unset($_contexte[1]); - if (preg_match("/^\s*'[^']*'/s", $nom)) - $nom = "'modeles/" . substr($nom,1); - else $nom = "'modeles/' . $nom"; + if (preg_match("/^\s*'[^']*'/s", $nom)) { + $nom = "'modeles/" . substr($nom, 1); + } else { + $nom = "'modeles/' . $nom"; + } + + $flag_env = false; + if (isset($_contexte['env'])) { + $flag_env = true; + unset($_contexte['env']); + } // Incoherence dans la syntaxe du contexte. A revoir. // Reserver la cle primaire de la boucle courante si elle existe if (isset($p->boucles[$p->id_boucle]->primary)) { $primary = $p->boucles[$p->id_boucle]->primary; - if (!strpos($primary,',')) { + if (!strpos($primary, ',')) { $id = champ_sql($primary, $p); - $_contexte[] = "'$primary'=>".$id; - $_contexte[] = "'id'=>".$id; + $_contexte[] = "'$primary'=>" . $id; + $_contexte[] = "'id'=>" . $id; } } $_contexte[] = "'recurs'=>(++\$recurs)"; $connect = ''; - if (isset($p->boucles[$p->id_boucle])) + if (isset($p->boucles[$p->id_boucle])) { $connect = $p->boucles[$p->id_boucle]->sql_serveur; + } $_options = memoriser_contexte_compil($p); $_options = "'compil'=>array($_options), 'trim'=>true"; - if (isset($_contexte['ajax'])){ - $_options .= ", ".preg_replace(",=>(.*)$,ims",'=> ($v=(\\1))?$v:true',$_contexte['ajax']); + if (isset($_contexte['ajax'])) { + $_options .= ", " . preg_replace(",=>(.*)$,ims", '=> ($v=(\\1))?$v:true', $_contexte['ajax']); unset($_contexte['ajax']); - } + } + + $_l = 'array(' . join(",\n\t", $_contexte) . ')'; + if ($flag_env) { + $_l = "array_merge(\$Pile[0],$_l)"; + } - $page = sprintf(CODE_RECUPERER_FOND, $nom, 'array(' . join(',', $_contexte) .')', $_options, _q($connect)); + $page = sprintf(CODE_RECUPERER_FOND, $nom, $_l, $_options, _q($connect)); $p->code = "\n\t(((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))>=5)? '' :\n\t$page)\n"; @@ -1176,69 +2146,111 @@ function balise_MODELE_dist($p) { return $p; } -// -// #SET -// Affecte une variable locale au squelette -// #SET{nom,valeur} -// la balise renvoie la valeur -// http://doc.spip.org/@balise_SET_dist -function balise_SET_dist($p){ - $_nom = interprete_argument_balise(1,$p); - $_val = interprete_argument_balise(2,$p); - - if (!$_nom OR !$_val) { + +/** + * Compile la balise `#SET` qui affecte une variable locale au squelette + * + * Signature : `#SET{cle,valeur}` + * + * @balise + * @link http://www.spip.net/3990 Balises #SET et #GET + * @see balise_GET_dist() + * @example + * ``` + * #SET{nb,5} + * #GET{nb} // affiche 5 + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_SET_dist($p) { + $_nom = interprete_argument_balise(1, $p); + $_val = interprete_argument_balise(2, $p); + + if (!$_nom or !$_val) { $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'SET')); erreur_squelette($err_b_s_a, $p); } // affectation $_zzz inutile, mais permet de contourner un bug OpCode cache sous PHP 5.5.4 // cf https://bugs.php.net/bug.php?id=65845 - else $p->code = "vide(\$Pile['vars'][\$_zzz=(string)$_nom] = $_val)"; + else { + $p->code = "vide(\$Pile['vars'][\$_zzz=(string)$_nom] = $_val)"; + } $p->interdire_scripts = false; // la balise ne renvoie rien return $p; } -// -// #GET -// Recupere une variable locale au squelette -// #GET{nom,defaut} renvoie defaut si la variable nom n'a pas ete affectee -// -// http://doc.spip.org/@balise_GET_dist + +/** + * Compile la balise `#GET` qui récupère une variable locale au squelette + * + * Signature : `#GET{cle[,defaut]}` + * + * La clé peut obtenir des sous clés séparés par des `/` + * + * @balise + * @link http://www.spip.net/3990 Balises #SET et #GET + * @see balise_SET_dist() + * @example + * ``` + * #SET{nb,5} + * #GET{nb} affiche 5 + * #GET{nb,3} affiche la valeur de nb, sinon 3 + * + * #SET{nb,#ARRAY{boucles,3}} + * #GET{nb/boucles} affiche 3, équivalent à #GET{nb}|table_valeur{boucles} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_GET_dist($p) { $p->interdire_scripts = false; // le contenu vient de #SET, donc il est de confiance - if (function_exists('balise_ENV')) + if (function_exists('balise_ENV')) { return balise_ENV($p, '$Pile["vars"]'); - else + } else { return balise_ENV_dist($p, '$Pile["vars"]'); + } } /** - * Compile la balise #DOUBLONS - * - * #DOUBLONS{mots} ou #DOUBLONS{mots,famille} - * donne l'etat des doublons (MOTS) a cet endroit - * sous forme de tableau d'id_mot array(1,2,3,...) - * #DOUBLONS tout seul donne la liste brute de tous les doublons - * #DOUBLONS*{mots} donne la chaine brute ",1,2,3,..." - * (changera si la gestion des doublons evolue) - * + * Compile la balise `#DOUBLONS` qui redonne les doublons enregistrés + * + * - `#DOUBLONS{mots}` ou `#DOUBLONS{mots,famille}` + * donne l'état des doublons `(MOTS)` à cet endroit + * sous forme de tableau d'id_mot comme `array(1,2,3,...)` + * - `#DOUBLONS` tout seul donne la liste brute de tous les doublons + * - `#DOUBLONS*{mots}` donne la chaine brute `,1,2,3,...` + * (changera si la gestion des doublons evolue) + * + * @balise + * @link http://www.spip.net/4123 + * * @param Champ $p - * Pile au niveau de la balise + * Pile au niveau de la balise * @return Champ - * Pile complétée par le code à générer -**/ + * Pile complétée par le code à générer + **/ function balise_DOUBLONS_dist($p) { - if ($type = interprete_argument_balise(1,$p)) { - if ($famille = interprete_argument_balise(2,$p)) + if ($type = interprete_argument_balise(1, $p)) { + if ($famille = interprete_argument_balise(2, $p)) { $type .= '.' . $famille; - $p->code = '$doublons['.$type.']'; - if (!$p->etoile) + } + $p->code = '(isset($doublons[' . $type . ']) ? $doublons[' . $type . '] : "")'; + if (!$p->etoile) { $p->code = 'array_filter(array_map("intval",explode(",",' . $p->code . ')))'; - } - else + } + } else { $p->code = '$doublons'; + } $p->interdire_scripts = false; @@ -1246,139 +2258,288 @@ function balise_DOUBLONS_dist($p) { } -// -// #PIPELINE -// pour permettre aux plugins d'inserer des sorties de pipeline dans un squelette -// #PIPELINE{insert_body} -// #PIPELINE{insert_body,flux} -// -// http://doc.spip.org/@balise_PIPELINE_dist +/** + * Compile la balise `#PIPELINE` pour permettre d'insérer des sorties de + * pipeline dans un squelette + * + * @balise + * @see pipeline() + * @example + * ``` + * #PIPELINE{nom} + * #PIPELINE{nom,données} + * #PIPELINE{boite_infos,#ARRAY{data,'',args,#ARRAY{type,rubrique,id,#ENV{id_rubrique}}}} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_PIPELINE_dist($p) { - $_pipe = interprete_argument_balise(1,$p); + $_pipe = interprete_argument_balise(1, $p); if (!$_pipe) { $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'PIPELINE')); erreur_squelette($err_b_s_a, $p); } else { - $_flux = interprete_argument_balise(2,$p); - $_flux = $_flux?$_flux:"''"; + $_flux = interprete_argument_balise(2, $p); + $_flux = $_flux ? $_flux : "''"; $p->code = "pipeline( $_pipe , $_flux )"; $p->interdire_scripts = false; } + return $p; } -// -// #EDIT -// une balise qui ne fait rien, pour surcharge par le plugin widgets -// -// http://doc.spip.org/@balise_EDIT_dist + +/** + * Compile la balise `#EDIT` qui ne fait rien dans SPIP + * + * Cette balise ne retourne rien mais permet d'indiquer, pour certains plugins + * qui redéfinissent cette balise, le nom du champ SQL (ou le nom d'un contrôleur) + * correspondant à ce qui est édité. Cela sert particulièrement au plugin Crayons. + * Ainsi en absence du plugin, la balise est toujours reconnue (mais n'a aucune action). + * + * @balise + * @link http://www.spip.net/4584 + * @example + * ``` + * [
(#TEXTE)
] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_EDIT_dist($p) { $p->code = "''"; $p->interdire_scripts = false; + return $p; } -// -// #TOTAL_UNIQUE -// pour recuperer le nombre d'elements affiches par l'intermediaire du filtre -// |unique -// usage: -// #TOTAL_UNIQUE afiche le nombre de #BALISE|unique -// #TOTAL_UNIQUE{famille} afiche le nombre de #BALISE|unique{famille} -// -// http://doc.spip.org/@balise_TOTAL_UNIQUE_dist +/** + * Compile la balise `#TOTAL_UNIQUE` qui récupère le nombre d'éléments + * différents affichés par le filtre `unique` + * + * @balise + * @link http://www.spip.net/4374 + * @see unique() + * @example + * ``` + * #TOTAL_UNIQUE affiche le nombre de #BALISE|unique + * #TOTAL_UNIQUE{famille} afiche le nombre de #BALISE|unique{famille} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_TOTAL_UNIQUE_dist($p) { - $_famille = interprete_argument_balise(1,$p); + $_famille = interprete_argument_balise(1, $p); $_famille = $_famille ? $_famille : "''"; $p->code = "unique('', $_famille, true)"; + return $p; } -// -// #ARRAY -// pour creer un array php a partir d'arguments calcules -// #ARRAY{key1,val1,key2,val2 ...} retourne array(key1=>val1,...) -// -// http://doc.spip.org/@balise_ARRAY_dist +/** + * Compile la balise `#ARRAY` créant un tableau PHP associatif + * + * Crée un `array` PHP à partir d'arguments calculés. + * Chaque paire d'arguments représente la clé et la valeur du tableau. + * + * @balise + * @link http://www.spip.net/4009 + * @example + * ``` + * #ARRAY{key1,val1,key2,val2 ...} retourne + * array( key1 => val1, key2 => val2, ...) + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_ARRAY_dist($p) { $_code = array(); - $n=1; + $n = 1; do { - $_key = interprete_argument_balise($n++,$p); - $_val = interprete_argument_balise($n++,$p); - if ($_key AND $_val) $_code[] = "$_key => $_val"; + $_key = interprete_argument_balise($n++, $p); + $_val = interprete_argument_balise($n++, $p); + if ($_key and $_val) { + $_code[] = "$_key => $_val"; + } } while ($_key && $_val); - $p->code = 'array(' . join(', ',$_code).')'; + $p->code = 'array(' . join(', ', $_code) . ')'; $p->interdire_scripts = false; + return $p; } /** - * #LISTE{a,b,c,d,e} cree un array avec les valeurs, sans preciser les cles + * Compile la balise `#LISTE` qui crée un tableau PHP avec les valeurs, sans préciser les clés + * + * @balise + * @link http://www.spip.net/5547 + * @example + * ``` + * #LISTE{a,b,c,d,e} + * ``` * - * @param $p - * @return + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ function balise_LISTE_dist($p) { $_code = array(); - $n=1; - while ($_val = interprete_argument_balise($n++,$p)) + $n = 1; + while ($_val = interprete_argument_balise($n++, $p)) { $_code[] = $_val; - $p->code = 'array(' . join(', ',$_code).')'; + } + $p->code = 'array(' . join(', ', $_code) . ')'; $p->interdire_scripts = false; + return $p; } -// Appelle la fonction autoriser et renvoie ' ' si OK, '' si niet -// A noter : la priorite des operateurs exige && plutot que AND -// Cette balise cree un cache par session -// http://doc.spip.org/@balise_AUTORISER_dist + +/** + * Compile la balise `#AUTORISER` qui teste une autorisation + * + * Appelle la fonction `autoriser()` avec les mêmes arguments, + * et renvoie un espace ' ' si OK (l'action est autorisée), + * sinon une chaine vide '' (l'action n'est pas autorisée). + * + * Cette balise créée un cache par session. + * + * Signature : `#AUTORISER{faire[,type[,id[,auteur[,options]]]}` + * + * @note + * La priorité des opérateurs exige && plutot que AND + * + * @balise + * @link http://www.spip.net/3896 + * @see autoriser() + * @see sinon_interdire_acces() + * @example + * ``` + * [(#AUTORISER{modifier,rubrique,#ID_RUBRIQUE}) ... ] + * [(#AUTORISER{voir,rubrique,#ID_RUBRIQUE}|sinon_interdire_acces)] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_AUTORISER_dist($p) { $_code = array(); $p->descr['session'] = true; // faire un cache par session - $n=1; - while ($_v = interprete_argument_balise($n++,$p)) + $n = 1; + while ($_v = interprete_argument_balise($n++, $p)) { $_code[] = $_v; + } - $p->code = '((function_exists("autoriser")||include_spip("inc/autoriser"))&&autoriser(' . join(', ',$_code).')?" ":"")'; + $p->code = '((function_exists("autoriser")||include_spip("inc/autoriser"))&&autoriser(' . join(', ', + $_code) . ')?" ":"")'; $p->interdire_scripts = false; + return $p; } -// Appelle la fonction info_plugin -// Afficher des informations sur les plugins dans le site public -// http://doc.spip.org/@balise_PLUGIN_dist + +/** + * Compile la balise `#PLUGIN` qui permet d’afficher les informations d'un plugin actif + * + * @balise + * @see filtre_info_plugin_dist() + * @link http://www.spip.net/4591 + * @example + * ``` + * #PLUGIN Retourne la liste sérialisée des préfixes de plugins actifs + * #PLUGIN{prefixe} Renvoie true si le plugin avec ce préfixe est actif + * #PLUGIN{prefixe, x} Renvoie l'information x du plugin (s'il est actif) + * #PLUGIN{prefixe, tout} Renvoie toutes les informations du plugin (s'il est actif) + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_PLUGIN_dist($p) { - $plugin = interprete_argument_balise(1,$p); + $plugin = interprete_argument_balise(1, $p); $plugin = isset($plugin) ? str_replace('\'', '"', $plugin) : '""'; - $type_info = interprete_argument_balise(2,$p); + $type_info = interprete_argument_balise(2, $p); $type_info = isset($type_info) ? str_replace('\'', '"', $type_info) : '"est_actif"'; $f = chercher_filtre('info_plugin'); - $p->code = $f.'('.$plugin.', '.$type_info.')'; + $p->code = $f . '(' . $plugin . ', ' . $type_info . ')'; + return $p; } -// Appelle la fonction inc_aider_dist -// http://doc.spip.org/@balise_AIDER_dist +/** + * Compile la balise `#AIDER` qui permet d’afficher l’icone de l’aide + * au sein des squelettes. + * + * @balise + * @see inc_aide_dist() + * @link http://www.spip.net/4733 + * @example + * ``` + * #AIDER{titre} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ function balise_AIDER_dist($p) { - $_motif = interprete_argument_balise(1,$p); + $_motif = interprete_argument_balise(1, $p); $s = "'" . addslashes($p->descr['sourcefile']) . "'"; - $aider = charger_fonction('aider','inc'); - $p->code = "((\$aider=charger_fonction('aider','inc'))?\$aider($_motif,$s, \$Pile[0]):'')"; + $p->code = "((\$aider=charger_fonction('aide','inc',true))?\$aider($_motif,$s, \$Pile[0]):'')"; + return $p; } -// Insertion du contexte des formulaires charger/verifier/traiter -// avec les hidden de l'url d'action -// http://doc.spip.org/@balise_ACTION_FORMULAIRE -function balise_ACTION_FORMULAIRE($p){ - if (!$_url = interprete_argument_balise(1,$p)) +/** + * Compile la balise `#ACTION_FORMULAIRE` qui insère le contexte + * des formulaires charger / vérifier / traiter avec les hidden de + * l'URL d'action + * + * Accèpte 2 arguments optionnels : + * - L'url de l'action (par défaut `#ENV{action}` + * - Le nom du formulaire (par défaut `#ENV{form}` + * + * @balise + * @see form_hidden() + * @example + * ``` + *
+ * #ACTION_FORMULAIRE + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_ACTION_FORMULAIRE($p) { + if (!$_url = interprete_argument_balise(1, $p)) { $_url = "@\$Pile[0]['action']"; - if (!$_form = interprete_argument_balise(2,$p)) + } + if (!$_form = interprete_argument_balise(2, $p)) { $_form = "@\$Pile[0]['form']"; + } // envoyer le nom du formulaire que l'on traite // transmettre les eventuels args de la balise formulaire @@ -1388,77 +2549,134 @@ function balise_ACTION_FORMULAIRE($p){ value=\'' . $_form . '\' />' . '' . - (@\$Pile[0]['_hidden']?@\$Pile[0]['_hidden']:'') . + (!empty(\$Pile[0]['_hidden']) ? @\$Pile[0]['_hidden'] : '') . '
'"; $p->interdire_scripts = false; + return $p; } /** - * Generer un bouton d'action en post, ajaxable - * a utiliser a la place des liens action_auteur, sous la forme - * #BOUTON_ACTION{libelle,url} - * ou - * #BOUTON_ACTION{libelle,url,ajax} pour que l'action soit ajax comme un lien class='ajax' - * ou - * #BOUTON_ACTION{libelle,url,ajax,message_confirmation} pour utiliser un message de confirmation - * - * #BOUTON_ACTION{libelle[,url[,ajax[,message_confirmation[,title[,callback]]]]]} + * Compile la balise `#BOUTON_ACTION` qui génère un bouton d'action en post, ajaxable + * + * Cette balise s'utilise à la place des liens `action_auteur`, sous la forme * - * @param unknown_type $p - * @return unknown + * - `#BOUTON_ACTION{libelle,url}` + * - ou `#BOUTON_ACTION{libelle,url,ajax}` pour que l'action soit ajax comme un lien `class='ajax'` + * - ou `#BOUTON_ACTION{libelle,url,ajax,message_confirmation}` pour utiliser un message de confirmation + * - ou encore `#BOUTON_ACTION{libelle[,url[,ajax[,message_confirmation[,title[,callback]]]]]}` + * + * @balise + * @link http://www.spip.net/4583 + * @example + * ``` + * [(#AUTORISER{reparer,base}) + * [(#BOUTON_ACTION{<:bouton_tenter_recuperation:>,#URL_ECRIRE{base_repair}})] + * ] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ -function balise_BOUTON_ACTION_dist($p){ +function balise_BOUTON_ACTION_dist($p) { $args = array(); - for ($k=1;$k<=6;$k++){ - $_a = interprete_argument_balise($k,$p); - if (!$_a) $_a="''"; - $args[] = $_a; + for ($k = 1; $k <= 6; $k++) { + $_a = interprete_argument_balise($k, $p); + if (!$_a) { + $_a = "''"; + } + $args[] = $_a; } // supprimer les args vides - while(end($args)=="''" AND count($args)>2) + while (end($args) == "''" and count($args) > 2) { array_pop($args); - $args = implode(",",$args); + } + $args = implode(",", $args); $bouton_action = chercher_filtre("bouton_action"); $p->code = "$bouton_action($args)"; $p->interdire_scripts = false; + return $p; } - +/** + * Compile la balise `#SLOGAN_SITE_SPIP` qui retourne le slogan du site + * + * @balise + * @example + * ``` + * [

(#SLOGAN_SITE_SPIP)

] + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + */ function balise_SLOGAN_SITE_SPIP_dist($p) { $p->code = "\$GLOBALS['meta']['slogan_site']"; + #$p->interdire_scripts = true; return $p; } -// #HTML5 -// Renvoie ' ' si le webmestre souhaite que SPIP genere du code (X)HTML5 sur -// le site public, et '' si le code doit etre strictement compatible HTML4 -// http://doc.spip.org/@balise_HTML5_dist + +/** + * Compile la balise `#HTML5` indiquant si l'espace public peut utiliser du HTML5 + * + * Renvoie `' '` si le webmestre souhaite que SPIP génère du code (X)HTML5 sur + * le site public, et `''` si le code doit être strictement compatible HTML4 + * + * @balise + * @uses html5_permis() + * @example + * ``` + * [(#HTML5) required="required"] + * + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + */ function balise_HTML5_dist($p) { $p->code = html5_permis() ? "' '" : "''"; $p->interdire_scripts = false; + return $p; } - /** - * #TRI{champ[,libelle]} - * champ prend > ou < pour afficher le lien de changement de sens - * croissant ou decroissant (> < indiquent un sens par une fleche) + * Compile la balise `#TRI` permettant d'afficher un lien de changement d'ordre de tri + * d'une colonne de la boucle + * + * La balise `#TRI{champ[,libelle]}` champ prend `>` ou `<` pour afficher + * le lien de changement de sens croissant ou decroissant (`>` `<` indiquent + * un sens par une flèche) + * + * @balise + * @example + * ``` + * [(#TRI{titre,<:info_titre:>,ajax})] + * ``` * - * @param unknown_type $p - * @param unknown_type $liste - * @return unknown + * @param Champ $p + * Pile au niveau de la balise + * @param string $liste + * Inutilisé + * @return Champ + * Pile complétée par le code à générer */ -function balise_TRI_dist($p, $liste='true') { +function balise_TRI_dist($p, $liste = 'true') { $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere']; // s'il n'y a pas de nom de boucle, on ne peut pas trier @@ -1468,6 +2686,7 @@ function balise_TRI_dist($p, $liste='true') { array('champ' => '#TRI') ), $p->id_boucle); $p->code = "''"; + return $p; } $boucle = $p->boucles[$b]; @@ -1480,127 +2699,196 @@ function balise_TRI_dist($p, $liste='true') { array('champ' => '#TRI') ), $p->id_boucle); $p->code = "''"; + return $p; } - $_champ = interprete_argument_balise(1,$p); + $_champ = interprete_argument_balise(1, $p); // si pas de champ, renvoyer le critere de tri utilise - if (!$_champ){ + if (!$_champ) { $p->code = $boucle->modificateur['tri_champ']; + return $p; } // forcer la jointure si besoin, et si le champ est statique - if (preg_match(",^'([\w.]+)'$,i",$_champ,$m)){ - index_pile($b, $m[1], $p->boucles); + if (preg_match(",^'([\w.]+)'$,i", $_champ, $m)) { + index_pile($b, $m[1], $p->boucles, '', null, true, false); } - $_libelle = interprete_argument_balise(2,$p); - $_libelle = $_libelle?$_libelle:$_champ; + $_libelle = interprete_argument_balise(2, $p); + $_libelle = $_libelle ? $_libelle : $_champ; - $_class = interprete_argument_balise(3,$p); + $_class = interprete_argument_balise(3, $p); // si champ = ">" c'est un lien vers le tri croissant : de gauche a droite ==> 1 // si champ = "<" c'est un lien vers le tri decroissant : (sens inverse) == -1 $_issens = "in_array($_champ,array('>','<'))"; $_sens = "(strpos('< >',$_champ)-1)"; - $_variable = "((\$s=$_issens)?'sens':'tri').".$boucle->modificateur['tri_nom']; + $_variable = "((\$s=$_issens)?'sens':'tri')." . $boucle->modificateur['tri_nom']; $_url = "parametre_url(self(),$_variable,\$s?$_sens:$_champ)"; - $_on = "\$s?(".$boucle->modificateur['tri_sens']."==$_sens".'):('.$boucle->modificateur['tri_champ']."==$_champ)"; + $_url = "parametre_url($_url,'var_memotri',strncmp(" . $boucle->modificateur['tri_nom'] . ",'session',7)==0?$_variable:'')"; + $_on = "\$s?(" . $boucle->modificateur['tri_sens'] . "==$_sens" . '):(' . $boucle->modificateur['tri_champ'] . "==$_champ)"; - $p->code = "lien_ou_expose($_url,$_libelle,$_on".($_class?",$_class":"").")"; + $p->code = "lien_ou_expose($_url,$_libelle,$_on" . ($_class ? ",$_class" : "") . ")"; //$p->code = "''"; $p->interdire_scripts = false; + return $p; } /** - * #SAUTER{n} permet de sauter en avant n resultats dans une boucle + * Compile la balise `#SAUTER{n}` qui permet de sauter en avant n resultats dans une boucle + * * La balise modifie le compteur courant de la boucle, mais pas les autres * champs qui restent les valeurs de la boucle avant le saut. Il est donc - * preferable d'utiliser la balise juste avant la fermeture + * preferable d'utiliser la balise juste avant la fermeture `` * - * L'argument n doit etre superieur a zero sinon la balise ne fait rien + * L'argument `n` doit être supérieur à zéro sinon la balise ne fait rien + * + * @balise * - * @param $p - * @return + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ -function balise_SAUTER_dist($p){ +function balise_SAUTER_dist($p) { $id_boucle = $p->id_boucle; - $boucle = $p->boucles[$id_boucle]; - if (!$boucle) { + if (empty($p->boucles[$id_boucle])) { $msg = array('zbug_champ_hors_boucle', array('champ' => '#SAUTER')); erreur_squelette($msg, $p); - } - else { - $_saut = interprete_argument_balise(1,$p); + } else { + $boucle = $p->boucles[$id_boucle]; + $_saut = interprete_argument_balise(1, $p); $_compteur = "\$Numrows['$id_boucle']['compteur_boucle']"; $_total = "\$Numrows['$id_boucle']['total']"; $p->code = "vide($_compteur=\$iter->skip($_saut,$_total))"; } $p->interdire_scripts = false; + return $p; } /** - * Savoir si on objet est publie ou non + * Compile la balise `#PUBLIE` qui indique si un objet est publié ou non + * + * @balise + * @link http://www.spip.net/5545 + * @see objet_test_si_publie() + * @example + * ``` + * #PUBLIE : porte sur la boucle en cours + * [(#PUBLIE{article, 3}|oui) ... ] : pour l'objet indiqué + * ``` * - * @param $p - * @return + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ function balise_PUBLIE_dist($p) { - if (!$_type = interprete_argument_balise(1,$p)){ + if (!$_type = interprete_argument_balise(1, $p)) { $_type = _q($p->type_requete); - $_id = champ_sql($p->boucles[$p->id_boucle]->primary,$p); + $_id = champ_sql($p->boucles[$p->id_boucle]->primary, $p); + } else { + $_id = interprete_argument_balise(2, $p); } - else - $_id = interprete_argument_balise(2,$p); - $connect = $p->boucles[$p->id_boucle]->sql_serveur; + $connect = ''; + if (isset($p->boucles[$p->id_boucle])) { + $connect = $p->boucles[$p->id_boucle]->sql_serveur; + } - $p->code = "(objet_test_si_publie(".$_type.",intval(".$_id."),"._q($connect).")?' ':'')"; + $p->code = "(objet_test_si_publie(" . $_type . ",intval(" . $_id . ")," . _q($connect) . ")?' ':'')"; $p->interdire_scripts = false; + return $p; } /** - * #PRODUIRE - * generer un fichier statique a partir d'un squelette SPIP + * Compile la balise `#PRODUIRE` qui génère un fichier statique à partir + * d'un squelette SPIP * - * Le format du fichier sera extrait de la preextension du squelette (typo.css.html, messcripts.js.html) - * ou par l'argument format=css ou format=js passe en argument. + * Le format du fichier sera extrait de la pre-extension du squelette + * (typo.css.html, messcripts.js.html) + * ou par l'argument `format=css` ou `format=js` passé en argument. * - * Si pas de format detectable, on utilise .html, comme pour les squelettes + * S'il n'y a pas de format détectable, on utilise `.html`, comme pour les squelettes. * - * - * la syntaxe de la balise est la meme que celle de #INCLURE + * La syntaxe de la balise est la même que celle de `#INCLURE`. * - * @param object $p - * @return object + * @balise + * @see balise_INCLURE_dist() + * @link http://www.spip.net/5505 + * @example + * ``` + * + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ -function balise_PRODUIRE_dist($p){ - $balise_inclure = charger_fonction('INCLURE','balise'); +function balise_PRODUIRE_dist($p) { + $balise_inclure = charger_fonction('INCLURE', 'balise'); $p = $balise_inclure($p); - $p->code = str_replace('recuperer_fond(','produire_fond_statique(',$p->code); + $p->code = str_replace('recuperer_fond(', 'produire_fond_statique(', $p->code); return $p; } /** - * Definir la largeur d'ecran dans l'espace prive - * #LARGEUR_ECRAN{pleine_largeur} - * - * @param $p - * @return + * Compile la balise `#LARGEUR_ECRAN` qui définit la largeur d'écran + * dans l'espace privé + * + * @balise + * @example + * ``` + * #LARGEUR_ECRAN{pleine_largeur} + * ``` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer */ -function balise_LARGEUR_ECRAN_dist($p){ - $_class = interprete_argument_balise(1,$p); - if (!$_class) $_class='null'; +function balise_LARGEUR_ECRAN_dist($p) { + $_class = interprete_argument_balise(1, $p); + if (!$_class) { + $_class = 'null'; + } $p->code = "(is_string($_class)?vide(\$GLOBALS['largeur_ecran']=$_class):(isset(\$GLOBALS['largeur_ecran'])?\$GLOBALS['largeur_ecran']:''))"; + + return $p; +} + + +/** + * Compile la balise `#CONST` qui retourne la valeur de la constante passée en argument + * + * @balise + * @example `#CONST{_DIR_IMG}` + * + * @param Champ $p + * Pile au niveau de la balise + * @return Champ + * Pile complétée par le code à générer + **/ +function balise_CONST_dist($p) { + $_const = interprete_argument_balise(1, $p); + if (!strlen($_const)) { + $p->code = "''"; + } + else { + $p->code = "(defined($_const)?constant($_const):'')"; + } + $p->interdire_scripts = false; + return $p; } -?>