[SPIP] v3.2.1-->v3.2.2
[lhc/web/www.git] / www / ecrire / public / parametrer.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
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')) {
14 return;
15 }
16
17 include_spip('inc/lang');
18
19 // NB: mes_fonctions peut initialiser $dossier_squelettes (old-style)
20 // donc il faut l'inclure "en globals"
21 if ($f = find_in_path('mes_fonctions.php')) {
22 global $dossier_squelettes;
23 include_once(_ROOT_CWD . $f);
24 }
25
26 if (@is_readable(_CACHE_PLUGINS_FCT)) {
27 // chargement optimise precompile
28 include_once(_CACHE_PLUGINS_FCT);
29 }
30 if (test_espace_prive()) {
31 include_spip('inc/filtres_ecrire');
32 }
33
34 # Determine le squelette associe a une requete
35 # et l'applique sur le contexte, le nom du cache et le serveur
36 # en ayant evacue au prealable le cas de la redirection
37 # Retourne un tableau ainsi construit
38 # 'texte' => la page calculee
39 # 'process_ins' => 'html' ou 'php' si presence d'un '< ?php'
40 # 'invalideurs' => les invalideurs de ce cache
41 # 'entetes' => headers http
42 # 'duree' => duree de vie du cache
43 # 'signal' => contexte (les id_* globales)
44
45 # En cas d'erreur process_ins est absent et texte est un tableau de 2 chaines
46
47 // http://code.spip.net/@public_parametrer_dist
48 function public_parametrer_dist($fond, $contexte = '', $cache = '', $connect = '') {
49 static $composer, $styliser, $notes = null;
50 $page = tester_redirection($fond, $contexte, $connect);
51 if ($page) {
52 return $page;
53 }
54
55 if (isset($contexte['lang'])) {
56 $lang = $contexte['lang'];
57 } elseif (!isset($lang)) {
58 $lang = $GLOBALS['meta']['langue_site'];
59 }
60
61 $select = ((!isset($GLOBALS['forcer_lang']) or !$GLOBALS['forcer_lang']) and $lang <> $GLOBALS['spip_lang']);
62 if ($select) {
63 $select = lang_select($lang);
64 }
65
66 $debug = (defined('_VAR_MODE') && _VAR_MODE == 'debug');
67
68 if (!$styliser) {
69 $styliser = charger_fonction('styliser', 'public');
70 }
71 list($skel, $mime_type, $gram, $sourcefile) =
72 $styliser($fond, $contexte, $GLOBALS['spip_lang'], $connect);
73
74 if ($skel) {
75
76 // sauver le nom de l'eventuel squelette en cours d'execution
77 // (recursion possible a cause des modeles)
78 if ($debug) {
79 $courant = @$GLOBALS['debug_objets']['courant'];
80 $GLOBALS['debug_objets']['contexte'][$sourcefile] = $contexte;
81 }
82
83 // charger le squelette en specifiant les langages cibles et source
84 // au cas il faudrait le compiler (source posterieure au resultat)
85
86 if (!$composer) {
87 $composer = charger_fonction('composer', 'public');
88 }
89 $fonc = $composer($skel, $mime_type, $gram, $sourcefile, $connect);
90 } else {
91 $fonc = '';
92 }
93
94 if (!$fonc) { // squelette inconnu (==='') ou faux (===false)
95 $page = $fonc;
96 } else {
97 // Preparer l'appel de la fonction principale du squelette
98
99 spip_timer($a = 'calcul page ' . rand(0, 1000));
100
101 // On cree un marqueur de notes unique lie a cette composition
102 // et on enregistre l'etat courant des globales de notes...
103 if (is_null($notes)) {
104 $notes = charger_fonction('notes', 'inc', true);
105 }
106 if ($notes) {
107 $notes('', 'empiler');
108 }
109
110 // Rajouter d'office ces deux parametres
111 // (mais vaudrait mieux que le compilateur sache le simuler
112 // car ca interdit l'usage de criteres conditionnels dessus).
113 if (!isset($contexte['date'])) {
114 $contexte['date'] = date("Y-m-d H:i:s");
115 $contexte['date_default'] = true;
116 } else {
117 $contexte['date'] = normaliser_date($contexte['date'], true);
118 }
119
120 if (!isset($contexte['date_redac'])) {
121 $contexte['date_redac'] = date("Y-m-d H:i:s");
122 $contexte['date_redac_default'] = true;
123 } else {
124 $contexte['date_redac'] = normaliser_date($contexte['date_redac'], true);
125 }
126
127 // Passer le nom du cache pour produire sa destruction automatique
128 $page = $fonc(array('cache' => $cache), array($contexte));
129
130 // Restituer les globales de notes telles qu'elles etaient avant l'appel
131 // Si l'inclus n'a pas affiche ses notes, tant pis (elles *doivent*
132 // etre dans son resultat, autrement elles ne seraient pas prises en
133 // compte a chaque calcul d'un texte contenant un modele, mais seulement
134 // quand le modele serait calcule, et on aurait des resultats incoherents)
135 if ($notes) {
136 $notes('', 'depiler');
137 }
138
139 // reinjecter en dynamique la pile des notes
140 // si il y a des inclure dynamiques
141 // si la pile n'est pas vide
142 // la generalisation de cette injection permettrait de corriger le point juste au dessus
143 // en faisant remonter les notes a l'incluant (A tester et valider avant application)
144 if ($notes) {
145 $page['notes'] = $notes('', 'sauver_etat');
146 }
147
148 // spip_log: un joli contexte
149 $infos = array();
150 foreach (array_filter($contexte) as $var => $val) {
151 if (is_array($val)) {
152 $val = serialize($val);
153 }
154 if (strlen("$val") > 30) {
155 $val = substr("$val", 0, 27) . '..';
156 }
157 if (strstr($val, ' ')) {
158 $val = "'$val'";
159 }
160 $infos[] = $var . '=' . $val;
161 }
162 $profile = spip_timer($a);
163 spip_log("calcul ($profile) [$skel] "
164 . join(', ', $infos)
165 . ' (' . strlen($page['texte']) . ' octets)');
166
167 if (defined('_CALCUL_PROFILER') AND intval($profile)>_CALCUL_PROFILER){
168 spip_log("calcul ($profile) [$skel] "
169 . join(', ', $infos)
170 .' ('.strlen($page['texte']).' octets) | '.$_SERVER['REQUEST_URI'],"profiler"._LOG_AVERTISSEMENT);
171 }
172
173 if ($debug) {
174 // si c'est ce que demande le debusqueur, lui passer la main
175 $t = strlen($page['texte']) ? $page['texte'] : " ";
176 $GLOBALS['debug_objets']['resultat'][$fonc . 'tout'] = $t;
177 $GLOBALS['debug_objets']['courant'] = $courant;
178 $GLOBALS['debug_objets']['profile'][$sourcefile] = $profile;
179 if ($GLOBALS['debug_objets']['sourcefile']
180 and (_request('var_mode_objet') == $fonc)
181 and (_request('var_mode_affiche') == 'resultat')
182 ) {
183 erreur_squelette();
184 }
185 }
186 // Si #CACHE{} n'etait pas la, le mettre a $delais
187 if (!isset($page['entetes']['X-Spip-Cache'])) {
188 // Dans l'espace prive ou dans un modeles/ on pose un cache 0 par defaut
189 // si aucun #CACHE{} spécifié
190 // le contexte implicite qui conditionne le cache assure qu'on retombe pas sur le meme
191 // entre public et prive
192 if (test_espace_prive() or strncmp($fond, 'modeles/', 8) == 0) {
193 $page['entetes']['X-Spip-Cache'] = 0;
194 } else {
195 $page['entetes']['X-Spip-Cache'] = isset($GLOBALS['delais']) ? $GLOBALS['delais'] : 36000;
196 }
197 }
198
199 $page['contexte'] = $contexte;
200
201 // faire remonter le fichier source
202 static $js_inclus = false;
203 if (defined('_VAR_INCLURE') and _VAR_INCLURE) {
204 $page['sourcefile'] = $sourcefile;
205 $page['texte'] =
206 "<div class='inclure_blocs'><h6>" . $page['sourcefile'] . "</h6>" . $page['texte'] . "</div>"
207 . ($js_inclus ? "" : "<script type='text/javascript'>jQuery(function(){jQuery('.inclure_blocs > h6:first-child').hover(function(){jQuery(this).parent().addClass('hover')},function(){jQuery(this).parent().removeClass('hover')})});</script>");
208 $js_inclus = true;
209 }
210
211 // Si un modele contenait #SESSION, on note l'info dans $page
212 if (isset($GLOBALS['cache_utilise_session'])) {
213 $page['invalideurs']['session'] = $GLOBALS['cache_utilise_session'];
214 unset($GLOBALS['cache_utilise_session']);
215 }
216 }
217
218 if ($select) {
219 lang_select();
220 }
221
222 return $page;
223 }
224
225
226 /**
227 * Si le champ virtuel est non vide c'est une redirection.
228 * avec un eventuel raccourci Spip
229 *
230 * si le raccourci a un titre il sera pris comme corps du 302
231 *
232 * @uses public_tester_redirection_dist()
233 * @param string $fond
234 * @param array $contexte
235 * @param string $connect
236 * @return array|bool
237 */
238 function tester_redirection($fond, $contexte, $connect) {
239 static $tester_redirection = null;
240 if (is_null($tester_redirection)) {
241 $tester_redirection = charger_fonction('tester_redirection', 'public');
242 }
243 return $tester_redirection($fond, $contexte, $connect);
244 }
245
246
247 /**
248 * Si le champ virtuel est non vide c'est une redirection.
249 * avec un eventuel raccourci Spip
250 *
251 * si le raccourci a un titre il sera pris comme corps du 302
252 *
253 * @param string $fond
254 * @param array $contexte
255 * @param string $connect
256 * @return array|bool
257 */
258 function public_tester_redirection_dist($fond, $contexte, $connect) {
259 if ($fond == 'article'
260 and $id_article = intval($contexte['id_article'])
261 ) {
262 include_spip('public/quete'); // pour quete_virtuel et ses dependances
263 $m = quete_virtuel($id_article, $connect);
264 if (strlen($m)) {
265 include_spip('inc/texte');
266 // les navigateurs pataugent si l'URL est vide
267 if ($url = virtuel_redirige($m, true)) {
268 // passer en url absolue car cette redirection pourra
269 // etre utilisee dans un contexte d'url qui change
270 // y compris url arbo
271 $status = 302;
272 if (defined('_STATUS_REDIRECTION_VIRTUEL')) {
273 $status = _STATUS_REDIRECTION_VIRTUEL;
274 }
275 if (!preg_match(',^\w+:,', $url)) {
276 include_spip('inc/filtres_mini');
277 $url = url_absolue($url);
278 }
279 $url = str_replace('&amp;', '&', $url);
280
281 return array(
282 'texte' => "<"
283 . "?php include_spip('inc/headers');redirige_par_entete('"
284 . texte_script($url)
285 . "','',$status);"
286 . "?" . ">",
287 'process_ins' => 'php',
288 'status' => $status
289 );
290 }
291 }
292 }
293
294 return false;
295 }