3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2007 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
13 if (!defined("_ECRIRE_INC_VERSION")) return;
16 // Ce fichier calcule une page en executant un squelette.
19 include_spip('base/abstract_sql');
20 include_spip('inc/lang');
22 // NB: Ce fichier peut initialiser $dossier_squelettes (old-style)
23 // donc il faut l'inclure "en globals"
24 if ($f = find_in_path('mes_fonctions.php')
25 OR $f = find_in_path('mes_fonctions.php3')) {
26 global $dossier_squelettes;
29 if (@is_readable(_DIR_TMP
."charger_plugins_fonctions.php")){
30 // chargement optimise precompile
31 include_once(_DIR_TMP
."charger_plugins_fonctions.php");
34 charger_generer_url(); # pour recuperer_parametres_url
37 // Contexte : lors du calcul d'une page spip etablit le contexte a partir
38 // des variables $_GET et $_POST, et leur ajoute la date
39 // Note : pour hacker le contexte depuis le fichier d'appel (page.php),
40 // il est recommande de modifier $_GET['toto'] (meme si la page est
41 // appelee avec la methode POST).
43 // http://doc.spip.org/@calculer_contexte
44 function calculer_contexte() {
48 foreach($_GET as $var => $val) {
49 if (strpos($var, 'var_') !== 0)
50 $contexte[$var] = $val;
52 foreach($_POST as $var => $val) {
53 if (strpos($var, 'var_') !== 0)
54 $contexte[$var] = $val;
57 if (isset($GLOBALS['date']))
58 $contexte['date'] = $contexte['date_redac'] = normaliser_date($GLOBALS['date']);
60 $contexte['date'] = $contexte['date_redac'] = date("Y-m-d H:i:s");
65 // http://doc.spip.org/@analyse_resultat_skel
66 function analyse_resultat_skel($nom, $cache, $corps) {
69 // Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
70 // note: on essaie d'attrapper aussi certains de ces entetes codes
71 // "a la main" dans les squelettes, mais evidemment sans exhaustivite
73 '/(<[?]php\s+)@?header\s*\(\s*.([^:]*):\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
74 $corps, $regs, PREG_SET_ORDER
))
75 foreach ($regs as $r) {
76 $corps = str_replace($r[0], '', $corps);
77 # $j = Content-Type, et pas content-TYPE.
78 $j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
82 return array('texte' => $corps,
84 'process_ins' => ((strpos($corps,'<'.'?')=== false
)?
'html':'php'),
85 'invalideurs' => $cache,
86 'entetes' => $headers,
87 'duree' => isset($headers['X-Spip-Cache']) ?
intval($headers['X-Spip-Cache']) : 0
91 // Calcul de la rubrique associee a la requete
92 // (selection de squelette specifique par id_rubrique & lang)
94 // http://doc.spip.org/@sql_rubrique_fond
95 function sql_rubrique_fond($contexte) {
97 if (isset($contexte['id_rubrique'])) {
98 $id = intval($contexte['id_rubrique']);
99 $row = spip_abstract_fetsel(array('lang'),
100 array('spip_rubriques'),
101 array("id_rubrique=$id"));
103 $lang = $row['lang'];
104 return array ($id, $lang);
107 if (isset($contexte['id_breve'])) {
108 $id = intval($contexte['id_breve']);
109 $row = spip_abstract_fetsel(array('id_rubrique', 'lang'),
110 array('spip_breves'),
111 array("id_breve=$id"));
112 $id_rubrique_fond = $row['id_rubrique'];
114 $lang = $row['lang'];
115 return array($id_rubrique_fond, $lang);
118 if (isset($contexte['id_syndic'])) {
119 $id = intval($contexte['id_syndic']);
120 $row = spip_abstract_fetsel(array('id_rubrique'),
121 array('spip_syndic'),
122 array("id_syndic=$id"));
123 $id_rubrique_fond = $row['id_rubrique'];
124 $row = spip_abstract_fetsel(array('lang'),
125 array('spip_rubriques'),
126 array("id_rubrique='$id_rubrique_fond'"));
128 $lang = $row['lang'];
129 return array($id_rubrique_fond, $lang);
132 if (isset($contexte['id_article'])) {
133 $id = intval($contexte['id_article']);
134 $row = spip_abstract_fetsel(array('id_rubrique', 'lang'),
135 array('spip_articles'),
136 array("id_article=$id"));
137 $id_rubrique_fond = $row['id_rubrique'];
139 $lang = $row['lang'];
140 return array($id_rubrique_fond, $lang);
144 # retourne le chapeau d'un article, et seulement s'il est publie
146 // http://doc.spip.org/@sql_chapo
147 function sql_chapo($id_article) {
148 $chapo= spip_abstract_fetsel(array('chapo'),
149 array('spip_articles'),
150 array("id_article=".intval($id_article),
152 return $chapo['chapo'];
155 # retourne le parent d'une rubrique
157 // http://doc.spip.org/@sql_parent
158 function sql_parent($id_rubrique) {
159 if (!$id_rubrique = intval($id_rubrique))
162 $id_parent = spip_abstract_fetsel(array('id_parent'),
163 array('spip_rubriques'),
164 array("id_rubrique=" . $id_rubrique));
166 if ($id_parent['id_parent']!=$id_rubrique)
167 return intval($id_parent['id_parent']);
169 spip_log("erreur: la rubrique $id_rubrique est son propre parent");
172 # retourne la profondeur d'une rubrique
174 // http://doc.spip.org/@sql_profondeur
175 function sql_profondeur($id) {
179 $id = sql_parent($id);
184 # retourne la rubrique d'un article
186 // http://doc.spip.org/@sql_rubrique
187 function sql_rubrique($id_article) {
188 $id_rubrique = spip_abstract_fetsel(array('id_rubrique'),
189 array('spip_articles'),
190 array("id_article=" . intval($id_article)));
191 return $id_rubrique['id_rubrique'];
194 // http://doc.spip.org/@sql_petitions
195 function sql_petitions($id_article, $table, $id_boucle, $serveur, &$cache) {
196 $retour = spip_abstract_fetsel(
198 array('spip_petitions'),
199 array("id_article=".intval($id_article)),
201 $table, $id_boucle, $serveur);
203 if (!$retour) return '';
204 # cette page est invalidee par toute petition
205 $cache['varia']['pet'.$id_article] = 1;
206 # ne pas retourner '' car le texte sert aussi de presence
207 return ($retour['texte'] ?
$retour['texte'] : ' ');
210 # retourne le champ 'accepter_forum' d'un article
211 // http://doc.spip.org/@sql_accepter_forum
212 function sql_accepter_forum($id_article) {
213 static $cache = array();
215 if (!$id_article) return;
217 if (!isset($cache[$id_article])) {
218 $row = spip_abstract_fetsel(array('accepter_forum'),
219 array('spip_articles'),
220 array("id_article=".intval($id_article)));
221 $cache[$id_article] = $row['accepter_forum'];
224 return $cache[$id_article];
227 # Determine les parametres d'URL (hors réécriture) et consorts
228 # En deduit un contexte disant si la page est une redirection ou
229 # exige un squelette deductible de $fond et du contexte linguistique.
230 # Applique alors le squelette sur le contexte et le nom du cache.
231 # Retourne un tableau ainsi construit
232 # 'texte' => la page calculee
233 # 'process_ins' => 'html' ou 'php' si presence d'un '< ?php'
234 # 'invalideurs' => les invalideurs de ce cache
235 # 'entetes' => headers http
236 # 'duree' => duree de vie du cache
237 # 'signal' => contexte (les id_* globales)
239 # En cas d'erreur process_ins est absent et texte est un tableau de 2 chaines
241 // http://doc.spip.org/@public_parametrer_dist
242 function public_parametrer_dist($fond, $local='', $cache='') {
243 // verifier que la fonction assembler est bien chargee (cf. #608)
244 $assembler = charger_fonction('assembler', 'public');
246 // distinguer le premier appel des appels par inclusion
247 if (!is_array($local)) {
249 // ATTENTION, gestion des URLs personnalises (propre etc):
250 // 1. $contexte est global car cette fonction le modifie.
251 // 2. $fond est passe par reference, pour la meme raison
252 // Bref, les URL dites propres ont une implementation sale.
253 // Interdit de nettoyer, faut assumer l'histoire.
254 include_spip('inc/filtres'); // pour normaliser_date
255 $contexte = calculer_contexte();
256 if (function_exists("recuperer_parametres_url")) {
257 recuperer_parametres_url($fond, nettoyer_uri());
258 // remettre les globales (bouton "Modifier cet article" etc)
259 foreach ($contexte as $var=>$val) {
260 if (substr($var,0,3) == 'id_') $GLOBALS[$var] = $val;
265 // si le champ chapo commence par '=' c'est une redirection.
266 // avec un eventuel raccourci Spip
267 // si le raccourci a un titre il sera pris comme corps du 302
268 if ($fond == 'article'
269 AND $id_article = intval($local['id_article'])) {
270 $m = sql_chapo($id_article);
272 include_spip('inc/texte');
273 // les navigateurs pataugent si l'URL est vide
274 if ($m = chapo_redirige(substr($m,1)))
275 if ($url = calculer_url($m[3]))
276 return array('texte' => "<"
277 . "?php header('Location: "
278 . texte_script(str_replace('&', '&', $url))
282 'process_ins' => 'php');
287 // Choisir entre $fond-dist.html, $fond=7.html, etc?
288 $id_rubrique_fond = 0;
289 // Chercher le fond qui va servir de squelette
290 if ($r = sql_rubrique_fond($local))
291 list($id_rubrique_fond, $lang) = $r;
293 // Si inc-urls ou un appel dynamique veut fixer la langue, la recuperer
294 if (isset($local['lang']))
295 $lang = $local['lang'];
298 $lang = $GLOBALS['meta']['langue_site'];
300 $lang_select = false
;
301 if (!$GLOBALS['forcer_lang']
302 AND $lang <> $GLOBALS['spip_lang']
308 $styliser = charger_fonction('styliser', 'public');
309 list($skel,$mime_type, $gram, $sourcefile) =
310 $styliser($fond, $id_rubrique_fond, $GLOBALS['spip_lang']);
312 // Charger le squelette en specifiant les langages cibles et source
313 // au cas il faudrait le compiler (source posterieure au resultat)
314 // et appliquer sa fonction principale sur le contexte.
315 // Passer le nom du cache pour produire sa destruction automatique
317 $composer = charger_fonction('composer', 'public');
319 if ($fonc = $composer($skel, $mime_type, $gram, $sourcefile)){
320 spip_timer($a = 'calcul page '.rand(0,1000));
321 $page = $fonc(array('cache' => $cache), array($local));
323 // spip_log: un joli contexte
325 foreach($local as $var => $val)
327 $info[] = "$var='$val'";
332 .' ('.strlen($page['texte']).' octets)'
335 // Si #CACHE{} n'etait pas la, le mettre a $delais
336 if (!isset($page['entetes']['X-Spip-Cache']))
337 $page['entetes']['X-Spip-Cache'] = $GLOBALS['delais'];
342 if ($GLOBALS['var_mode'] == 'debug') {
343 include_spip('public/debug');
344 debug_dumpfile (strlen($page['texte'])?
$page['texte']:" ", $fonc, 'resultat');
346 $page['contexte'] = $local;