squellete2
[aidenligne_francais_universite.git] / ecrire / public / parametrer.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2007 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
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 \***************************************************************************/
12
13 if (!defined("_ECRIRE_INC_VERSION")) return;
14
15 //
16 // Ce fichier calcule une page en executant un squelette.
17 //
18
19 include_spip('base/abstract_sql');
20 include_spip('inc/lang');
21
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;
27 @include ($f);
28 }
29 if (@is_readable(_DIR_TMP."charger_plugins_fonctions.php")){
30 // chargement optimise precompile
31 include_once(_DIR_TMP."charger_plugins_fonctions.php");
32 }
33
34 charger_generer_url(); # pour recuperer_parametres_url
35
36 //
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).
42 //
43 // http://doc.spip.org/@calculer_contexte
44 function calculer_contexte() {
45 global $_GET, $_POST;
46
47 $contexte = array();
48 foreach($_GET as $var => $val) {
49 if (strpos($var, 'var_') !== 0)
50 $contexte[$var] = $val;
51 }
52 foreach($_POST as $var => $val) {
53 if (strpos($var, 'var_') !== 0)
54 $contexte[$var] = $val;
55 }
56
57 if (isset($GLOBALS['date']))
58 $contexte['date'] = $contexte['date_redac'] = normaliser_date($GLOBALS['date']);
59 else
60 $contexte['date'] = $contexte['date_redac'] = date("Y-m-d H:i:s");
61
62 return $contexte;
63 }
64
65 // http://doc.spip.org/@analyse_resultat_skel
66 function analyse_resultat_skel($nom, $cache, $corps) {
67 $headers = array();
68
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
72 if (preg_match_all(
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]))));
79 $headers[$j] = $r[3];
80 }
81
82 return array('texte' => $corps,
83 'squelette' => $nom,
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
88 );
89 }
90
91 // Calcul de la rubrique associee a la requete
92 // (selection de squelette specifique par id_rubrique & lang)
93
94 // http://doc.spip.org/@sql_rubrique_fond
95 function sql_rubrique_fond($contexte) {
96
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"));
102 if ($row['lang'])
103 $lang = $row['lang'];
104 return array ($id, $lang);
105 }
106
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'];
113 if ($row['lang'])
114 $lang = $row['lang'];
115 return array($id_rubrique_fond, $lang);
116 }
117
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'"));
127 if ($row['lang'])
128 $lang = $row['lang'];
129 return array($id_rubrique_fond, $lang);
130 }
131
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'];
138 if ($row['lang'])
139 $lang = $row['lang'];
140 return array($id_rubrique_fond, $lang);
141 }
142 }
143
144 # retourne le chapeau d'un article, et seulement s'il est publie
145
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),
151 "statut='publie'"));
152 return $chapo['chapo'];
153 }
154
155 # retourne le parent d'une rubrique
156
157 // http://doc.spip.org/@sql_parent
158 function sql_parent($id_rubrique) {
159 if (!$id_rubrique = intval($id_rubrique))
160 return 0;
161
162 $id_parent = spip_abstract_fetsel(array('id_parent'),
163 array('spip_rubriques'),
164 array("id_rubrique=" . $id_rubrique));
165
166 if ($id_parent['id_parent']!=$id_rubrique)
167 return intval($id_parent['id_parent']);
168 else
169 spip_log("erreur: la rubrique $id_rubrique est son propre parent");
170 }
171
172 # retourne la profondeur d'une rubrique
173
174 // http://doc.spip.org/@sql_profondeur
175 function sql_profondeur($id) {
176 $n = 0;
177 while ($id) {
178 $n++;
179 $id = sql_parent($id);
180 }
181 return $n;
182 }
183
184 # retourne la rubrique d'un article
185
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'];
192 }
193
194 // http://doc.spip.org/@sql_petitions
195 function sql_petitions($id_article, $table, $id_boucle, $serveur, &$cache) {
196 $retour = spip_abstract_fetsel(
197 array('texte'),
198 array('spip_petitions'),
199 array("id_article=".intval($id_article)),
200 '',array(),'','','',
201 $table, $id_boucle, $serveur);
202
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'] : ' ');
208 }
209
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();
214
215 if (!$id_article) return;
216
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'];
222 }
223
224 return $cache[$id_article];
225 }
226
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)
238
239 # En cas d'erreur process_ins est absent et texte est un tableau de 2 chaines
240
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');
245
246 // distinguer le premier appel des appels par inclusion
247 if (!is_array($local)) {
248 global $contexte;
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;
261 }
262 }
263 $local = $contexte;
264
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);
271 if ($m[0]=='=') {
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('&amp;', '&', $url))
279 . "'); echo '"
280 . addslashes($m[1])
281 . "'?" . ">",
282 'process_ins' => 'php');
283 }
284 }
285 }
286
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;
292
293 // Si inc-urls ou un appel dynamique veut fixer la langue, la recuperer
294 if (isset($local['lang']))
295 $lang = $local['lang'];
296
297 if (!isset($lang))
298 $lang = $GLOBALS['meta']['langue_site'];
299
300 $lang_select = false;
301 if (!$GLOBALS['forcer_lang']
302 AND $lang <> $GLOBALS['spip_lang']
303 ) {
304 lang_select($lang);
305 $lang_select = true;
306 }
307
308 $styliser = charger_fonction('styliser', 'public');
309 list($skel,$mime_type, $gram, $sourcefile) =
310 $styliser($fond, $id_rubrique_fond, $GLOBALS['spip_lang']);
311
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
316
317 $composer = charger_fonction('composer', 'public');
318
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));
322
323 // spip_log: un joli contexte
324 $info = array();
325 foreach($local as $var => $val)
326 if($val)
327 $info[] = "$var='$val'";
328 spip_log("calcul ("
329 .spip_timer($a)
330 .") [$skel] "
331 . join(', ',$info)
332 .' ('.strlen($page['texte']).' octets)'
333 );
334
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'];
338
339 } else
340 $page = array();
341
342 if ($GLOBALS['var_mode'] == 'debug') {
343 include_spip('public/debug');
344 debug_dumpfile (strlen($page['texte'])?$page['texte']:" ", $fonc, 'resultat');
345 }
346 $page['contexte'] = $local;
347
348 if ($lang_select)
349 lang_dselect();
350
351 return $page;
352 }
353
354 ?>