PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/spip/ecrire/public/assembler.php

https://github.com/eyeswebcrea/espace-couture-sittler.fr
PHP | 695 lines | 448 code | 80 blank | 167 comment | 91 complexity | e4c2804383c235180341a9d5b03507e1 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. if (!defined('_ECRIRE_INC_VERSION')) return;
  12. if (!defined('_CONTEXTE_IGNORE_VARIABLES')) define('_CONTEXTE_IGNORE_VARIABLES', "/(^var_|^PHPSESSID$)/");
  13. //
  14. // calcule la page et les entetes
  15. // determine le contexte donne par l'URL (en tenant compte des reecritures)
  16. // grace a la fonction de passage d'URL a id (reciproque dans urls/*php)
  17. //
  18. // http://doc.spip.org/@assembler
  19. function assembler($fond, $connect='') {
  20. global $flag_preserver,$lastmodified, $use_cache, $contexte;
  21. $contexte = calculer_contexte();
  22. $page = array('contexte_implicite'=>calculer_contexte_implicite());
  23. $page['contexte_implicite']['cache'] = $fond . preg_replace(',\.[a-zA-Z0-9]*$,', '', preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']));
  24. // Cette fonction est utilisee deux fois
  25. $cacher = charger_fonction('cacher', 'public');
  26. // Les quatre derniers parametres sont modifies par la fonction:
  27. // emplacement, validite, et, s'il est valide, contenu & age
  28. $res = $cacher($GLOBALS['contexte'], $use_cache, $chemin_cache, $page, $lastmodified);
  29. // Si un resultat est retourne, c'est un message d'impossibilite
  30. if ($res) {return array('texte' => $res);}
  31. if (!$chemin_cache || !$lastmodified) $lastmodified = time();
  32. $headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
  33. // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
  34. // une perennite valide a meme reponse qu'une requete HEAD (par defaut les
  35. // pages sont dynamiques)
  36. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
  37. AND !$GLOBALS['var_mode']
  38. AND $chemin_cache
  39. AND isset($page['entetes'])
  40. AND isset($page['entetes']['Cache-Control'])
  41. AND strstr($page['entetes']['Cache-Control'],'max-age=')
  42. AND !strstr($_SERVER['SERVER_SOFTWARE'],'IIS/')
  43. ) {
  44. $since = preg_replace('/;.*/', '',
  45. $_SERVER['HTTP_IF_MODIFIED_SINCE']);
  46. $since = str_replace('GMT', '', $since);
  47. if (trim($since) == gmdate("D, d M Y H:i:s", $lastmodified)) {
  48. $page['status'] = 304;
  49. $headers_only = true;
  50. }
  51. }
  52. // Si requete HEAD ou Last-modified compatible, ignorer le texte
  53. // et pas de content-type (pour contrer le bouton admin de inc-public)
  54. if ($headers_only) {
  55. $page['entetes']["Connection"] = "close";
  56. $page['texte'] = "";
  57. } else {
  58. // si la page est prise dans le cache
  59. if (!$use_cache) {
  60. // Informer les boutons d'admin du contexte
  61. // (fourni par $renommer ci-dessous lors de la mise en cache)
  62. $contexte = $page['contexte'];
  63. // vider les globales url propres qui ne doivent plus etre utilisees en cas
  64. // d'inversion url => objet
  65. unset($_SERVER['REDIRECT_url_propre']);
  66. unset($_ENV['url_propre']);
  67. }
  68. // ATTENTION, gestion des URLs transformee par le htaccess
  69. // $renommer = 'urls_propres_dist';
  70. // renvoie array($contexte, $type, $url_redirect, $nfond)
  71. // $nfond n'est retourne que si l'url est definie apres le ?
  72. // et risque d'etre effacee par un form en get
  73. // elle est utilisee par form_hidden exclusivement
  74. // Compat ascendante si le retour est null:
  75. // 1. $contexte est global car cette fonction le modifie.
  76. // 2. $fond est passe par reference, pour la meme raison
  77. // et calculer la page
  78. else {
  79. $renommer = generer_url_entite();
  80. if ($renommer) {
  81. $url = nettoyer_uri();
  82. $a = $renommer($url, $fond, $contexte);
  83. if (is_array($a)) {
  84. list($ncontexte, $type, $url_redirect, $nfond) = $a;
  85. if (strlen($url_redirect)
  86. AND $url !== $url_redirect) {
  87. spip_log("Redirige $url vers $url_redirect");
  88. include_spip('inc/headers');
  89. redirige_par_entete($url_redirect, '', 301);
  90. }
  91. if (isset($nfond))
  92. $fond = $nfond;
  93. else if ($fond == ''
  94. OR $fond == 'type_urls' /* compat avec htaccess 2.0.0 */
  95. )
  96. $fond = ($type === 'syndic') ? 'site' : $type;
  97. if (isset($ncontexte))
  98. $contexte = $ncontexte;
  99. if (defined('_DEFINIR_CONTEXTE_TYPE') AND _DEFINIR_CONTEXTE_TYPE)
  100. $contexte['type'] = ($type === 'syndic') ? 'site' : $type;
  101. }
  102. }
  103. // compatibilite <= 1.9.2
  104. elseif (function_exists('recuperer_parametres_url'))
  105. recuperer_parametres_url($fond, nettoyer_uri());
  106. // vider les globales url propres qui ne doivent plus etre utilisees en cas
  107. // d'inversion url => objet
  108. unset($_SERVER['REDIRECT_url_propre']);
  109. unset($_ENV['url_propre']);
  110. // squelette par defaut
  111. if (!strlen($fond))
  112. $fond = 'sommaire';
  113. // produire la page : peut mettre a jour $lastmodified
  114. $produire_page = charger_fonction('produire_page','public');
  115. $page = $produire_page($fond, $GLOBALS['contexte'], $use_cache, $chemin_cache, NULL, $page, $lastmodified, $connect);
  116. if ($page === '')
  117. erreur_squelette(_T('info_erreur_squelette2',
  118. array('fichier'=>htmlspecialchars($fond).'.'._EXTENSION_SQUELETTES)));
  119. }
  120. if ($page AND $chemin_cache) $page['cache'] = $chemin_cache;
  121. auto_content_type($page);
  122. $flag_preserver |= headers_sent();
  123. // Definir les entetes si ce n'est fait
  124. if (!$flag_preserver) {
  125. if ($GLOBALS['flag_ob']) {
  126. // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
  127. if (trim($page['texte']) === ''
  128. AND $GLOBALS['var_mode'] != 'debug'
  129. AND !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
  130. ) {
  131. // passer le type d'objet recherche au contexte de la page d'erreur
  132. $contexte['type'] = (isset($type)?$type:$fond);
  133. $page = message_page_indisponible($page, $contexte);
  134. // cacher la page d'erreur car celle ci est contextuelle
  135. if ($chemin_cache
  136. AND is_array($page)
  137. AND count($page)
  138. AND $page['entetes']['X-Spip-Cache'] > 0){
  139. $cacher = charger_fonction('cacher', 'public');
  140. $lastinclude = time();
  141. $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
  142. }
  143. }
  144. // pas de cache client en mode 'observation'
  145. if ($GLOBALS['var_mode']) {
  146. $page['entetes']["Cache-Control"]= "no-cache,must-revalidate";
  147. $page['entetes']["Pragma"] = "no-cache";
  148. }
  149. }
  150. }
  151. }
  152. // Entete Last-Modified:
  153. // eviter d'etre incoherent en envoyant un lastmodified identique
  154. // a celui qu'on a refuse d'honorer plus haut (cf. #655)
  155. if ($lastmodified
  156. AND !isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
  157. AND !isset($page['entetes']["Last-Modified"]))
  158. $page['entetes']["Last-Modified"]=gmdate("D, d M Y H:i:s", $lastmodified)." GMT";
  159. return $page;
  160. }
  161. //
  162. // Contexte : lors du calcul d'une page spip etablit le contexte a partir
  163. // des variables $_GET et $_POST, purgees des fausses variables var_*
  164. // Note : pour hacker le contexte depuis le fichier d'appel (page.php),
  165. // il est recommande de modifier $_GET['toto'] (meme si la page est
  166. // appelee avec la methode POST).
  167. //
  168. // http://doc.spip.org/@calculer_contexte
  169. function calculer_contexte() {
  170. $contexte = array();
  171. foreach($_GET as $var => $val) {
  172. if (!preg_match(_CONTEXTE_IGNORE_VARIABLES,$var))
  173. $contexte[$var] = $val;
  174. }
  175. foreach($_POST as $var => $val) {
  176. if (!preg_match(_CONTEXTE_IGNORE_VARIABLES,$var))
  177. $contexte[$var] = $val;
  178. }
  179. return $contexte;
  180. }
  181. /**
  182. * Calculer le contexte implicite, qui n'apparait pas dans le ENV d'un cache
  183. * mais est utilise pour distinguer deux caches differents
  184. *
  185. * @staticvar string $notes
  186. * @return array
  187. */
  188. function calculer_contexte_implicite(){
  189. static $notes = null;
  190. if (is_null($notes))
  191. $notes = charger_fonction('notes','inc');
  192. $contexte_implicite = array(
  193. 'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
  194. 'host' => $_SERVER['HTTP_HOST'],
  195. 'https' => $_SERVER['HTTPS'],
  196. 'espace' => test_espace_prive(),
  197. 'marqueur' => (isset($GLOBALS['marqueur']) ? $GLOBALS['marqueur'] : ''),
  198. 'notes' => $notes('','contexter_cache'),
  199. );
  200. return $contexte_implicite;
  201. }
  202. //
  203. // fonction pour compatibilite arriere, probablement superflue
  204. //
  205. // http://doc.spip.org/@auto_content_type
  206. function auto_content_type($page)
  207. {
  208. global $flag_preserver;
  209. if (!isset($flag_preserver))
  210. {
  211. $flag_preserver = ($page && preg_match("/header\s*\(\s*.content\-type:/isx",$page['texte']) || (isset($page['entetes']['Content-Type'])));
  212. }
  213. }
  214. // http://doc.spip.org/@inclure_page
  215. function inclure_page($fond, $contexte, $connect='') {
  216. global $lastmodified;
  217. // enlever le fond de contexte inclus car sinon il prend la main
  218. // dans les sous inclusions -> boucle infinie d'inclusion identique
  219. // (cette precaution n'est probablement plus utile)
  220. unset($contexte['fond']);
  221. $page = array('contexte_implicite'=>calculer_contexte_implicite());
  222. $page['contexte_implicite']['cache'] = $fond;
  223. $cacher = charger_fonction('cacher', 'public');
  224. // Les quatre derniers parametres sont modifies par la fonction:
  225. // emplacement, validite, et, s'il est valide, contenu & age
  226. $res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
  227. // $res = message d'erreur : on sort de la
  228. if ($res) {return array('texte' => $res);}
  229. // Si use_cache ne vaut pas 0, la page doit etre calculee
  230. // produire la page : peut mettre a jour $lastinclude
  231. // le contexte_cache envoye a cacher() a ete conserve et est passe a produire
  232. if ($use_cache) {
  233. $produire_page = charger_fonction('produire_page','public');
  234. $page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
  235. }
  236. // dans tous les cas, mettre a jour $lastmodified
  237. $lastmodified = max($lastmodified, $lastinclude);
  238. return $page;
  239. }
  240. /**
  241. * Produire la page et la mettre en cache
  242. * lorsque c'est necessaire
  243. *
  244. * @param string $fond
  245. * @param array $contexte
  246. * @param int $use_cache
  247. * @param string $chemin_cache
  248. * @param array $contexte_cache
  249. * @param array $page
  250. * @param int $lastinclude
  251. * @param string $connect
  252. * @return array
  253. */
  254. function public_produire_page_dist($fond, $contexte, $use_cache, $chemin_cache, $contexte_cache, &$page, &$lastinclude, $connect=''){
  255. #var_dump($page);
  256. $parametrer = charger_fonction('parametrer', 'public');
  257. $page = $parametrer($fond, $contexte, $chemin_cache, $connect);
  258. // et on l'enregistre sur le disque
  259. if ($chemin_cache
  260. AND $use_cache>-1
  261. AND is_array($page)
  262. AND count($page)
  263. AND $page['entetes']['X-Spip-Cache'] > 0){
  264. $cacher = charger_fonction('cacher', 'public');
  265. $lastinclude = time();
  266. $cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
  267. }
  268. return $page;
  269. }
  270. // Fonction inseree par le compilateur dans le code compile.
  271. // Elle recoit un contexte pour inclure un squelette,
  272. // et les valeurs du contexte de compil prepare par memoriser_contexte_compil
  273. // elle-meme appelee par calculer_balise_dynamique dans references.php:
  274. // 0: sourcefile
  275. // 1: codefile
  276. // 2: id_boucle
  277. // 3: ligne
  278. // 4: langue
  279. function inserer_balise_dynamique($contexte_exec, $contexte_compil)
  280. {
  281. if (!is_array($contexte_exec))
  282. echo $contexte_exec; // message d'erreur etc
  283. else {
  284. inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
  285. }
  286. }
  287. // Attention, un appel explicite a cette fonction suppose certains include
  288. // $echo = faut-il faire echo ou return
  289. // http://doc.spip.org/@inclure_balise_dynamique
  290. function inclure_balise_dynamique($texte, $echo=true, $contexte_compil=array())
  291. {
  292. if (is_array($texte)) {
  293. list($fond, $delainc, $contexte_inclus) = $texte;
  294. // delais a l'ancienne, c'est pratiquement mort
  295. $d = isset($GLOBALS['delais']) ? $GLOBALS['delais'] : NULL;
  296. $GLOBALS['delais'] = $delainc;
  297. $page = recuperer_fond($fond,$contexte_inclus,array('trim'=>false, 'raw' => true, 'compil' => $contexte_compil));
  298. $texte = $page['texte'];
  299. $GLOBALS['delais'] = $d;
  300. // Faire remonter les entetes
  301. if (is_array($page['entetes'])) {
  302. // mais pas toutes
  303. unset($page['entetes']['X-Spip-Cache']);
  304. unset($page['entetes']['Content-Type']);
  305. if (isset($GLOBALS['page']) AND is_array($GLOBALS['page'])) {
  306. if (!is_array($GLOBALS['page']['entetes']))
  307. $GLOBALS['page']['entetes'] = array();
  308. $GLOBALS['page']['entetes'] =
  309. array_merge($GLOBALS['page']['entetes'],$page['entetes']);
  310. }
  311. }
  312. // on se refere a $page['contexte'] a la place
  313. if (isset($page['contexte']['_pipeline'])) {
  314. $pipe = is_array($page['contexte']['_pipeline'])?reset($page['contexte']['_pipeline']):$page['contexte']['_pipeline'];
  315. $args = is_array($page['contexte']['_pipeline'])?end($page['contexte']['_pipeline']):array();
  316. $args['contexte'] = $page['contexte'];
  317. unset($args['contexte']['_pipeline']); // par precaution, meme si le risque de boucle infinie est a priori nul
  318. if (isset($GLOBALS['spip_pipeline'][$pipe]))
  319. $texte = pipeline($pipe,array(
  320. 'data'=>$texte,
  321. 'args'=>$args));
  322. }
  323. }
  324. if ($GLOBALS['var_mode'] == 'debug') {
  325. // compatibilite : avant on donnait le numero de ligne ou rien.
  326. $ligne = intval(isset($contexte_compil[3]) ? $contexte_compil[3] : $contexte_compil);
  327. $GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
  328. }
  329. if ($echo)
  330. echo $texte;
  331. else
  332. return $texte;
  333. }
  334. // Traiter var_recherche ou le referrer pour surligner les mots
  335. // http://doc.spip.org/@f_surligne
  336. function f_surligne ($texte) {
  337. if (!$GLOBALS['html']) return $texte;
  338. $rech = _request('var_recherche');
  339. if (!$rech AND !isset($_SERVER['HTTP_REFERER'])) return $texte;
  340. include_spip('inc/surligne');
  341. return surligner_mots($texte, $rech);
  342. }
  343. // Valider/indenter a la demande.
  344. // http://doc.spip.org/@f_tidy
  345. function f_tidy ($texte) {
  346. global $xhtml;
  347. if ($xhtml # tidy demande
  348. AND $GLOBALS['html'] # verifie que la page avait l'entete text/html
  349. AND strlen($texte)
  350. AND !headers_sent()) {
  351. # Compatibilite ascendante
  352. if (!is_string($xhtml)) $xhtml ='tidy';
  353. if (!$f = charger_fonction($xhtml, 'inc', true)) {
  354. spip_log("tidy absent, l'indenteur SPIP le remplace");
  355. $f = charger_fonction('sax', 'xml');
  356. }
  357. return $f($texte);
  358. }
  359. return $texte;
  360. }
  361. // Offre #INSERT_HEAD sur tous les squelettes (bourrin)
  362. // a activer dans mes_options via :
  363. // $spip_pipeline['affichage_final'] .= '|f_insert_head';
  364. // http://doc.spip.org/@f_insert_head
  365. function f_insert_head($texte) {
  366. if (!$GLOBALS['html']) return $texte;
  367. include_spip('public/admin'); // pour strripos
  368. ($pos = stripos($texte, '</head>'))
  369. || ($pos = stripos($texte, '<body>'))
  370. || ($pos = 0);
  371. if (false === strpos(substr($texte, 0,$pos), '<!-- insert_head -->')) {
  372. $insert = "\n".pipeline('insert_head','<!-- f_insert_head -->')."\n";
  373. $texte = substr_replace($texte, $insert, $pos, 0);
  374. }
  375. return $texte;
  376. }
  377. // Inserer au besoin les boutons admins
  378. // http://doc.spip.org/@f_admin
  379. function f_admin ($texte) {
  380. if ($GLOBALS['affiche_boutons_admin']) {
  381. include_spip('public/admin');
  382. $texte = affiche_boutons_admin($texte);
  383. }
  384. if (_request('var_mode')=='noajax'){
  385. $texte = preg_replace(',(class=[\'"][^\'"]*)ajax([^\'"]*[\'"]),Uims',"\\1\\2",$texte);
  386. }
  387. return $texte;
  388. }
  389. // http://doc.spip.org/@message_page_indisponible
  390. function message_page_indisponible ($page, $contexte) {
  391. static $deja = false;
  392. if ($deja) return "erreur";
  393. $codes = array(
  394. '404' => '404 Not Found',
  395. '503' => '503 Service Unavailable',
  396. );
  397. $contexte['status'] = ($page !== false) ? '404' : '503';
  398. $contexte['code'] = $codes[$contexte['status']];
  399. $contexte['fond'] = '404'; // gere les 2 erreurs
  400. $contexte['erreur'] = _T($erreur);
  401. if (!isset($contexte['lang']))
  402. $contexte['lang'] = $GLOBALS['spip_lang'];
  403. $deja = true;
  404. // passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
  405. // ex restriction d'acces => 401
  406. $contexte = pipeline('page_indisponible',$contexte);
  407. // produire la page d'erreur
  408. $page = inclure_page($contexte['fond'], $contexte);
  409. if (!$page)
  410. $page = inclure_page('404', $contexte);
  411. $page['status'] = $contexte['status'];
  412. return $page;
  413. }
  414. // temporairement ici : a mettre dans le futur inc/modeles
  415. // creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array()
  416. // http://doc.spip.org/@creer_contexte_de_modele
  417. function creer_contexte_de_modele($args) {
  418. $contexte = array();
  419. foreach ($args as $var=>$val) {
  420. if (is_int($var)){ // argument pas formate
  421. if (in_array($val, array('left', 'right', 'center'))) {
  422. $var = 'align';
  423. $contexte[$var] = $val;
  424. } else {
  425. $args = explode('=', $val);
  426. if (count($args)>=2) // Flashvars=arg1=machin&arg2=truc genere plus de deux args
  427. $contexte[trim($args[0])] = substr($val,strlen($args[0])+1);
  428. else // notation abregee
  429. $contexte[trim($val)] = trim($val);
  430. }
  431. }
  432. else
  433. $contexte[$var] = $val;
  434. }
  435. return $contexte;
  436. }
  437. // Calcule le modele et retourne la mini-page ainsi calculee
  438. // http://doc.spip.org/@inclure_modele
  439. function inclure_modele($type, $id, $params, $lien, $connect='') {
  440. static $compteur;
  441. if (++$compteur>10) return ''; # ne pas boucler indefiniment
  442. $type = strtolower($type);
  443. $fond = $class = '';
  444. $params = array_filter(explode('|', $params));
  445. if ($params) {
  446. list(,$soustype) = each($params);
  447. $soustype = strtolower($soustype);
  448. if (in_array($soustype,
  449. array('left', 'right', 'center', 'ajax'))) {
  450. list(,$soustype) = each($params);
  451. $soustype = strtolower($soustype);
  452. }
  453. if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
  454. if (!trouve_modele($fond = ($type.'_'.$soustype))) {
  455. $fond = '';
  456. $class = $soustype;
  457. }
  458. // enlever le sous type des params
  459. $params = array_diff($params,array($soustype));
  460. }
  461. }
  462. // Si ca marche pas en precisant le sous-type, prendre le type
  463. if (!$fond AND !trouve_modele($fond = $type))
  464. return false;
  465. $fond = 'modeles/'.$fond;
  466. // Creer le contexte
  467. $contexte = array(
  468. 'dir_racine' => _DIR_RACINE # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
  469. );
  470. // Le numero du modele est mis dans l'environnement
  471. // d'une part sous l'identifiant "id"
  472. // et d'autre part sous l'identifiant de la cle primaire supposee
  473. // par la fonction table_objet,
  474. // qui ne marche vraiment que pour les tables std de SPIP
  475. // (<site1> =>> site =>> id_syndic =>> id_syndic=1)
  476. $_id = 'id_' . table_objet($type);
  477. if (preg_match('/s$/',$_id)) $_id = substr($_id,0,-1);
  478. $contexte['id'] = $contexte[$_id] = $id;
  479. if (isset($class))
  480. $contexte['class'] = $class;
  481. // Si un lien a ete passe en parametre, ex: [<modele1>->url]
  482. if ($lien) {
  483. # un eventuel guillemet (") sera reechappe par #ENV
  484. $contexte['lien'] = str_replace("&quot;",'"', $lien['href']);
  485. $contexte['lien_class'] = $lien['class'];
  486. $contexte['lien_mime'] = $lien['mime'];
  487. }
  488. // Traiter les parametres
  489. // par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
  490. $arg_list = creer_contexte_de_modele($params);
  491. $contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
  492. $contexte = array_merge($contexte,$arg_list);
  493. // Appliquer le modele avec le contexte
  494. $retour = recuperer_fond($fond, $contexte, array(), $connect);
  495. // Regarder si le modele tient compte des liens (il *doit* alors indiquer
  496. // spip_lien_ok dans les classes de son conteneur de premier niveau ;
  497. // sinon, s'il y a un lien, on l'ajoute classiquement
  498. if (strstr(' ' . ($classes = extraire_attribut($retour, 'class')).' ',
  499. 'spip_lien_ok')) {
  500. $retour = inserer_attribut($retour, 'class',
  501. trim(str_replace(' spip_lien_ok ', ' ', " $classes ")));
  502. } else if ($lien)
  503. $retour = "<a href='".$lien['href']."' class='".$lien['class']."'>".$retour."</a>";
  504. $compteur--;
  505. return (isset($arg_list['ajax'])AND $arg_list['ajax']=='ajax')
  506. ? encoder_contexte_ajax($contexte,'',$retour)
  507. : $retour;
  508. }
  509. // Un inclure_page qui marche aussi pour l'espace prive
  510. // fonction interne a spip, ne pas appeler directement
  511. // pour recuperer $page complet, utiliser:
  512. // recuperer_fond($fond,$contexte,array('raw'=>true))
  513. // http://doc.spip.org/@evaluer_fond
  514. function evaluer_fond ($fond, $contexte=array(), $connect=null) {
  515. $page = inclure_page($fond, $contexte, $connect);
  516. if (!$page) return $page;
  517. if ($page['process_ins'] != 'html') {
  518. // restaurer l'etat des notes
  519. if (isset($page['notes']) AND $page['notes']){
  520. $notes = charger_fonction("notes","inc");
  521. $notes($page['notes'],'restaurer_etat');
  522. }
  523. ob_start();
  524. xml_hack($page, true);
  525. eval('?' . '>' . $page['texte']);
  526. $page['texte'] = ob_get_contents();
  527. xml_hack($page);
  528. $page['process_ins'] = 'html';
  529. ob_end_clean();
  530. }
  531. page_base_href($page['texte']);
  532. // Lever un drapeau (global) si le fond utilise #SESSION
  533. // a destination de public/parametrer
  534. // pour remonter vers les inclusions appelantes
  535. // il faut bien lever ce drapeau apres avoir evalue le fond
  536. // pour ne pas faire descendre le flag vers les inclusions appelees
  537. if (isset($page['invalideurs'])
  538. AND isset($page['invalideurs']['session']))
  539. $GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
  540. return $page;
  541. }
  542. // Appeler avant et apres chaque eval()
  543. // http://doc.spip.org/@xml_hack
  544. function xml_hack(&$page, $echap = false) {
  545. if ($echap)
  546. $page['texte'] = str_replace('<'.'?xml', "<\1?xml", $page['texte']);
  547. else
  548. $page['texte'] = str_replace("<\1?xml", '<'.'?xml', $page['texte']);
  549. }
  550. // http://doc.spip.org/@page_base_href
  551. function page_base_href(&$texte){
  552. if (!defined('_SET_HTML_BASE'))
  553. // si la profondeur est superieure a 1
  554. // est que ce n'est pas une url page ni une url action
  555. // activer par defaut
  556. define('_SET_HTML_BASE',
  557. $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT?1:2)
  558. AND _request(_SPIP_PAGE) !== 'login'
  559. AND !_request('action'));
  560. if (_SET_HTML_BASE
  561. AND isset($GLOBALS['html']) AND $GLOBALS['html']
  562. AND $GLOBALS['profondeur_url']>0
  563. AND ($poshead = strpos($texte,'</head>'))!==FALSE){
  564. $head = substr($texte,0,$poshead);
  565. $insert = false;
  566. if (strpos($head, '<base')===false)
  567. $insert = true;
  568. else {
  569. // si aucun <base ...> n'a de href c'est bon quand meme !
  570. $insert = true;
  571. include_spip('inc/filtres');
  572. $bases = extraire_balises($head,'base');
  573. foreach ($bases as $base)
  574. if (extraire_attribut($base,'href'))
  575. $insert = false;
  576. }
  577. if ($insert) {
  578. include_spip('inc/filtres_mini');
  579. // ajouter un base qui reglera tous les liens relatifs
  580. $base = url_absolue('./');
  581. $bbase = "\n<base href=\"$base\" />";
  582. if (($pos = strpos($head, '<head>')) !== false)
  583. $head = substr_replace($head, $bbase, $pos+6, 0);
  584. elseif(preg_match(",<head[^>]*>,i",$head,$r)){
  585. $head = str_replace($r[0], $r[0].$bbase, $head);
  586. }
  587. $texte = $head . substr($texte,$poshead);
  588. // gerer les ancres
  589. $base = $_SERVER['REQUEST_URI'];
  590. if (strpos($texte,"href='#")!==false)
  591. $texte = str_replace("href='#","href='$base#",$texte);
  592. if (strpos($texte, "href=\"#")!==false)
  593. $texte = str_replace("href=\"#","href=\"$base#",$texte);
  594. }
  595. }
  596. }
  597. // Envoyer les entetes, en retenant ceux qui sont a usage interne
  598. // et demarrent par X-Spip-...
  599. // http://doc.spip.org/@envoyer_entetes
  600. function envoyer_entetes($entetes) {
  601. foreach ($entetes as $k => $v)
  602. # if (strncmp($k, 'X-Spip-', 7))
  603. @header("$k: $v");
  604. }
  605. ?>