PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/spip/ecrire/public/balises.php

https://github.com/eyeswebcrea/espace-couture-sittler.fr
PHP | 1377 lines | 863 code | 173 blank | 341 comment | 107 complexity | 287194f54d4d7a1c571887cd311e721e MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2011 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. // Ce fichier regroupe la quasi totalite des definitions de #BALISES de spip
  12. // Pour chaque balise, il est possible de surcharger, dans mes_fonctions,
  13. // la fonction balise_TOTO_dist par une fonction balise_TOTO() respectant la
  14. // meme API :
  15. // elle recoit en entree un objet de classe CHAMP, le modifie et le retourne.
  16. // Cette classe est definie dans public/interfaces
  17. if (!defined('_ECRIRE_INC_VERSION')) return;
  18. // http://doc.spip.org/@interprete_argument_balise
  19. function interprete_argument_balise($n,$p) {
  20. if (($p->param) && (!$p->param[0][0]) && (count($p->param[0])>$n))
  21. return calculer_liste($p->param[0][$n],
  22. $p->descr,
  23. $p->boucles,
  24. $p->id_boucle);
  25. else
  26. return NULL;
  27. }
  28. //
  29. // Definition des balises
  30. //
  31. // http://doc.spip.org/@balise_NOM_SITE_SPIP_dist
  32. function balise_NOM_SITE_SPIP_dist($p) {
  33. $p->code = "\$GLOBALS['meta']['nom_site']";
  34. #$p->interdire_scripts = true;
  35. return $p;
  36. }
  37. // http://doc.spip.org/@balise_EMAIL_WEBMASTER_dist
  38. function balise_EMAIL_WEBMASTER_dist($p) {
  39. $p->code = "\$GLOBALS['meta']['email_webmaster']";
  40. #$p->interdire_scripts = true;
  41. return $p;
  42. }
  43. // http://doc.spip.org/@balise_DESCRIPTIF_SITE_SPIP_dist
  44. function balise_DESCRIPTIF_SITE_SPIP_dist($p) {
  45. $p->code = "\$GLOBALS['meta']['descriptif_site']";
  46. #$p->interdire_scripts = true;
  47. return $p;
  48. }
  49. // http://doc.spip.org/@balise_CHARSET_dist
  50. function balise_CHARSET_dist($p) {
  51. $p->code = "\$GLOBALS['meta']['charset']";
  52. #$p->interdire_scripts = true;
  53. return $p;
  54. }
  55. // http://doc.spip.org/@balise_LANG_LEFT_dist
  56. function balise_LANG_LEFT_dist($p) {
  57. $_lang = champ_sql('lang', $p);
  58. $p->code = "lang_dir($_lang, 'left','right')";
  59. $p->interdire_scripts = false;
  60. return $p;
  61. }
  62. // http://doc.spip.org/@balise_LANG_RIGHT_dist
  63. function balise_LANG_RIGHT_dist($p) {
  64. $_lang = champ_sql('lang', $p);
  65. $p->code = "lang_dir($_lang, 'right','left')";
  66. $p->interdire_scripts = false;
  67. return $p;
  68. }
  69. // http://doc.spip.org/@balise_LANG_DIR_dist
  70. function balise_LANG_DIR_dist($p) {
  71. $_lang = champ_sql('lang', $p);
  72. $p->code = "lang_dir($_lang, 'ltr','rtl')";
  73. $p->interdire_scripts = false;
  74. return $p;
  75. }
  76. // http://doc.spip.org/@balise_PUCE_dist
  77. function balise_PUCE_dist($p) {
  78. $p->code = "definir_puce()";
  79. $p->interdire_scripts = false;
  80. return $p;
  81. }
  82. // #DATE
  83. // Cette fonction sait aller chercher dans le contexte general
  84. // quand #DATE est en dehors des boucles
  85. // http://www.spip.net/fr_article1971.html
  86. // http://doc.spip.org/@balise_DATE_dist
  87. function balise_DATE_dist ($p) {
  88. $d = champ_sql('date', $p);
  89. # if ($d === "@\$Pile[0]['date']")
  90. # $d = "isset(\$Pile[0]['date']) ? $d : time()";
  91. $p->code = $d;
  92. return $p;
  93. }
  94. // #DATE_REDAC
  95. // http://www.spip.net/fr_article1971.html
  96. // http://doc.spip.org/@balise_DATE_REDAC_dist
  97. function balise_DATE_REDAC_dist ($p) {
  98. $d = champ_sql('date_redac', $p);
  99. # if ($d === "@\$Pile[0]['date_redac']")
  100. # $d = "isset(\$Pile[0]['date_redac']) ? $d : time()";
  101. $p->code = $d;
  102. $p->interdire_scripts = false;
  103. return $p;
  104. }
  105. // #DATE_MODIF
  106. // http://www.spip.net/fr_article1971.html
  107. // http://doc.spip.org/@balise_DATE_MODIF_dist
  108. function balise_DATE_MODIF_dist ($p) {
  109. $p->code = champ_sql('date_modif', $p);
  110. $p->interdire_scripts = false;
  111. return $p;
  112. }
  113. // #DATE_NOUVEAUTES
  114. // http://www.spip.net/fr_article1971.html
  115. // http://doc.spip.org/@balise_DATE_NOUVEAUTES_dist
  116. function balise_DATE_NOUVEAUTES_dist($p) {
  117. $p->code = "((\$GLOBALS['meta']['quoi_de_neuf'] == 'oui'
  118. AND @is_readable(_DIR_TMP . 'mail.lock')) ?
  119. @filemtime(_DIR_TMP . 'mail.lock') :
  120. \"'0000-00-00'\")";
  121. $p->interdire_scripts = false;
  122. return $p;
  123. }
  124. // http://doc.spip.org/@balise_DOSSIER_SQUELETTE_dist
  125. function balise_DOSSIER_SQUELETTE_dist($p) {
  126. $code = substr(addslashes(dirname($p->descr['sourcefile'])), strlen(_DIR_RACINE));
  127. $p->code = "_DIR_RACINE . '$code'" .
  128. $p->interdire_scripts = false;
  129. return $p;
  130. }
  131. // http://doc.spip.org/@balise_SQUELETTE_dist
  132. function balise_SQUELETTE_dist($p) {
  133. $code = addslashes($p->descr['sourcefile']);
  134. $p->code = "'$code'" .
  135. $p->interdire_scripts = false;
  136. return $p;
  137. }
  138. // http://doc.spip.org/@balise_SPIP_VERSION_dist
  139. function balise_SPIP_VERSION_dist($p) {
  140. $p->code = "spip_version()";
  141. $p->interdire_scripts = false;
  142. return $p;
  143. }
  144. // #NOM_SITE affiche le nom du site, ou sinon l'URL ou le titre de l'objet
  145. // http://doc.spip.org/@balise_NOM_SITE_dist
  146. function balise_NOM_SITE_dist($p) {
  147. if (!$p->etoile) {
  148. $p->code = "supprimer_numero(calculer_url(" .
  149. champ_sql('url_site',$p) ."," .
  150. champ_sql('nom_site',$p) .
  151. ", 'titre', \$connect))";
  152. } else
  153. $p->code = champ_sql('nom_site',$p);
  154. $p->interdire_scripts = true;
  155. return $p;
  156. }
  157. // http://doc.spip.org/@balise_NOTES_dist
  158. function balise_NOTES_dist($p) {
  159. // Recuperer les notes
  160. $p->code = 'calculer_notes()';
  161. #$p->interdire_scripts = true;
  162. return $p;
  163. }
  164. // http://doc.spip.org/@balise_RECHERCHE_dist
  165. function balise_RECHERCHE_dist($p) {
  166. $p->code = 'entites_html(_request("recherche"))';
  167. $p->interdire_scripts = false;
  168. return $p;
  169. }
  170. // http://doc.spip.org/@balise_COMPTEUR_BOUCLE_dist
  171. function balise_COMPTEUR_BOUCLE_dist($p) {
  172. $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
  173. if ($b === '') {
  174. $msg = array('zbug_champ_hors_boucle',
  175. array('champ' => '#COMPTEUR_BOUCLE')
  176. );
  177. erreur_squelette($msg, $p);
  178. } else {
  179. $p->code = "\$Numrows['$b']['compteur_boucle']";
  180. $p->boucles[$b]->cptrows = true;
  181. $p->interdire_scripts = false;
  182. return $p;
  183. }
  184. }
  185. // http://doc.spip.org/@balise_TOTAL_BOUCLE_dist
  186. function balise_TOTAL_BOUCLE_dist($p) {
  187. $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
  188. if ($b === '' || !isset($p->boucles[$b])) {
  189. $msg = array('zbug_champ_hors_boucle',
  190. array('champ' => "#$b" . 'TOTAL_BOUCLE')
  191. );
  192. erreur_squelette($msg, $p);
  193. } else {
  194. $p->code = "\$Numrows['$b']['total']";
  195. $p->boucles[$b]->numrows = true;
  196. $p->interdire_scripts = false;
  197. }
  198. return $p;
  199. }
  200. // Si on est hors d'une boucle {recherche}, ne pas "prendre" cette balise
  201. // http://doc.spip.org/@balise_POINTS_dist
  202. function balise_POINTS_dist($p) {
  203. return rindex_pile($p, 'points', 'recherche');
  204. }
  205. // http://doc.spip.org/@balise_POPULARITE_ABSOLUE_dist
  206. function balise_POPULARITE_ABSOLUE_dist($p) {
  207. $p->code = 'ceil(' .
  208. champ_sql('popularite', $p) .
  209. ')';
  210. $p->interdire_scripts = false;
  211. return $p;
  212. }
  213. // http://doc.spip.org/@balise_POPULARITE_SITE_dist
  214. function balise_POPULARITE_SITE_dist($p) {
  215. $p->code = 'ceil($GLOBALS["meta"][\'popularite_total\'])';
  216. $p->interdire_scripts = false;
  217. return $p;
  218. }
  219. // http://doc.spip.org/@balise_POPULARITE_MAX_dist
  220. function balise_POPULARITE_MAX_dist($p) {
  221. $p->code = 'ceil($GLOBALS["meta"][\'popularite_max\'])';
  222. $p->interdire_scripts = false;
  223. return $p;
  224. }
  225. // http://doc.spip.org/@balise_EXPOSE_dist
  226. function balise_EXPOSE_dist($p) {
  227. $on = "'on'";
  228. $off= "''";
  229. if (($v = interprete_argument_balise(1,$p))!==NULL){
  230. $on = $v;
  231. if (($v = interprete_argument_balise(2,$p))!==NULL)
  232. $off = $v;
  233. }
  234. return calculer_balise_expose($p, $on, $off);
  235. }
  236. // http://doc.spip.org/@calculer_balise_expose
  237. function calculer_balise_expose($p, $on, $off)
  238. {
  239. $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
  240. $key = $p->boucles[$b]->primary;
  241. $type = $p->boucles[$p->id_boucle]->primary;
  242. $desc = $p->boucles[$b]->show;
  243. $connect = sql_quote($p->boucles[$b]->sql_serveur);
  244. if (!$key) {
  245. $msg = array('zbug_champ_hors_boucle', array('champ' => '#EXPOSER'));
  246. erreur_squelette($msg, $p);
  247. }
  248. // Ne pas utiliser champ_sql, on jongle avec le nom boucle explicite
  249. $c = index_pile($p->id_boucle, $type, $p->boucles);
  250. if (isset($desc['field']['id_parent'])) {
  251. $parent = 0; // pour if (!$parent) dans calculer_expose
  252. } elseif (isset($desc['field']['id_rubrique'])) {
  253. $parent = index_pile($p->id_boucle, 'id_rubrique', $p->boucles, $b);
  254. } elseif (isset($desc['field']['id_groupe'])) {
  255. $parent = index_pile($p->id_boucle, 'id_groupe', $p->boucles, $b);
  256. } else $parent = "''";
  257. $p->code = "(calcul_exposer($c, '$type', \$Pile[0], $parent, '$key', $connect) ? $on : $off)";
  258. $p->interdire_scripts = false;
  259. return $p;
  260. }
  261. // Debut et fin de surlignage auto des mots de la recherche
  262. // on insere une balise Span avec une classe sans spec:
  263. // c'est transparent s'il n'y a pas de recherche,
  264. // sinon elles seront remplacees par les fontions de inc_surligne
  265. // http://doc.spip.org/@balise_DEBUT_SURLIGNE_dist
  266. function balise_DEBUT_SURLIGNE_dist($p) {
  267. include_spip('inc/surligne');
  268. $p->code = "'<!-- " . MARQUEUR_SURLIGNE . " -->'";
  269. return $p;
  270. }
  271. // http://doc.spip.org/@balise_FIN_SURLIGNE_dist
  272. function balise_FIN_SURLIGNE_dist($p) {
  273. include_spip('inc/surligne');
  274. $p->code = "'<!-- " . MARQUEUR_FSURLIGNE . "-->'";
  275. return $p;
  276. }
  277. // #SPIP_CRON
  278. // a documenter
  279. // insere un <div> avec un lien background-image vers les taches de fond.
  280. // Si cette balise est presente sur la page de sommaire, le site ne devrait
  281. // quasiment jamais se trouver ralenti par des taches de fond un peu lentes
  282. // http://doc.spip.org/@balise_SPIP_CRON_dist
  283. function balise_SPIP_CRON_dist ($p) {
  284. $p->code = '"<!-- SPIP-CRON --><div style=\"background-image: url(\'' .
  285. generer_url_action('cron') .
  286. '\');\"></div>"';
  287. $p->interdire_scripts = false;
  288. return $p;
  289. }
  290. // #INTRODUCTION
  291. // #INTRODUCTION{longueur}
  292. // http://www.spip.net/@introduction
  293. // http://doc.spip.org/@balise_INTRODUCTION_dist
  294. function balise_INTRODUCTION_dist($p) {
  295. $type = $p->type_requete;
  296. $_texte = champ_sql('texte', $p);
  297. $_descriptif = ($type == 'articles' OR $type == 'rubriques') ? champ_sql('descriptif', $p) : "''";
  298. if ($type == 'articles') {
  299. $_chapo = champ_sql('chapo', $p);
  300. $_texte = "(strlen($_descriptif) OR chapo_redirigetil($_chapo))
  301. ? ''
  302. : $_chapo . \"\\n\\n\" . $_texte";
  303. }
  304. // longueur en parametre, ou valeur par defaut
  305. if (($v = interprete_argument_balise(1,$p))!==NULL) {
  306. $longueur = 'intval('.$v.')';
  307. } else {
  308. switch ($type) {
  309. case 'articles':
  310. $longueur = '500';
  311. break;
  312. case 'breves':
  313. $longueur = '300';
  314. break;
  315. case 'rubriques':
  316. default:
  317. $longueur = '600';
  318. break;
  319. }
  320. }
  321. $f = chercher_filtre('introduction');
  322. $p->code = "$f($_descriptif, $_texte, $longueur, \$connect)";
  323. #$p->interdire_scripts = true;
  324. $p->etoile = '*'; // propre est deja fait dans le calcul de l'intro
  325. return $p;
  326. }
  327. // #LANG
  328. // affiche la langue de l'objet (ou superieure), et a defaut la langue courante
  329. // (celle du site ou celle qui a ete passee dans l'URL par le visiteur)
  330. // #LANG* n'affiche rien si aucune langue n'est trouvee dans le sql/le contexte
  331. // http://doc.spip.org/@balise_LANG_dist
  332. function balise_LANG_dist ($p) {
  333. $_lang = champ_sql('lang', $p);
  334. if (!$p->etoile)
  335. $p->code = "htmlentities($_lang ? $_lang : \$GLOBALS['spip_lang'])";
  336. else
  337. $p->code = "htmlentities($_lang)";
  338. $p->interdire_scripts = false;
  339. return $p;
  340. }
  341. // http://doc.spip.org/@balise_CHAPO_dist
  342. function balise_CHAPO_dist ($p) {
  343. $_chapo = champ_sql('chapo', $p);
  344. if (($p->etoile) OR (strpos($_chapo, '$Pile[$SP') === false))
  345. $p->code = $_chapo;
  346. else
  347. $p->code = "nettoyer_chapo($_chapo)";
  348. $p->interdire_scripts = true;
  349. return $p;
  350. }
  351. // #LESAUTEURS
  352. // les auteurs d'un article (ou d'un article syndique)
  353. // http://www.spip.net/fr_article902.html
  354. // http://www.spip.net/fr_article911.html
  355. // http://doc.spip.org/@balise_LESAUTEURS_dist
  356. function balise_LESAUTEURS_dist ($p) {
  357. // Cherche le champ 'lesauteurs' dans la pile
  358. $_lesauteurs = champ_sql('lesauteurs', $p);
  359. // Si le champ n'existe pas (cas de spip_articles), on applique
  360. // le modele lesauteurs.html en passant id_article dans le contexte;
  361. // dans le cas contraire on prend le champ 'lesauteurs' (cas de
  362. // spip_syndic_articles)
  363. if ($_lesauteurs
  364. AND $_lesauteurs != '@$Pile[0][\'lesauteurs\']') {
  365. $p->code = "safehtml($_lesauteurs)";
  366. // $p->interdire_scripts = true;
  367. } else {
  368. $connect = !$p->id_boucle ? ''
  369. : $p->boucles[$p->id_boucle]->sql_serveur;
  370. $c = memoriser_contexte_compil($p);
  371. $p->code = sprintf(CODE_RECUPERER_FOND, "'modeles/lesauteurs'",
  372. "array('id_article' => ".champ_sql('id_article', $p) .")",
  373. "'trim'=>true, 'compil'=>array($c)",
  374. _q($connect));
  375. $p->interdire_scripts = false; // securite apposee par recuperer_fond()
  376. }
  377. return $p;
  378. }
  379. // #RANG
  380. // affiche le "numero de l'article" quand on l'a titre '1. Premier article';
  381. // ceci est transitoire afin de preparer une migration vers un vrai systeme de
  382. // tri des articles dans une rubrique (et plus si affinites)
  383. // http://doc.spip.org/@balise_RANG_dist
  384. function balise_RANG_dist ($p) {
  385. $_titre = champ_sql('titre', $p);
  386. $_rang = champ_sql('rang', $p);
  387. $p->code = "(($_rang)?($_rang):recuperer_numero($_titre))";
  388. $p->interdire_scripts = false;
  389. return $p;
  390. }
  391. // #PETITION
  392. // retourne '' si l'article courant n'a pas de petition
  393. // le texte de celle-ci sinon (et ' ' si il est vide)
  394. // cf FORMULAIRE_PETITION
  395. // http://doc.spip.org/@balise_PETITION_dist
  396. function balise_PETITION_dist ($p) {
  397. $nom = $p->id_boucle;
  398. $p->code = "quete_petitions(" .
  399. champ_sql('id_article', $p) .
  400. ",'" .
  401. $p->boucles[$nom]->type_requete .
  402. "','" .
  403. $nom .
  404. "','" .
  405. $p->boucles[$nom]->sql_serveur .
  406. "', \$Cache)";
  407. $p->interdire_scripts = false;
  408. return $p;
  409. }
  410. // #POPULARITE
  411. // http://www.spip.net/fr_article1846.html
  412. // http://doc.spip.org/@balise_POPULARITE_dist
  413. function balise_POPULARITE_dist ($p) {
  414. $_popularite = champ_sql('popularite', $p);
  415. $p->code = "(ceil(min(100, 100 * $_popularite
  416. / max(1 , 0 + \$GLOBALS['meta']['popularite_max']))))";
  417. $p->interdire_scripts = false;
  418. return $p;
  419. }
  420. // #PAGINATION
  421. // Le code produit est trompeur, car les modeles ne fournissent pas Pile[0].
  422. // On produit un appel a _request si on ne l'a pas, mais c'est inexact:
  423. // l'absence peut etre due a une faute de frappe dans le contexte inclus.
  424. define('CODE_PAGINATION',
  425. '%s($Numrows["%s"]["grand_total"],
  426. %s,
  427. isset($Pile[0][%4$s])?$Pile[0][%4$s]:intval(_request(%4$s)),
  428. %5$s, %6$s, %7$s, %8$s, array(%9$s))');
  429. // http://www.spip.net/fr_article3367.html
  430. // http://doc.spip.org/@balise_PAGINATION_dist
  431. function balise_PAGINATION_dist($p, $liste='true') {
  432. $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
  433. // s'il n'y a pas de nom de boucle, on ne peut pas paginer
  434. if ($b === '') {
  435. $msg = array('zbug_champ_hors_boucle',
  436. array('champ' => $liste ? 'PAGINATION' : 'ANCRE_PAGINATION')
  437. );
  438. erreur_squelette($msg, $p);
  439. return $p;
  440. }
  441. // s'il n'y a pas de mode_partie, c'est qu'on se trouve
  442. // dans un boucle recursive ou qu'on a oublie le critere {pagination}
  443. if (!$p->boucles[$b]->mode_partie) {
  444. if (!$p->boucles[$b]->table_optionnelle) {
  445. $msg = array('zbug_pagination_sans_critere',
  446. array('champ' => '#PAGINATION')
  447. );
  448. erreur_squelette($msg, $p);
  449. }
  450. return $p;
  451. }
  452. $__modele = interprete_argument_balise(1,$p);
  453. if ($p->param) {
  454. $params = $p->param;
  455. array_shift($params);
  456. // a priori true
  457. // si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise
  458. // si true, les arguments simples (sans truc=chose) vont degager
  459. $code_contexte = argumenter_inclure($params, true, $p, $p->boucles, $p->id_boucle, false);
  460. $code_contexte = implode(',',$code_contexte);
  461. } else $code_contexte = '';
  462. $connect = $p->boucles[$b]->sql_serveur;
  463. $pas = $p->boucles[$b]->total_parties;
  464. $f_pagination = chercher_filtre('pagination');
  465. $type = $p->boucles[$b]->modificateur['debut_nom'];
  466. $modif = ($type[0]!=="'") ? "'debut'.$type"
  467. : ("'debut" .substr($type,1));
  468. $p->code = sprintf(CODE_PAGINATION, $f_pagination,$b, $type, $modif, $pas, $liste, ($__modele ? $__modele : "''"), _q($connect), $code_contexte);
  469. $p->boucles[$b]->numrows = true;
  470. $p->interdire_scripts = false;
  471. return $p;
  472. }
  473. // N'afficher que l'ancre de la pagination (au-dessus, par exemple, alors
  474. // qu'on mettra les liens en-dessous de la liste paginee)
  475. // http://doc.spip.org/@balise_ANCRE_PAGINATION_dist
  476. function balise_ANCRE_PAGINATION_dist($p) {
  477. if ($f = charger_fonction('PAGINATION', 'balise', true))
  478. return $f($p, $liste='false');
  479. else return NULL; // ou une erreur ?
  480. }
  481. // equivalent a #TOTAL_BOUCLE sauf pour les boucles paginees, ou elle
  482. // indique le nombre total d'articles repondant aux criteres hors pagination
  483. // http://doc.spip.org/@balise_GRAND_TOTAL_dist
  484. function balise_GRAND_TOTAL_dist($p) {
  485. $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
  486. if ($b === '' || !isset($p->boucles[$b])) {
  487. $msg = array('zbug_champ_hors_boucle',
  488. array('champ' => "#$b" . 'TOTAL_BOUCLE')
  489. );
  490. erreur_squelette($msg, $p);
  491. } else {
  492. $p->code = "(isset(\$Numrows['$b']['grand_total'])
  493. ? \$Numrows['$b']['grand_total'] : \$Numrows['$b']['total'])";
  494. $p->boucles[$b]->numrows = true;
  495. $p->interdire_scripts = false;
  496. }
  497. return $p;
  498. }
  499. //
  500. // Parametres de reponse a un forum
  501. //
  502. // http://doc.spip.org/@balise_PARAMETRES_FORUM_dist
  503. function balise_PARAMETRES_FORUM_dist($p) {
  504. $_id_article = champ_sql('id_article', $p);
  505. $p->code = '
  506. // refus des forums ?
  507. (quete_accepter_forum('.$_id_article.')=="non" OR
  508. ($GLOBALS["meta"]["forums_publics"] == "non"
  509. AND quete_accepter_forum('.$_id_article.') == ""))
  510. ? "" : // sinon:
  511. ';
  512. // pas de calculs superflus si le site est monolingue
  513. $lang = strpos($GLOBALS['meta']['langues_utilisees'], ',');
  514. switch ($p->type_requete) {
  515. case 'articles':
  516. $c = '"id_article=".' . champ_sql('id_article', $p);
  517. if ($lang) $lang = champ_sql('lang', $p);
  518. break;
  519. case 'breves':
  520. $c = '"id_breve=".' . champ_sql('id_breve', $p);
  521. if ($lang) $lang = champ_sql('lang', $p);
  522. break;
  523. case 'rubriques':
  524. $c = '"id_rubrique=".' . champ_sql('id_rubrique', $p);
  525. if ($lang) $lang = champ_sql('lang', $p);
  526. break;
  527. case 'syndication':
  528. case 'syndic':
  529. // passer par la rubrique pour avoir un champ Lang
  530. // la table syndic n'en ayant pas
  531. $c = '"id_syndic=".' . champ_sql('id_syndic', $p);
  532. if ($lang) $lang = 'sql_getfetsel("lang", "spip_rubriques", ("id_rubrique=" . intval("' . champ_sql('id_rubrique', $p) . '")))';
  533. break;
  534. case 'forums':
  535. default:
  536. // ATTENTION mettre 'id_rubrique' avant 'id_syndic':
  537. // a l'execution lang_parametres_forum
  538. // y cherchera l'identifiant donnant la langue
  539. // et pour id_syndic c'est id_rubrique car sa table n'en a pas
  540. $liste_table = array ("article","breve","rubrique","syndic","forum");
  541. $c = '';
  542. $tables = array();
  543. foreach ($liste_table as $t) {
  544. $champ = 'id_' . $t;
  545. $x = champ_sql($champ, $p);
  546. $c .= (($c) ? ".\n" : "") . "((!$x) ? '' : ('&$champ='.$x))";
  547. if ($lang AND $t!='forum') $tables[]=
  548. "'$champ' => '" . table_objet_sql($t) . "'";
  549. }
  550. $c = "substr($c,1)";
  551. if ($lang)
  552. $lang = "array(" . join(",",$tables) .")";
  553. break;
  554. }
  555. if ($lang) $c = "lang_parametres_forum($c,$lang)";
  556. // Syntaxe [(#PARAMETRES_FORUM{#SELF})] pour fixer le retour du forum
  557. # note : ce bloc qui sert a recuperer des arguments calcules pourrait
  558. # porter un nom et faire partie de l'API.
  559. $retour = interprete_argument_balise(1,$p);
  560. if ($retour===NULL)
  561. $retour = "''";
  562. // Attention un eventuel &retour=xxx dans l'URL est prioritaire
  563. $c .= '.
  564. (($lien = (_request("retour") ? _request("retour") : str_replace("&amp;", "&", '.$retour.'))) ? "&retour=".rawurlencode($lien) : "")';
  565. // Ajouter le code d'invalideur specifique a cette balise
  566. include_spip('inc/invalideur');
  567. if (function_exists($i = 'code_invalideur_forums'))
  568. $p->code .= $i($p, '('.$c.')');
  569. $p->interdire_scripts = false;
  570. return $p;
  571. }
  572. // Reference a l'URL de la page courante
  573. // Attention dans un INCLURE() ou une balise dynamique on n'a pas le droit de
  574. // mettre en cache #SELF car il peut correspondre a une autre page (attaque XSS)
  575. // (Dans ce cas faire <INCLURE{self=#SELF}> pour differencier les caches.)
  576. // http://www.spip.net/@self
  577. // http://doc.spip.org/@balise_SELF_dist
  578. function balise_SELF_dist($p) {
  579. $p->code = 'self()';
  580. $p->interdire_scripts = false;
  581. return $p;
  582. }
  583. //
  584. // #CHEMIN{fichier} -> find_in_path(fichier)
  585. //
  586. // http://doc.spip.org/@balise_CHEMIN_dist
  587. function balise_CHEMIN_dist($p) {
  588. $arg = interprete_argument_balise(1,$p);
  589. if (!$arg) {
  590. $msg = array('zbug_balise_sans_argument', array('balise' => ' CHEMIN'));
  591. erreur_squelette($msg, $p);
  592. } else
  593. $p->code = 'find_in_path(' . $arg .')';
  594. #$p->interdire_scripts = true;
  595. return $p;
  596. }
  597. function balise_CHEMIN_IMAGE_dist($p) {
  598. $arg = interprete_argument_balise(1,$p);
  599. if (!$arg) {
  600. $msg = array('zbug_balise_sans_argument', array('balise' => ' CHEMIN_IMAGE'));
  601. erreur_squelette($msg, $p);
  602. } else $p->code = 'chemin_image(' . $arg .')';
  603. #$p->interdire_scripts = true;
  604. return $p;
  605. }
  606. //
  607. // #ENV
  608. // l'"environnement", id est le $contexte (ou $contexte_inclus)
  609. //
  610. // en standard on applique |entites_html, mais si vous utilisez
  611. // [(#ENV*{toto})] il *faut* vous assurer vous-memes de la securite
  612. // anti-javascript (par exemple en filtrant avec |safehtml)
  613. //
  614. // La syntaxe #ENV{toto, rempl} renverra 'rempl' si $toto est vide
  615. //
  616. // Si le tableau est vide on renvoie '' (utile pour #SESSION)
  617. //
  618. // http://doc.spip.org/@balise_ENV_dist
  619. function balise_ENV_dist($p, $src = NULL) {
  620. // le tableau de base de la balise (cf #META ci-dessous)
  621. $_nom = interprete_argument_balise(1,$p);
  622. $_sinon = interprete_argument_balise(2,$p);
  623. if (!$_nom) {
  624. // cas de #ENV sans argument : on retourne le serialize() du tableau
  625. // une belle fonction [(#ENV|affiche_env)] serait pratique
  626. $p->code = $src
  627. ? ('(is_array($a = ('.$src.')) ? serialize($a) : "")')
  628. : '@serialize($Pile[0])';
  629. } else {
  630. // admet deux arguments : nom de variable, valeur par defaut si vide
  631. $p->code = $src
  632. ? ('is_array($a = ('.$src.')) ? $a['.$_nom.'] : ""')
  633. : ('@$Pile[0][' . $_nom . ']');
  634. if ($_sinon)
  635. $p->code = 'sinon('.
  636. $p->code.",$_sinon)";
  637. else
  638. $p->code = '('.$p->code.')';
  639. }
  640. #$p->interdire_scripts = true;
  641. return $p;
  642. }
  643. //
  644. // #CONFIG
  645. // les reglages du site
  646. //
  647. // Par exemple #CONFIG{gerer_trad} donne 'oui' ou 'non' selon le reglage
  648. // Attention c'est brut de decoffrage de la table spip_meta
  649. //
  650. // La balise fonctionne exactement comme #ENV (ci-dessus)
  651. //
  652. // http://doc.spip.org/@balise_CONFIG_dist
  653. function balise_CONFIG_dist($p) {
  654. if(function_exists('balise_ENV'))
  655. return balise_ENV($p, '$GLOBALS["meta"]');
  656. else
  657. return balise_ENV_dist($p, '$GLOBALS["meta"]');
  658. }
  659. // http://doc.spip.org/@balise_CONNECT_dist
  660. function balise_CONNECT_dist($p) {
  661. $p->code = '($connect ? $connect : NULL)';
  662. $p->interdire_scripts = false;
  663. return $p;
  664. }
  665. //
  666. // #SESSION
  667. // Cette balise est un tableau des donnees du visiteur (nom, email etc)
  668. // Si elle est invoquee, elle leve un drapeau dans le fichier cache, qui
  669. // permet a public/cacher d'invalider le cache si le visiteur suivant n'a
  670. // pas la meme session
  671. // http://doc.spip.org/@balise_SESSION_dist
  672. function balise_SESSION_dist($p) {
  673. $p->descr['session'] = true;
  674. $f = function_exists('balise_ENV')
  675. ? 'balise_ENV'
  676. : 'balise_ENV_dist';
  677. $p = $f($p, '$GLOBALS["visiteur_session"]');
  678. return $p;
  679. }
  680. //
  681. // #SESSION_SET{x,y}
  682. // Ajoute x=y dans la session du visiteur
  683. // http://doc.spip.org/@balise_SESSION_SET_dist
  684. function balise_SESSION_SET_dist($p) {
  685. $_nom = interprete_argument_balise(1,$p);
  686. $_val = interprete_argument_balise(2,$p);
  687. if (!$_nom OR !$_val) {
  688. $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'SESSION_SET'));
  689. erreur_squelette($err_b_s_a, $p);
  690. } else $p->code = '(include_spip("inc/session") AND session_set('.$_nom.','.$_val.'))';
  691. $p->interdire_scripts = false;
  692. return $p;
  693. }
  694. //
  695. // #EVAL{...}
  696. // evalue un code php ; a utiliser avec precaution :-)
  697. //
  698. // rq: #EVAL{code} produit eval('return code;')
  699. // mais si le code est une expression sans balise, on se dispense
  700. // de passer par une construction si compliquee, et le code est
  701. // passe tel quel (entre parentheses, et protege par interdire_scripts)
  702. // Exemples : #EVAL**{6+9} #EVAL**{_DIR_IMG_PACK} #EVAL{'date("Y-m-d")'}
  703. // #EVAL{'str_replace("r","z", "roger")'} (attention les "'" sont interdits)
  704. // http://doc.spip.org/@balise_EVAL_dist
  705. function balise_EVAL_dist($p) {
  706. $php = interprete_argument_balise(1,$p);
  707. if ($php) {
  708. # optimisation sur les #EVAL{une expression sans #BALISE}
  709. # attention au commentaire "// x signes" qui precede
  710. if (preg_match(",^([[:space:]]*//[^\n]*\n)'([^']+)'$,ms",
  711. $php,$r))
  712. $p->code = /* $r[1]. */'('.$r[2].')';
  713. else
  714. $p->code = "eval('return '.$php.';')";
  715. } else {
  716. $msg = array('zbug_balise_sans_argument', array('balise' => ' EVAL'));
  717. erreur_squelette($msg, $p);
  718. }
  719. #$p->interdire_scripts = true;
  720. return $p;
  721. }
  722. // #CHAMP_SQL{x} renvoie la valeur du champ sql 'x'
  723. // permet de recuperer par exemple un champ notes dans une table sql externe
  724. // (impossible via #NOTES qui est une balise calculee)
  725. // ne permet pas de passer une expression pour x qui ne peut etre qu'un texte statique !
  726. // http://doc.spip.org/@balise_CHAMP_SQL_dist
  727. function balise_CHAMP_SQL_dist($p){
  728. if ($p->param
  729. AND isset($p->param[0][1][0])
  730. AND $champ = ($p->param[0][1][0]->texte))
  731. $p->code = champ_sql($champ, $p);
  732. else {
  733. $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => ' URL_'));
  734. erreur_squelette($err_b_s_a, $p);
  735. }
  736. #$p->interdire_scripts = true;
  737. return $p;
  738. }
  739. // #VAL{x} renvoie 'x' (permet d'appliquer un filtre a une chaine)
  740. // Attention #VAL{1,2} renvoie '1', indiquer #VAL{'1,2'}
  741. // http://doc.spip.org/@balise_VAL_dist
  742. function balise_VAL_dist($p){
  743. $p->code = interprete_argument_balise(1,$p);
  744. if (!strlen($p->code))
  745. $p->code = "''";
  746. $p->interdire_scripts = false;
  747. return $p;
  748. }
  749. // #NOOP est un alias pour regler #948, ne pas documenter
  750. // http://doc.spip.org/@balise_NOOP_dist
  751. function balise_NOOP_dist($p) { return balise_VAL_dist($p); }
  752. //
  753. // #REM
  754. // pour les remarques : renvoie toujours ''
  755. //
  756. // http://doc.spip.org/@balise_REM_dist
  757. function balise_REM_dist($p) {
  758. $p->code="''";
  759. $p->interdire_scripts = false;
  760. return $p;
  761. }
  762. //
  763. // #HTTP_HEADER
  764. // pour les entetes de retour http
  765. // Ne fonctionne pas sur les INCLURE !
  766. // #HTTP_HEADER{Content-Type: text/css}
  767. //
  768. // http://doc.spip.org/@balise_HTTP_HEADER_dist
  769. function balise_HTTP_HEADER_dist($p) {
  770. $header = interprete_argument_balise(1,$p);
  771. if (!$header) {
  772. $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'HTTP_HEADER'));
  773. erreur_squelette($err_b_s_a, $p);
  774. } else $p->code = "'<'.'?php header(\"' . "
  775. . $header
  776. . " . '\"); ?'.'>'";
  777. $p->interdire_scripts = false;
  778. return $p;
  779. }
  780. // Filtre a appliquer a l'ensemble de la page une fois calculee
  781. // (filtrage fait au niveau du squelette, et sans s'appliquer aux <INCLURE>)
  782. // http://doc.spip.org/@balise_FILTRE_dist
  783. function balise_FILTRE_dist($p) {
  784. if ($p->param) {
  785. $args = array();
  786. foreach ($p->param as $i => $ignore)
  787. $args[] = interprete_argument_balise($i+1,$p);
  788. $p->code = "'<' . '"
  789. .'?php header("X-Spip-Filtre: \'.'
  790. .join('.\'|\'.', $args)
  791. . " . '\"); ?'.'>'";
  792. $p->interdire_scripts = false;
  793. return $p;
  794. }
  795. }
  796. //
  797. // #CACHE
  798. // definit la duree de vie ($delais) du squelette
  799. // #CACHE{24*3600}
  800. // parametre(s) supplementaire(s) :
  801. // #CACHE{24*3600, cache-client} autorise gestion du IF_MODIFIED_SINCE
  802. // #CACHE{24*3600, statique} ne respecte pas l'invalidation par modif de la base
  803. // (mais s'invalide tout de meme a l'expiration du delai)
  804. // par defaut cache-client => statique
  805. // cf. ecrire/public/cacher.php
  806. // http://doc.spip.org/@balise_CACHE_dist
  807. function balise_CACHE_dist($p) {
  808. if ($p->param) {
  809. $duree = valeur_numerique($p->param[0][1][0]->texte);
  810. // noter la duree du cache dans un entete proprietaire
  811. $code = '\'<'.'?php header("X-Spip-Cache: '
  812. . $duree
  813. . '"); ?'.'>\'';
  814. // Remplir le header Cache-Control
  815. // cas #CACHE{0}
  816. if ($duree == 0)
  817. $code .= '.\'<'
  818. .'?php header("Cache-Control: no-store, no-cache, must-revalidate"); ?'
  819. .'><'
  820. .'?php header("Pragma: no-cache"); ?'
  821. .'>\'';
  822. // recuperer les parametres suivants
  823. $i = 1;
  824. while (isset($p->param[0][++$i])) {
  825. $pa = ($p->param[0][$i][0]->texte);
  826. if ($pa == 'cache-client'
  827. AND $duree > 0) {
  828. $code .= '.\'<'.'?php header("Cache-Control: max-age='
  829. . $duree
  830. . '"); ?'.'>\'';
  831. // il semble logique, si on cache-client, de ne pas invalider
  832. $pa = 'statique';
  833. }
  834. if ($pa == 'statique'
  835. AND $duree > 0)
  836. $code .= '.\'<'.'?php header("X-Spip-Statique: oui"); ?'.'>\'';
  837. }
  838. } else $code = "''";
  839. $p->code = $code;
  840. $p->interdire_scripts = false;
  841. return $p;
  842. }
  843. //
  844. // #INSERT_HEAD
  845. // pour permettre aux plugins d'inserer des styles, js ou autre
  846. // dans l'entete sans modification du squelette
  847. // les css doivent etre inserees de preference par #INSERT_HEAD_CSS
  848. // pour en faciliter la surcharge
  849. //
  850. // http://doc.spip.org/@balise_INSERT_HEAD_dist
  851. function balise_INSERT_HEAD_dist($p) {
  852. $p->code = "insert_head_css().pipeline('insert_head','<!-- insert_head -->')";
  853. $p->code .= '. \'<'
  854. .'?php header("X-Spip-Filtre: \'.'
  855. .'\'compacte_head\''
  856. . " . '\"); ?'.'>'";
  857. $p->interdire_scripts = false;
  858. return $p;
  859. }
  860. // http://doc.spip.org/@balise_INSERT_HEAD_CSS_dist
  861. function balise_INSERT_HEAD_CSS_dist($p) {
  862. $p->code = "insert_head_css()";
  863. $p->interdire_scripts = false;
  864. return $p;
  865. }
  866. //
  867. // #INCLURE statique
  868. // l'inclusion est realisee au calcul du squelette, pas au service
  869. // ainsi le produit du squelette peut etre utilise en entree de filtres a suivre
  870. // on peut faire un #INCLURE{fichier} sans squelette
  871. // (Incompatible avec les balises dynamiques)
  872. // http://doc.spip.org/@balise_INCLUDE_dist
  873. function balise_INCLUDE_dist($p) {
  874. if(function_exists('balise_INCLURE'))
  875. return balise_INCLURE($p);
  876. else
  877. return balise_INCLURE_dist($p);
  878. }
  879. // http://doc.spip.org/@balise_INCLURE_dist
  880. function balise_INCLURE_dist($p) {
  881. $id_boucle = $p->id_boucle;
  882. // la lang n'est pas passe de facon automatique par argumenter
  883. // mais le sera pas recuperer_fond, sauf si etoile=>true est passe
  884. // en option
  885. $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $id_boucle, false, false);
  886. // erreur de syntaxe = fond absent
  887. // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
  888. if (!$_contexte) $contexte = array();
  889. if (isset($_contexte['fond'])) {
  890. $f = $_contexte['fond'];
  891. // toujours vrai :
  892. if (preg_match('/^.fond.\s*=>(.*)$/s', $f, $r)) {
  893. $f = $r[1];
  894. unset($_contexte['fond']);
  895. } else spip_log("compilation de #INCLURE a revoir");
  896. // #INCLURE{doublons}
  897. if (isset($_contexte['doublons'])) {
  898. $_contexte['doublons'] = "'doublons' => \$doublons";
  899. }
  900. // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
  901. if (isset($_contexte['env'])
  902. || isset($_contexte['self'])
  903. ) {
  904. $flag_env = true;
  905. unset($_contexte['env']);
  906. } else $flag_env = false;
  907. $_options = array();
  908. if (isset($_contexte['ajax'])) {
  909. $_options[] = "'ajax'=>true";
  910. unset($_contexte['ajax']);
  911. }
  912. if ($p->etoile) $_options[] = "'etoile'=>true";
  913. $_options[] = "'compil'=>array(" . memoriser_contexte_compil($p) .")";
  914. $_l = 'array(' . join(",\n\t", $_contexte) .')';
  915. if ($flag_env) $_l = "array_merge(\$Pile[0],$_l)";
  916. $p->code = sprintf(CODE_RECUPERER_FOND, $f, $_l, join(',',$_options),"''");
  917. } elseif (!isset($_contexte[1])) {
  918. $msg = array('zbug_balise_sans_argument', array('balise' => ' INCLURE'));
  919. erreur_squelette($msg, $p);
  920. } else $p->code = '(($c = find_in_path(' . $_contexte[1] . ')) ? spip_file_get_contents($c) : "")';
  921. $p->interdire_scripts = false; // la securite est assuree par recuperer_fond
  922. return $p;
  923. }
  924. // Inclure un modele : #MODELE{modele, params}
  925. // http://doc.spip.org/@balise_MODELE_dist
  926. function balise_MODELE_dist($p) {
  927. $_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false);
  928. // erreur de syntaxe = fond absent
  929. // (2 messages d'erreur SPIP pour le prix d'un, mais pas d'erreur PHP
  930. if (!$_contexte) $contexte = array();
  931. if (!isset($_contexte[1])) {
  932. $msg = array('zbug_balise_sans_argument', array('balise' => ' MODELE'));
  933. erreur_squelette($msg, $p);
  934. } else {
  935. $nom = $_contexte[1];
  936. unset($_contexte[1]);
  937. if (preg_match("/^\s*'[^']*'/s", $nom))
  938. $nom = "'modeles/" . substr($nom,1);
  939. else $nom = "'modeles/' . $nom";
  940. // Incoherence dans la syntaxe du contexte. A revoir.
  941. // Reserver la cle primaire de la boucle courante si elle existe
  942. if (isset($p->boucles[$p->id_boucle]->primary)) {
  943. $primary = $p->boucles[$p->id_boucle]->primary;
  944. if (!strpos($primary,',')) {
  945. $id = champ_sql($primary, $p);
  946. $_contexte[] = "'$primary'=>".$id;
  947. $_contexte[] = "'id'=>".$id;
  948. }
  949. }
  950. $_contexte[] = "'recurs'=>(++\$recurs)";
  951. $connect = '';
  952. if (isset($p->boucles[$p->id_boucle]))
  953. $connect = $p->boucles[$p->id_boucle]->sql_serveur;
  954. $_options = memoriser_contexte_compil($p);
  955. $_options = "'compil'=>array($_options), 'trim'=>true"
  956. . (isset($_contexte['ajax'])?", 'ajax'=>true":'');
  957. $page = sprintf(CODE_RECUPERER_FOND, $nom, 'array(' . join(',', $_contexte) .')', $_options, _q($connect));
  958. $p->code = "\n\t(((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))>=5)? '' :\n\t$page)\n";
  959. $p->interdire_scripts = false; // securite assuree par le squelette
  960. }
  961. return $p;
  962. }
  963. //
  964. // #SET
  965. // Affecte une variable locale au squelette
  966. // #SET{nom,valeur}
  967. // la balise renvoie la valeur
  968. // http://doc.spip.org/@balise_SET_dist
  969. function balise_SET_dist($p){
  970. $_nom = interprete_argument_balise(1,$p);
  971. $_val = interprete_argument_balise(2,$p);
  972. if (!$_nom OR !$_val) {
  973. $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'SET'));
  974. erreur_squelette($err_b_s_a, $p);
  975. } else $p->code = "vide(\$Pile['vars'][$_nom] = $_val)";
  976. $p->interdire_scripts = false; // la balise ne renvoie rien
  977. return $p;
  978. }
  979. //
  980. // #GET
  981. // Recupere une variable locale au squelette
  982. // #GET{nom,defaut} renvoie defaut si la variable nom n'a pas ete affectee
  983. //
  984. // http://doc.spip.org/@balise_GET_dist
  985. function balise_GET_dist($p) {
  986. $p->interdire_scripts = false; // le contenu vient de #SET, donc il est de confiance
  987. if (function_exists('balise_ENV'))
  988. return balise_ENV($p, '$Pile["vars"]');
  989. else
  990. return balise_ENV_dist($p, '$Pile["vars"]');
  991. }
  992. // #DOUBLONS{mots} ou #DOUBLONS{mots,famille}
  993. // donne l'etat des doublons (MOTS) a cet endroit
  994. // sous forme de tableau d'id_mot array(1,2,3,...)
  995. // #DOUBLONS tout seul donne la liste brute de tous les doublons
  996. // #DOUBLONS*{mots} donne la chaine brute ",1,2,3,..."
  997. // (changera si la gestion des doublons evolue)
  998. //
  999. // http://doc.spip.org/@balise_DOUBLONS_dist
  1000. function balise_DOUBLONS_dist($p) {
  1001. if ($type = interprete_argument_balise(1,$p)) {
  1002. if ($famille = interprete_argument_balise(2,$p))
  1003. $type .= '.' . $famille;
  1004. $p->code = '$doublons['.$type.']';
  1005. if (!$p->etoile)
  1006. $p->code = 'array_filter(array_map("intval",explode(",",'
  1007. . $p->code . ')))';
  1008. }
  1009. else
  1010. $p->code = '$doublons';
  1011. $p->interdire_scripts = false;
  1012. return $p;
  1013. }
  1014. //
  1015. // #PIPELINE
  1016. // pour permettre aux plugins d'inserer des sorties de pipeline dans un squelette
  1017. // #PIPELINE{insert_body}
  1018. // #PIPELINE{insert_body,flux}
  1019. //
  1020. // http://doc.spip.org/@balise_PIPELINE_dist
  1021. function balise_PIPELINE_dist($p) {
  1022. $_pipe = interprete_argument_balise(1,$p);
  1023. if (!$_pipe) {
  1024. $err_b_s_a = array('zbug_balise_sans_argument', array('balise' => 'PIPELINE'));
  1025. erreur_squelette($err_b_s_a, $p);
  1026. } else {
  1027. $_flux = interprete_argument_balise(2,$p);
  1028. $_flux = $_flux?$_flux:"''";
  1029. $p->code = "pipeline( $_pipe , $_flux )";
  1030. $p->interdire_scripts = false;
  1031. }
  1032. return $p;
  1033. }
  1034. //
  1035. // #EDIT
  1036. // une balise qui ne fait rien, pour surcharge par le plugin widgets
  1037. //
  1038. // http://doc.spip.org/@balise_EDIT_dist
  1039. function balise_EDIT_dist($p) {
  1040. $p->code = "''";
  1041. $p->interdire_scripts = false;
  1042. return $p;
  1043. }
  1044. //
  1045. // #TOTAL_UNIQUE
  1046. // pour recuperer le nombre d'elements affiches par l'intermediaire du filtre
  1047. // |unique
  1048. // usage:
  1049. // #TOTAL_UNIQUE afiche le nombre de #BALISE|unique
  1050. // #TOTAL_UNIQUE{famille} afiche le nombre de #BALISE|unique{famille}
  1051. //
  1052. // http://doc.spip.org/@balise_TOTAL_UNIQUE_dist
  1053. function balise_TOTAL_UNIQUE_dist($p) {
  1054. $_famille = interprete_argument_balise(1,$p);
  1055. $_famille = $_famille ? $_famille : "''";
  1056. $p->code = "unique('', $_famille, true)";
  1057. return $p;
  1058. }
  1059. //
  1060. // #ARRAY
  1061. // pour creer un array php a partir d'arguments calcules
  1062. // #ARRAY{key1,val1,key2,val2 ...} retourne array(key1=>val1,...)
  1063. //
  1064. // http://doc.spip.org/@balise_ARRAY_dist
  1065. function balise_ARRAY_dist($p) {
  1066. $_code = array();
  1067. $n=1;
  1068. do {
  1069. $_key = interprete_argument_balise($n++,$p);
  1070. $_val = interprete_argument_balise($n++,$p);
  1071. if ($_key AND $_val) $_code[] = "$_key => $_val";
  1072. } while ($_key && $_val);
  1073. $p->code = 'array(' . join(', ',$_code).')';
  1074. $p->interdire_scripts = false;
  1075. return $p;
  1076. }
  1077. //#FOREACH
  1078. //
  1079. // http://doc.spip.org/@balise_FOREACH_dist
  1080. function balise_FOREACH_dist($p) {
  1081. $_tableau = interprete_argument_balise(1,$p);
  1082. $_tableau = str_replace("'", "", strtoupper($_tableau));
  1083. $_tableau = sinon($_tableau, 'ENV');
  1084. $f = 'balise_'.$_tableau;
  1085. $balise = function_exists($f) ? $f : (function_exists($g = $f.'_dist') ? $g : '');
  1086. if($balise) {
  1087. $_modele = interprete_argument_balise(2,$p);
  1088. $_modele = str_replace("'", "", strtolower($_modele));
  1089. $__modele = 'foreach_'.strtolower($_tableau);
  1090. $_modele = (!$_modele AND trouve_modele($__modele)) ?
  1091. $__modele :
  1092. ($_modele ? $_modele : 'foreach');
  1093. // on passe a la balise seulement les parametres
  1094. // mais on enleve les 2 deja utilise
  1095. // [(#FOREACH{CONFIG,'',suivants}|filtre)]
  1096. $p->param[0] = array_merge(array(""),array_slice($p->param[0],3));
  1097. $p = $balise($p);
  1098. $filtre = chercher_filtre('foreach');
  1099. $p->code = $filtre . "(unserialize(" . $p->code . "), '" . $_modele . "')";
  1100. }
  1101. //On a pas trouve la balise correspondant au tableau a traiter
  1102. else {
  1103. $msg = array('zbug_balise_inexistante',array('from'=>'#FOREACH','balise'=>$_tableau));
  1104. erreur_squelette($msg, $p);
  1105. }
  1106. return $p;
  1107. }
  1108. // Appelle la fonction autoriser et renvoie ' ' si OK, '' si niet
  1109. // A noter : la priorite des operateurs exige && plutot que AND
  1110. // Cette balise cree un cache par session
  1111. // http://doc.spip.org/@balise_AUTORISER_dist
  1112. function balise_AUTORISER_dist($p) {
  1113. $_code = array();
  1114. $p->descr['session'] = true; // faire un cache par session
  1115. $n=1;
  1116. while ($_v = interprete_argument_balise($n++,$p))
  1117. $_code[] = $_v;
  1118. $p->code = '(include_spip("inc/autoriser")&&autoriser(' . join(', ',$_code).')?" ":"")';
  1119. $p->interdire_scripts = false;
  1120. return $p;
  1121. }
  1122. // Appelle la fonction info_plugin
  1123. // Afficher des informations sur les plugins dans le site public
  1124. // http://doc.spip.org/@balise_PLUGIN_dist
  1125. function balise_PLUGIN_dist($p) {
  1126. $plugin = interprete_argument_balise(1,$p);
  1127. $plugin = isset($plugin) ? str_replace('\'', '"', $plugin) : '""';
  1128. $type_info = interprete_argument_balise(2,$p);
  1129. $type_info = isset($type_info) ? str_replace('\'', '"', $type_info) : '"est_actif"';
  1130. $f = chercher_filtre('info_plugin');
  1131. $p->code = $f.'('.$plugin.', '.$type_info.')';
  1132. return $p;
  1133. }
  1134. // Appelle la fonction inc_aider_dist
  1135. // http://doc.spip.org/@balise_AIDER_dist
  1136. function balise_AIDER_dist($p) {
  1137. $_motif = interprete_argument_balise(1,$p);
  1138. $s = "'" . addslashes($p->descr['sourcefile']) . "'";
  1139. $aider = charger_fonction('aider','inc');
  1140. $p->code = "((\$aider=charger_fonction('aider','inc'))?\$aider($_motif,$s, \$Pile[0]):'')";
  1141. return $p;
  1142. }
  1143. // Insertion du contexte des formulaires charger/verifier/traiter
  1144. // avec les hidden de l'url d'action
  1145. // http://doc.spip.org/@balise_ACTION_FORMULAIRE
  1146. function balise_ACTION_FORMULAIRE($p){
  1147. if (!$_url = interprete_argument_balise(1,$p))
  1148. $_url = "@\$Pile[0]['action']";
  1149. if (!$_form = interprete_argument_balise(2,$p))
  1150. $_form = "@\$Pile[0]['form']";
  1151. // envoyer le nom du formulaire que l'on traite
  1152. // transmettre les eventuels args de la balise formulaire
  1153. $p->code = " '<div>' .
  1154. form_hidden($_url) .
  1155. '<input name=\'formulaire_action\' type=\'hidden\'
  1156. value=\'' . $_form . '\' />' .
  1157. '<input name=\'formulaire_action_args\' type=\'hidden\'
  1158. value=\'' . @\$Pile[0]['formulaire_args']. '\' />' .
  1159. (@\$Pile[0]['_hidden']?@\$Pile[0]['_hidden']:'') .
  1160. '</div>'";
  1161. $p->interdire_scripts = false;
  1162. return $p;
  1163. }
  1164. /**
  1165. * Generer un bouton d'action en post, ajaxable
  1166. * a utiliser a la place des liens action_auteur, sous la forme
  1167. * #BOUTON_ACTION{libelle,url}
  1168. * ou
  1169. * #BOUTON_ACTION{libelle,url,ajax} pour que l'action soit ajax comme un lien class='ajax'
  1170. * ou
  1171. * #BOUTON_ACTION{libelle,url,ajax,message_confirmation} pour utiliser un message de confirmation
  1172. *
  1173. * @param unknown_type $p
  1174. * @return unknown
  1175. */
  1176. function balise_BOUTON_ACTION_dist($p){
  1177. $_label = interprete_argument_balise(1,$p);
  1178. if (!$_label) $_label="''";
  1179. $_url = interprete_argument_balise(2,$p);
  1180. if (!$_url) $_url="''";
  1181. $_class = interprete_argument_balise(3,$p);
  1182. if (!$_class) $_class="''";
  1183. $_confirm = interprete_argument_balise(4,$p);
  1184. if (!$_confirm) $_confirm="''";
  1185. $_title = interprete_argument_balise(5,$p);
  1186. if (!$_title) $_title="''";
  1187. $p->code = "bouton_action($_label, $_url, $_class, $_confirm, $_title)";
  1188. $p->interdire_scripts = false;
  1189. return $p;
  1190. }
  1191. ?>